diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cbb3a13 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.rpm +*.log +*spec-20* +*.tar.gz diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4eaf6e8 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +# Makefile for source rpm: smeserver-phpsysinfo +# $Id: Makefile,v 1.1 2020/10/24 08:32:48 brianr Exp $ +NAME := smeserver-phpsysinfo +SPECFILE = $(firstword $(wildcard *.spec)) + +define find-makefile-common +for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done +endef + +MAKEFILE_COMMON := $(shell $(find-makefile-common)) + +ifeq ($(MAKEFILE_COMMON),) +# attept a checkout +define checkout-makefile-common +test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2 +endef + +MAKEFILE_COMMON := $(shell $(checkout-makefile-common)) +endif + +include $(MAKEFILE_COMMON) diff --git a/README.md b/README.md index 34adc87..88feb0d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ -# smeserver-phpsysinfo +# smeserver-phpsysinfo -SMEServer Koozali developed git repo for smeserver-phpsysinfo smecontribs \ No newline at end of file +SMEServer Koozali developed git repo for smeserver-phpsysinfo smecontribs + +## Wiki +
https://wiki.koozali.org/Phpsysinfo +
https://wiki.koozali.org/Phpsysinfo/fr + +## Bugzilla +Show list of outstanding bugs: [here](https://bugs.koozali.org/buglist.cgi?component=smeserver-phpsysinfo&product=SME%20Contribs&query_format=advanced&limit=0&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=CONFIRMED) + +## Description + +
*This description has been generated by an LLM AI system and cannot be relied on to be fully correct.* +*Once it has been checked, then this comment will be deleted* +
diff --git a/additional/CHANGELOG.git b/additional/CHANGELOG.git new file mode 100644 index 0000000..3e15765 --- /dev/null +++ b/additional/CHANGELOG.git @@ -0,0 +1,57 @@ +commit 6a9efeb32f280ce307491450e6cd876c547d2a76 +Author: Stephane de Labrusse +Date: Tue Sep 22 08:07:37 2015 +0200 + + * Wed Sep 22 2015 stephane de Labrusse 3.2.3-1.sme + - Upgrade to upstream 3.2.3 + - Require hddtemp lm_sensors + +commit f4051d7cf72ec48f88c2dfdcec84fb9ead4edf72 +Author: Stephane de Labrusse +Date: Sun Jun 22 01:32:25 2014 +0200 + + - added a menu in the administration panel of server-manager + +commit 2bea40307fdfe6724aeb2cdc66ff3dc7c98ad21d +Author: Stephane de Labrusse +Date: Sun Jun 22 00:29:20 2014 +0200 + + createlinks and root/etc/e-smith/web/functions/phpsysinfo + +commit 8cf00cc167fba208c86ad0b1054218d65427859a +Author: Stephane de Labrusse +Date: Sun Jun 22 00:25:29 2014 +0200 + + createlinks and root/etc/e-smith/web/functions/phpsysinfo + +commit 2c63503593c13c7b6bccbba7af462853831ccc01 +Author: Stephane de Labrusse +Date: Sun Jun 22 00:22:10 2014 +0200 + + createlinks and root/etc/e-smith/web/functions/phpsysinfo + +commit 41a595743e45b9421c2b0fb4b2a87ba904cbddda +Author: Stephane de Labrusse +Date: Sun Jun 22 00:02:58 2014 +0200 + + added backup of phpsysinfo.ini + +commit 846f98c82d8434650addf9136978946952a68b0b +Author: Stephane de Labrusse +Date: Sat Jun 21 23:57:35 2014 +0200 + + added backup of phpsysinfo.ini + +commit aaff0ff14a86cb55a4a3b18d377e62644be32eed +Author: Stephane de Labrusse +Date: Sat Jun 21 19:28:45 2014 +0200 + + * Sat Jun 21 2014 stephane de Labrusse 3.1.13-1.sme + - Initial release to sme9 + - upgrade of phpsysinfo to 3.1.13 https://github.com/phpsysinfo/phpsysinfo/releases/tag/v3.1.13 + +commit 3de6c405b6b998ba4af41c1ab78b445d1427ef9d +Author: Stephane de Labrusse +Date: Sat Jun 21 19:19:49 2014 +0200 + + first commit to SME Server 9 diff --git a/additional/README.md b/additional/README.md new file mode 100644 index 0000000..75a8b35 --- /dev/null +++ b/additional/README.md @@ -0,0 +1 @@ +smeserver-phpsysinfo is a contrib for SME Server, a Linux distro oriented server. see http://wiki.contribs.org diff --git a/additional/smeserver-phpsysinfo.spec b/additional/smeserver-phpsysinfo.spec new file mode 100644 index 0000000..4b26681 --- /dev/null +++ b/additional/smeserver-phpsysinfo.spec @@ -0,0 +1,118 @@ +# $Id: smeserver-phpsysinfo.spec,v 1.1 2013/03/03 21:49:49 unnilennium Exp $ +# Authority: darrellmay +# Name: Darrell May + +Summary: phpSysInfo for SME Server +%define name smeserver-phpsysinfo +Name: %{name} +%define version 3.2.3 +%define release 1 +Version: %{version} +Release: %{release}%{?dist} +License: GPL +Group: SME/addon +Source: %{name}-%{version}.tar.gz +URL: http://phpsysinfo.sourceforge.net +BuildRoot: /var/tmp/%{name}-%{version}-%{release}-buildroot +BuildArchitectures: noarch +Requires: smeserver-release >= 9.0 +Requires: hddtemp lm_sensors +BuildRequires: e-smith-devtools +AutoReqProv: no + +%description +%name is an implementation of phpSysInfo on SME Server. +Access with admin login credentials via https://yourdomain/phpsysinfo + +%changelog +* Wed Sep 22 2015 stephane de Labrusse 3.2.3-1.sme +- Upgrade to upstream 3.2.3 +- Require hddtemp lm_sensors + +* Sat Jun 21 2014 stephane de Labrusse 3.1.13-1.sme +- Initial release to sme9 +- upgrade of phpsysinfo to 3.1.13 https://github.com/phpsysinfo/phpsysinfo/releases/tag/v3.1.13 +- added a menu in the administration panel of server-manager + +* Mon Apr 21 2008 Shad L. Lords +- Prep for import into buildsys +- Clean up spec + +* Fri Oct 19 2007 Darrell May +- accounts and configuration db phpsysinfo defaults added +- default access restricted to private (private|public) +- phpsysinfo-2.5.4 +- [2.5.4-0dmay] +* Mon Apr 09 2007 Darrell May +- [2.5.3-1dmay] +* Sun Apr 01 2007 Darrell May +- phpsysinfo-2.5.3 +- [2.5.3-0dmay] +* Tue Jan 02 2007 Darrell May +- phpsysinfo-2.5.2 +- [2.5.2-0] +* Fri Aug 04 2006 Darrell May +- phpsysinfo-2.5.2-rc3 +- [2.5.2-rc3] +* Wed Dec 14 2005 Darrell May +- phpsysinfo-2.5 +- [2.5-0] +* Fri Apr 22 2005 Darrell May +- added support for SME Server 7.x +- [2.3-2] +* Mon Nov 15 2004 Darrell May +- updated to release 2.3 +- renamed smeserver-phpsysinfo +- updated includes/os/class.Linux.inc.php to recognize SME Server +- [2.3-1] +* Sat Jun 29 2002 Darrell May +- updated to release 2.1 +- [2.1-1] +* Sun Mar 10 2002 Darrell May +- updated to release 2.0 +- [2.0-1] +* Sun Mar 10 2002 Darrell May +- changed rights/ownership to tighten security +- [1.9-2] +* Tue Mar 05 2002 Darrell May +- changed %post/postun to graceful +- [1.9-1] +* Mon Jan 21 2002 Darrell May +- updated to version 1.9 +- [1.9-0] +* Wed Oct 31 2001 Darrell May +- updated to version 1.8 +- [1.8-0] +* Sun Sep 23 2001 Darrell May +- name change +* Thu May 30 2001 Darrell May +- 2.1.0-1 +- Original version + +%prep +%setup + +%build +perl createlinks + + +%install +/bin/rm -rf $RPM_BUILD_ROOT +(cd root ; /usr/bin/find . -depth -print | /bin/cpio -dump $RPM_BUILD_ROOT) +/bin/rm -f %{name}-%{version}-filelist +/sbin/e-smith/genfilelist $RPM_BUILD_ROOT > %{name}-%{version}-filelist + +%clean +/bin/rm -rf $RPM_BUILD_ROOT + +%files -f %{name}-%{version}-filelist +%defattr(-,root,root) + +%pre +if [[ -f /opt/phpsysinfo/phpsysinfo.ini ]]; then + /bin/cp /opt/phpsysinfo/phpsysinfo.ini /opt/phpsysinfo/phpsysinfo.ini-$(date +"%H:%M-%b-%d-%Y") +fi +%post +if ! [[ -f /opt/phpsysinfo/phpsysinfo.ini ]]; then + cp /opt/phpsysinfo/phpsysinfo.ini.new /opt/phpsysinfo/phpsysinfo.ini +fi diff --git a/contriborbase b/contriborbase new file mode 100644 index 0000000..9b7fd51 --- /dev/null +++ b/contriborbase @@ -0,0 +1 @@ +contribs10 diff --git a/createlinks b/createlinks new file mode 100644 index 0000000..0a0b4dc --- /dev/null +++ b/createlinks @@ -0,0 +1,25 @@ +#! /usr/bin/perl -w +use esmith::Build::CreateLinks qw(:all); +# our event specific for updating with yum without reboot +$event = 'smeserver-phpsysinfo-update'; +#add here the path to your templates needed to expand +#see the /etc/systemd/system-preset/49-koozali.preset should be present for systemd integration on all you yum update event + +foreach my $file (qw( + /etc/systemd/system-preset/49-koozali.preset + /etc/httpd/conf/httpd.conf +)) +{ + templates2events( $file, $event ); +} +#action needed in case we have a systemd unit +event_link('systemd-default', $event, '10'); +event_link('systemd-reload', $event, '50'); +#action specific to this package +#event_link('action', $event, '30'); +#services we need to restart +safe_symlink('restart',"root/etc/e-smith/events/$event/services2adjust/httpd-e-smith"); +#and Server Manager panel link +#panel_link('somefunction', 'manager'); +# Links for the panel +panel_link("phpsysinfo", "manager"); diff --git a/root/etc/e-smith/db/accounts/defaults/phpsysinfo/type b/root/etc/e-smith/db/accounts/defaults/phpsysinfo/type new file mode 100644 index 0000000..123f60c --- /dev/null +++ b/root/etc/e-smith/db/accounts/defaults/phpsysinfo/type @@ -0,0 +1 @@ +reserved diff --git a/root/etc/e-smith/db/configuration/defaults/phpsysinfo/access b/root/etc/e-smith/db/configuration/defaults/phpsysinfo/access new file mode 100644 index 0000000..3e18ebf --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/phpsysinfo/access @@ -0,0 +1 @@ +private diff --git a/root/etc/e-smith/db/configuration/defaults/phpsysinfo/type b/root/etc/e-smith/db/configuration/defaults/phpsysinfo/type new file mode 100644 index 0000000..f92f363 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/phpsysinfo/type @@ -0,0 +1 @@ +configuration diff --git a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias new file mode 100644 index 0000000..86a6212 --- /dev/null +++ b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/86PhpsysinfoAlias @@ -0,0 +1,23 @@ + +# phpsysinfo +Alias /phpsysinfo /opt/phpsysinfo + + SSLRequireSSL + Options -Indexes + AuthName "phpSysInfo" + AuthBasicProvider external + AuthType Basic + AuthExternal pwauth + + + Require user admin + Require {(($phpmyadmin{access} || 'private' ) eq "public" ) ? "all granted": "ip $localAccess $externalSSLAccess";} + + + AddType application/x-httpd-php .php .php3 + + SetHandler "proxy:unix:/var/run/php-fpm/php.sock|fcgi://localhost" + + + + diff --git a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/30PhpsysinfoAlias b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/30PhpsysinfoAlias new file mode 100644 index 0000000..6686e79 --- /dev/null +++ b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/30PhpsysinfoAlias @@ -0,0 +1,8 @@ +{ + $haveSSL = (exists ${modSSL}{status} and ${modSSL}{status} eq "enabled") ? 'yes' : 'no'; + + if (($port eq "80") && ($haveSSL eq 'yes')) + { + $OUT .= " RewriteRule ^/phpsysinfo(/.*|\$) https://%{HTTP_HOST}/phpsysinfo\$1 [L,R]\n"; + } +} diff --git a/root/etc/e-smith/web/functions/phpsysinfo b/root/etc/e-smith/web/functions/phpsysinfo new file mode 100644 index 0000000..aa42fc1 --- /dev/null +++ b/root/etc/e-smith/web/functions/phpsysinfo @@ -0,0 +1,30 @@ +#!/usr/bin/perl +#---------------------------------------------------------------------- +# heading : Administration +# description : PhpSysInfo +# navigation : 4000 4200 +#---------------------------------------------------------------------- + +use strict; +use CGI':all'; +use CGI::Carp qw(fatalsToBrowser); + + +BEGIN +{ + $ENV {'PATH'} = '/bin:/usr/bin:/sbin'; + $ENV {'SHELL'} = '/bin/bash'; + delete $ENV {'ENV'}; +} + + +my $q = new CGI; +my $content="0; url=https://".$ENV {'HTTP_X_FORWARDED_HOST'}."/phpsysinfo"; +$q->default_dtd('-//W3C//DTD XHTML 1.0 Transitional//EN'); + +print $q->header ('text/html'); +print $q->start_html (-head=>meta({-http_equiv=>'refresh', -content=>$content})); + + + +print $q->end_html; diff --git a/root/opt/phpsysinfo/.gitignore b/root/opt/phpsysinfo/.gitignore new file mode 100644 index 0000000..dbb8d5e --- /dev/null +++ b/root/opt/phpsysinfo/.gitignore @@ -0,0 +1 @@ +phpsysinfo.ini diff --git a/root/opt/phpsysinfo/.htaccess b/root/opt/phpsysinfo/.htaccess new file mode 100644 index 0000000..9c15814 --- /dev/null +++ b/root/opt/phpsysinfo/.htaccess @@ -0,0 +1,11 @@ + +# Deny all requests from Apache 2.0-2.2 + + order deny,allow + deny from all + +# Deny all requests from Apache 2.4+ + + Require all granted + + diff --git a/root/opt/phpsysinfo/.travis.yml b/root/opt/phpsysinfo/.travis.yml new file mode 100644 index 0000000..9ed9bd0 --- /dev/null +++ b/root/opt/phpsysinfo/.travis.yml @@ -0,0 +1,18 @@ +language: php + +php: + - 5.2 + - 5.3 + - 5.4 + - 5.5 + - 5.6 + +script: for i in `find . -name "*.php"`; do php -l $i; done; + +branches: + only: + - "master" + - "stable" + +notifications: + email: false diff --git a/root/opt/phpsysinfo/CHANGELOG.md b/root/opt/phpsysinfo/CHANGELOG.md new file mode 100644 index 0000000..0451ba5 --- /dev/null +++ b/root/opt/phpsysinfo/CHANGELOG.md @@ -0,0 +1,255 @@ +Changelog of phpSysInfo +======================= + +http://phpsysinfo.sourceforge.net/ + +phpSysInfo 3.2.3 +---------------- + - [UPD] jQuery 2.1.4 and jQuery 1.11.3 + - [UPD] bootstrap 3.3.5 + + - [NEW] I2C devices list on Android and Linux + + - [ADD] blue template + +phpSysInfo 3.2.2 +---------------- + - [UPD] bootstrap 3.3.4 + + - [NEW] Thunderbolt (TB) devices list on Darwin + + - [ADD] cleansyn template + - [ADD] PS plugin - support for Android + - [ADD] PS plugin - SHOW_KTHREADD_EXPANDED option + - [ADD] Qubes and HandyLinux to detected distros + + - [FIX] PS plugin - fixed display of the processes tree + +phpSysInfo 3.2.1 +---------------- + - [UPD] bootstrap 3.3.2 + + - [NEW] REFRESH parameter also for frontend "bootstrap" + + - [ADD] pfSense to detected distros + + - [FIX] Percentage memory usage + +phpSysInfo 3.2.0 +---------------- + - [UPD] jQuery 2.1.3 and jQuery 1.11.2 + + - [NEW] Frontend "bootstrap" with Bootstrap3 and Transparency (JSON) + + - [ADD] Catalan Translation ca.xml + - [ADD] Mer (core of Sailfish OS) and Tizen to detected distros + - [ADD] ThermalZone sensor support for Linux and Android + - [ADD] Temperature, voltage and current sensor for Banana Pi + + - [UPD] German Translation de.xml + +phpSysInfo 3.1.17 +---------------- + + - [UPD] BAT plugin - capacity unit, cycle count, FreeBSD support + - [UPD] Brazilian Portuguese Translation pt-br.xml + + - [ADD] Show the number of processes on Haiku + - [ADD] ThermalZone sensor support for WinNT + - [ADD] Tanglu to detected distros + - [ADD] Android and OS X version name + + - [FIX] Fixed display of treetables + +phpSysInfo 3.1.16 +---------------- + + - [ADD] Show the number of processes + - [ADD] Lunar and 4MLinux to detected distros + +phpSysInfo 3.1.15 +---------------- + + - [ADD] CoreOS and Pisi Linux to detected distros + - [ADD] pmset - UPS support on Darwin (thanks to pelletierr) + - [ADD] lspci support on Darwin + - [ADD] SHOW_CPULIST_EXPANDED option + - [ADD] lxc/docker detection on Linux + - [ADD] ability to hide all disks and all network interfaces + + - [FIX] Small CSS fix + + - [UPD] Memory informations on Darwin systems + - [UPD] BAT plugin - Darwin support + +phpSysInfo 3.1.14 +---------------- + + - [ADD] FreeIPMI sensor program support + - [ADD] IPMIutil sensor program support + - [ADD] PowerSoftPlus (EVER) UPS program support + - [ADD] Line frequency for the UPS info + - [ADD] SENSOR_EVENTS option - show events of sensors + - [ADD] HIDE_RAID_DEVICES option for plugins MDStatus and DMRaid - list of RAID devices to hide + - [ADD] idash template + +phpSysInfo 3.1.13 +---------------- + + - [UPD] jQuery 2.1.1 and jQuery 1.11.1 + - [UPD] Romanian Translation ro.xml + + - [ADD] SHOW_CPUINFO_EXPANDED option + - [ADD] Machine detection on WINNT, Linux, Android and Darwin systems + +phpSysInfo 3.1.12 +---------------- + + - [ADD] GoboLinux, UltimateEdition, BOSS, Canaima, VortexBox, KaOS and NixOS to detected distros + - [ADD] OpenHardwareMonitor sensor program support + - [ADD] Possibility to define multiple UPS_PROGRAM + - [ADD] UPS_NUT_LIST option + + - [FIX] Fixed incorrect network usage on FreeBSD + + - [UPD] SMART plugin - Smartctl --device option value setting method + +phpSysInfo 3.1.11 +---------------- + + - [ADD] Add Access-Control-Allow-Origin on XML (JSON) interface for Ajax Load PR#47 + - [ADD] Generations Linux and SliTaz to detected distros + - [ADD] IPMI and LMSensors currents information + - [ADD] Plugin IPMIInfo - added powers and currents values + - [ADD] Partial support of QNX + + - [FIX] Reduce execution time on Linux systems when showing load average PR#47 + +phpSysInfo 3.1.10 +---------------- + + - [ADD] Zenwalk and Raspbian to detected distros + + - [FIX] /etc/os-release Linux distro detection + +phpSysInfo 3.1.9 +---------------- + + - [NEW] New plugin DMRaid - software raid status + + - [ADD] Calculate, Tails, SMEServer, Semplice, SolydXK, Parsix, RedFlag, Amazon, Korora, OpenMandriva, SteamOS, ROSA Enterprise Server and ROSA Desktop Fresh to detected distros + + - [UPD] Rebuilding of the Linux distribution detection + - [UPD] jQuery 2.1.0 and jQuery 1.11.0 + +phpSysInfo 3.1.8 +---------------- + + - [ADD] Add printers messages in the XML output + - [ADD] PSStatus plugin - added optional regular expression search in the process name + - [ADD] RedHatEnterpriseClient distro icon #40 + - [ADD] Hebrew Translation he.xml + + - [FIX] BAT plugin - fix for old and new kernel /proc/acpi and /sys/class/power_supply + + - [UPD] LMSensors name for Mac hardware sensors + +phpSysInfo 3.1.7 +---------------- + + - [ADD] Ksplice support for Linux + - [ADD] Show CPU frequency max and min for Darwin (Mac OS X) + - [ADD] Show System Language and Code Page on Darwin (Mac OS X) + - [ADD] Show network interfaces infos for Minix and SunOS + - [ADD] SMS, gNewSense and Vector to detected distros + - [ADD] LMSensors power information + - [ADD] Battery installation date for the UPS info + + - [UPD] Network interfaces infos and filesystems infos for FreeBSD + - [UPD] Updated support of SunOS + - [UPD] Memory informations on Darwin systems + - [UPD] BAT plugin - updated Linux support + - [UPD] Updated HWSensors - OpenBSD sensor program + +phpSysInfo 3.1.6 +---------------- + + - [ADD] Porteus, Peppermint, Manjaro, Netrunner and Salix to detected distros + - [ADD] Show CPU frequency max for WINNT + - [ADD] Show network interfaces infos for Darwin (Mac OS X) + + - [UPD] SNMPPInfo plugin, ink level for some of the data + - [UPD] jQuery 2.0.3 and jQuery 1.10.2 + - [UPD] Russian Translation ru.xml + - [UPD] BAT plugin - WINNT support + + - [SEC] Fix JSONP + +phpSysInfo 3.1.5 +---------------- + + - [ADD] Possibility to define multiple SENSOR_PROGRAM + - [ADD] Added display of temperature and fan speed for IPMI sensor program + - [ADD] openSUSE and Eisfair to detected distros + - [ADD] Portuguese Translation pt-pt.xml + + - [FIX] Fixed incorrect display of the minimum fan speed + - [FIX] Fix recovery detection of RAID arrays on debian systems #18 + +phpSysInfo 3.1.4 +---------------- + + - [ADD] Option for reading the results of functions executeProgram() and rfts() from log + - [ADD] Show CPU frequency max and min for variable speed processors for Linux and Android + - [ADD] Filesystem usage warning on defined threshold FS_USAGE_THRESHOLD + + - [UPD] BAT plugin - added temperature, condition and type of battery, Android support + - [UPD] jQuery 2.0.2 and jQuery 1.10.1 + +phpSysInfo 3.1.3 +---------------- + + - [ADD] IPFire, Sabayon, PearOS, ClearOS, Frugalware, Fuduntu, Foresight, Tinycore, ALT Linux, ROSA Desktop Marathon and RedHatEnterpriseServer to detected distros + + - [UPD] Added "username" to filtered mount credentials + - [UPD] jQuery 2.0 coexistent with jQuery 1.9.1 for old Internet Explorer browser versions (IE 6/7/8) + + - [FIX] proc_open() malfunction on some PHP for Android by replacing by popen() + - [FIX] Run php-cs-fixer on php files (PSR-2 fixer) + +phpSysInfo 3.1.2 +---------------- + + - [ADD] Tempsensor and CPU frequency for Raspberry Pi (thanks to hawkeyexp) + - [ADD] Linaro to detected distros + - [ADD] Option for logging of functions executeProgram() and rfts() + - [ADD] Add support of JSONP + + - [FIX] Incorrect display of chunk size for the plugin mdstatus for some results + +phpSysInfo 3.1.1 +---------------- + + - [ADD] SolusOS, Deepin and antiX to detected distros + - [ADD] Simplified Chinese translation + + - [UPD] jQuery 1.9.1 + +phpSysInfo 3.1.0 +---------------- + + - [NEW] Configuration moved from config.php and subdirs of "plugins" to one file phpsysinfo.ini + + - [ADD] Turbolinux, Oracle Linux, CloudLinux, PCLinuxOS, StartOS, Trisquel, CRUX, Slax, Pear, Android, Zorin and elementary OS to detected distros + - [ADD] Show System Language and Code Page on Linux, Haiku and WINNT + - [ADD] Minor support of ReactOS + - [ADD] apcupsd-cgi support (thanks to duhast) + + - [UPD] Plugin ipmi renamed to IPMIInfo and Update-Notifier to UpdateNotifier (to avoid name conflicts) + - [UPD] Case-insensitive for most of parameters + - [UPD] Detection of Mac OS X and Linux distribution + - [UPD] CPU detection on Mac OS X + + - [FIX] Fixed UTF8 encoding for Linux + - [FIX] SMART plugin doesn't display for some results + - [FIX] Incorrect display of mountpoint on Mac OS X diff --git a/root/opt/phpsysinfo/COPYING b/root/opt/phpsysinfo/COPYING new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/root/opt/phpsysinfo/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/root/opt/phpsysinfo/Dockerfile b/root/opt/phpsysinfo/Dockerfile new file mode 100644 index 0000000..5b62375 --- /dev/null +++ b/root/opt/phpsysinfo/Dockerfile @@ -0,0 +1,26 @@ +# phpSysInfo +# VERSION 2 + +FROM ubuntu:14.04 + +MAINTAINER phpSysInfo + +# Update sources +RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main universe" > /etc/apt/sources.list +RUN apt-get update + +RUN apt-get install -y apache2 php5 git pciutils + +RUN git clone https://github.com/phpsysinfo/phpsysinfo.git /var/www/html/phpsysinfo +#RUN cp /var/www/html/phpsysinfo/phpsysinfo.ini.new /var/www/html/phpsysinfo/phpsysinfo.ini +RUN cat /var/www/html/phpsysinfo/phpsysinfo.ini.new | sed 's/^LOAD_BAR=false/LOAD_BAR=true/' >/var/www/html/phpsysinfo/phpsysinfo.ini + +ENV APACHE_RUN_USER www-data +ENV APACHE_RUN_GROUP www-data +ENV APACHE_LOG_DIR /var/log/apache2 +ENV APACHE_LOCK_DIR /var/lock/apache2 +ENV APACHE_PID_FILE /var/run/apache2/apache2.pid + +CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"] + +EXPOSE 80 diff --git a/root/opt/phpsysinfo/README.md b/root/opt/phpsysinfo/README.md new file mode 100644 index 0000000..8f342bb --- /dev/null +++ b/root/opt/phpsysinfo/README.md @@ -0,0 +1,121 @@ +phpSysInfo +============== + +* Copyright (c), 1999-2008, Uriah Welcome (precision@users.sf.net) +* Copyright (c), 1999-2009, Michael Cramer (bigmichi1@users.sf.net) +* Copyright (c), 2007-2008, Audun Larsen (xqus@users.sf.net) +* Copyright (c), 2007-2015, Erkan Valentin +* Copyright (c), 2009-2015, Mieczyslaw Nalewaj (namiltd@users.sf.net) +* Copyright (c), 2010-2012, Damien Roth (iysaak@users.sf.net) + + + +CURRENT TESTED PLATFORMS +------------------------ + +- Linux 2.6.x +- FreeBSD 7.x +- OpenBSD 2.8+ +- NetBSD +- DragonFly +- HP-UX +- Darwin/OSX +- Windows 2000 / 2003 / XP / Vista / 7 / 8 / 8.1 / 10 +- Android +- > PHP 5.2 or later + - With PCRE, XML, XSL, MBString and SimpleXML extension. + +####Platforms currently in progress: +- Haiku +- Minix +- SunOS +- ReactOS +- IBM AIX +- QNX + +If your platform is not here try checking out the mailing list archives or +the message boards on SourceForge. + +INSTALLATION AND CONFIGURATION +------------------------------ + +####Typical installation + +Just decompress and untar the source (which you should have done by now, +if you're reading this...), into your webserver's document root. + +There is a configuration file called phpsysinfo.ini.new. If this a brand new +installation, you should copy this file to phpsysinfo.ini and edit it. + +- make sure your `php.ini` file's `include_path` entry contains "." +- make sure your `php.ini` has `safe_mode` set to 'off'. + +phpSysInfo require php-xml extension. + +Please keep in the mind that because phpSysInfo requires access to many +files in `/proc` and other system binary you **MUST DISABLE** `php's safe_mode`. +Please see the PHP documentation for information on how you +can do this. + +That's it. Restart your webserver (if you changed php.ini), and voila. + +####Docker container installation + +- sudo docker build -t phpsysinfo github.com/phpsysinfo/phpsysinfo +- sudo docker run -i -p 8080:80 -t phpsysinfo +- go to http://localhost:8080/phpsysinfo/ + +KNOWN PROBLEMS +-------------- + +- phpSysInfo is not compatible with SELinux Systems +- small bug under FreeBSD with memory reporting + +PLATFORM SPECIFIC ISSUES +------------------------ + +####Windows with IIS + On Windows systems we get our informations through the WMI interface. + If you run phpSysInfo on the IIS webserver, phpSysInfo will not connect + to the WMI interface for security reasons. At this point you MUST set + an authentication mechanism for the directory in the IIS admin + interface for the directory where phpSysInfo is installed. Then you + will be asked for an user and a password when opening the page. At this + point it is necassary to log in with an user that will be able to + connect to the WMI interface. If you use the wrong user and/or password + you might get an "ACCESS DENIED ERROR". + +SENSOR RELATED INFORMATION +--------------------------- + +####MBM5 + Make sure you set MBM5 Interval Logging to csv and to the data + directory of phpSysInfo. The file must be called MBM5. Also make sure + MBM5 doesn't add symbols to the values. This is a Quick MBM5 log parser, + need more csv logs to make it better. + +WHAT TO DO IF IT DOESN'T WORK +----------------------------- + +First make sure you've read this file completely, especially the +"INSTALLATION AND CONFIGURATION" section. If it still doesn't work then +you can: + +Submit a bug on SourceForge (preferred) (http://sourceforge.net/projects/phpsysinfo/) + +Ask for help in the forum (http://sourceforge.net/projects/phpsysinfo/) + +***!! If you have any problems, please set `DEBUG` to true in `phpsysinfo.ini` +and include any error messages in your bug report / help request !!*** + +OTHER NOTES +----------- + +If you have a great idea or want to help out, just drop by the project +page at SourceForge (http://sourceforge.net/projects/phpsysinfo/). + +LICENSING +--------- + +This program and all associated files are released under the GNU Public +License, see [COPYING](COPYING) for details. diff --git a/root/opt/phpsysinfo/README_PLUGIN.md b/root/opt/phpsysinfo/README_PLUGIN.md new file mode 100644 index 0000000..26140ac --- /dev/null +++ b/root/opt/phpsysinfo/README_PLUGIN.md @@ -0,0 +1,134 @@ +phpSysInfo 3.1 - http://phpsysinfo.sourceforge.net/ +=================================================== + +Document written by Michael Cramer (bigmichi1 at sourceforge.net) + +!!Please read if you want to develop a plugin to understand our plugin system!! + + +Plugins +------- + +Beginning with phpSysInfo 3.0, phpSysInfo can be extended by Plugins. So here is +a description that a developer of a plugin must take care of. Plugins can be +enabled through the `phpsysinfo.ini` in the PLUGINS variable. The name of the +plugin is essential for the function of the plugin system. Lets say you write a +plugin with the name 'hdd_stats', then this name is added to the PLUGINS +variable in `phpsysinfo.ini`. And this is also then the name which is everywhere in +the plugin system used, like creating the object, locate the needed files and +so on. + +So if the name is now specified, phpSysInfo needs a special directory structure +to find the needed files. The directory structure for the example `hdd_stats` +plugin can be seen here: + +``` +-+ phpSysInfo root + | + +---+ plugins (directory in that plugins are installed) + | | + | +---+ hdd_stats (the real plugin directory, must have the same name like + | | | the plugin named in PLUGINS, else it won't be found) + | | | + | | +---+ js (directory in which the needed JavaScript file is located, + | | | | to generate the html output out of the xml) + | | | # hdd_stats.js (the js file must have the same name, like the + | | | plugin in PSI_PLUGINS with the extension js) + | | +---+ css (directory in which the needed style sheet information are + | | | | located, can exists, but it's up to the author) + | | | # hdd_stats.css (the css file must have the same name, like the + | | | plugin in PSI_PLUGINS with the extension css) + | | +---+ lang (directory where translations for the plugin are located) + | | | | + | | | # en.xml (at least an english translation file must exist) + | | | + | | # class.hdd_stats.inc.php (this is the core file of the plugin, + | | name must consists of 'class' + + | | name from PSI_PLUGINS + '.inc.php') +``` + +other files or directorys can be included in the plugin directory, but then +its up to the developer to include them in the plugin. So it might be possible +to have a 'gfx' directory in which some pics are located that are used in the +output. + +If the directory structure is build up, then it's time to start programming. + +Files +----- + +An example implementation is the mdstat plugin, which is shipped with phpSysInfo + +* en.xml - at least this file must exist to get the translation working, and the + the first entry in this file is normally the headline of the plugin. + So one translation migth exists everytime. Other translation files + are also in the same directory like the `en.xml` file. + The id's specified in the translation file SHOULD have the following + look `plugin_hdd_status_001`. First we say that this is a plugin + translation, then the name of plugin and at last a increasing number + for each translation. Please create your id's in that way, so that + other plugins don't redefine your translations. At the time of writing + this, there is no check to verify the id's, so be carfull. + +* hdd_stats.css - here can all custom style sheet informations written down. The + names of the id's and classes SHOULD also begin, like the translation + id's, with `'plugin_' + pluginname`. If thats not the case it might be + possible that another plugin is overwriting your css definitions. + +* class.hdd_stats.inc.php - this file MUST include a class with the plugin name + and also this class MUST extend the 'psi_plugin' class. A check that + such a class exist and also extends 'psi_plugin' will be included in + the near future. And if the check fails the plugin won't be loaded. + The psi_plugin class checks the existens of the js and the en.xml + files. Also an extra configuration of the plugin is loaded + automatically from `phpsysinfo.ini`, if present. + Through the extension of the psi_plugin class there is a need to + include at least two public function. These are the execute() function + and the xml() function. Other functions can be exist, that depends on + the plugin needs or the author of the class. The execute() function is + called to get the required information that should be later included + in the xml file. The xml() function is called when the xml output + should be generated. This function must return a simplexml object. This + object is then included in another xml at the right position or as a + standalone xml. So there is no need to do some special things, only + create a xml object for the plugin. + +* hdd_stats.js - this file is called when the page is loaded. A block for the + plugin is automatically created. This one is a div container with the + id `'plugin_'+ pluginname ("plugin_hdd_stats")`. The entire output must be + placed in that container. + There is a helper function for creating the headline: buildBlock() that + can be called. This function returns a string with the html code of the + headline, this code can then be appended to the plugin block. The + generated headline can provide a reload icon for an ajax request. Only + the click action of that icon must be created. The id of this icon is + `'reload_' + pluginname + 'Table' ("reload_hdd_statsTable")`. + Everything that then is done to get the html output out of the xml is up + to the author. + To get the xml document the ajax request url is `'xml.php?plugin=' + + pluginname (xml.php?plugin=hdd_stats)`. This xml includes only the xml + from the plugin nothing more. + The last two executed commands should/must be the translation call and + the unhide of the filled div container. + The translation function that needs to be called is named + plugin_traslate() with one argument, that is the pluginname like in + `PSI_PLUGINS (plugin_translate("hdd_stats");)`. + To unhide the filled container call the .show() function of it. + `$("plugin_" + pluginname).show() ($("plugin_hdd_stat").show())`. + +FAQ +--- + +Q: Is the plugin system ready to use? + +A: It can be used, but it might change slightly in the future, if there are some + special needs. + +SUGGESTION +---------- + +If anybody out there has some suggestions in improving the plugin system let us +know. We are looking forward to get some feedback, suggestions and patches and +more. Feel free to contact us on our website: http://phpsysinfo.sourceforge.net. + +$Id: README_PLUGIN 463 2011-04-19 17:34:41Z namiltd $ diff --git a/root/opt/phpsysinfo/composer.json b/root/opt/phpsysinfo/composer.json new file mode 100644 index 0000000..d839520 --- /dev/null +++ b/root/opt/phpsysinfo/composer.json @@ -0,0 +1,18 @@ +{ + "name": "phpsysinfo/phpsysinfo", + "description": "phpSysInfo is a customizable PHP Script that parses /proc, and formats information nicely. It will display information about system facts like Uptime, CPU, Memory, PCI devices, SCSI devices, IDE devices, Network adapters, Disk usage, and more.", + "license": "GPL", + "homepage": "http://phpsysinfo.github.io/phpsysinfo/", + "require": { + "php": ">=5.2.0", + "ext-simplexml": "*", + "ext-pcre": "*", + "ext-xml": "*", + "ext-dom": "*" + }, + "suggest": { + "ext-mbstring": "Required for *nix non UTF-8 systems", + "ext-com_dotnet": "Required for Windows environments", + "ext-xsl": "Required for static mode" + } +} \ No newline at end of file diff --git a/root/opt/phpsysinfo/data/ModelTranslation.txt b/root/opt/phpsysinfo/data/ModelTranslation.txt new file mode 100644 index 0000000..dfa05e1 --- /dev/null +++ b/root/opt/phpsysinfo/data/ModelTranslation.txt @@ -0,0 +1,143 @@ +ADP2,1:Developer Transition Kit:Intel Pentium 4 +iMac,1:iMac G3:PowerPC 750 (G3) +iMac1,1:iMac G3*:PowerPC 750 (G3) +iMac4,1:iMac Core Duo:Intel Core Duo T2400/T2500 +iMac4,2:iMac Core Duo:Intel Core Duo T2400 +iMac5,1:iMac Core 2 Duo:Intel Core 2 Duo T7200/T7400/T7600 +iMac5,2:iMac Core 2 Duo:Intel Core 2 Duo T5600 +iMac6,1:iMac Core 2 Duo:Intel Core 2 Duo T7400/T7600 +iMac7,1:iMac Core 2 Duo/Extreme:Intel Core 2 Duo T7300/T7700/X7900 +iMac8,1:iMac Core 2 Duo:Intel Core 2 Duo E8135/E8335/E8235/E8435 +iMac9,1:iMac Core 2 Duo:Intel Core 2 Duo P7350/P7550/E8135/E8335/E8435 +iMac10,1:iMac Core 2 Duo:Intel Core 2 Duo E7600/E8600 +iMac10,2:iMac Core 2 Duo*:Intel Core 2 Duo E7500/E7600/E8600 +iMac11,1:iMac Core i5/i7:Intel Core I5-750/I7-860 +iMac11,2:iMac Core i3/i5:Intel Core I3-540/I3-550/I5-680 +iMac11,3:iMac Core i3/i5/i7:Intel Core I3-550/I5-760/I5-680/I7-870 +iMac12,1:iMac Core i3/i5/i7:Intel Core I3-2100/I5-2400S/I5-2500S/I5-2600S +iMac12,2:iMac Core i5/i7:Intel Core I5-2400/I5-2500S/I7-2600 +iMac13,1:iMac Core i3/i5/i7:Intel Core I3-3225/I5-3335S/I5-3470S/I7-3770S +iMac13,2:iMac Core i5/i7:Intel Core I5-3470/I5-3470S/I7-3770 +iMac14,1:iMac Core i5:Intel Core I5-4570R +iMac14,2:iMac Core i5/i7:Intel Core I5-4570/I5-4670/I7-4771 +iMac14,3:iMac Core i5/i7:Intel Core I5-4570S/I7-4770S +M43ADP1,1:Development Mac Pro:Intel Xeon X5340 +MacBook1,1:MacBook Core Duo:Intel Core Duo T2400/T2500 +MacBook2,1:MacBook Core 2 Duo:Intel Core 2 Duo T5600/T7200/T7400 +MacBook3,1:MacBook Core 2 Duo:Intel Core 2 Duo T7300/T7500 +MacBook4,1:MacBook Core 2 Duo:Intel Core 2 Duo T8100/T8300 +MacBook5,1:MacBook Core 2 Duo:Intel Core 2 Duo P7350/P8600 +MacBook5,2:MacBook Core 2 Duo:Intel Core 2 Duo P7350/P7450 +MacBook6,1:MacBook Core 2 Duo:Intel Core 2 Duo P7550 +MacBook7,1:MacBook Core 2 Duo:Intel Core 2 Duo P8600 +MacBookAir1,1:MacBook Air Core 2 Duo:Intel Core 2 Duo P7500/P7700 +MacBookAir2,1:MacBook Air Core 2 Duo:Intel Core 2 Duo SL9300/SL9400/SL9600 +MacBookAir3,1:MacBook Air Core 2 Duo:Intel Core 2 Duo SU9400/SU9600 +MacBookAir3,2:MacBook Air Core 2 Duo:Intel Core 2 Duo SL9400/SL9600 +MacBookAir4,1:MacBook Air Core i5/i7:Intel Core I5-2467M/I7-2677M +MacBookAir4,2:MacBook Air Core i5/i7:Intel Core I5-2467M/I5-2557M/I7-2677M +MacBookAir5,1:MacBook Air Core i5/i7:Intel Core I5-3317U/I7-3667U +MacBookAir5,2:MacBook Air Core i5/i7:Intel Core I5-3427U/I7-3667U +MacBookAir6,1:MacBook Air Core i5/i7:Intel Core I5-4250U/I5-4260U/I7-4650U +MacBookAir6,2:MacBook Air Core i5/i7:Intel Core I5-4250U/I5-4260U/I7-4650U +MacBookPro1,1:MacBook Pro Core Duo:Intel Core Duo L2400/T2400/T2500/T2600 +MacBookPro1,2:MacBook Pro Core Duo:Intel Core Duo T2600 +MacBookPro2,1:MacBook Pro Core 2 Duo:Intel Core 2 Duo T7600 +MacBookPro2,2:MacBook Pro Core 2 Duo:Intel Core 2 Duo T7400/T7600 +MacBookPro3,1:MacBook Pro Core 2 Duo:Intel Core 2 Duo T7500/T7700/T7800 +MacBookPro4,1:MacBook Pro Core 2 Duo:Intel Core 2 Duo T8300/T9300/T9500 +MacBookPro5,1:MacBook Pro Core 2 Duo:Intel Core 2 Duo P8600/T9400/T9550/T9600/T9800 +MacBookPro5,2:MacBook Pro Core 2 Duo:Intel Core 2 Duo T9550/T9600/T9800/T9900 +MacBookPro5,3:MacBook Pro Core 2 Duo:Intel Core 2 Duo P8800/T9600/T9900 +MacBookPro5,4:MacBook Pro Core 2 Duo:Intel Core 2 Duo P8700 +MacBookPro5,5:MacBook Pro Core 2 Duo:Intel Core 2 Duo P8400/P8700 +MacBookPro6,1:MacBook Pro Core i5/i7:Intel Core I5-540M/I7-620M/I7-640M +MacBookPro6,2:MacBook Pro Core i5/i7:Intel Core I5-520M/I5-540M/I7-620M/I7-640M +MacBookPro7,1:MacBook Pro Core 2 Duo:Intel Core 2 Duo P8600/P8800 +MacBookPro8,1:MacBook Pro Core i5/i7:Intel Core I5-2415M/I5-2435M/I7-2620M/I7-2640M +MacBookPro8,2:MacBook Pro Core i7:Intel Core I7-2635QM/I7-2720QM/I7-2675QM/I7-2820QM/I7-2760QM/I7-2860QM +MacBookPro8,3:MacBook Pro Core i7:Intel Core I7-2720QM/I7-2820QM/I7-2760QM/I7-2860QM +MacBookPro9,1:MacBook Pro Core i7:Intel Core I7-3615QM/I7-3720QM/I7-3820QM +MacBookPro9,2:MacBook Pro Core i5/i7:Intel Core I5-3210M/I7-3520M +MacBookPro10,1:MacBook Pro Core i7:Intel Core I7-3615QM/I7-3635QM/I7-3720QM/I7-3740QM/I7-3820QM/I7-3840QM +MacBookPro10,2:MacBook Pro Core i5/i7:Intel Core I5-3210M/I5-3230M/I7-3520M/I7-3540M +MacBookPro11,1:MacBook Pro Core i5/i7:Intel Core I5-4258U/I5-4288U/I7-4558U +MacBookPro11,2:MacBook Pro Core i7:Intel Core I7-4750HQ/I7-4850HQ/I7-4960HQ +MacBookPro11,3:MacBook Pro Core i7:Intel Core I7-4850HQ/I7-4960HQ +Macmini1,1:Mac mini Core Solo/Duo:Intel Core Duo T2300/T2400 Solo T1200 +Macmini2,1:Mac mini Core 2 Duo:Intel Core 2 Duo T5600/T7200 +Macmini3,1:Mac mini Core 2 Duo:Intel Core 2 Duo P7350/P8400/P7550/P8700/P8800 +Macmini4,1:Mac mini Core 2 Duo:Intel Core 2 Duo P8600/P8800 +Macmini5,1:Mac mini Core i5:Intel Core I5-2415M +Macmini5,2:Mac mini Core i5/i7:Intel Core I5-2520M/I7-2620M +Macmini5,3:Mac mini Core i7:Intel Core I7-2635QM +Macmini6,1:Mac mini Core i5:Intel Core I5-3210M +Macmini6,2:Mac mini Core i7:Intel Core i7 I7-3615QM/I7-3720QM +MacPro1,1:Mac Pro Quad Core:Intel Xeon 5130/5150/5160 +MacPro2,1:Mac Pro Eight Core:Intel Xeon X5365 +MacPro3,1:Mac Pro Quad/Eight Core:Intel Xeon E5462/E5472/X5482 +MacPro4,1:Mac Pro Quad/Eight Core:Intel Xeon E5520/E5550/X5570/W3520/W3540/W3580 +MacPro5,1:Mac Pro Quad/Six/Eight/Twelve Core:Intel Xeon E5620/E5645/W3530/W3565/W3680/X5650/X5670/X5675 +MacPro6,1:Mac Pro Quad/Six/Eight/Twelve Core:Intel Xeon E5-1620v2/E5-1650v2/E5-1680v2/E5-2697v2 +PowerBook1,1:PowerBook G3:PowerPC 750 (G3) +PowerBook2,1:iBook G3:PowerPC 750 (G3) +PowerBook2,2:iBook G3:PowerPC 750cx (G3) +PowerBook2,3:iBook G3*:PowerPC 750cx (G3) +PowerBook2,4:iBook G3*:PowerPC 750cx (G3) +PowerBook3,1:PowerBook G3:PowerPC 750 (G3) +PowerBook3,2:PowerBook G4:PowerPC 7410 (G4) +PowerBook3,3:PowerBook G4:PowerPC 7440 (G4) +PowerBook3,4:PowerBook G4:PowerPC 7451 (G4) +PowerBook3,5:PowerBook G4:PowerPC 7455 (G4) +PowerBook4,1:iBook G3:PowerPC 750cx (G3) +PowerBook4,2:iBook G3 600:PowerPC 750cx (G3) +PowerBook4,3:iBook G3:PowerPC 750fx (G3) +PowerBook5,1:PowerBook G4:PowerPC 7455 (G4) +PowerBook5,2:PowerBook G4:PowerPC 7447 (G4) +PowerBook5,3:PowerBook G4:PowerPC 7447 (G4) +PowerBook5,4:PowerBook G4:PowerPC 7447a (G4) +PowerBook5,5:PowerBook G4:PowerPC 7447a (G4) +PowerBook5,6:PowerBook G4:PowerPC 7447a (G4) +PowerBook5,7:PowerBook G4:PowerPC 7447a (G4) +PowerBook5,8:PowerBook G4:PowerPC 7447a (G4) +PowerBook5,9:PowerBook G4:PowerPC 7447a (G4) +PowerBook6,1:PowerBook G4:PowerPC 7455 (G4) +PowerBook6,2:PowerBook G4:PowerPC 7447 (G4) +PowerBook6,3:iBook G4:PowerPC 7457 (G4) +PowerBook6,4:PowerBook G4:PowerPC 7447a (G4) +PowerBook6,5:iBook G4:PowerPC 7447a (G4) +PowerBook6,7:iBook G4:PowerPC 7447a (G4) +PowerBook6,8:PowerBook G4:PowerPC 7447a (G4) +PowerMac1,1:Power Macintosh/Mac Server G3:PowerPC 750 (G3) +PowerMac1,2:Power Macintosh G4:PowerPC 7400 (G4) +PowerMac2,1:iMac G3:PowerPC 750 (G3) +PowerMac2,2:iMac G3:PowerPC 750 (G3) +PowerMac3,1:Power Macintosh/Mac Server G4:PowerPC 7400 (G4) +PowerMac3,2:Power Macintosh/Mac Server G4*:PowerPC 7400 (G4) +PowerMac3,3:Power Macintosh/Mac Server G4:PowerPC 7400 (G4) +PowerMac3,4:Power Macintosh/Mac Server G4:PowerPC 7410 (G4) +PowerMac3,5:Power Macintosh/Mac Server G4:PowerPC 7450/7455 (G4) +PowerMac3,6:Power Macintosh/Mac Server G4:PowerPC 7455 (G4) +PowerMac4,1:iMac G3:PowerPC 750/750cx (G3) +PowerMac4,2:iMac G4:PowerPC 7441/7445 (G4) +PowerMac4,4:eMac G4:PowerPC 7441/7445 (G4) +PowerMac4,5:iMac G4:PowerPC 7445 (G4) +PowerMac5,1:Power Macintosh G4 Cube:PowerPC 7400 (G4) +PowerMac6,1:iMac G4:PowerPC 7445 (G4) +PowerMac6,3:iMac G4:PowerPC 7445 (G4) +PowerMac6,4:eMac G4:PowerPC 7447a (G4) +PowerMac7,2:Power Macintosh G5:PowerPC 970 (G5) +PowerMac7,3:Power Macintosh G5:PowerPC 970fx (G5) +PowerMac8,1:iMac G5:PowerPC 970 (G5) +PowerMac8,2:iMac G5:PowerPC 970 (G5) +PowerMac9,1:Power Macintosh G5:PowerPC 970fx (G5) +PowerMac10,1:Mac mini G4:PowerPC 7447a (G4) +PowerMac10,2:Mac mini G4:PowerPC 7447a (G4) +PowerMac11,2:Power Macintosh G5 Dual/Quad Core:PowerPC 970MP (G5) +PowerMac12,1:iMac G5:PowerPC 970fx (G5) +RackMac1,1:Xserve G4:PowerPC 7455 (G4) +RackMac1,2:Xserve G4:PowerPC 7455 (G4) +RackMac3,1:Xserve G5:PowerPC 970fx (G5) +Xserve1,1:Xserve Xeon Quad Core:Intel Xeon 5130/5150/5160 +Xserve2,1:Xserve Xeon Quad/Eight Core:Intel Xeon E5462/E5472 +Xserve3,1:Xserve Xeon Nehalem Quad/Eight Core:Intel Xeon E5520/E5550/E5570 diff --git a/root/opt/phpsysinfo/data/distros.ini b/root/opt/phpsysinfo/data/distros.ini new file mode 100644 index 0000000..16747ab --- /dev/null +++ b/root/opt/phpsysinfo/data/distros.ini @@ -0,0 +1,799 @@ +; linux-distros.ini - Defines known linux distros for phpSysInfo. +; http://phpsysinfo.sourceforge.net/ +; $Id: distros.ini 709 2012-12-05 11:20:40Z namiltd $ +; + +[GoboLinux] +Image = "Gobo.png" +Name = "GoboLinux" +Files = "/etc/GoboLinuxVersion" + +[SliTaz] +Image = "SliTaz.png" +Name = "SliTaz" +Files = "/etc/slitaz-release" + +[eisfair] +Image = "Eisfair.png" +Files = "/etc/eisfair-system" +Files2 = "/etc/version" + +[TinyCore] +Image = "TinyCore.png" +Name = "Tiny Core Linux" +Files = "/usr/share/doc/tc/release.txt" + +[Frugalware] +Image = "Frugalware.png" +Files = "/etc/frugalware-release" +;detected in "/etc/os-release" + +[antiX] +Image = "antiX.png" +Files = "/etc/antix-version" +;wrong in "/etc/os-release" Debian GNU/Linux +;wrong in "/etc/debian_version" Debian + +[IPFire] +Image = "IPFire.png" +;detected in "/etc/system-release" + +[4MLinux] +Image = "4MLinux.png" +Name = "4MLinux" +Files = "/etc/4MLinux-version" + +[Lunar Linux] +Image = "Lunar.png" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" + +[CRUX] +Image = "Crux.png" +Mode = "Execute" +Files = "/usr/bin/crux" + +[Foresight] +Image = "Foresight.png" +;detected in "/etc/distro-release" + +[Trustix] +Image = "Trustix.png" +Files = "/etc/trustix-release;/etc/trustix-version" + +[NixOS] +Image = "NixOS.png" +;detected in "/etc/os-release" + +[FreeEOS] +Image = "free-eos.png" +Files = "/etc/eos-version" + +[generations] +Image = "Generations.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[Generations Linux] +Image = "Generations.png" +;detected in "/etc/os-release" + +[Manjaro Linux] +Image = "Manjaro.png" +Files = "/etc/manjaro-release" +;detected in "/etc/os-release" + +[ManjaroLinux] +Image = "Manjaro.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[Arch Linux] +Image = "Arch.png" +Files = "/etc/arch-release" +;detected in "/etc/os-release" + +[Arch] +Image = "Arch.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[Cobalt] +Image = "Cobalt.png" +Files = "/etc/cobalt-release" + +[LinuxFromScratch] +Image = "LFS.png" +Files = "/etc/lfs-release" + +[Rubix] +Image = "Rubix.png" +Files = "/etc/rubix-version" + +[Tails] +Image = "Tails.png" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[Tanglu] +Image = "Tanglu.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[Tanglu GNU/Linux] +Image = "Tanglu.png" +;detected in "/etc/os-release" + +[Mer] +Image = "Mer.png" +Mode = "Analyse" +Files = "/etc/mer-release;/etc/meego-release;/etc/moblin-release" +;detected in "lsb_release -a" +;detected in "/etc/system-release" + +[KaOS] +Image = "KaOS.png" +Files = "/etc/KaOS-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" + +[CoreOS] +Image = "CoreOS.png" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" + +[BOSS] +Image = "BOSS.png" +Name = "BOSS GNU/Linux" +Files = "/etc/boss_version" +;detected in "lsb_release -a" +;wrong in "/etc/debian_version" Debian + +[BOSS GNU/Linux] +Image = "BOSS.png" +;detected in "/etc/os-release" + +[BOSS Server Beta] +Image = "BOSS.png" +;detected in "lsb_release -a" + +[Canaima] +Image = "Canaima.png" +Name = "Canaima GNU/Linux" +Files = "/etc/canaima_version" +;detected in "lsb_release -a" +;wrong in "/etc/debian_version" Debian + +[Canaima GNU/Linux] +Image = "Canaima.png" +;detected in "/etc/os-release" + +[Semplice] +Image = "Semplice.png" +Name = "Semplice" +Files = "/etc/semplice_version" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[SolydXK] +Image = "SolydXK.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/solydxk/info" +;wrong in "/etc/os-release" Debian GNU/Linux +;wrong in "/etc/debian_version" Debian + +[HandyLinux] +Image = "Handy.png" +Files = "/etc/handylinux_version" +;detected in "lsb_release -a" +;wrong in "/etc/os-release" Debian GNU/Linux +;wrong in "/etc/debian_version" Debian + +[Parsix] +Image = "Parsix.png" +Files = "/etc/parsix-version" +;detected in "lsb_release -a" +;detected or wrong version in "/etc/os-release" | Parsix 4.0 +;wrong in "/etc/debian_version" Debian + +[Linaro] +Image = "Linaro.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[LinuxDeepin] +Image = "Deepin.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Debian GNU/Linux +;wrong in "/etc/debian_version" Debian + +[Ultimate_Edition] +Image = "UltimateEdition.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[elementary OS] +Image = "elementaryOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[PearLinux] +Image = "Pear.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Ubuntu +;wrong in "/etc/debian_version" Debian + +[Pear Linux] +Image = "Pear.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Ubuntu +;wrong in "/etc/debian_version" Debian + +[PearOS] +Image = "Pear.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Ubuntu +;wrong in "/etc/debian_version" Debian + +[SolusOS] +Image = "SolusOS.png" +Files = "/etc/solusos_version" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Debian GNU/Linux +;wrong in "/etc/debian_version" Debian + +[LinuxMint] +Image = "Mint.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Ubuntu +;wrong in "/etc/debian_version" Debian + +[Trisquel] +Image = "Trisquel.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/os-release" Ubuntu +;wrong in "/etc/debian_version" Debian + +[Zorin] +Image = "Zorin.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong or almost in "/etc/os-release" Ubuntu | Zorin OS +;wrong in "/etc/debian_version" Debian + +[Zorin OS] +Image = "Zorin.png" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[Netrunner] +Image = "Netrunner.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[NetrunnerSE] +Image = "Netrunner.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[Netrunner Rolling] +Image = "Netrunner.png" +;detected in "/etc/os-release" +;wrong in "/etc/manjaro-release" Manjaro + +[Peppermint] +Image = "Peppermint.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[Ubuntu] +Image = "Ubuntu.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" +;wrong in "/etc/debian_version" Debian + +[Chakra] +Image = "Chakra.png" +Files = "/etc/chakra-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[The Chakra-Project] +Image = "Chakra.png" +;detected in "/etc/os-release" + +[IYCC] +Image = "iycc.png" +;detected in "/etc/lsb-release" + +[Mageia] +Image = "Mageia.png" +Files = "/etc/mageia-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/mandriva-release" +;detected in "/etc/mandrake-release;/etc/mandrakelinux-release" +;detected in "/etc/redhat-release" +;detected in "/etc/os-release" + +[PLD Linux] +Image = "PLD.png" +Files = "/etc/pld-release" +;detected in "/etc/os-release" + +[LFS] +Image = "lfs.png" +Files = "/etc/lfs-release;/etc/lfs_version" + +[HLFS] +Image = "lfs.png" +Files = "/etc/hlfs-release;/etc/hlfs_version" + +[Synology] +Image = "Synology.png" +Mode = "Detection" +Files = "/etc/synoinfo.conf" +Files2 = "/etc/VERSION" + +[Alpine] +Name = "Alpine" +Image = "Alpine.png" +Files = "/etc/alpine-release" + +[Puppy] +Image = "Puppy.png" +;detected in "/etc/DISTRO_SPECS" + +[Lucid] +Name = "Lucid Puppy" +Image = "Puppy.png" +;detected in "/etc/DISTRO_SPECS" + +[Slacko Puppy] +Image = "Puppy.png" +;detected in "/etc/DISTRO_SPECS" + +[Wary Puppy] +Image = "Puppy.png" +;detected in "/etc/DISTRO_SPECS" + +[Turbolinux] +Image = "Turbo.png" +Files = "/etc/turbolinux-release" + +[Amazon] +Image = "Amazon.png" +;detected in "/etc/system-release" + +[AmazonAMI] +Image = "Amazon.png" +;detected in "lsb_release -a" + +[RedFlag] +Image = "RedFlag.png" +Files = "/etc/redflag-release" +;detected in "/etc/system-release" + +[Red Flag inWise] +Image = "RedFlag.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" + +[StartOS] +Image = "StartOS.png" +Files = "/etc/startos-release" +;detected in "lsb_release -a" + +[PisiLinux] +Image = "Pisi.png" +Files = "/etc/pisilinux-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[Pisi_Linux] +Image = "Pisi.png" +;detected in "/etc/system-release" + +[SME] +Image = "SMEServer.png" +Files = "/etc/e-smith-release" +;wrong in "/etc/centos-release" CentOS +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[SMEServer] +Image = "SMEServer.png" +;detected in "lsb_release -a" + +[Scientific] +Image = "Scientific.png" +;detected in "lsb_release -a" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[ScientificSL] +Image = "Scientific.png" +;detected in "lsb_release -a" + +[ScientificCERNSLC] +Image = "Scientific.png" +;detected in "lsb_release -a" + +[ScientificFermi] +Image = "Scientific.png" +;detected in "lsb_release -a" + +[ScientificFermiLTS] +Image = "Scientific.png" +;detected in "lsb_release -a" + +[ScientificSLF] +Image = "Scientific.png" +;detected in "lsb_release -a" + +[ClearOS] +Image = "ClearOS.png" +Files = "/etc/clearos-release" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[CloudLinuxServer] +Image = "Cloud.png" +;detected in "lsb_release -a" + +[CloudLinux] +Image = "Cloud.png" +Files = "/etc/CloudLinux-release" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +; at the end because some distros may also have the same files (like SMEServer) +[CentOS] +Image = "CentOS.png" +Files = "/etc/centos-release" +;detected in "lsb_release -a" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[Oracle] +Image = "Oracle.png" +Files = "/etc/oracle-release;/etc/enterprise-release" +;detected in "/etc/system-release" +;wrong in "/etc/redhat-release" RedHat + +[OracleServer] +Image = "Oracle.png" +;detected in "lsb_release -a" + +[EnterpriseEnterpriseServer] +Image = "Oracle.png" +;detected in "lsb_release -a" + +[PCLinuxOS] +Image = "PCLinuxOS.png" +Files = "/etc/pclinuxos-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/mandriva-release" +;detected in "/etc/mandrake-release;/etc/mandrakelinux-release" +;detected in "/etc/redhat-release" + +[Salix] +Image = "Salix.png" +Mode = "Detection" +Files = "/etc/salix-update-notifier.conf" +Files2 = "/etc/slackware-version" +;wrong in "/etc/os-release" Slackware +;wrong in "/etc/slackware-version" Slackware + +[Slax] +Image = "Slax.png" +Files = "/etc/slax-version" +;wrong in "/etc/os-release" Slackware +;wrong in "/etc/slackware-version" Slackware + +[SMS] +Image = "SMS.png" +Files = "/etc/sms-version" +;detected in "/etc/os-release" +;wrong in "/etc/slackware-version" Slackware + +[Porteus] +Image = "Porteus.png" +Files = "/etc/porteus-version" +;wrong in "/etc/os-release" Slackware +;wrong in "/etc/slackware-version" Slackware + +[Vector] +Image = "Vector.png" +Files = "/etc/vector-version" +;wrong in "/etc/slackware-version" Slackware + +[Zenwalk] +Name = "Zenwalk" +Image = "Zenwalk.png" +Files = "/etc/zenwalk-version" +;detected in "/etc/os-release" +;wrong in "/etc/slackware-version" Slackware + +[Calculate] +Image = "Calculate.png" +;detected in "/etc/gentoo-release" +;wrong in "/etc/os-release" Gentoo + +[Tizen] +Image = "Tizen.png" +Files = "/etc/tizen-release" +;detected in "/etc/system-release" +;detected in "/etc/os-release" + +[Sabayon] +Image = "Sabayon.png" +Files = "/etc/sabayon-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/system-release" +;detected in "/etc/os-release" +;wrong in "/etc/gentoo-release" Gentoo + +[VortexBox] +Image = "VortexBox.png" +Name = "VortexBox" +Files = "/etc/vortexbox/vortexbox-version" +;wrong in "/etc/fedora-release" Fedora +;wrong in "/etc/redhat-release" Fedora +;wrong in "/etc/system-release" Fedora +;wrong in "/etc/os-release" Fedora + +[ALT] +Image = "ALT.png" +Files = "/etc/altlinux-release" +;detected in "/etc/fedora-release" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[Simply] +Image = "ALT.png" +;detected in "/etc/fedora-release" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[Simply Linux] +Image = "ALT.png" +;detected in "/etc/os-release" + +[ALT Linux] +Image = "ALT.png" +;detected in "/etc/os-release" + +[Fuduntu] +Image = "Fuduntu.png" +Files = "/etc/fuduntu-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/fedora-release" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" + +[gNewSense] +Image = "gNewSense.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[SteamOS] +Image = "SteamOS.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;wrong in "/etc/debian_version" Debian + +[SteamOS GNU/Linux] +Image = "SteamOS.png" +;detected in "/etc/os-release" + +[Raspbian] +Image = "Raspbian.png" +;detected in "lsb_release -a" +;wrong in "/etc/debian_version" Debian + +[Raspbian GNU/Linux] +Image = "Raspbian.png" +;detected in "/etc/os-release" + +[Debian] +Name = "Debian" +Image = "Debian.png" +Files = "/etc/debian_release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/debian_version" + +[Debian GNU/Linux] +Image = "Debian.png" +;detected in "/etc/os-release" + +[openSUSE] +Image = "openSUSE.png" +;detected in "/etc/os-release" +;detected in "/etc/SuSE-release" + +[openSUSE project] +Image = "openSUSE.png" +;detected in "lsb_release -a" + +; at the end because some distros may also have the same files (like openSUSE) +[SUSE LINUX] +Image = "SUSE.png" +Mode = "Analyse" +Files = "/etc/SuSE-release;/etc/UnitedLinux-release" + +; at the end because some distros may also have the same files (like Sabayon, Calculate) +[Gentoo] +Image = "Gentoo.png" +Mode = "Analyse" +Files = "/etc/gentoo-release" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" +;detected in "/etc/os-release" + +; at the end because some distros may also have the same files (like Salix, Slax, SMS, Porteus, Vector, Zenwalk) +[Slackware] +Image = "Slackware.png" +Files = "/etc/slackware-release;/etc/slackware-version" +;detected in "/etc/os-release" + +[Qubes] +Image = "Qubes.png" +Files = "/etc/qubes-release" +;detected in "/etc/fedora-release" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" +;detected in "/etc/os-release" + +[Korora] +Image = "Korora.png" +;detected in "lsb_release -a" +;detected in "/etc/fedora-release" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" +;detected in "/etc/os-release" + +; at the end because some distros may also have the same files (like Fuduntu, ALT, VortexBox, Qubes, Korora) +[Fedora] +Image = "Fedora.png" +Mode = "Analyse" +Files = "/etc/fedora-release" +;detected in "lsb_release -a" +;detected in "/etc/redhat-release" +;detected in "/etc/system-release" +;detected in "/etc/os-release" + +[FedoraCore] +Image = "Fedora.png" +;detected in "/etc/lsb-release" + +[OpenMandriva] +Image = "OpenMandriva.png" +;detected in "/etc/rosa-release" +;detected in "/etc/mandriva-release" +;detected in "/etc/mandrake-release;/etc/mandrakelinux-release" +;detected in "/etc/redhat-release" +;detected in "/etc/distro-release" +;detected in "/etc/system-release" + +[OpenMandriva Lx] +Image = "OpenMandriva.png" +;detected in "/etc/os-release" + +[OpenMandrivaLinux] +Image = "OpenMandriva.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[ROSA MarathonLinux] +Image = "ROSA.png" +;detected in "/etc/lsb-release" + +[RosaDesktop.Marathon] +Image = "ROSA.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[RosaDesktop.Fresh] +Image = "ROSA.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +[ROSA Desktop Fresh] +Image = "ROSA.png" +;detected in "/etc/os-release" + +[ROSA Marathon] +Image = "ROSA.png" +;detected in "/etc/os-release" + +[ROSAEnterpriseServer] +Image = "ROSA.png" +;detected in "lsb_release -a" + +; at the end because some distros may also have the same files (like OpenMandriva) +[ROSA] +Image = "ROSA.png" +Mode = "Analyse" +Files = "/etc/rosa-release" +;detected in "lsb_release -a" +;detected in "/etc/system-release" +;detected in "/etc/mandriva-release" +;detected in "/etc/mandrake-release;/etc/mandrakelinux-release" +;detected in "/etc/redhat-release" + +[MandrivaLinux] +Image = "Mandrake.png" +;detected in "lsb_release -a" +;detected in "/etc/lsb-release" + +; at the end because some distros may also have the same files (like Mageia, PCLinuxOS, ROSA, OpenMandriva) +[Mandriva] +Image = "Mandrake.png" +Mode = "Analyse" +Files = "/etc/mandriva-release" +;detected in "/etc/mandrake-release;/etc/mandrakelinux-release" +;detected in "/etc/redhat-release" + +; at the end because some distros may also have the same files (like Mandriva, Mageia, PCLinuxOS, ROSA, OpenMandriva) +[Mandrake] +Image = "Mandrake.png" +Mode = "Analyse" +Files = "/etc/mandrake-release;/etc/mandrakelinux-release" + +; at the end because some distros may also have the same files (like SMEServer, Fuduntu, ALT, VortexBox, Qubes, Korora, Fedora, CentOS, Oracle, Scientific, CloudLinux, Mandrake, MandrivaLinux, Mageia, PCLinuxOS, ROSA, OpenMandriva) +[RedHat] +Image = "RedHat.png" +Mode = "Analyse" +Files = "/etc/redhat-release;/etc/redhat_version" +;detected in "/etc/system-release" + +[Red Hat Enterprise Linux Everything] +Image = "RedHat.png" +;detected in "/etc/os-release" + +[RedHatEnterpriseES] +Image = "RedHat.png" +;detected in "lsb_release -a" + +[RedHatEnterpriseAS] +Image = "RedHat.png" +;detected in "lsb_release -a" + +[RedHatEnterpriseServer] +Image = "RedHat.png" +;detected in "lsb_release -a" + +[RedHatEnterpriseClient] +Image = "RedHat.png" +;detected in "lsb_release -a" diff --git a/root/opt/phpsysinfo/data/languages.ini b/root/opt/phpsysinfo/data/languages.ini new file mode 100644 index 0000000..c93aea4 --- /dev/null +++ b/root/opt/phpsysinfo/data/languages.ini @@ -0,0 +1,1025 @@ +[WINNT] +1="Arabic" +4="Simplified Chinese - China" +9="English" +1025="Arabic - Saudi Arabia" +1026="Bulgarian" +1027="Catalan" +1028="Traditional Chinese - Taiwan" +1029="Czech" +1030="Danish" +1031="German - Germany" +1032="Greek" +1033="English - United States" +1034="Spanish - Traditional Sort" +1035="Finnish" +1036="French - France" +1037="Hebrew" +1038="Hungarian" +1039="Icelandic" +1040="Italian - Italy" +1041="Japanese" +1042="Korean" +1043="Dutch - Netherlands" +1044="Norwegian - Bokmal" +1045="Polish" +1046="Portuguese - Brazil" +1047="Rhaeto-Romanic" +1048="Romanian" +1049="Russian" +1050="Croatian" +1051="Slovak" +1052="Albanian" +1053="Swedish" +1054="Thai" +1055="Turkish" +1056="Urdu" +1057="Indonesian" +1058="Ukrainian" +1059="Belarusian" +1060="Slovenian" +1061="Estonian" +1062="Latvian" +1063="Lithuanian" +1065="Persion" +1066="Vietnamese" +1069="Basque" +1070="Serbian" +1071="Macedonian (FYROM)" +1072="Sutu" +1073="Tsonga" +1074="Tswana" +1076="Xhosa" +1077="Zulu" +1078="Afrikaans" +1080="Faeroese" +1081="Hindi" +1082="Maltese" +1084="Scottish Gaelic" +1085="Yiddish" +1086="Malay - Malaysia" +2049="Arabic - Iraq" +2052="Simplified Chinese - PRC" +2055="German - Switzerland" +2057="English - United Kingdom" +2058="Spanish - Mexico" +2060="French - Belgium" +2064="Italian - Switzerland" +2067="Dutch - Belgium" +2068="Norwegian - Nynorsk" +2070="Portuguese - Portugal" +2072="Romanian - Moldova" +2073="Russian - Moldova" +2074="Serbian - Latin" +2077="Swedish - Finland" +3073="Arabic - Egypt" +3076="Traditional Chinese - Hong Kong SAR" +3079="German - Austria" +3081="English - Australia" +3082="Spanish - International Sort" +3084="French - Canada" +3098="Serbian - Cyrillic" +4097="Arabic - Libya" +4100="Simplified Chinese - Singapore" +4103="German - Luxembourg" +4105="English - Canada" +4106="Spanish - Guatemala" +4108="French - Switzerland" +5121="Arabic - Algeria" +5127="German - Liechtenstein" +5129="English - New Zealand" +5130="Spanish - Costa Rica" +5132="French - Luxembourg" +6145="Arabic - Morocco" +6153="English - Ireland" +6154="Spanish - Panama" +7169="Arabic - Tunisia" +7177="English - South Africa" +7178="Spanish - Dominican Republic" +8193="Arabic - Oman" +8201="English - Jamaica" +8202="Spanish - Venezuela" +9217="Arabic - Yemen" +9226="Spanish - Colombia" +10241="Arabic - Syria" +10249="English - Belize" +10250="Spanish - Peru" +11265="Arabic - Jordan" +11273="English - Trinidad" +11274="Spanish - Argentina" +12289="Arabic - Lebanon" +12298="Spanish - Ecuador" +13313="Arabic - Kuwait" +13322="Spanish - Chile" +14337="Arabic - U.A.E." +14346="Spanish - Uruguay" +15361="Arabic - Bahrain" +15370="Spanish - Paraguay" +16385="Arabic - Qatar" +16394="Spanish - Bolivia" +17418="Spanish - El Salvador" +18442="Spanish - Honduras" +19466="Spanish - Nicaragua" +20490="Spanish - Puerto Rico" + +[Linux] +_aa="Afar" +_aa_DJ="Afar Djibouti" +_aa_ER="Afar Eritrea" +_aa_ER_SAAHO="Afar Eritrea Saho" +_aa_ET="Afar Ethiopia" +_aar="Afar" +_aar_DJ="Afar Djibouti" +_aar_ER="Afar Eritrea" +_aar_ER_SAAHO="Afar Eritrea Saho" +_aar_ET="Afar Ethiopia" +_af="Afrikaans" +_af_NA="Afrikaans Namibia" +_afr="Afrikaans" +_afr_NA="Afrikaans Namibia" +_afr_ZA="Afrikaans South Africa" +_af_ZA="Afrikaans South Africa" +_aka="Akan" +_aka_GH="Akan Ghana" +_ak="Akan" +_ak_GH="Akan Ghana" +_alb_AL="Albanian Albania" +_alb="Albanian" +_am="Amharic" +_am_ET="Amharic Ethiopia" +_amh="Amharic" +_amh_ET="Amharic Ethiopia" +_ara_AE="Arabic United Arab Emirates" +_ara="Arabic" +_ara_BH="Arabic Bahrain" +_ara_DZ="Arabic Algeria" +_ar_AE="Arabic United Arab Emirates" +_ara_EG="Arabic Egypt" +_ara_IQ="Arabic Iraq" +_ara_JO="Arabic Jordan" +_ara_KW="Arabic Kuwait" +_ara_LB="Arabic Lebanon" +_ara_LY="Arabic Libya" +_ara_MA="Arabic Morocco" +_ara_OM="Arabic Oman" +_ara_QA="Arabic Qatar" +_ar="Arabic" +_ara_SA="Arabic Saudi Arabia" +_ara_SD="Arabic Sudan" +_ara_SY="Arabic Syria" +_ara_TN="Arabic Tunisia" +_ara_YE="Arabic Yemen" +_ar_BH="Arabic Bahrain" +_ar_DZ="Arabic Algeria" +_ar_EG="Arabic Egypt" +_ar_IQ="Arabic Iraq" +_ar_JO="Arabic Jordan" +_ar_KW="Arabic Kuwait" +_ar_LB="Arabic Lebanon" +_ar_LY="Arabic Libya" +_ar_MA="Arabic Morocco" +_arm_AM="Armenian Armenia" +_arm_AM_REVISED="Armenian Armenia Revised Orthography" +_arm="Armenian" +_ar_OM="Arabic Oman" +_ar_QA="Arabic Qatar" +_ar_SA="Arabic Saudi Arabia" +_ar_SD="Arabic Sudan" +_ar_SY="Arabic Syria" +_ar_TN="Arabic Tunisia" +_ar_YE="Arabic Yemen" +_as="Assamese" +_as_IN="Assamese India" +_asm="Assamese" +_asm_IN="Assamese India" +_az_AZ="Azerbaijani Azerbaijan" +_az="Azerbaijani" +_az_Cyrl_AZ="Azerbaijani Azerbaijan (Cyrillic)" +_az_Cyrl="Azerbaijani (Cyrillic)" +_aze_AZ="Azerbaijani Azerbaijan" +_aze_AZ_Cyrl="Azerbaijani Azerbaijan (Cyrillic)" +_aze="Azerbaijani" +_aze_AZ_Latn="Azerbaijani Azerbaijan (Latin)" +_aze_Cyrl="Azerbaijani (Cyrillic)" +_aze_Latn="Azerbaijani (Latin)" +_az_Latn_AZ="Azerbaijani Azerbaijan (Latin)" +_az_Latn="Azerbaijani (Latin)" +_baq="Basque" +_baq_ES="Basque Spain" +_be="Belarusian" +_be_BY="Belarusian Belarus" +_bel="Belarusian" +_bel_BY="Belarusian Belarus" +_ben_BD="Bengali Bangladesh" +_ben="Bengali" +_ben_IN="Bengali India" +_bg_BG="Bulgarian Bulgaria" +_bg="Bulgarian" +_bn_BD="Bengali Bangladesh" +_bn="Bengali" +_bn_IN="Bengali India" +_bokmal="Norwegian BokmÃ¥l" +_bokmÃ¥l="Norwegian BokmÃ¥l" +_bos_BA="Bosnian Bosnia and Herzegovina" +_bos="Bosnian" +_bs_BA="Bosnian Bosnia and Herzegovina" +_bs="Bosnian" +_bul_BG="Bulgarian Bulgaria" +_bul="Bulgarian" +_bur="Burmese" +_bur_MM="Burmese Myanmar" +_byn="Blin" +_byn_ER="Blin Eritrea" +_ca="Catalan" +_ca_ES="Catalan Spain" +_catalan="Catalan Spain" +_cat="Catalan" +_cat_ES="Catalan Spain" +_cch="Atsam" +_cch_NG="Atsam Nigeria" +_C="English United States Computer" +_chi="Chinese" +_chi_CN="Chinese China" +_chi_CN_Hans="Chinese China (Simplified Han)" +_chi_Hans="Chinese (Simplified Han)" +_chi_Hant="Chinese (Traditional Han)" +_chi_HK="Chinese Hong Kong SAR China" +_chi_HK_Hans="Chinese Hong Kong SAR China (Simplified Han)" +_chi_HK_Hant="Chinese Hong Kong SAR China (Traditional Han)" +_chi_MO="Chinese Macau SAR China" +_chi_MO_Hans="Chinese Macau SAR China (Simplified Han)" +_chi_MO_Hant="Chinese Macau SAR China (Traditional Han)" +_chi_SG="Chinese Singapore" +_chi_SG_Hans="Chinese Singapore (Simplified Han)" +_chi_TW="Chinese Taiwan" +_chi_TW_Hant="Chinese Taiwan (Traditional Han)" +_cop="Coptic" +_cor="Cornish" +_cor_GB="Cornish United Kingdom" +_croatian="Croatian" +_cs_CZ="Czech Czech Republic" +_cs="Czech" +_cy_GB="Welsh United Kingdom" +_cy="Welsh" +_czech="Czech" +_cze_CZ="Czech Czech Republic" +_cze="Czech" +_da="Danish" +_da_DK="Danish Denmark" +_dan="Danish" +_dan_DK="Danish Denmark" +_danish="Danish" +_dansk="Danish" +_de_AT="German Austria" +_de_BE="German Belgium" +_de_CH="German Switzerland" +_de_DE="German Germany" +_de="German" +_de_LI="German Liechtenstein" +_de_LU="German Luxembourg" +_deutsch="German" +_div="Divehi" +_div_MV="Divehi Maldives" +_dut_BE="Dutch Belgium" +_dutch="Dutch" +_dut="Dutch" +_dut_NL="Dutch Netherlands" +_dv="Divehi" +_dv_MV="Divehi Maldives" +_dz_BT="Dzongkha Bhutan" +_dz="Dzongkha" +_dzo_BT="Dzongkha Bhutan" +_dzo="Dzongkha" +_ee="Ewe" +_ee_GH="Ewe Ghana" +_eesti="Estonian" +_ee_TG="Ewe Togo" +_el_CY="Greek Cyprus" +_el="Greek" +_el_GR="Greek Greece" +_el_POLYTON="Greek" +_en_AS="English American Samoa" +_en_AU="English Australia" +_en_BE="English Belgium" +_en_BW="English Botswana" +_en_BZ="English Belize" +_en_CA="English Canada" +_en_Dsrt="English (Deseret)" +_en_Dsrt_US="English United States (Deseret)" +_en="English" +_eng_AS="English American Samoa" +_eng_AU="English Australia" +_eng_BE="English Belgium" +_en_GB="English United Kingdom" +_eng_BW="English Botswana" +_eng_BZ="English Belize" +_eng_CA="English Canada" +_eng_Dsrt="English (Deseret)" +_eng="English" +_eng_GB="English United Kingdom" +_eng_GU="English Guam" +_eng_HK="English Hong Kong SAR China" +_eng_IE="English Ireland" +_eng_IN="English India" +_eng_JM="English Jamaica" +_eng_MH="English Marshall Islands" +_eng_MP="English Northern Mariana Islands" +_eng_MT="English Malta" +_eng_NA="English Namibia" +_eng_NZ="English New Zealand" +_eng_PH="English Philippines" +_eng_PK="English Pakistan" +_eng_SG="English Singapore" +_eng_Shaw="English (Shavian)" +_eng_TT="English Trinidad and Tobago" +_en_GU="English Guam" +_eng_UM="English United States Minor Outlying Islands" +_eng_US_Dsrt="English United States (Deseret)" +_eng_US="English United States" +_eng_US_POSIX="English United States Computer" +_eng_VI="English U.S. Virgin Islands" +_eng_ZA="English South Africa" +_eng_ZW="English Zimbabwe" +_en_HK="English Hong Kong SAR China" +_en_IE="English Ireland" +_en_IN="English India" +_en_JM="English Jamaica" +_en_MH="English Marshall Islands" +_en_MP="English Northern Mariana Islands" +_en_MT="English Malta" +_en_NA="English Namibia" +_en_NZ="English New Zealand" +_en_PH="English Philippines" +_en_PK="English Pakistan" +_en_SG="English Singapore" +_en_Shaw="English (Shavian)" +_en_TT="English Trinidad and Tobago" +_en_UM="English United States Minor Outlying Islands" +_en_US="English United States" +_en_US_POSIX="English United States Computer" +_en_VI="English U.S. Virgin Islands" +_en_ZA="English South Africa" +_en_ZW="English Zimbabwe" +_eo="Esperanto" +_epo="Esperanto" +_es_AR="Spanish Argentina" +_es_BO="Spanish Bolivia" +_es_CL="Spanish Chile" +_es_CO="Spanish Colombia" +_es_CR="Spanish Costa Rica" +_es_DO="Spanish Dominican Republic" +_es_EC="Spanish Ecuador" +_es_ES="Spanish Spain" +_es_GT="Spanish Guatemala" +_es_HN="Spanish Honduras" +_es_MX="Spanish Mexico" +_es_NI="Spanish Nicaragua" +_es_PA="Spanish Panama" +_es_PE="Spanish Peru" +_es_PR="Spanish Puerto Rico" +_es_PY="Spanish Paraguay" +_es="Spanish" +_es_SV="Spanish El Salvador" +_est_EE="Estonian Estonia" +_est="Estonian" +_estonian="Estonian" +_es_US="Spanish United States" +_es_UY="Spanish Uruguay" +_es_VE="Spanish Venezuela" +_et_EE="Estonian Estonia" +_et="Estonian" +_eu="Basque" +_eu_ES="Basque Spain" +_ewe="Ewe" +_ewe_GH="Ewe Ghana" +_ewe_TG="Ewe Togo" +_fa_AF="Persian Afghanistan" +_fa_IR="Persian Iran" +_fao="Faroese" +_fao_FO="Faroese Faroe Islands" +_fa="Persian" +_fi_FI="Finnish Finland" +_fi="Finnish" +_fil="Filipino" +_fil_PH="Filipino Philippines" +_fin_FI="Finnish Finland" +_fin="Finnish" +_finnish="finnish" +_fo="Faroese" +_fo_FO="Faroese Faroe Islands" +_français="French" +_fr_BE="French Belgium" +_fr_CA="French Canada" +_fr_CH="French Switzerland" +_fre_BE="French Belgium" +_fre_CA="French Canada" +_fre_CH="French Switzerland" +_fre="French" +_fre_FR="French France" +_fre_LU="French Luxembourg" +_fre_MC="French Monaco" +_french="French" +_fre_SN="French Senegal" +_fr="French" +_fr_FR="French France" +_fr_LU="French Luxembourg" +_fr_MC="French Monaco" +_fr_SN="French Senegal" +_fur="Friulian" +_fur_IT="Friulian Italy" +_gaa="Ga" +_gaa_GH="Ga Ghana" +_ga_IE="Irish Ireland" +_ga="Irish" +_galego="Galician" +_galician="Galician" +_geo_GE="Georgian Georgia" +_geo="Georgian" +_ger_AT="German Austria" +_ger_BE="German Belgium" +_ger_CH="German Switzerland" +_ger_DE="German Germany" +_ger="German" +_ger_LI="German Liechtenstein" +_ger_LU="German Luxembourg" +_german="German" +_gez_ER="Geez Eritrea" +_gez_ET="Geez Ethiopia" +_gez="Geez" +_gle_IE="Irish Ireland" +_gle="Irish" +_gl_ES="Galician Spain" +_gl="Galician" +_glg_ES="Galician Spain" +_glg="Galician" +_glv_GB="Manx United Kingdom" +_glv="Manx" +_gre_CY="Greek Cyprus" +_greek="Greek" +_gre="Greek" +_gre_GR="Greek Greece" +_gre_POLYTON="Greek" +_gu="Gujarati" +_gu_IN="Gujarati India" +_guj="Gujarati" +_guj_IN="Gujarati India" +_gv_GB="Manx United Kingdom" +_gv="Manx" +_ha_Arab="Hausa (Arabic)" +_ha_Arab_NG="Hausa Nigeria (Arabic)" +_ha_Arab_SD="Hausa Sudan (Arabic)" +_ha_GH="Hausa Ghana" +_ha="Hausa" +_ha_Latn_GH="Hausa Ghana (Latin)" +_ha_Latn="Hausa (Latin)" +_ha_Latn_NE="Hausa Niger (Latin)" +_ha_Latn_NG="Hausa Nigeria (Latin)" +_ha_NE="Hausa Niger" +_ha_NG="Hausa Nigeria" +_ha_SD="Hausa Sudan" +_hau_Arab="Hausa (Arabic)" +_hau_GH="Hausa Ghana" +_hau_GH_Latn="Hausa Ghana (Latin)" +_hau="Hausa" +_hau_Latn="Hausa (Latin)" +_hau_NE="Hausa Niger" +_hau_NE_Latn="Hausa Niger (Latin)" +_hau_NG_Arab="Hausa Nigeria (Arabic)" +_hau_NG="Hausa Nigeria" +_hau_NG_Latn="Hausa Nigeria (Latin)" +_hau_SD_Arab="Hausa Sudan (Arabic)" +_hau_SD="Hausa Sudan" +_haw="Hawaiian" +_haw_US="Hawaiian United States" +_heb="Hebrew" +_heb_IL="Hebrew Israel" +_hebrew="Hebrew" +_he="Hebrew" +_he_IL="Hebrew Israel" +_hi="Hindi" +_hi_IN="Hindi India" +_hin="Hindi" +_hin_IN="Hindi India" +_hr="Croatian" +_hr_HR="Croatian Croatia" +_hrvatski="Croatian" +_hrv="Croatian" +_hrv_HR="Croatian Croatia" +_hu_HU="Hungarian Hungary" +_hu="Hungarian" +_hungarian="Hungarian" +_hun_HU="Hungarian Hungary" +_hun="Hungarian" +_hy_AM="Armenian Armenia" +_hy_AM_REVISED="Armenian Armenia Revised Orthography" +_hy="Armenian" +_ia="Interlingua" +_ibo="Igbo" +_ibo_NG="Igbo Nigeria" +_ice="Icelandic" +_ice_IS="Icelandic Iceland" +_icelandic="Icelandic" +_id_ID="Indonesian Indonesia" +_id="Indonesian" +_ig="Igbo" +_ig_NG="Igbo Nigeria" +_ii_CN="Sichuan Yi China" +_iii_CN="Sichuan Yi China" +_iii="Sichuan Yi" +_ii="Sichuan Yi" +_iku="Inuktitut" +_ina="Interlingua" +_ind_ID="Indonesian Indonesia" +_ind="Indonesian" +_is="Icelandic" +_is_IS="Icelandic Iceland" +_ita_CH="Italian Switzerland" +_ita="Italian" +_ita_IT="Italian Italy" +_italian="Italian" +_it_CH="Italian Switzerland" +_it="Italian" +_it_IT="Italian Italy" +_iu="Inuktitut" +_iw="Hebrew" +_iw_IL="Hebrew Israel" +_ja="Japanese" +_ja_JP="Japanese Japan" +_japanese="Japanese" +_jpn="Japanese" +_jpn_JP="Japanese Japan" +_ka_GE="Georgian Georgia" +_ka="Georgian" +_kaj="Jju" +_kaj_NG="Jju Nigeria" +_kal_GL="Kalaallisut Greenland" +_kal="Kalaallisut" +_kam="Kamba" +_kam_KE="Kamba Kenya" +_kan_IN="Kannada India" +_kan="Kannada" +_kaz_Cyrl="Kazakh (Cyrillic)" +_kaz="Kazakh" +_kaz_KZ_Cyrl="Kazakh Kazakhstan (Cyrillic)" +_kaz_KZ="Kazakh Kazakhstan" +_kcg_NG="Tyap Nigeria" +_kcg="Tyap" +_kfo_CI="Koro Ivory Coast" +_kfo="Koro" +_khm_KH="Khmer Cambodia" +_khm="Khmer" +_kin="Kinyarwanda" +_kin_RW="Kinyarwanda Rwanda" +_kir_KG="Kirghiz Kyrgyzstan" +_kir="Kirghiz" +_kk_Cyrl="Kazakh (Cyrillic)" +_kk_Cyrl_KZ="Kazakh Kazakhstan (Cyrillic)" +_kk="Kazakh" +_kk_KZ="Kazakh Kazakhstan" +_kl_GL="Kalaallisut Greenland" +_kl="Kalaallisut" +_km_KH="Khmer Cambodia" +_km="Khmer" +_kn_IN="Kannada India" +_kn="Kannada" +_kok_IN="Konkani India" +_kok="Konkani" +_ko="Korean" +_ko_KR="Korean South Korea" +_korean="Korean" +_kor="Korean" +_kor_KR="Korean South Korea" +_kpe_GN="Kpelle Guinea" +_kpe="Kpelle" +_kpe_LR="Kpelle Liberia" +_ku_Arab="Kurdish (Arabic)" +_ku="Kurdish" +_ku_Latn="Kurdish (Latin)" +_ku_Latn_TR="Kurdish Turkey (Latin)" +_kur_Arab="Kurdish (Arabic)" +_kur="Kurdish" +_kur_Latn="Kurdish (Latin)" +_kur_TR="Kurdish Turkey" +_kur_TR_Latn="Kurdish Turkey (Latin)" +_ku_TR="Kurdish Turkey" +_kw="Cornish" +_kw_GB="Cornish United Kingdom" +_ky_KG="Kirghiz Kyrgyzstan" +_ky="Kirghiz" +_lao_LA="Lao Laos" +_lao="Lao" +_lav="Latvian" +_lav_LV="Latvian Latvia" +_lin_CD="Lingala Congo - Kinshasa" +_lin_CG="Lingala Congo - Brazzaville" +_lin="Lingala" +_lithuanian="Lithuanian" +_lit="Lithuanian" +_lit_LT="Lithuanian Lithuania" +_ln_CD="Lingala Congo - Kinshasa" +_ln_CG="Lingala Congo - Brazzaville" +_ln="Lingala" +_lo_LA="Lao Laos" +_lo="Lao" +_lt="Lithuanian" +_lt_LT="Lithuanian Lithuania" +_lv="Latvian" +_lv_LV="Latvian Latvia" +_mac="Macedonian" +_mac_MK="Macedonian Macedonia" +_mal_IN="Malayalam India" +_mal="Malayalam" +_mar_IN="Marathi India" +_mar="Marathi" +_may_BN="Malay Brunei" +_may="Malay" +_may_MY="Malay Malaysia" +_mk="Macedonian" +_mk_MK="Macedonian Macedonia" +_ml_IN="Malayalam India" +_ml="Malayalam" +_mlt="Maltese" +_mlt_MT="Maltese Malta" +_mn_CN="Mongolian China" +_mn_Cyrl_MN="Mongolian Mongolia (Cyrillic)" +_mn_Cyrl="Mongolian (Cyrillic)" +_mn_MN="Mongolian Mongolia" +_mn_Mong_CN="Mongolian China (Mongolian)" +_mn_Mong="Mongolian (Mongolian)" +_mn="Mongolian" +_mol="Moldavian" +_mo="Moldavian" +_mon_CN_Mong="Mongolian China (Mongolian)" +_mon_CN="Mongolian China" +_mon_Cyrl="Mongolian (Cyrillic)" +_mon_MN_Cyrl="Mongolian Mongolia (Cyrillic)" +_mon_MN="Mongolian Mongolia" +_mon_Mong="Mongolian (Mongolian)" +_mon="Mongolian" +_mr_IN="Marathi India" +_mr="Marathi" +_ms_BN="Malay Brunei" +_ms="Malay" +_ms_MY="Malay Malaysia" +_mt="Maltese" +_mt_MT="Maltese Malta" +_my="Burmese" +_my_MM="Burmese Myanmar" +_nbl="South Ndebele" +_nbl_ZA="South Ndebele South Africa" +_nb_NO="Norwegian BokmÃ¥l Norway" +_nb="Norwegian BokmÃ¥l" +_ne_IN="Nepali India" +_ne="Nepali" +_ne_NP="Nepali Nepal" +_nep_IN="Nepali India" +_nep="Nepali" +_nep_NP="Nepali Nepal" +_nl_BE="Dutch Belgium" +_nl="Dutch" +_nl_NL="Dutch Netherlands" +_nn_NO="Norwegian Nynorsk Norway" +_nn="Norwegian Nynorsk" +_nno_NO="Norwegian Nynorsk Norway" +_nno="Norwegian Nynorsk" +_nob_NO="Norwegian BokmÃ¥l Norway" +_nob="Norwegian BokmÃ¥l" +_no_NO="Norwegian Nynorsk Norway" +_no_NO_NY="Norwegian Nynorsk Norway" +_no="Norwegian" +_no="Norwegian Nynorsk" +_nor="Norwegian" +_norwegian="Norwegian" +_nr="South Ndebele" +_nr_ZA="South Ndebele South Africa" +_nso="Northern Sotho" +_nso_ZA="Northern Sotho South Africa" +_nya_MW="Nyanja Malawi" +_nya="Nyanja" +_ny_MW="Nyanja Malawi" +_nynorsk="Norwegian Nynorsk" +_ny="Nyanja" +_om_ET="Oromo Ethiopia" +_om_KE="Oromo Kenya" +_om="Oromo" +_ori_IN="Oriya India" +_or_IN="Oriya India" +_ori="Oriya" +_orm_ET="Oromo Ethiopia" +_orm_KE="Oromo Kenya" +_orm="Oromo" +_or="Oriya" +_pa_Arab_PK="Punjabi Pakistan (Arabic)" +_pa_Arab="Punjabi (Arabic)" +_pa_Guru_IN="Punjabi India (Gurmukhi)" +_pa_Guru="Punjabi (Gurmukhi)" +_pa_IN="Punjabi India" +_pan_Arab="Punjabi (Arabic)" +_pan_Guru="Punjabi (Gurmukhi)" +_pan_IN_Guru="Punjabi India (Gurmukhi)" +_pan_IN="Punjabi India" +_pan_PK_Arab="Punjabi Pakistan (Arabic)" +_pan_PK="Punjabi Pakistan" +_pan="Punjabi" +_pa_PK="Punjabi Pakistan" +_pa="Punjabi" +_per_AF="Persian Afghanistan" +_per_IR="Persian Iran" +_per="Persian" +_pl_PL="Polish Poland" +_pl="Polish" +_polish="Polish" +_pol_PL="Polish Poland" +_pol="Polish" +_por_BR="Portuguese Brazil" +_por="Portuguese" +_por_PT="Portuguese Portugal" +_portuguese="Portuguese" +_POSIX="English United States Computer" +_ps_AF="Pashto Afghanistan" +_ps="Pashto" +_pt_BR="Portuguese Brazil" +_pt="Portuguese" +_pt_PT="Portuguese Portugal" +_pus_AF="Pashto Afghanistan" +_pus="Pashto" +_romanian="Romanian" +_ro_MD="Romanian Moldova" +_root="Root" +_ro="Romanian" +_ro_RO="Romanian Romania" +_rum_MD="Romanian Moldova" +_rum="Romanian" +_rum_RO="Romanian Romania" +_ru_RU="Russian Russia" +_ru="Russian" +_rus_RU="Russian Russia" +_rus="Russian" +_russian="Russian" +_rus_UA="Russian Ukraine" +_ru_UA="Russian Ukraine" +_rw="Kinyarwanda" +_rw_RW="Kinyarwanda Rwanda" +_sa_IN="Sanskrit India" +_san_IN="Sanskrit India" +_san="Sanskrit" +_sa="Sanskrit" +_se_FI="Northern Sami Finland" +_se_NO="Northern Sami Norway" +_se="Northern Sami" +_sh_BA="Serbo-Croatian Bosnia and Herzegovina" +_sh_CS="Serbo-Croatian Serbia and Montenegro" +_sh="Serbo-Croatian" +_sh_YU="Serbo-Croatian" +_sid_ET="Sidamo Ethiopia" +_sid="Sidamo" +_si_LK="Sinhala Sri Lanka" +_sin_LK="Sinhala Sri Lanka" +_sin="Sinhala" +_si="Sinhala" +_sk_SK="Slovak Slovakia" +_sk="Slovak" +_slo_SK="Slovak Slovakia" +_slo="Slovak" +_slovak="Slovak" +_slovene="Slovenian" +_slovenian="Slovenian" +_sl_SI="Slovenian Slovenia" +_sl="Slovenian" +_slv_SI="Slovenian Slovenia" +_slv="Slovenian" +_sme_FI="Northern Sami Finland" +_sme_NO="Northern Sami Norway" +_sme="Northern Sami" +_so_DJ="Somali Djibouti" +_so_ET="Somali Ethiopia" +_so_KE="Somali Kenya" +_som_DJ="Somali Djibouti" +_som_ET="Somali Ethiopia" +_som_KE="Somali Kenya" +_som="Somali" +_som_SO="Somali Somalia" +_so="Somali" +_so_SO="Somali Somalia" +_sot_LS="Southern Sotho Lesotho" +_sot="Southern Sotho" +_sot_ZA="Southern Sotho South Africa" +_spa_AR="Spanish Argentina" +_spa_BO="Spanish Bolivia" +_spa_CL="Spanish Chile" +_spa_CO="Spanish Colombia" +_spa_CR="Spanish Costa Rica" +_spa_DO="Spanish Dominican Republic" +_spa_EC="Spanish Ecuador" +_spa_ES="Spanish Spain" +_spa_GT="Spanish Guatemala" +_spa_HN="Spanish Honduras" +_spa_MX="Spanish Mexico" +_spanish="Spanish" +_spa_NI="Spanish Nicaragua" +_spa_PA="Spanish Panama" +_spa_PE="Spanish Peru" +_spa_PR="Spanish Puerto Rico" +_spa_PY="Spanish Paraguay" +_spa="Spanish" +_spa_SV="Spanish El Salvador" +_spa_US="Spanish United States" +_spa_UY="Spanish Uruguay" +_spa_VE="Spanish Venezuela" +_sq_AL="Albanian Albania" +_sq="Albanian" +_sr_BA="Serbian Bosnia and Herzegovina" +_sr_CS="Serbian Serbia and Montenegro" +_sr_Cyrl_BA="Serbian Bosnia and Herzegovina (Cyrillic)" +_sr_Cyrl_CS="Serbian Serbia and Montenegro (Cyrillic)" +_sr_Cyrl_ME="Serbian Montenegro (Cyrillic)" +_sr_Cyrl_RS="Serbian Serbia (Cyrillic)" +_sr_Cyrl="Serbian (Cyrillic)" +_sr_Cyrl_YU="Serbian (Cyrillic)" +_sr_Latn_BA="Serbian Bosnia and Herzegovina (Latin)" +_sr_Latn_CS="Serbian Serbia and Montenegro (Latin)" +_sr_Latn_ME="Serbian Montenegro (Latin)" +_sr_Latn_RS="Serbian Serbia (Latin)" +_sr_Latn="Serbian (Latin)" +_sr_Latn_YU="Serbian (Latin)" +_sr_ME="Serbian Montenegro" +_srp_BA_Cyrl="Serbian Bosnia and Herzegovina (Cyrillic)" +_srp_BA_Latn="Serbian Bosnia and Herzegovina (Latin)" +_srp_BA="Serbian Bosnia and Herzegovina" +_srp_CS_Cyrl="Serbian Serbia and Montenegro (Cyrillic)" +_srp_CS_Latn="Serbian Serbia and Montenegro (Latin)" +_srp_CS="Serbian Serbia and Montenegro" +_srp_Cyrl="Serbian (Cyrillic)" +_srp_Latn="Serbian (Latin)" +_srp_ME_Cyrl="Serbian Montenegro (Cyrillic)" +_srp_ME_Latn="Serbian Montenegro (Latin)" +_srp_ME="Serbian Montenegro" +_srp_RS_Cyrl="Serbian Serbia (Cyrillic)" +_srp_RS_Latn="Serbian Serbia (Latin)" +_srp_RS="Serbian Serbia" +_srp="Serbian" +_srp_YU_Cyrl="Serbian (Cyrillic)" +_srp_YU_Latn="Serbian (Latin)" +_srp_YU="Serbian" +_sr_RS="Serbian Serbia" +_sr="Serbian" +_sr_YU="Serbian" +_ss="Swati" +_ss_SZ="Swati Swaziland" +_ssw="Swati" +_ssw_SZ="Swati Swaziland" +_ssw_ZA="Swati South Africa" +_ss_ZA="Swati South Africa" +_st_LS="Southern Sotho Lesotho" +_st="Southern Sotho" +_st_ZA="Southern Sotho South Africa" +_sv_FI="Swedish Finland" +_sv_SE="Swedish Sweden" +_sv="Swedish" +_swa_KE="Swahili Kenya" +_swa="Swahili" +_swa_TZ="Swahili Tanzania" +_swedish="Swedish" +_swe_FI="Swedish Finland" +_swe_SE="Swedish Sweden" +_swe="Swedish" +_sw_KE="Swahili Kenya" +_sw="Swahili" +_sw_TZ="Swahili Tanzania" +_syr="Syriac" +_syr_SY="Syriac Syria" +_ta_IN="Tamil India" +_tam_IN="Tamil India" +_tam="Tamil" +_ta="Tamil" +_tat_RU="Tatar Russia" +_tat="Tatar" +_te_IN="Telugu India" +_tel_IN="Telugu India" +_tel="Telugu" +_te="Telugu" +_tg_Cyrl="Tajik (Cyrillic)" +_tg_Cyrl_TJ="Tajik Tajikistan (Cyrillic)" +_tgk_Cyrl="Tajik (Cyrillic)" +_tgk="Tajik" +_tgk_TJ_Cyrl="Tajik Tajikistan (Cyrillic)" +_tgk_TJ="Tajik Tajikistan" +_tgl="Tagalog" +_tg="Tajik" +_tg_TJ="Tajik Tajikistan" +_thai="Thai" +_tha="Thai" +_tha_TH="Thai Thailand" +_th="Thai" +_th_TH="Thai Thailand" +_ti_ER="Tigrinya Eritrea" +_ti_ET="Tigrinya Ethiopia" +_tig_ER="Tigre Eritrea" +_tig="Tigre" +_tir_ER="Tigrinya Eritrea" +_tir_ET="Tigrinya Ethiopia" +_tir="Tigrinya" +_ti="Tigrinya" +_tl="Tagalog" +_tn="Tswana" +_tn_ZA="Tswana South Africa" +_ton="Tonga" +_ton_TO="Tonga Tonga" +_to="Tonga" +_to_TO="Tonga Tonga" +_tr_TR="Turkish Turkey" +_tr="Turkish" +_tsn="Tswana" +_tsn_ZA="Tswana South Africa" +_tso="Tsonga" +_tso_ZA="Tsonga South Africa" +_ts="Tsonga" +_ts_ZA="Tsonga South Africa" +_tt_RU="Tatar Russia" +_tt="Tatar" +_turkish="Turkish" +_tur_TR="Turkish Turkey" +_tur="Turkish" +_ug_Arab_CN="Uighur China (Arabic)" +_ug_Arab="Uighur (Arabic)" +_ug_CN="Uighur China" +_ug="Uighur" +_uig_Arab="Uighur (Arabic)" +_uig_CN_Arab="Uighur China (Arabic)" +_uig_CN="Uighur China" +_uig="Uighur" +_ukr_UA="Ukrainian Ukraine" +_ukr="Ukrainian" +_uk_UA="Ukrainian Ukraine" +_uk="Ukrainian" +_urd_IN="Urdu India" +_urd_PK="Urdu Pakistan" +_urd="Urdu" +_ur_IN="Urdu India" +_ur_PK="Urdu Pakistan" +_ur="Urdu" +_uz_AF="Uzbek Afghanistan" +_uz_Arab_AF="Uzbek Afghanistan (Arabic)" +_uz_Arab="Uzbek (Arabic)" +_uzb_AF_Arab="Uzbek Afghanistan (Arabic)" +_uzb_AF="Uzbek Afghanistan" +_uzb_Arab="Uzbek (Arabic)" +_uzb_Cyrl="Uzbek (Cyrillic)" +_uzb_Latn="Uzbek (Latin)" +_uzb="Uzbek" +_uzb_UZ_Cyrl="Uzbek Uzbekistan (Cyrillic)" +_uzb_UZ_Latn="Uzbek Uzbekistan (Latin)" +_uzb_UZ="Uzbek Uzbekistan" +_uz_Cyrl="Uzbek (Cyrillic)" +_uz_Cyrl_UZ="Uzbek Uzbekistan (Cyrillic)" +_uz_Latn="Uzbek (Latin)" +_uz_Latn_UZ="Uzbek Uzbekistan (Latin)" +_uz="Uzbek" +_uz_UZ="Uzbek Uzbekistan" +_ven="Venda" +_ven_ZA="Venda South Africa" +_ve="Venda" +_ve_ZA="Venda South Africa" +_vie="Vietnamese" +_vie_VN="Vietnamese Vietnam" +_vi="Vietnamese" +_vi_VN="Vietnamese Vietnam" +_wal_ET="Walamo Ethiopia" +_wal="Walamo" +_wel_GB="Welsh United Kingdom" +_wel="Welsh" +_wo_Latn_SN="Wolof Senegal (Latin)" +_wo_Latn="Wolof (Latin)" +_wol_Latn="Wolof (Latin)" +_wol_SN_Latn="Wolof Senegal (Latin)" +_wol_SN="Wolof Senegal" +_wol="Wolof" +_wo_SN="Wolof Senegal" +_wo="Wolof" +_xho="Xhosa" +_xho_ZA="Xhosa South Africa" +_xh="Xhosa" +_xh_ZA="Xhosa South Africa" +_yo_NG="Yoruba Nigeria" +_yor_NG="Yoruba Nigeria" +_yor="Yoruba" +_yo="Yoruba" +_zh="Chinese" +_zh_CN="Chinese China" +_zh_Hans="Chinese (Simplified Han)" +_zh_Hans_CN="Chinese China (Simplified Han)" +_zh_Hans_HK="Chinese Hong Kong SAR China (Simplified Han)" +_zh_Hans_MO="Chinese Macau SAR China (Simplified Han)" +_zh_Hans_SG="Chinese Singapore (Simplified Han)" +_zh_Hant="Chinese (Traditional Han)" +_zh_Hant_HK="Chinese Hong Kong SAR China (Traditional Han)" +_zh_Hant_MO="Chinese Macau SAR China (Traditional Han)" +_zh_Hant_TW="Chinese Taiwan (Traditional Han)" +_zh_HK="Chinese Hong Kong SAR China" +_zh_MO="Chinese Macau SAR China" +_zh_SG="Chinese Singapore" +_zh_TW="Chinese Taiwan" +_zul_ZA="Zulu South Africa" +_zul="Zulu" +_zu_ZA="Zulu South Africa" +_zu="Zulu" diff --git a/root/opt/phpsysinfo/data/osnames.ini b/root/opt/phpsysinfo/data/osnames.ini new file mode 100644 index 0000000..08751d6 --- /dev/null +++ b/root/opt/phpsysinfo/data/osnames.ini @@ -0,0 +1,34 @@ +[Android] +1.0="Apple Pie" +1.1="Banana Bread" +1.5="Cupcake" +1.6="Donut" +2.0="Eclair" +2.1="Eclair" +2.2="Froyo" +2.3="Gingerbread" +3.0="Honeycomb" +3.1="Honeycomb" +3.2="Honeycomb" +4.0="Ice Cream Sandwich" +4.1="Jelly Bean" +4.2="Jelly Bean" +4.3="Jelly Bean" +4.4="KitKat" +5.0="Lollipop" +5.1="Lollipop" +6.0="Marshmallow" + +[OS X] +10.0="Cheetah" +10.1="Puma" +10.2="Jaguar" +10.3="Panther" +10.4="Tiger" +10.5="Leopard" +10.6="Snow Leopard" +10.7="Lion" +10.8="Mountain Lion" +10.9="Mavericks" +10.10="Yosemite" +10.11="El Capitan" diff --git a/root/opt/phpsysinfo/gfx/ajax-loader.gif b/root/opt/phpsysinfo/gfx/ajax-loader.gif new file mode 100644 index 0000000..028e8e6 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/ajax-loader.gif differ diff --git a/root/opt/phpsysinfo/gfx/ajaxLoader.gif b/root/opt/phpsysinfo/gfx/ajaxLoader.gif new file mode 100644 index 0000000..2b35424 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/ajaxLoader.gif differ diff --git a/root/opt/phpsysinfo/gfx/attention.png b/root/opt/phpsysinfo/gfx/attention.png new file mode 100644 index 0000000..4170d83 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/attention.png differ diff --git a/root/opt/phpsysinfo/gfx/body.png b/root/opt/phpsysinfo/gfx/body.png new file mode 100644 index 0000000..6bcf6d3 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/body.png differ diff --git a/root/opt/phpsysinfo/gfx/bullet_toggle_minus.png b/root/opt/phpsysinfo/gfx/bullet_toggle_minus.png new file mode 100644 index 0000000..b47ce55 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/bullet_toggle_minus.png differ diff --git a/root/opt/phpsysinfo/gfx/bullet_toggle_plus.png b/root/opt/phpsysinfo/gfx/bullet_toggle_plus.png new file mode 100644 index 0000000..9ab4a89 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/bullet_toggle_plus.png differ diff --git a/root/opt/phpsysinfo/gfx/close.gif b/root/opt/phpsysinfo/gfx/close.gif new file mode 100644 index 0000000..fa09621 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/close.gif differ diff --git a/root/opt/phpsysinfo/gfx/favicon.ico b/root/opt/phpsysinfo/gfx/favicon.ico new file mode 100644 index 0000000..cda1799 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/favicon.ico differ diff --git a/root/opt/phpsysinfo/gfx/favicon.png b/root/opt/phpsysinfo/gfx/favicon.png new file mode 100644 index 0000000..80dd64e Binary files /dev/null and b/root/opt/phpsysinfo/gfx/favicon.png differ diff --git a/root/opt/phpsysinfo/gfx/html.gif b/root/opt/phpsysinfo/gfx/html.gif new file mode 100644 index 0000000..9c5d471 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/html.gif differ diff --git a/root/opt/phpsysinfo/gfx/htmlwarn.gif b/root/opt/phpsysinfo/gfx/htmlwarn.gif new file mode 100644 index 0000000..78cbef3 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/htmlwarn.gif differ diff --git a/root/opt/phpsysinfo/gfx/images/4MLinux.png b/root/opt/phpsysinfo/gfx/images/4MLinux.png new file mode 100644 index 0000000..e504fc7 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/4MLinux.png differ diff --git a/root/opt/phpsysinfo/gfx/images/AIX.png b/root/opt/phpsysinfo/gfx/images/AIX.png new file mode 100644 index 0000000..f3314f5 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/AIX.png differ diff --git a/root/opt/phpsysinfo/gfx/images/ALT.png b/root/opt/phpsysinfo/gfx/images/ALT.png new file mode 100644 index 0000000..e9c64a5 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/ALT.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Alpine.png b/root/opt/phpsysinfo/gfx/images/Alpine.png new file mode 100644 index 0000000..a0963a2 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Alpine.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Amazon.png b/root/opt/phpsysinfo/gfx/images/Amazon.png new file mode 100644 index 0000000..3ed73c2 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Amazon.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Android.png b/root/opt/phpsysinfo/gfx/images/Android.png new file mode 100644 index 0000000..fdf819e Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Android.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Apple.png b/root/opt/phpsysinfo/gfx/images/Apple.png new file mode 100644 index 0000000..ac1178d Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Apple.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Arch.png b/root/opt/phpsysinfo/gfx/images/Arch.png new file mode 100644 index 0000000..eb35007 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Arch.png differ diff --git a/root/opt/phpsysinfo/gfx/images/BOSS.png b/root/opt/phpsysinfo/gfx/images/BOSS.png new file mode 100644 index 0000000..23745c6 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/BOSS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Calculate.png b/root/opt/phpsysinfo/gfx/images/Calculate.png new file mode 100644 index 0000000..808b295 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Calculate.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Canaima.png b/root/opt/phpsysinfo/gfx/images/Canaima.png new file mode 100644 index 0000000..7388c47 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Canaima.png differ diff --git a/root/opt/phpsysinfo/gfx/images/CentOS.png b/root/opt/phpsysinfo/gfx/images/CentOS.png new file mode 100644 index 0000000..e2c8a11 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/CentOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Chakra.png b/root/opt/phpsysinfo/gfx/images/Chakra.png new file mode 100644 index 0000000..06a5609 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Chakra.png differ diff --git a/root/opt/phpsysinfo/gfx/images/ClearOS.png b/root/opt/phpsysinfo/gfx/images/ClearOS.png new file mode 100644 index 0000000..f2a1f2e Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/ClearOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Cloud.png b/root/opt/phpsysinfo/gfx/images/Cloud.png new file mode 100644 index 0000000..0b0fd83 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Cloud.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Cobalt.png b/root/opt/phpsysinfo/gfx/images/Cobalt.png new file mode 100644 index 0000000..674def8 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Cobalt.png differ diff --git a/root/opt/phpsysinfo/gfx/images/CoreOS.png b/root/opt/phpsysinfo/gfx/images/CoreOS.png new file mode 100644 index 0000000..c955f77 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/CoreOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Crux.png b/root/opt/phpsysinfo/gfx/images/Crux.png new file mode 100644 index 0000000..ba889da Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Crux.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Darwin.png b/root/opt/phpsysinfo/gfx/images/Darwin.png new file mode 100644 index 0000000..a4d8d2d Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Darwin.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Debian.png b/root/opt/phpsysinfo/gfx/images/Debian.png new file mode 100644 index 0000000..00093f9 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Debian.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Deepin.png b/root/opt/phpsysinfo/gfx/images/Deepin.png new file mode 100644 index 0000000..8a9e502 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Deepin.png differ diff --git a/root/opt/phpsysinfo/gfx/images/DragonFly.png b/root/opt/phpsysinfo/gfx/images/DragonFly.png new file mode 100644 index 0000000..e51e1ae Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/DragonFly.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Eisfair.png b/root/opt/phpsysinfo/gfx/images/Eisfair.png new file mode 100644 index 0000000..3450cef Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Eisfair.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Fedora.png b/root/opt/phpsysinfo/gfx/images/Fedora.png new file mode 100644 index 0000000..883e96a Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Fedora.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Foresight.png b/root/opt/phpsysinfo/gfx/images/Foresight.png new file mode 100644 index 0000000..34d427d Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Foresight.png differ diff --git a/root/opt/phpsysinfo/gfx/images/FreeBSD.png b/root/opt/phpsysinfo/gfx/images/FreeBSD.png new file mode 100644 index 0000000..597afb5 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/FreeBSD.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Frugalware.png b/root/opt/phpsysinfo/gfx/images/Frugalware.png new file mode 100644 index 0000000..b30c4cd Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Frugalware.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Fuduntu.png b/root/opt/phpsysinfo/gfx/images/Fuduntu.png new file mode 100644 index 0000000..73e2e43 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Fuduntu.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Generations.png b/root/opt/phpsysinfo/gfx/images/Generations.png new file mode 100644 index 0000000..f3adfd0 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Generations.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Gentoo.png b/root/opt/phpsysinfo/gfx/images/Gentoo.png new file mode 100644 index 0000000..d806c57 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Gentoo.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Gobo.png b/root/opt/phpsysinfo/gfx/images/Gobo.png new file mode 100644 index 0000000..9efde30 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Gobo.png differ diff --git a/root/opt/phpsysinfo/gfx/images/HPUX.png b/root/opt/phpsysinfo/gfx/images/HPUX.png new file mode 100644 index 0000000..6f55dd4 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/HPUX.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Haiku.png b/root/opt/phpsysinfo/gfx/images/Haiku.png new file mode 100644 index 0000000..21fb376 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Haiku.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Handy.png b/root/opt/phpsysinfo/gfx/images/Handy.png new file mode 100644 index 0000000..436de66 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Handy.png differ diff --git a/root/opt/phpsysinfo/gfx/images/IPFire.png b/root/opt/phpsysinfo/gfx/images/IPFire.png new file mode 100644 index 0000000..5e7870f Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/IPFire.png differ diff --git a/root/opt/phpsysinfo/gfx/images/KaOS.png b/root/opt/phpsysinfo/gfx/images/KaOS.png new file mode 100644 index 0000000..ea6bdad Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/KaOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Korora.png b/root/opt/phpsysinfo/gfx/images/Korora.png new file mode 100644 index 0000000..8abd2f3 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Korora.png differ diff --git a/root/opt/phpsysinfo/gfx/images/LFS.png b/root/opt/phpsysinfo/gfx/images/LFS.png new file mode 100644 index 0000000..3796f48 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/LFS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Linaro.png b/root/opt/phpsysinfo/gfx/images/Linaro.png new file mode 100644 index 0000000..b076f7a Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Linaro.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Lunar.png b/root/opt/phpsysinfo/gfx/images/Lunar.png new file mode 100644 index 0000000..4d25176 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Lunar.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Mageia.png b/root/opt/phpsysinfo/gfx/images/Mageia.png new file mode 100644 index 0000000..0bfd1a8 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Mageia.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Mandrake.png b/root/opt/phpsysinfo/gfx/images/Mandrake.png new file mode 100644 index 0000000..09ccd20 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Mandrake.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Manjaro.png b/root/opt/phpsysinfo/gfx/images/Manjaro.png new file mode 100644 index 0000000..ae3a642 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Manjaro.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Mer.png b/root/opt/phpsysinfo/gfx/images/Mer.png new file mode 100644 index 0000000..9048964 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Mer.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Minix.png b/root/opt/phpsysinfo/gfx/images/Minix.png new file mode 100644 index 0000000..73feadb Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Minix.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Mint.png b/root/opt/phpsysinfo/gfx/images/Mint.png new file mode 100644 index 0000000..a886bb3 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Mint.png differ diff --git a/root/opt/phpsysinfo/gfx/images/NetBSD.png b/root/opt/phpsysinfo/gfx/images/NetBSD.png new file mode 100644 index 0000000..d3ea334 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/NetBSD.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Netrunner.png b/root/opt/phpsysinfo/gfx/images/Netrunner.png new file mode 100644 index 0000000..7616118 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Netrunner.png differ diff --git a/root/opt/phpsysinfo/gfx/images/NixOS.png b/root/opt/phpsysinfo/gfx/images/NixOS.png new file mode 100644 index 0000000..054a0b0 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/NixOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/OpenBSD.png b/root/opt/phpsysinfo/gfx/images/OpenBSD.png new file mode 100644 index 0000000..84da5c7 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/OpenBSD.png differ diff --git a/root/opt/phpsysinfo/gfx/images/OpenMandriva.png b/root/opt/phpsysinfo/gfx/images/OpenMandriva.png new file mode 100644 index 0000000..0df0ebf Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/OpenMandriva.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Oracle.png b/root/opt/phpsysinfo/gfx/images/Oracle.png new file mode 100644 index 0000000..a9b1de1 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Oracle.png differ diff --git a/root/opt/phpsysinfo/gfx/images/PCLinuxOS.png b/root/opt/phpsysinfo/gfx/images/PCLinuxOS.png new file mode 100644 index 0000000..4a3a4bb Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/PCLinuxOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/PLD.png b/root/opt/phpsysinfo/gfx/images/PLD.png new file mode 100644 index 0000000..2b09d7d Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/PLD.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Parsix.png b/root/opt/phpsysinfo/gfx/images/Parsix.png new file mode 100644 index 0000000..9cddb1d Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Parsix.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Pear.png b/root/opt/phpsysinfo/gfx/images/Pear.png new file mode 100644 index 0000000..8811a7b Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Pear.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Peppermint.png b/root/opt/phpsysinfo/gfx/images/Peppermint.png new file mode 100644 index 0000000..59d8e68 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Peppermint.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Pisi.png b/root/opt/phpsysinfo/gfx/images/Pisi.png new file mode 100644 index 0000000..3d44955 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Pisi.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Porteus.png b/root/opt/phpsysinfo/gfx/images/Porteus.png new file mode 100644 index 0000000..0ddafdb Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Porteus.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Puppy.png b/root/opt/phpsysinfo/gfx/images/Puppy.png new file mode 100644 index 0000000..b4835e8 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Puppy.png differ diff --git a/root/opt/phpsysinfo/gfx/images/QNX.png b/root/opt/phpsysinfo/gfx/images/QNX.png new file mode 100644 index 0000000..cb0f559 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/QNX.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Qubes.png b/root/opt/phpsysinfo/gfx/images/Qubes.png new file mode 100644 index 0000000..96d568a Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Qubes.png differ diff --git a/root/opt/phpsysinfo/gfx/images/ROSA.png b/root/opt/phpsysinfo/gfx/images/ROSA.png new file mode 100644 index 0000000..de0a0b5 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/ROSA.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Raspbian.png b/root/opt/phpsysinfo/gfx/images/Raspbian.png new file mode 100644 index 0000000..8c2ced5 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Raspbian.png differ diff --git a/root/opt/phpsysinfo/gfx/images/ReactOS.png b/root/opt/phpsysinfo/gfx/images/ReactOS.png new file mode 100644 index 0000000..37495b6 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/ReactOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/RedFlag.png b/root/opt/phpsysinfo/gfx/images/RedFlag.png new file mode 100644 index 0000000..c291121 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/RedFlag.png differ diff --git a/root/opt/phpsysinfo/gfx/images/RedHat.png b/root/opt/phpsysinfo/gfx/images/RedHat.png new file mode 100644 index 0000000..2092015 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/RedHat.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Rubix.png b/root/opt/phpsysinfo/gfx/images/Rubix.png new file mode 100644 index 0000000..ace28b0 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Rubix.png differ diff --git a/root/opt/phpsysinfo/gfx/images/SMEServer.png b/root/opt/phpsysinfo/gfx/images/SMEServer.png new file mode 100644 index 0000000..75712f6 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/SMEServer.png differ diff --git a/root/opt/phpsysinfo/gfx/images/SMS.png b/root/opt/phpsysinfo/gfx/images/SMS.png new file mode 100644 index 0000000..fdabecd Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/SMS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/SUSE.png b/root/opt/phpsysinfo/gfx/images/SUSE.png new file mode 100644 index 0000000..f4a3536 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/SUSE.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Sabayon.png b/root/opt/phpsysinfo/gfx/images/Sabayon.png new file mode 100644 index 0000000..8213c2b Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Sabayon.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Salix.png b/root/opt/phpsysinfo/gfx/images/Salix.png new file mode 100644 index 0000000..fe1b474 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Salix.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Scientific.png b/root/opt/phpsysinfo/gfx/images/Scientific.png new file mode 100644 index 0000000..cb5621f Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Scientific.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Semplice.png b/root/opt/phpsysinfo/gfx/images/Semplice.png new file mode 100644 index 0000000..9875c7e Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Semplice.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Slackware.png b/root/opt/phpsysinfo/gfx/images/Slackware.png new file mode 100644 index 0000000..b711e48 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Slackware.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Slax.png b/root/opt/phpsysinfo/gfx/images/Slax.png new file mode 100644 index 0000000..6f01c94 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Slax.png differ diff --git a/root/opt/phpsysinfo/gfx/images/SliTaz.png b/root/opt/phpsysinfo/gfx/images/SliTaz.png new file mode 100644 index 0000000..8dd4293 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/SliTaz.png differ diff --git a/root/opt/phpsysinfo/gfx/images/SolusOS.png b/root/opt/phpsysinfo/gfx/images/SolusOS.png new file mode 100644 index 0000000..522d160 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/SolusOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/SolydXK.png b/root/opt/phpsysinfo/gfx/images/SolydXK.png new file mode 100644 index 0000000..2143593 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/SolydXK.png differ diff --git a/root/opt/phpsysinfo/gfx/images/StartOS.png b/root/opt/phpsysinfo/gfx/images/StartOS.png new file mode 100644 index 0000000..a133f42 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/StartOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/SteamOS.png b/root/opt/phpsysinfo/gfx/images/SteamOS.png new file mode 100644 index 0000000..ed61bc3 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/SteamOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/SunOS.png b/root/opt/phpsysinfo/gfx/images/SunOS.png new file mode 100644 index 0000000..e7de00f Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/SunOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Synology.png b/root/opt/phpsysinfo/gfx/images/Synology.png new file mode 100644 index 0000000..06662d5 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Synology.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Tails.png b/root/opt/phpsysinfo/gfx/images/Tails.png new file mode 100644 index 0000000..4058145 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Tails.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Tanglu.png b/root/opt/phpsysinfo/gfx/images/Tanglu.png new file mode 100644 index 0000000..f215845 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Tanglu.png differ diff --git a/root/opt/phpsysinfo/gfx/images/TinyCore.png b/root/opt/phpsysinfo/gfx/images/TinyCore.png new file mode 100644 index 0000000..cf72da4 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/TinyCore.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Tizen.png b/root/opt/phpsysinfo/gfx/images/Tizen.png new file mode 100644 index 0000000..08100f4 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Tizen.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Trisquel.png b/root/opt/phpsysinfo/gfx/images/Trisquel.png new file mode 100644 index 0000000..d632108 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Trisquel.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Trustix.png b/root/opt/phpsysinfo/gfx/images/Trustix.png new file mode 100644 index 0000000..6b2dd70 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Trustix.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Turbo.png b/root/opt/phpsysinfo/gfx/images/Turbo.png new file mode 100644 index 0000000..4d040d9 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Turbo.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Ubuntu.png b/root/opt/phpsysinfo/gfx/images/Ubuntu.png new file mode 100644 index 0000000..a0ea4a4 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Ubuntu.png differ diff --git a/root/opt/phpsysinfo/gfx/images/UltimateEdition.png b/root/opt/phpsysinfo/gfx/images/UltimateEdition.png new file mode 100644 index 0000000..9eb8f0b Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/UltimateEdition.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Vector.png b/root/opt/phpsysinfo/gfx/images/Vector.png new file mode 100644 index 0000000..b469504 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Vector.png differ diff --git a/root/opt/phpsysinfo/gfx/images/VortexBox.png b/root/opt/phpsysinfo/gfx/images/VortexBox.png new file mode 100644 index 0000000..db6158e Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/VortexBox.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Win2000.png b/root/opt/phpsysinfo/gfx/images/Win2000.png new file mode 100644 index 0000000..3147daa Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Win2000.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Win8.png b/root/opt/phpsysinfo/gfx/images/Win8.png new file mode 100644 index 0000000..96f0ae1 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Win8.png differ diff --git a/root/opt/phpsysinfo/gfx/images/WinVista.png b/root/opt/phpsysinfo/gfx/images/WinVista.png new file mode 100644 index 0000000..6cbed9e Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/WinVista.png differ diff --git a/root/opt/phpsysinfo/gfx/images/WinXP.png b/root/opt/phpsysinfo/gfx/images/WinXP.png new file mode 100644 index 0000000..5d2e08d Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/WinXP.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Zenwalk.png b/root/opt/phpsysinfo/gfx/images/Zenwalk.png new file mode 100644 index 0000000..0820e02 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Zenwalk.png differ diff --git a/root/opt/phpsysinfo/gfx/images/Zorin.png b/root/opt/phpsysinfo/gfx/images/Zorin.png new file mode 100644 index 0000000..215ea8a Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/Zorin.png differ diff --git a/root/opt/phpsysinfo/gfx/images/antiX.png b/root/opt/phpsysinfo/gfx/images/antiX.png new file mode 100644 index 0000000..014811e Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/antiX.png differ diff --git a/root/opt/phpsysinfo/gfx/images/elementaryOS.png b/root/opt/phpsysinfo/gfx/images/elementaryOS.png new file mode 100644 index 0000000..263d4de Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/elementaryOS.png differ diff --git a/root/opt/phpsysinfo/gfx/images/free-eos.png b/root/opt/phpsysinfo/gfx/images/free-eos.png new file mode 100644 index 0000000..0cee490 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/free-eos.png differ diff --git a/root/opt/phpsysinfo/gfx/images/gNewSense.png b/root/opt/phpsysinfo/gfx/images/gNewSense.png new file mode 100644 index 0000000..8ea5932 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/gNewSense.png differ diff --git a/root/opt/phpsysinfo/gfx/images/iycc.png b/root/opt/phpsysinfo/gfx/images/iycc.png new file mode 100644 index 0000000..4a92f70 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/iycc.png differ diff --git a/root/opt/phpsysinfo/gfx/images/openSUSE.png b/root/opt/phpsysinfo/gfx/images/openSUSE.png new file mode 100644 index 0000000..7bd7d8d Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/openSUSE.png differ diff --git a/root/opt/phpsysinfo/gfx/images/pfSense.png b/root/opt/phpsysinfo/gfx/images/pfSense.png new file mode 100644 index 0000000..eeba67f Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/pfSense.png differ diff --git a/root/opt/phpsysinfo/gfx/images/unknown.png b/root/opt/phpsysinfo/gfx/images/unknown.png new file mode 100644 index 0000000..63e5e3c Binary files /dev/null and b/root/opt/phpsysinfo/gfx/images/unknown.png differ diff --git a/root/opt/phpsysinfo/gfx/logo_48.png b/root/opt/phpsysinfo/gfx/logo_48.png new file mode 100644 index 0000000..2157475 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/logo_48.png differ diff --git a/root/opt/phpsysinfo/gfx/next.png b/root/opt/phpsysinfo/gfx/next.png new file mode 100644 index 0000000..53a3475 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/next.png differ diff --git a/root/opt/phpsysinfo/gfx/prev.png b/root/opt/phpsysinfo/gfx/prev.png new file mode 100644 index 0000000..5c5c551 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/prev.png differ diff --git a/root/opt/phpsysinfo/gfx/reload.png b/root/opt/phpsysinfo/gfx/reload.png new file mode 100644 index 0000000..0de2656 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/reload.png differ diff --git a/root/opt/phpsysinfo/gfx/sort_asc.png b/root/opt/phpsysinfo/gfx/sort_asc.png new file mode 100644 index 0000000..6393e0e Binary files /dev/null and b/root/opt/phpsysinfo/gfx/sort_asc.png differ diff --git a/root/opt/phpsysinfo/gfx/sort_both.png b/root/opt/phpsysinfo/gfx/sort_both.png new file mode 100644 index 0000000..7a1c378 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/sort_both.png differ diff --git a/root/opt/phpsysinfo/gfx/sort_desc.png b/root/opt/phpsysinfo/gfx/sort_desc.png new file mode 100644 index 0000000..b768c6f Binary files /dev/null and b/root/opt/phpsysinfo/gfx/sort_desc.png differ diff --git a/root/opt/phpsysinfo/gfx/treeTable/blank.gif b/root/opt/phpsysinfo/gfx/treeTable/blank.gif new file mode 100644 index 0000000..2c93354 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/treeTable/blank.gif differ diff --git a/root/opt/phpsysinfo/gfx/treeTable/tv-collapsable-last.gif b/root/opt/phpsysinfo/gfx/treeTable/tv-collapsable-last.gif new file mode 100644 index 0000000..7b4f2bc Binary files /dev/null and b/root/opt/phpsysinfo/gfx/treeTable/tv-collapsable-last.gif differ diff --git a/root/opt/phpsysinfo/gfx/treeTable/tv-collapsable.gif b/root/opt/phpsysinfo/gfx/treeTable/tv-collapsable.gif new file mode 100644 index 0000000..512da85 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/treeTable/tv-collapsable.gif differ diff --git a/root/opt/phpsysinfo/gfx/treeTable/tv-expandable-last.gif b/root/opt/phpsysinfo/gfx/treeTable/tv-expandable-last.gif new file mode 100644 index 0000000..f1eb592 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/treeTable/tv-expandable-last.gif differ diff --git a/root/opt/phpsysinfo/gfx/treeTable/tv-expandable.gif b/root/opt/phpsysinfo/gfx/treeTable/tv-expandable.gif new file mode 100644 index 0000000..a57904b Binary files /dev/null and b/root/opt/phpsysinfo/gfx/treeTable/tv-expandable.gif differ diff --git a/root/opt/phpsysinfo/gfx/treeTable/tv-item-last.gif b/root/opt/phpsysinfo/gfx/treeTable/tv-item-last.gif new file mode 100644 index 0000000..39aaeb5 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/treeTable/tv-item-last.gif differ diff --git a/root/opt/phpsysinfo/gfx/treeTable/tv-item.gif b/root/opt/phpsysinfo/gfx/treeTable/tv-item.gif new file mode 100644 index 0000000..93050d7 Binary files /dev/null and b/root/opt/phpsysinfo/gfx/treeTable/tv-item.gif differ diff --git a/root/opt/phpsysinfo/gfx/treeTable/vertline.gif b/root/opt/phpsysinfo/gfx/treeTable/vertline.gif new file mode 100644 index 0000000..0fbc5aa Binary files /dev/null and b/root/opt/phpsysinfo/gfx/treeTable/vertline.gif differ diff --git a/root/opt/phpsysinfo/includes/autoloader.inc.php b/root/opt/phpsysinfo/includes/autoloader.inc.php new file mode 100644 index 0000000..75e6f7f --- /dev/null +++ b/root/opt/phpsysinfo/includes/autoloader.inc.php @@ -0,0 +1,73 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: autoloader.inc.php 660 2012-08-27 11:08:40Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + +error_reporting(E_ALL | E_STRICT); + +/** + * automatic loading classes when using them + * + * @param string $class_name name of the class which must be loaded + * + * @return void + */ +function __autoload($class_name) +{ + //$class_name = str_replace('-', '', $class_name); + + /* case-insensitive folders */ + $dirs = array('/plugins/'.strtolower($class_name).'/', '/includes/mb/', '/includes/ups/'); + + foreach ($dirs as $dir) { + if (file_exists(APP_ROOT.$dir.'class.'.strtolower($class_name).'.inc.php')) { + include_once APP_ROOT.$dir.'class.'.strtolower($class_name).'.inc.php'; + + return; + } + } + + /* case-sensitive folders */ + $dirs = array('/includes/', '/includes/interface/', '/includes/to/', '/includes/to/device/', '/includes/os/', '/includes/plugin/', '/includes/xml/', '/includes/web/', '/includes/error/', '/includes/js/', '/includes/output/'); + + foreach ($dirs as $dir) { + if (file_exists(APP_ROOT.$dir.'class.'.$class_name.'.inc.php')) { + include_once APP_ROOT.$dir.'class.'.$class_name.'.inc.php'; + + return; + } + } + + $error = Error::singleton(); + + $error->addError("_autoload(\"".$class_name."\")", "autoloading of class file (class.".$class_name.".inc.php) failed!"); + $error->errorsAsXML(); +} + +/** + * sets a user-defined error handler function + * + * @param integer $level contains the level of the error raised, as an integer. + * @param string $message contains the error message, as a string. + * @param string $file which contains the filename that the error was raised in, as a string. + * @param integer $line which contains the line number the error was raised at, as an integer. + * + * @return void + */ +function errorHandlerPsi($level, $message, $file, $line) +{ + $error = Error::singleton(); + $error->addPhpError("errorHandlerPsi : ", "Level : ".$level." Message : ".$message." File : ".$file." Line : ".$line); +} + +set_error_handler('errorHandlerPsi'); diff --git a/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php b/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php new file mode 100644 index 0000000..d7885c0 --- /dev/null +++ b/root/opt/phpsysinfo/includes/class.CommonFunctions.inc.php @@ -0,0 +1,563 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.CommonFunctions.inc.php 699 2012-09-15 11:57:13Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * class with common functions used in all places + * + * @category PHP + * @package PSI + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class CommonFunctions +{ + private static function _parse_log_file($string) + { + if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) { + $log_file = substr(PSI_LOG, 1); + if (file_exists($log_file)) { + $contents = @file_get_contents($log_file); + if ($contents && preg_match("/^\-\-\-[^-\r\n]+\-\-\- ".preg_quote($string, '/')."\r?\n/m", $contents, $matches, PREG_OFFSET_CAPTURE)) { + $findIndex = $matches[0][1]; + if (preg_match("/\r?\n/m", $contents, $matches, PREG_OFFSET_CAPTURE, $findIndex)) { + $startIndex = $matches[0][1]+1; + if (preg_match("/^\-\-\-[^-\r\n]+\-\-\- /m", $contents, $matches, PREG_OFFSET_CAPTURE, $startIndex)) { + $stopIndex = $matches[0][1]; + + return substr($contents, $startIndex, $stopIndex-$startIndex); + } else { + return substr($contents, $startIndex); + } + } + } + } + } + + return false; + } + + /** + * Find a system program, do also path checking when not running on WINNT + * on WINNT we simply return the name with the exe extension to the program name + * + * @param string $strProgram name of the program + * + * @return string complete path and name of the program + */ + private static function _findProgram($strProgram) + { + $path_parts = pathinfo($strProgram); + if (empty($path_parts['basename'])) { + return; + } + $arrPath = array(); + if ((PSI_OS == 'WINNT') && empty($path_parts['extension'])) { + $strProgram .= '.exe'; + $path_parts = pathinfo($strProgram); + } + if (empty($path_parts['dirname']) || ($path_parts['dirname'] == '.')) { + if (PSI_OS == 'WINNT') { + $arrPath = preg_split('/;/', getenv("Path"), -1, PREG_SPLIT_NO_EMPTY); + } else { + $arrPath = preg_split('/:/', getenv("PATH"), -1, PREG_SPLIT_NO_EMPTY); + } + if (defined('PSI_ADD_PATHS') && is_string(PSI_ADD_PATHS)) { + if (preg_match(ARRAY_EXP, PSI_ADD_PATHS)) { + $arrPath = array_merge(eval(PSI_ADD_PATHS), $arrPath); // In this order so $addpaths is before $arrPath when looking for a program + } else { + $arrPath = array_merge(array(PSI_ADD_PATHS), $arrPath); // In this order so $addpaths is before $arrPath when looking for a program + } + } + } else { + array_push($arrPath, $path_parts['dirname']); + $strProgram = $path_parts['basename']; + } + + //add some default paths if we still have no paths here + if (empty($arrPath) && PSI_OS != 'WINNT') { + if (PSI_OS == 'Android') { + array_push($arrPath, '/system/bin'); + } else { + array_push($arrPath, '/bin', '/sbin', '/usr/bin', '/usr/sbin', '/usr/local/bin', '/usr/local/sbin'); + } + } + + $exceptPath = ""; + if ((PSI_OS == 'WINNT') && (($windir = getenv("WinDir")) !== false)) { + $windir = strtolower($windir); + foreach ($arrPath as $strPath) { + if ((strtolower($strPath) == $windir."\\system32") && is_dir($windir."\\SysWOW64")) { + $exceptPath = $windir."\\sysnative"; + array_push($arrPath, $exceptPath); + break; + } + } + } else if (PSI_OS == 'Android') { + $exceptPath = '/system/bin'; + } + + // If open_basedir defined, fill the $open_basedir array with authorized paths,. (Not tested when no open_basedir restriction) + if ((bool) ini_get('open_basedir')) { + if (PSI_OS == 'WINNT') { + $open_basedir = preg_split('/;/', ini_get('open_basedir'), -1, PREG_SPLIT_NO_EMPTY); + } else { + $open_basedir = preg_split('/:/', ini_get('open_basedir'), -1, PREG_SPLIT_NO_EMPTY); + } + } + foreach ($arrPath as $strPath) { + // Path with trailing slash + if (PSI_OS == 'WINNT') { + $strPathS = rtrim($strPath, "\\")."\\"; + } else { + $strPathS = rtrim($strPath, "/")."/"; + } + // To avoid "open_basedir restriction in effect" error when testing paths if restriction is enabled + if (isset($open_basedir)) { + $inBaseDir = false; + if (PSI_OS == 'WINNT') { + foreach ($open_basedir as $openbasedir) { + if (substr($openbasedir, -1)=="\\") { + $str_Path = $strPathS; + } else { + $str_Path = $strPath; + } + if (stripos($str_Path, $openbasedir) === 0) { + $inBaseDir = true; + break; + } + } + } else { + foreach ($open_basedir as $openbasedir) { + if (substr($openbasedir, -1)=="/") { + $str_Path = $strPathS; + } else { + $str_Path = $strPath; + } + if (strpos($str_Path, $openbasedir) === 0) { + $inBaseDir = true; + break; + } + } + } + if ($inBaseDir == false) { + continue; + } + } + if (($strPath !== $exceptPath) && !is_dir($strPath)) { + continue; + } + if (PSI_OS == 'WINNT') { + $strProgrammpath = rtrim($strPath, "\\")."\\".$strProgram; + } else { + $strProgrammpath = rtrim($strPath, "/")."/".$strProgram; + } + if (is_executable($strProgrammpath)) { + return $strProgrammpath; + } + } + } + + /** + * Execute a system program. return a trim()'d result. + * does very crude pipe checking. you need ' | ' for it to work + * ie $program = CommonFunctions::executeProgram('netstat', '-anp | grep LIST'); + * NOT $program = CommonFunctions::executeProgram('netstat', '-anp|grep LIST'); + * + * @param string $strProgramname name of the program + * @param string $strArgs arguments to the program + * @param string &$strBuffer output of the command + * @param boolean $booErrorRep en- or disables the reporting of errors which should be logged + * + * @return boolean command successfull or not + */ + public static function executeProgram($strProgramname, $strArgs, &$strBuffer, $booErrorRep = true) + { + if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) { + $out = self::_parse_log_file("Executing: ".trim($strProgramname.' '.$strArgs)); + if ($out == false) { + if (substr(PSI_LOG, 0, 1)=="-") { + $strBuffer = ''; + + return false; + } + } else { + $strBuffer = $out; + + return true; + } + } + + $strBuffer = ''; + $strError = ''; + $pipes = array(); + $strProgram = self::_findProgram($strProgramname); + $error = Error::singleton(); + if (!$strProgram) { + if ($booErrorRep) { + $error->addError('find_program('.$strProgramname.')', 'program not found on the machine'); + } + + return false; + } + // see if we've gotten a |, if we have we need to do path checking on the cmd + if ($strArgs) { + $arrArgs = preg_split('/ /', $strArgs, -1, PREG_SPLIT_NO_EMPTY); + for ($i = 0, $cnt_args = count($arrArgs); $i < $cnt_args; $i++) { + if ($arrArgs[$i] == '|') { + $strCmd = $arrArgs[$i + 1]; + $strNewcmd = self::_findProgram($strCmd); + $strArgs = preg_replace("/\| ".$strCmd.'/', '| "'.$strNewcmd.'"', $strArgs); + } + } + } + $descriptorspec = array(0=>array("pipe", "r"), 1=>array("pipe", "w"), 2=>array("pipe", "w")); + if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) { + if (PSI_OS == 'WINNT') { + $process = $pipes[1] = popen('"'.$strProgram.'" '.$strArgs." 2>nul", "r"); + } else { + $process = $pipes[1] = popen('"'.$strProgram.'" '.$strArgs." 2>/dev/null", "r"); + } + } else { + $process = proc_open('"'.$strProgram.'" '.$strArgs, $descriptorspec, $pipes); + } + if (is_resource($process)) { + self::_timeoutfgets($pipes, $strBuffer, $strError); + if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) { + $return_value = pclose($pipes[1]); + } else { + fclose($pipes[0]); + fclose($pipes[1]); + fclose($pipes[2]); + // It is important that you close any pipes before calling + // proc_close in order to avoid a deadlock + $return_value = proc_close($process); + } + } else { + if ($booErrorRep) { + $error->addError($strProgram, "\nOpen process error"); + } + + return false; + } + $strError = trim($strError); + $strBuffer = trim($strBuffer); + if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && (substr(PSI_LOG, 0, 1)!="-") && (substr(PSI_LOG, 0, 1)!="+")) { + error_log("---".gmdate('r T')."--- Executing: ".trim($strProgramname.' '.$strArgs)."\n".$strBuffer."\n", 3, PSI_LOG); + } + if (! empty($strError)) { + if ($booErrorRep) { + $error->addError($strProgram, $strError."\nReturn value: ".$return_value); + } + + return $return_value == 0; + } + + return true; + } + + /** + * read a file and return the content as a string + * + * @param string $strFileName name of the file which should be read + * @param string &$strRet content of the file (reference) + * @param integer $intLines control how many lines should be read + * @param integer $intBytes control how many bytes of each line should be read + * @param boolean $booErrorRep en- or disables the reporting of errors which should be logged + * + * @return boolean command successfull or not + */ + public static function rfts($strFileName, &$strRet, $intLines = 0, $intBytes = 4096, $booErrorRep = true) + { + if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) { + $out = self::_parse_log_file("Reading: ".$strFileName); + if ($out == false) { + if (substr(PSI_LOG, 0, 1)=="-") { + $strRet = ''; + + return false; + } + } else { + $strRet = $out; + + return true; + } + } + + $strFile = ""; + $intCurLine = 1; + $error = Error::singleton(); + if (file_exists($strFileName)) { + if (is_readable($strFileName)) { + if ($fd = fopen($strFileName, 'r')) { + while (!feof($fd)) { + $strFile .= fgets($fd, $intBytes); + if ($intLines <= $intCurLine && $intLines != 0) { + break; + } else { + $intCurLine++; + } + } + fclose($fd); + $strRet = $strFile; + if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && (substr(PSI_LOG, 0, 1)!="-") && (substr(PSI_LOG, 0, 1)!="+")) { + if ((strlen($strRet)>0)&&(substr($strRet, -1)!="\n")) { + error_log("---".gmdate('r T')."--- Reading: ".$strFileName."\n".$strRet."\n", 3, PSI_LOG); + } else { + error_log("---".gmdate('r T')."--- Reading: ".$strFileName."\n".$strRet, 3, PSI_LOG); + } + } + } else { + if ($booErrorRep) { + $error->addError('fopen('.$strFileName.')', 'file can not read by phpsysinfo'); + } + + return false; + } + } else { + if ($booErrorRep) { + $error->addError('fopen('.$strFileName.')', 'file permission error'); + } + + return false; + } + } else { + if ($booErrorRep) { + $error->addError('file_exists('.$strFileName.')', 'the file does not exist on your machine'); + } + + return false; + } + + return true; + } + + /** + * file exists + * + * @param string $strFileName name of the file which should be check + * + * @return boolean command successfull or not + */ + public static function fileexists($strFileName) + { + if (defined('PSI_LOG') && is_string(PSI_LOG) && (strlen(PSI_LOG)>0) && ((substr(PSI_LOG, 0, 1)=="-") || (substr(PSI_LOG, 0, 1)=="+"))) { + $log_file = substr(PSI_LOG, 1); + if (file_exists($log_file) + && ($contents = @file_get_contents($log_file)) + && preg_match("/^\-\-\-[^-\n]+\-\-\- ".preg_quote("Reading: ".$strFileName, '/')."\n/m", $contents)) { + return true; + } else { + if (substr(PSI_LOG, 0, 1)=="-") { + return false; + } + } + } + + return file_exists($strFileName); + } + + /** + * reads a directory and return the name of the files and directorys in it + * + * @param string $strPath path of the directory which should be read + * @param boolean $booErrorRep en- or disables the reporting of errors which should be logged + * + * @return array content of the directory excluding . and .. + */ + public static function gdc($strPath, $booErrorRep = true) + { + $arrDirectoryContent = array(); + $error = Error::singleton(); + if (is_dir($strPath)) { + if ($handle = opendir($strPath)) { + while (($strFile = readdir($handle)) !== false) { + if ($strFile != "." && $strFile != "..") { + $arrDirectoryContent[] = $strFile; + } + } + closedir($handle); + } else { + if ($booErrorRep) { + $error->addError('opendir('.$strPath.')', 'directory can not be read by phpsysinfo'); + } + } + } else { + if ($booErrorRep) { + $error->addError('is_dir('.$strPath.')', 'directory does not exist on your machine'); + } + } + + return $arrDirectoryContent; + } + + /** + * Check for needed php extensions + * + * We need that extensions for almost everything + * This function will return a hard coded + * XML string (with headers) if the SimpleXML extension isn't loaded. + * Then it will terminate the script. + * See bug #1787137 + * + * @param array $arrExt additional extensions for which a check should run + * + * @return void + */ + public static function checkForExtensions($arrExt = array()) + { + if ((strcasecmp(PSI_SYSTEM_CODEPAGE, "UTF-8") == 0) || (strcasecmp(PSI_SYSTEM_CODEPAGE, "CP437") == 0)) + $arrReq = array('simplexml', 'pcre', 'xml', 'dom'); + elseif (PSI_OS == "WINNT") + $arrReq = array('simplexml', 'pcre', 'xml', 'mbstring', 'dom', 'com_dotnet'); + else + $arrReq = array('simplexml', 'pcre', 'xml', 'mbstring', 'dom'); + $extensions = array_merge($arrExt, $arrReq); + $text = ""; + $error = false; + $text .= "\n"; + $text .= "\n"; + $text .= " \n"; + foreach ($extensions as $extension) { + if (!extension_loaded($extension)) { + $text .= " checkForExtensions\n"; + $text .= " phpSysInfo requires the ".$extension." extension to php in order to work properly.\n"; + $error = true; + } + } + $text .= " \n"; + $text .= ""; + if ($error) { + header("Content-Type: text/xml\n\n"); + echo $text; + die(); + } + } + + /** + * get the content of stdout/stderr with the option to set a timeout for reading + * + * @param array $pipes array of file pointers for stdin, stdout, stderr (proc_open()) + * @param string &$out target string for the output message (reference) + * @param string &$err target string for the error message (reference) + * @param integer $timeout timeout value in seconds (default value is 30) + * + * @return void + */ + private static function _timeoutfgets($pipes, &$out, &$err, $timeout = 30) + { + $w = null; + $e = null; + + if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) { + $pipe2 = false; + } else { + $pipe2 = true; + } + while (!(feof($pipes[1]) && (!$pipe2 || feof($pipes[2])))) { + if ($pipe2) { + $read = array($pipes[1], $pipes[2]); + } else { + $read = array($pipes[1]); + } + + $n = stream_select($read, $w, $e, $timeout); + + if ($n === false) { + error_log('stream_select: failed !'); + break; + } elseif ($n === 0) { + error_log('stream_select: timeout expired !'); + break; + } + + foreach ($read as $r) { + if ($r == $pipes[1]) { + $out .= fread($r, 4096); + } else if (feof($pipes[1]) && $pipe2 && ($r == $pipes[2])) {//read STDERR after STDOUT + $err .= fread($r, 4096); + } + } + } + } + + /** + * function for getting a list of values in the specified context + * optionally filter this list, based on the list from third parameter + * + * @param $wmi holds the COM object that we pull the WMI data from + * @param string $strClass name of the class where the values are stored + * @param array $strValue filter out only needed values, if not set all values of the class are returned + * + * @return array content of the class stored in an array + */ + public static function getWMI($wmi, $strClass, $strValue = array()) + { + $arrData = array(); + if ($wmi) { + $value = ""; + try { + $objWEBM = $wmi->Get($strClass); + $arrProp = $objWEBM->Properties_; + $arrWEBMCol = $objWEBM->Instances_(); + foreach ($arrWEBMCol as $objItem) { + if (is_array($arrProp)) { + reset($arrProp); + } + $arrInstance = array(); + foreach ($arrProp as $propItem) { + $value = $objItem->{$propItem->Name}; //instead exploitable eval("\$value = \$objItem->".$propItem->Name.";"); + if (empty($strValue)) { + if (is_string($value)) $arrInstance[$propItem->Name] = trim($value); + else $arrInstance[$propItem->Name] = $value; + } else { + if (in_array($propItem->Name, $strValue)) { + if (is_string($value)) $arrInstance[$propItem->Name] = trim($value); + else $arrInstance[$propItem->Name] = $value; + } + } + } + $arrData[] = $arrInstance; + } + } catch (Exception $e) { + if (PSI_DEBUG) { + $error = Error::singleton(); + $error->addError($e->getCode(), $e->getMessage()); + } + } + } + + return $arrData; + } + + /** + * get all configured plugins from phpsysinfo.ini (file must be included and processed before calling this function) + * + * @return array + */ + public static function getPlugins() + { + if (defined('PSI_PLUGINS') && is_string(PSI_PLUGINS)) { + if (preg_match(ARRAY_EXP, PSI_PLUGINS)) { + return eval(strtolower(PSI_PLUGINS)); + } else { + return array(strtolower(PSI_PLUGINS)); + } + } else { + return array(); + } + } +} diff --git a/root/opt/phpsysinfo/includes/class.Parser.inc.php b/root/opt/phpsysinfo/includes/class.Parser.inc.php new file mode 100644 index 0000000..f137e4a --- /dev/null +++ b/root/opt/phpsysinfo/includes/class.Parser.inc.php @@ -0,0 +1,216 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.Parser.inc.php 604 2012-07-10 07:31:34Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * parser class with common used parsing metods + * + * @category PHP + * @package PSI + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Parser +{ + /** + * parsing the output of lspci command + * + * @return Array + */ + public static function lspci($debug = PSI_DEBUG) + { + $arrResults = array(); + if (CommonFunctions::executeProgram("lspci", "", $strBuf, $debug)) { + $arrLines = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY); + foreach ($arrLines as $strLine) { + $arrParams = preg_split('/ /', trim($strLine), 2); + if (count($arrParams) == 2) + $strName = $arrParams[1]; + else + $strName = "unknown"; + $strName = preg_replace('/\(.*\)/', '', $strName); + $dev = new HWDevice(); + $dev->setName($strName); + $arrResults[] = $dev; + } + } + + return $arrResults; + } + + /** + * parsing the output of df command + * + * @param string $df_param additional parameter for df command + * + * @return array + */ + public static function df($df_param = "") + { + $arrResult = array(); + if (CommonFunctions::executeProgram('mount', '', $mount, PSI_DEBUG)) { + $mount = preg_split("/\n/", $mount, -1, PREG_SPLIT_NO_EMPTY); + foreach ($mount as $mount_line) { + if (preg_match("/(\S+) on ([\S ]+) type (.*) \((.*)\)/", $mount_line, $mount_buf)) { + $mount_parm[$mount_buf[2]]['fstype'] = $mount_buf[3]; + $mount_parm[$mount_buf[2]]['name'] = $mount_buf[1]; + if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[2]]['options'] = $mount_buf[4]; + } elseif (preg_match("/(\S+) is (.*) mounted on (\S+) \(type (.*)\)/", $mount_line, $mount_buf)) { + $mount_parm[$mount_buf[3]]['fstype'] = $mount_buf[4]; + $mount_parm[$mount_buf[3]]['name'] = $mount_buf[1]; + if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[3]]['options'] = $mount_buf[2]; + } elseif (preg_match("/(\S+) (.*) on (\S+) \((.*)\)/", $mount_line, $mount_buf)) { + $mount_parm[$mount_buf[3]]['fstype'] = $mount_buf[2]; + $mount_parm[$mount_buf[3]]['name'] = $mount_buf[1]; + if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[3]]['options'] = $mount_buf[4]; + } elseif (preg_match("/(\S+) on ([\S ]+) \((\S+)(,\s(.*))?\)/", $mount_line, $mount_buf)) { + $mount_parm[$mount_buf[2]]['fstype'] = $mount_buf[3]; + $mount_parm[$mount_buf[2]]['name'] = $mount_buf[1]; + if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[2]]['options'] = isset($mount_buf[5]) ? $mount_buf[5] : ''; + } + } + } elseif (CommonFunctions::rfts("/etc/mtab", $mount)) { + $mount = preg_split("/\n/", $mount, -1, PREG_SPLIT_NO_EMPTY); + foreach ($mount as $mount_line) { + if (preg_match("/(\S+) (\S+) (\S+) (\S+) ([0-9]+) ([0-9]+)/", $mount_line, $mount_buf)) { + $mount_point = preg_replace("/\\\\040/i", ' ', $mount_buf[2]); //space as \040 + $mount_parm[$mount_point]['fstype'] = $mount_buf[3]; + $mount_parm[$mount_point]['name'] = $mount_buf[1]; + if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_point]['options'] = $mount_buf[4]; + } + } + } + if (CommonFunctions::executeProgram('df', '-k '.$df_param, $df, PSI_DEBUG)) { + $df = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); + if (PSI_SHOW_INODES) { + if (CommonFunctions::executeProgram('df', '-i '.$df_param, $df2, PSI_DEBUG)) { + $df2 = preg_split("/\n/", $df2, -1, PREG_SPLIT_NO_EMPTY); + // Store inode use% in an associative array (df_inodes) for later use + foreach ($df2 as $df2_line) { + if (preg_match("/^(\S+).*\s([0-9]+)%/", $df2_line, $inode_buf)) { + $df_inodes[$inode_buf[1]] = $inode_buf[2]; + } + } + } + } + foreach ($df as $df_line) { + $df_buf1 = preg_split("/(\%\s)/", $df_line, 3); + if (count($df_buf1) < 2) { + continue; + } + if (preg_match("/(.*)(\s+)(([0-9]+)(\s+)([0-9]+)(\s+)([\-0-9]+)(\s+)([0-9]+)$)/", $df_buf1[0], $df_buf2)) { + if (count($df_buf1) == 3) { + $df_buf = array($df_buf2[1], $df_buf2[4], $df_buf2[6], $df_buf2[8], $df_buf2[10], $df_buf1[2]); + } else { + $df_buf = array($df_buf2[1], $df_buf2[4], $df_buf2[6], $df_buf2[8], $df_buf2[10], $df_buf1[1]); + } + if (count($df_buf) == 6) { + $df_buf[5] = trim($df_buf[5]); + $dev = new DiskDevice(); + $dev->setName(trim($df_buf[0])); + if ($df_buf[2] < 0) { + $dev->setTotal($df_buf[3] * 1024); + $dev->setUsed($df_buf[3] * 1024); + } else { + $dev->setTotal($df_buf[1] * 1024); + $dev->setUsed($df_buf[2] * 1024); + if ($df_buf[3]>0) { + $dev->setFree($df_buf[3] * 1024); + } + } + if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($df_buf[5]); + + if (isset($mount_parm[$df_buf[5]])) { + $dev->setFsType($mount_parm[$df_buf[5]]['fstype']); + if (PSI_SHOW_MOUNT_OPTION) { + if (PSI_SHOW_MOUNT_CREDENTIALS) { + $dev->setOptions($mount_parm[$df_buf[5]]['options']); + } else { + $mpo=$mount_parm[$df_buf[5]]['options']; + + $mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo); + $mpo=preg_replace('/,guest,/i', ',', $mpo); + + $mpo=preg_replace('/(^user=[^,]*,)|(^user=[^,]*$)|(,user=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,user=[^,]*,/i', ',', $mpo); + + $mpo=preg_replace('/(^username=[^,]*,)|(^username=[^,]*$)|(,username=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,username=[^,]*,/i', ',', $mpo); + + $mpo=preg_replace('/(^password=[^,]*,)|(^password=[^,]*$)|(,password=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,password=[^,]*,/i', ',', $mpo); + + $dev->setOptions($mpo); + } + } + } + if (PSI_SHOW_INODES && isset($df_inodes[trim($df_buf[0])])) { + $dev->setPercentInodesUsed($df_inodes[trim($df_buf[0])]); + } + $arrResult[] = $dev; + } + } + } + } else { + if (isset($mount_parm)) { + foreach ($mount_parm as $mount_point=>$mount_param) { + $total = disk_total_space($mount_point); + if (($mount_param['fstype'] != 'none') && ($total > 0)) { + $dev = new DiskDevice(); + $dev->setName($mount_param['name']); + $dev->setFsType($mount_param['fstype']); + + if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($mount_point); + + $dev->setTotal($total); + $free = disk_free_space($mount_point); + if ($free > 0) { + $dev->setFree($free); + } else { + $free = 0; + } + if ($total > $free) $dev->setUsed($total - $free); + + if (PSI_SHOW_MOUNT_OPTION) { + if (PSI_SHOW_MOUNT_CREDENTIALS) { + $dev->setOptions($mount_param['options']); + } else { + $mpo=$mount_param['options']; + + $mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo); + $mpo=preg_replace('/,guest,/i', ',', $mpo); + + $mpo=preg_replace('/(^user=[^,]*,)|(^user=[^,]*$)|(,user=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,user=[^,]*,/i', ',', $mpo); + + $mpo=preg_replace('/(^username=[^,]*,)|(^username=[^,]*$)|(,username=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,username=[^,]*,/i', ',', $mpo); + + $mpo=preg_replace('/(^password=[^,]*,)|(^password=[^,]*$)|(,password=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,password=[^,]*,/i', ',', $mpo); + + $dev->setOptions($mpo); + } + } + $arrResult[] = $dev; + } + } + } + } + + return $arrResult; + } +} diff --git a/root/opt/phpsysinfo/includes/error/class.Error.inc.php b/root/opt/phpsysinfo/includes/error/class.Error.inc.php new file mode 100644 index 0000000..684678f --- /dev/null +++ b/root/opt/phpsysinfo/includes/error/class.Error.inc.php @@ -0,0 +1,290 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.Error.inc.php 569 2012-04-16 06:08:18Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * class for the error handling in phpsysinfo + * + * @category PHP + * @package PSI_Error + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Error +{ + /** + * holds the instance of this class + * + * @static + * @var object + */ + private static $_instance; + + /** + * holds the error messages + * + * @var array + */ + private $_arrErrorList = array(); + + /** + * current number ob errors + * + * @var integer + */ + private $_errors = 0; + + /** + * initalize some used vars + */ + private function __construct() + { + $this->_errors = 0; + $this->_arrErrorList = array(); + } + + /** + * Singleton function + * + * @return Error instance of the class + */ + public static function singleton() + { + if (!isset(self::$_instance)) { + $c = __CLASS__; + self::$_instance = new $c; + } + + return self::$_instance; + } + + /** + * triggers an error when somebody tries to clone the object + * + * @return void + */ + public function __clone() + { + trigger_error("Can't be cloned", E_USER_ERROR); + } + + /** + * adds an phpsysinfo error to the internal list + * + * @param string $strCommand Command, which cause the Error + * @param string $strMessage additional Message, to describe the Error + * + * @return void + */ + public function addError($strCommand, $strMessage) + { + $this->_addError($strCommand, $this->_trace($strMessage)); + } + + /** + * adds an error to the internal list + * + * @param string $strCommand Command, which cause the Error + * @param string $strMessage message, that describe the Error + * + * @return void + */ + private function _addError($strCommand, $strMessage) + { + $index = count($this->_arrErrorList) + 1; + $this->_arrErrorList[$index]['command'] = $strCommand; + $this->_arrErrorList[$index]['message'] = $strMessage; + $this->_errors++; + } + + /** + * add a config error to the internal list + * + * @param object $strCommand Command, which cause the Error + * @param object $strMessage additional Message, to describe the Error + * + * @return void + */ + public function addConfigError($strCommand, $strMessage) + { + $this->_addError($strCommand, "Wrong Value in phpsysinfo.ini for ".$strMessage); + } + + /** + * add a php error to the internal list + * + * @param object $strCommand Command, which cause the Error + * @param object $strMessage additional Message, to describe the Error + * + * @return void + */ + public function addPhpError($strCommand, $strMessage) + { + $this->_addError($strCommand, "PHP throws a error\n".$strMessage); + } + + /** + * adds a waraning to the internal list + * + * @param string $strMessage Warning message to display + * + * @return void + */ + public function addWarning($strMessage) + { + $index = count($this->_arrErrorList) + 1; + $this->_arrErrorList[$index]['command'] = "WARN"; + $this->_arrErrorList[$index]['message'] = $strMessage; + } + + /** + * converts the internal error and warning list to a XML file + * + * @return void + */ + public function errorsAsXML() + { + $dom = new DOMDocument('1.0', 'UTF-8'); + $root = $dom->createElement("phpsysinfo"); + $dom->appendChild($root); + $xml = new SimpleXMLExtended(simplexml_import_dom($dom), 'UTF-8'); + $generation = $xml->addChild('Generation'); + $generation->addAttribute('version', PSI_VERSION_STRING); + $generation->addAttribute('timestamp', time()); + $xmlerr = $xml->addChild("Errors"); + foreach ($this->_arrErrorList as $arrLine) { +// $error = $xmlerr->addCData('Error', $arrLine['message']); + $error = $xmlerr->addChild('Error'); + $error->addAttribute('Message', $arrLine['message']); + $error->addAttribute('Function', $arrLine['command']); + } + header("Cache-Control: no-cache, must-revalidate\n"); + header("Content-Type: text/xml\n\n"); + echo $xml->getSimpleXmlElement()->asXML(); + exit(); + } + /** + * add the errors to an existing xml document + * + * @param String $encoding encoding + * + * @return SimpleXmlElement + */ + public function errorsAddToXML($encoding) + { + $dom = new DOMDocument('1.0', 'UTF-8'); + $root = $dom->createElement("Errors"); + $dom->appendChild($root); + $xml = simplexml_import_dom($dom); + $xmlerr = new SimpleXMLExtended($xml, $encoding); + foreach ($this->_arrErrorList as $arrLine) { +// $error = $xmlerr->addCData('Error', $arrLine['message']); + $error = $xmlerr->addChild('Error'); + $error->addAttribute('Message', $arrLine['message']); + $error->addAttribute('Function', $arrLine['command']); + } + + return $xmlerr->getSimpleXmlElement(); + } + /** + * check if errors exists + * + * @return boolean true if are errors logged, false if not + */ + public function errorsExist() + { + if ($this->_errors > 0) { + return true; + } else { + return false; + } + } + /** + * generate a function backtrace for error diagnostic, function is genearally based on code submitted in the php reference page + * + * @param string $strMessage additional message to display + * + * @return string formatted string of the backtrace + */ + private function _trace($strMessage) + { + $arrTrace = array_reverse(debug_backtrace()); + $strFunc = ''; + $strBacktrace = htmlspecialchars($strMessage)."\n\n"; + foreach ($arrTrace as $val) { + // avoid the last line, which says the error is from the error class + if ($val == $arrTrace[count($arrTrace) - 1]) { + break; + } + $strBacktrace .= str_replace(APP_ROOT, ".", $val['file']).' on line '.$val['line']; + if ($strFunc) { + $strBacktrace .= ' in function '.$strFunc; + } + if ($val['function'] == 'include' || $val['function'] == 'require' || $val['function'] == 'include_once' || $val['function'] == 'require_once') { + $strFunc = ''; + } else { + $strFunc = $val['function'].'('; + if (isset($val['args'][0])) { + $strFunc .= ' '; + $strComma = ''; + foreach ($val['args'] as $val) { + $strFunc .= $strComma.$this->_printVar($val); + $strComma = ', '; + } + $strFunc .= ' '; + } + $strFunc .= ')'; + } + $strBacktrace .= "\n"; + } + + return $strBacktrace; + } + /** + * convert some special vars into better readable output + * + * @param mixed $var value, which should be formatted + * + * @return string formatted string + */ + private function _printVar($var) + { + if (is_string($var)) { + $search = array("\x00", "\x0a", "\x0d", "\x1a", "\x09"); + $replace = array('\0', '\n', '\r', '\Z', '\t'); + + return ('"'.str_replace($search, $replace, $var).'"'); + } elseif (is_bool($var)) { + if ($var) { + return ('true'); + } else { + return ('false'); + } + } elseif (is_array($var)) { + $strResult = 'array( '; + $strComma = ''; + foreach ($var as $key=>$val) { + $strResult .= $strComma.$this->_printVar($key).' => '.$this->_printVar($val); + $strComma = ', '; + } + $strResult .= ' )'; + + return ($strResult); + } + // anything else, just let php try to print it + return (var_export($var, true)); + } +} diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php new file mode 100644 index 0000000..7fca97d --- /dev/null +++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_OS.inc.php @@ -0,0 +1,50 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.PSI_Interface_OS.inc.php 263 2009-06-22 13:01:52Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * define which methods a os class for phpsysinfo must implement + * to be recognized and fully work without errors, these are the methods which + * are called from outside to include the information in the main application + * + * @category PHP + * @package PSI_Interfaces + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +interface PSI_Interface_OS +{ + /** + * get a special encoding from os where phpsysinfo is running + * + * @return string + */ + public function getEncoding(); + + /** + * build the os information + * + * @return void + */ + public function build(); + + /** + * get the filled or unfilled (with default values) system object + * + * @return System + */ + public function getSys(); +} diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php new file mode 100644 index 0000000..7582403 --- /dev/null +++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Output.inc.php @@ -0,0 +1,35 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.PSI_Interface_Output.inc.php 214 2009-05-25 08:32:40Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * define which methods a output class for phpsysinfo must implement + * to be recognized and fully work without errors + * + * @category PHP + * @package PSI_Interfaces + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +interface PSI_Interface_Output +{ + /** + * generate the output + * + * @return void + */ + public function run(); +} diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php new file mode 100644 index 0000000..138169c --- /dev/null +++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Plugin.inc.php @@ -0,0 +1,43 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.PSI_Interface_Plugin.inc.php 273 2009-06-24 11:40:09Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * define which methods a plugin class for phpsysinfo must implement + * to be recognized and fully work without errors, these are the methods which + * are called from outside to include the information in the main application + * + * @category PHP + * @package PSI_Interfaces + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +interface PSI_Interface_Plugin +{ + /** + * doing all tasks before the xml can be build + * + * @return void + */ + public function execute(); + + /** + * build the xml + * + * @return SimpleXMLObject entire XML content for the plugin which than can be appended to the main XML + */ + public function xml(); +} diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php new file mode 100644 index 0000000..3113d37 --- /dev/null +++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_Sensor.inc.php @@ -0,0 +1,43 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.PSI_Interface_Sensor.inc.php 263 2009-06-22 13:01:52Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * define which methods every sensor class for phpsysinfo must implement + * to be recognized and fully work without errors, these are the methods which + * are called from outside to include the information in the main application + * + * @category PHP + * @package PSI_Interfaces + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +interface PSI_Interface_Sensor +{ + /** + * build the mbinfo information + * + * @return void + */ + public function build(); + + /** + * get the filled or unfilled (with default values) MBInfo object + * + * @return MBInfo + */ + public function getMBInfo(); +} diff --git a/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php new file mode 100644 index 0000000..73dd1f5 --- /dev/null +++ b/root/opt/phpsysinfo/includes/interface/class.PSI_Interface_UPS.inc.php @@ -0,0 +1,42 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.PSI_Interface_UPS.inc.php 263 2009-06-22 13:01:52Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * define which methods a ups class for phpsysinfo must implement + * to be recognized and fully work without errors + * + * @category PHP + * @package PSI_Interfaces + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +interface PSI_Interface_UPS +{ + /** + * build the ups information + * + * @return void + */ + public function build(); + + /** + * get the filled or unfilled (with default values) UPSInfo object + * + * @return UPSInfo + */ + public function getUPSInfo(); +} diff --git a/root/opt/phpsysinfo/includes/js/README b/root/opt/phpsysinfo/includes/js/README new file mode 100644 index 0000000..d01efd4 --- /dev/null +++ b/root/opt/phpsysinfo/includes/js/README @@ -0,0 +1,10 @@ +versions, links and simple description of used files +=========================================================== + +class.JavaScriptPacker.inc.php +--------- +VERSION : 1.1+FF4 +URL : http://dean.edwards.name +DESC : Downloaded from http://dean.edwards.name/download/ http://joliclic.free.fr/php/javascript-packer/en/ + Firefox 4 fix +LICENSE : LGPL 2.1 (http://creativecommons.org/licenses/LGPL/2.1/) +USED : define('PSI_JS_COMPRESSION', 'None'); or define('PSI_JS_COMPRESSION', 'Normal'); diff --git a/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php b/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php new file mode 100644 index 0000000..48e3ccd --- /dev/null +++ b/root/opt/phpsysinfo/includes/js/class.JavaScriptPacker.inc.php @@ -0,0 +1,788 @@ +pack(); + * + * or + * + * $myPacker = new JavaScriptPacker($script, 'Normal', true, false); + * $packed = $myPacker->pack(); + * + * or (default values) + * + * $myPacker = new JavaScriptPacker($script); + * $packed = $myPacker->pack(); + * + * + * params of the constructor : + * $script: the JavaScript to pack, string. + * $encoding: level of encoding, int or string : + * 0,10,62,95 or 'None', 'Numeric', 'Normal', 'High ASCII'. + * default: 62. + * $fastDecode: include the fast decoder in the packed result, boolean. + * default : true. + * $specialChars: if you are flagged your private and local variables + * in the script, boolean. + * default: false. + * + * The pack() method return the compressed JavasScript, as a string. + * + * see http://dean.edwards.name/packer/usage/ for more information. + * + * Notes : + * # need PHP 5 . Tested with PHP 5.1.2, 5.1.3, 5.1.4, 5.2.3 + * + * # The packed result may be different than with the Dean Edwards + * version, but with the same length. The reason is that the PHP + * function usort to sort array don't necessarily preserve the + * original order of two equal member. The Javascript sort function + * in fact preserve this order (but that's not require by the + * ECMAScript standard). So the encoded keywords order can be + * different in the two results. + * + * # Be careful with the 'High ASCII' Level encoding if you use + * UTF-8 in your files... + */ + + +class JavaScriptPacker +{ + // constants + const IGNORE = '$1'; + + // validate parameters + private $_script = ''; + private $_encoding = 62; + private $_fastDecode = true; + private $_specialChars = false; + + private $LITERAL_ENCODING = array( + 'None' => 0, + 'Numeric' => 10, + 'Normal' => 62, + 'High ASCII' => 95 + ); + + public function __construct($_script, $_encoding = 62, $_fastDecode = true, $_specialChars = false) + { + $this->_script = $_script . "\n"; + if (array_key_exists($_encoding, $this->LITERAL_ENCODING)) + $_encoding = $this->LITERAL_ENCODING[$_encoding]; + $this->_encoding = min((int) $_encoding, 95); + $this->_fastDecode = $_fastDecode; + $this->_specialChars = $_specialChars; + } + + public function pack() + { + $this->_addParser('_basicCompression'); + if ($this->_specialChars) + $this->_addParser('_encodeSpecialChars'); + if ($this->_encoding) + $this->_addParser('_encodeKeywords'); + + // go! + return $this->_pack($this->_script); + } + + // apply all parsing routines + private function _pack($script) + { + for ($i = 0; isset($this->_parsers[$i]); $i++) { + $script = call_user_func(array(&$this, $this->_parsers[$i]), $script); + } + + return $script; + } + + // keep a list of parsing functions, they'll be executed all at once + private $_parsers = array(); + private function _addParser($parser) + { + $this->_parsers[] = $parser; + } + + // zero encoding - just removal of white space and comments + private function _basicCompression($script) + { + $parser = new ParseMaster(); + // make safe + $parser->escapeChar = '\\'; + // protect strings + $parser->add('/\'[^\'\\n\\r]*\'/', self::IGNORE); + $parser->add('/"[^"\\n\\r]*"/', self::IGNORE); + // remove comments + $parser->add('/\\/\\/[^\\n\\r]*[\\n\\r]/', ' '); + $parser->add('/\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\//', ' '); + // protect regular expressions + $parser->add('/\\s+(\\/[^\\/\\n\\r\\*][^\\/\\n\\r]*\\/g?i?)/', '$2'); // IGNORE + $parser->add('/[^\\w\\x24\\/\'"*)\\?:]\\/[^\\/\\n\\r\\*][^\\/\\n\\r]*\\/g?i?/', self::IGNORE); + // remove: ;;; doSomething(); + if ($this->_specialChars) $parser->add('/;;;[^\\n\\r]+[\\n\\r]/'); + // remove redundant semi-colons + $parser->add('/\\(;;\\)/', self::IGNORE); // protect for (;;) loops + $parser->add('/;+\\s*([};])/', '$2'); + // apply the above + $script = $parser->exec($script); + + // remove white-space + $parser->add('/(\\b|\\x24)\\s+(\\b|\\x24)/', '$2 $3'); + $parser->add('/([+\\-])\\s+([+\\-])/', '$2 $3'); + $parser->add('/\\s+/', ''); + // done + return $parser->exec($script); + } + + private function _encodeSpecialChars($script) + { + $parser = new ParseMaster(); + // replace: $name -> n, $$name -> na + $parser->add('/((\\x24+)([a-zA-Z$_]+))(\\d*)/', + array('fn' => '_replace_name') + ); + // replace: _name -> _0, double-underscore (__name) is ignored + $regexp = '/\\b_[A-Za-z\\d]\\w*/'; + // build the word list + $keywords = $this->_analyze($script, $regexp, '_encodePrivate'); + // quick ref + $encoded = $keywords['encoded']; + + $parser->add($regexp, + array( + 'fn' => '_replace_encoded', + 'data' => $encoded + ) + ); + + return $parser->exec($script); + } + + private function _encodeKeywords($script) + { + // escape high-ascii values already in the script (i.e. in strings) + if ($this->_encoding > 62) + $script = $this->_escape95($script); + // create the parser + $parser = new ParseMaster(); + $encode = $this->_getEncoder($this->_encoding); + // for high-ascii, don't encode single character low-ascii + $regexp = ($this->_encoding > 62) ? '/\\w\\w+/' : '/\\w+/'; + // build the word list + $keywords = $this->_analyze($script, $regexp, $encode); + $encoded = $keywords['encoded']; + + // encode + $parser->add($regexp, + array( + 'fn' => '_replace_encoded', + 'data' => $encoded + ) + ); + if (empty($script)) return $script; + else { + //$res = $parser->exec($script); + //$res = $this->_bootStrap($res, $keywords); + //return $res; + return $this->_bootStrap($parser->exec($script), $keywords); + } + } + + private function _analyze($script, $regexp, $encode) + { + // analyse + // retreive all words in the script + $all = array(); + preg_match_all($regexp, $script, $all); + $_sorted = array(); // list of words sorted by frequency + $_encoded = array(); // dictionary of word->encoding + $_protected = array(); // instances of "protected" words + $all = $all[0]; // simulate the javascript comportement of global match + if (!empty($all)) { + $unsorted = array(); // same list, not sorted + $protected = array(); // "protected" words (dictionary of word->"word") + $value = array(); // dictionary of charCode->encoding (eg. 256->ff) + $this->_count = array(); // word->count + $i = count($all); $j = 0; //$word = null; + // count the occurrences - used for sorting later + do { + --$i; + $word = '$' . $all[$i]; + if (!isset($this->_count[$word])) { + $this->_count[$word] = 0; + $unsorted[$j] = $word; + // make a dictionary of all of the protected words in this script + // these are words that might be mistaken for encoding + //if (is_string($encode) && method_exists($this, $encode)) + $values[$j] = call_user_func(array(&$this, $encode), $j); + $protected['$' . $values[$j]] = $j++; + } + // increment the word counter + $this->_count[$word]++; + } while ($i > 0); + // prepare to sort the word list, first we must protect + // words that are also used as codes. we assign them a code + // equivalent to the word itself. + // e.g. if "do" falls within our encoding range + // then we store keywords["do"] = "do"; + // this avoids problems when decoding + $i = count($unsorted); + do { + $word = $unsorted[--$i]; + if (isset($protected[$word]) /*!= null*/) { + $_sorted[$protected[$word]] = substr($word, 1); + $_protected[$protected[$word]] = true; + $this->_count[$word] = 0; + } + } while ($i); + + // sort the words by frequency + // Note: the javascript and php version of sort can be different : + // in php manual, usort : + // " If two members compare as equal, + // their order in the sorted array is undefined." + // so the final packed script is different of the Dean's javascript version + // but equivalent. + // the ECMAscript standard does not guarantee this behaviour, + // and thus not all browsers (e.g. Mozilla versions dating back to at + // least 2003) respect this. + usort($unsorted, array(&$this, '_sortWords')); + $j = 0; + // because there are "protected" words in the list + // we must add the sorted words around them + do { + if (!isset($_sorted[$i])) + $_sorted[$i] = substr($unsorted[$j++], 1); + $_encoded[$_sorted[$i]] = $values[$i]; + } while (++$i < count($unsorted)); + } + + return array( + 'sorted' => $_sorted, + 'encoded' => $_encoded, + 'protected' => $_protected); + } + + private $_count = array(); + private function _sortWords($match1, $match2) + { + return $this->_count[$match2] - $this->_count[$match1]; + } + + // build the boot function used for loading and decoding + private function _bootStrap($packed, $keywords) + { + $ENCODE = $this->_safeRegExp('$encode\\($count\\)'); + + // $packed: the packed script + $packed = "'" . $this->_escape($packed) . "'"; + + // $ascii: base for encoding + $ascii = min(count($keywords['sorted']), $this->_encoding); + if ($ascii == 0) $ascii = 1; + + // $count: number of words contained in the script + $count = count($keywords['sorted']); + + // $keywords: list of words contained in the script + foreach ($keywords['protected'] as $i=>$value) { + $keywords['sorted'][$i] = ''; + } + // convert from a string to an array + ksort($keywords['sorted']); + $keywords = "'" . implode('|', $keywords['sorted']) . "'.split('|')"; + + $encode = ($this->_encoding > 62) ? '_encode95' : $this->_getEncoder($ascii); + $encode = $this->_getJSFunction($encode); + $encode = preg_replace('/_encoding/', '$ascii', $encode); + $encode = preg_replace('/arguments\\.callee/', '$encode', $encode); + $inline = '\\$count' . ($ascii > 10 ? '.toString(\\$ascii)' : ''); + + // $decode: code snippet to speed up decoding + if ($this->_fastDecode) { + // create the decoder + $decode = $this->_getJSFunction('_decodeBody'); + if ($this->_encoding > 62) + $decode = preg_replace('/\\\\w/', '[\\xa1-\\xff]', $decode); + // perform the encoding inline for lower ascii values + elseif ($ascii < 36) + $decode = preg_replace($ENCODE, $inline, $decode); + // special case: when $count==0 there are no keywords. I want to keep + // the basic shape of the unpacking funcion so i'll frig the code... + if ($count == 0) + $decode = preg_replace($this->_safeRegExp('($count)\\s*=\\s*1'), '$1=0', $decode, 1); + } + + // boot function + $unpack = $this->_getJSFunction('_unpack'); + if ($this->_fastDecode) { + // insert the decoder + $this->buffer = $decode; + $unpack = preg_replace_callback('/\\{/', array(&$this, '_insertFastDecode'), $unpack, 1); + } + $unpack = preg_replace('/"/', "'", $unpack); + if ($this->_encoding > 62) { // high-ascii + // get rid of the word-boundaries for regexp matches + $unpack = preg_replace('/\'\\\\\\\\b\'\s*\\+|\\+\s*\'\\\\\\\\b\'/', '', $unpack); + } + if ($ascii > 36 || $this->_encoding > 62 || $this->_fastDecode) { + // insert the encode function + $this->buffer = $encode; + $unpack = preg_replace_callback('/\\{/', array(&$this, '_insertFastEncode'), $unpack, 1); + } else { + // perform the encoding inline + $unpack = preg_replace($ENCODE, $inline, $unpack); + } + // pack the boot function too + $unpackPacker = new JavaScriptPacker($unpack, 0, false, true); + $unpack = $unpackPacker->pack(); + + // arguments + $params = array($packed, $ascii, $count, $keywords); + if ($this->_fastDecode) { + $params[] = 0; + $params[] = '{}'; + } + $params = implode(',', $params); + + // the whole thing + //Firefox 4 fix, old: return 'eval(' . $unpack . '(' . $params . "))\n"; + return "(typeof setTimeout=='function'?setTimeout:eval)(" . $unpack . "(" . $params . "));\n"; + } + + private $buffer; + private function _insertFastDecode($match) + { + return '{' . $this->buffer . ';'; + } + private function _insertFastEncode($match) + { + return '{$encode=' . $this->buffer . ';'; + } + + // mmm.. ..which one do i need ?? + private function _getEncoder($ascii) + { + return $ascii > 10 ? $ascii > 36 ? $ascii > 62 ? + '_encode95' : '_encode62' : '_encode36' : '_encode10'; + } + + // zero encoding + // characters: 0123456789 + private function _encode10($charCode) + { + return $charCode; + } + + // inherent base36 support + // characters: 0123456789abcdefghijklmnopqrstuvwxyz + private function _encode36($charCode) + { + return base_convert($charCode, 10, 36); + } + + // hitch a ride on base36 and add the upper case alpha characters + // characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + private function _encode62($charCode) + { + $res = ''; + if ($charCode >= $this->_encoding) { + $res = $this->_encode62((int) ($charCode / $this->_encoding)); + } + $charCode = $charCode % $this->_encoding; + + if ($charCode > 35) + return $res . chr($charCode + 29); + else + return $res . base_convert($charCode, 10, 36); + } + + // use high-ascii values + // characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖ×ØÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ + private function _encode95($charCode) + { + $res = ''; + if ($charCode >= $this->_encoding) + $res = $this->_encode95($charCode / $this->_encoding); + + return $res . chr(($charCode % $this->_encoding) + 161); + } + + private function _safeRegExp($string) + { + return '/'.preg_replace('/\$/', '\\\$', $string).'/'; + } + + private function _encodePrivate($charCode) + { + return "_" . $charCode; + } + + // protect characters used by the parser + private function _escape($script) + { + return preg_replace('/([\\\\\'])/', '\\\$1', $script); + } + + // protect high-ascii characters already in the script + private function _escape95($script) + { + return preg_replace_callback( + '/[\\xa1-\\xff]/', + array(&$this, '_escape95Bis'), + $script + ); + } + private function _escape95Bis($match) + { + return '\x'.((string) dechex(ord($match))); + } + + private function _getJSFunction($aName) + { + if (defined('self::JSFUNCTION'.$aName)) + return constant('self::JSFUNCTION'.$aName); + else + return ''; + } + + // JavaScript Functions used. + // Note : In Dean's version, these functions are converted + // with 'String(aFunctionName);'. + // This internal conversion complete the original code, ex : + // 'while (aBool) anAction();' is converted to + // 'while (aBool) { anAction(); }'. + // The JavaScript functions below are corrected. + + // unpacking function - this is the boot strap function + // data extracted from this packing routine is passed to + // this function when decoded in the target + // NOTE ! : without the ';' final. + const JSFUNCTION_unpack = + +'function ($packed, $ascii, $count, $keywords, $encode, $decode) { + while ($count--) { + if ($keywords[$count]) { + $packed = $packed.replace(new RegExp(\'\\\\b\' + $encode($count) + \'\\\\b\', \'g\'), $keywords[$count]); + } + } + + return $packed; +}'; +/* +'function ($packed, $ascii, $count, $keywords, $encode, $decode) { + while ($count--) + if ($keywords[$count]) + $packed = $packed.replace(new RegExp(\'\\\\b\' + $encode($count) + \'\\\\b\', \'g\'), $keywords[$count]); + + return $packed; +}'; +*/ + + // code-snippet inserted into the unpacker to speed up decoding + const JSFUNCTION_decodeBody = +//_decode = function () { +// does the browser support String.replace where the +// replacement value is a function? + +' if (!\'\'.replace(/^/, String)) { + // decode all the values we need + while ($count--) { + $decode[$encode($count)] = $keywords[$count] || $encode($count); + } + // global replacement function + $keywords = [function ($encoded) {return $decode[$encoded]}]; + // generic match + $encode = function () {return \'\\\\w+\'}; + // reset the loop counter - we are now doing a global replace + $count = 1; + } +'; +//}; +/* +' if (!\'\'.replace(/^/, String)) { + // decode all the values we need + while ($count--) $decode[$encode($count)] = $keywords[$count] || $encode($count); + // global replacement function + $keywords = [function ($encoded) {return $decode[$encoded]}]; + // generic match + $encode = function () {return\'\\\\w+\'}; + // reset the loop counter - we are now doing a global replace + $count = 1; + }'; +*/ + + // zero encoding + // characters: 0123456789 + const JSFUNCTION_encode10 = +'function ($charCode) { + return $charCode; +}';//;'; + + // inherent base36 support + // characters: 0123456789abcdefghijklmnopqrstuvwxyz + const JSFUNCTION_encode36 = +'function ($charCode) { + return $charCode.toString(36); +}';//;'; + + // hitch a ride on base36 and add the upper case alpha characters + // characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + const JSFUNCTION_encode62 = +'function ($charCode) { + return ($charCode < _encoding ? \'\' : arguments.callee(parseInt($charCode / _encoding))) + + (($charCode = $charCode % _encoding) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36)); +}'; + + // use high-ascii values + // characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖ×ØÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ + const JSFUNCTION_encode95 = +'function ($charCode) { + return ($charCode < _encoding ? \'\' : arguments.callee($charCode / _encoding)) + + String.fromCharCode($charCode % _encoding + 161); +}'; + +} + +class ParseMaster +{ + public $ignoreCase = false; + public $escapeChar = ''; + + // constants + const EXPRESSION = 0; + const REPLACEMENT = 1; + const LENGTH = 2; + + // used to determine nesting levels + private $GROUPS = '/\\(/';//g + private $SUB_REPLACE = '/\\$\\d/'; + private $INDEXED = '/^\\$\\d+$/'; + private $TRIM = '/([\'"])\\1\\.(.*)\\.\\1\\1$/'; + private $ESCAPE = '/\\\./';//g + private $QUOTE = '/\'/'; + private $DELETED = '/\\x01[^\\x01]*\\x01/';//g + + public function add($expression, $replacement = '') + { + // count the number of sub-expressions + // - add one because each pattern is itself a sub-expression + $length = 1 + preg_match_all($this->GROUPS, $this->_internalEscape((string) $expression), $out); + + // treat only strings $replacement + if (is_string($replacement)) { + // does the pattern deal with sub-expressions? + if (preg_match($this->SUB_REPLACE, $replacement)) { + // a simple lookup? (e.g. "$2") + if (preg_match($this->INDEXED, $replacement)) { + // store the index (used for fast retrieval of matched strings) + $replacement = (int) (substr($replacement, 1)) - 1; + } else { // a complicated lookup (e.g. "Hello $2 $1") + // build a function to do the lookup + $quote = preg_match($this->QUOTE, $this->_internalEscape($replacement)) + ? '"' : "'"; + $replacement = array( + 'fn' => '_backReferences', + 'data' => array( + 'replacement' => $replacement, + 'length' => $length, + 'quote' => $quote + ) + ); + } + } + } + // pass the modified arguments + if (!empty($expression)) $this->_add($expression, $replacement, $length); + else $this->_add('/^$/', $replacement, $length); + } + + public function exec($string) + { + // execute the global replacement + $this->_escaped = array(); + + // simulate the _patterns.toSTring of Dean + $regexp = '/'; + foreach ($this->_patterns as $reg) { + $regexp .= '(' . substr($reg[self::EXPRESSION], 1, -1) . ')|'; + } + $regexp = substr($regexp, 0, -1) . '/'; + $regexp .= ($this->ignoreCase) ? 'i' : ''; + + $string = $this->_escape($string, $this->escapeChar); + $string = preg_replace_callback( + $regexp, + array( + &$this, + '_replacement' + ), + $string + ); + $string = $this->_unescape($string, $this->escapeChar); + + return preg_replace($this->DELETED, '', $string); + } + + public function reset() + { + // clear the patterns collection so that this object may be re-used + $this->_patterns = array(); + } + + // private + private $_escaped = array(); // escaped characters + private $_patterns = array(); // patterns stored by index + + // create and add a new pattern to the patterns collection + private function _add() + { + $arguments = func_get_args(); + $this->_patterns[] = $arguments; + } + + // this is the global replace function (it's quite complicated) + private function _replacement($arguments) + { + if (empty($arguments)) return ''; + + $i = 1; $j = 0; + // loop through the patterns + while (isset($this->_patterns[$j])) { + $pattern = $this->_patterns[$j++]; + // do we have a result? + if (isset($arguments[$i]) && ($arguments[$i] != '')) { + $replacement = $pattern[self::REPLACEMENT]; + + if (is_array($replacement) && isset($replacement['fn'])) { + + if (isset($replacement['data'])) $this->buffer = $replacement['data']; + return call_user_func(array(&$this, $replacement['fn']), $arguments, $i); + + } elseif (is_int($replacement)) { + return $arguments[$replacement + $i]; + + } + $delete = ($this->escapeChar == '' || + strpos($arguments[$i], $this->escapeChar) === false) + ? '' : "\x01" . $arguments[$i] . "\x01"; + + return $delete . $replacement; + + // skip over references to sub-expressions + } else { + $i += $pattern[self::LENGTH]; + } + } + } + + private function _backReferences($match, $offset) + { + $replacement = $this->buffer['replacement']; + $quote = $this->buffer['quote']; + $i = $this->buffer['length']; + while ($i) { + $replacement = str_replace('$'.$i--, $match[$offset + $i], $replacement); + } + + return $replacement; + } + + private function _replace_name($match, $offset) + { + $length = strlen($match[$offset + 2]); + $start = $length - max($length - strlen($match[$offset + 3]), 0); + + return substr($match[$offset + 1], $start, $length) . $match[$offset + 4]; + } + + private function _replace_encoded($match, $offset) + { + return $this->buffer[$match[$offset]]; + } + + + // php : we cannot pass additional data to preg_replace_callback, + // and we cannot use &$this in create_function, so let's go to lower level + private $buffer; + + // encode escaped characters + private function _escape($string, $escapeChar) + { + if ($escapeChar) { + $this->buffer = $escapeChar; + + return preg_replace_callback( + '/\\' . $escapeChar . '(.)' .'/', + array(&$this, '_escapeBis'), + $string + ); + + } else { + return $string; + } + } + private function _escapeBis($match) + { + $this->_escaped[] = $match[1]; + + return $this->buffer; + } + + // decode escaped characters + private function _unescape($string, $escapeChar) + { + if ($escapeChar) { + $regexp = '/'.'\\'.$escapeChar.'/'; + $this->buffer = array('escapeChar'=> $escapeChar, 'i' => 0); + + return preg_replace_callback( + $regexp, + array(&$this, '_unescapeBis'), + $string + ); + + } else { + return $string; + } + } + private function _unescapeBis() + { + if (isset($this->_escaped[$this->buffer['i']]) + && $this->_escaped[$this->buffer['i']] != '') + { + $temp = $this->_escaped[$this->buffer['i']]; + } else { + $temp = ''; + } + $this->buffer['i']++; + + return $this->buffer['escapeChar'] . $temp; + } + + private function _internalEscape($string) + { + return preg_replace($this->ESCAPE, '', $string); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.coretemp.inc.php b/root/opt/phpsysinfo/includes/mb/class.coretemp.inc.php new file mode 100644 index 0000000..33af328 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.coretemp.inc.php @@ -0,0 +1,62 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.coretemp.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting hardware temperature information through sysctl + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @author William Johansson + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Coretemp extends Sensors +{ + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + $smp = 1; + CommonFunctions::executeProgram('sysctl', '-n kern.smp.cpus', $smp); + for ($i = 0; $i < $smp; $i++) { + $temp = 0; + if (CommonFunctions::executeProgram('sysctl', '-n dev.cpu.'.$i.'.temperature', $temp)) { + $temp = preg_replace('/C/', '', $temp); + $dev = new SensorDevice(); + $dev->setName("CPU ".($i + 1)); + $dev->setValue($temp); + $dev->setMax(70); + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php b/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php new file mode 100644 index 0000000..753e3d6 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.freeipmi.inc.php @@ -0,0 +1,177 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.freeipmi.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from ipmi-sensors + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class FreeIPMI extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_lines = array(); + + /** + * fill the private content var through tcp or file access + */ + public function __construct() + { + parent::__construct(); + switch (strtolower(PSI_SENSOR_ACCESS)) { + case 'command': + CommonFunctions::executeProgram('ipmi-sensors', '--output-sensor-thresholds', $lines); + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + break; + case 'file': + if (CommonFunctions::rfts(APP_ROOT.'/data/freeipmi.txt', $lines)) { + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + break; + default: + $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); + break; + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[2] == "Temperature" && $buffer[11] != "N/A" && $buffer[4] == "C") { + $dev = new SensorDevice(); + $dev->setName($buffer[1]); + $dev->setValue($buffer[3]); + if ($buffer[9] != "N/A") $dev->setMax($buffer[9]); + if ($buffer[11] != "'OK'") $dev->setEvent(trim($buffer[11], "'")); + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[2] == "Voltage" && $buffer[11] != "N/A" && $buffer[4] == "V") { + $dev = new SensorDevice(); + $dev->setName($buffer[1]); + $dev->setValue($buffer[3]); + if ($buffer[6] != "N/A") $dev->setMin($buffer[6]); + if ($buffer[9] != "N/A") $dev->setMax($buffer[9]); + if ($buffer[11] != "'OK'") $dev->setEvent(trim($buffer[11], "'")); + $this->mbinfo->setMbVolt($dev); + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[2] == "Fan" && $buffer[11] != "N/A" && $buffer[4] == "RPM") { + $dev = new SensorDevice(); + $dev->setName($buffer[1]); + $dev->setValue($buffer[3]); + if ($buffer[6] != "N/A") { + $dev->setMin($buffer[6]); + } elseif (($buffer[9] != "N/A") && ($buffer[9]<$buffer[3])) { //max instead min issue + $dev->setMin($buffer[9]); + } + if ($buffer[11] != "'OK'") $dev->setEvent(trim($buffer[11], "'")); + $this->mbinfo->setMbFan($dev); + } + } + } + + /** + * get power information + * + * @return void + */ + private function _power() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[2] == "Current" && $buffer[11] != "N/A" && $buffer[4] == "W") { + $dev = new SensorDevice(); + $dev->setName($buffer[1]); + $dev->setValue($buffer[3]); + if ($buffer[9] != "N/A") $dev->setMax($buffer[9]); + if ($buffer[11] != "'OK'") $dev->setEvent(trim($buffer[11], "'")); + $this->mbinfo->setMbPower($dev); + } + } + } + + /** + * get current information + * + * @return void + */ + private function _current() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[2] == "Current" && $buffer[11] != "N/A" && $buffer[4] == "A") { + $dev = new SensorDevice(); + $dev->setName($buffer[1]); + $dev->setValue($buffer[3]); + if ($buffer[9] != "N/A") $dev->setMax($buffer[9]); + if ($buffer[11] != "'OK'") $dev->setEvent(trim($buffer[11], "'")); + $this->mbinfo->setMbCurrent($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_fans(); + $this->_power(); + $this->_current(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php b/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php new file mode 100644 index 0000000..7b8add4 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.hddtemp.inc.php @@ -0,0 +1,135 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.hddtemp.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from hddtemp + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @author T.A. van Roermund + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class HDDTemp extends Sensors +{ + /** + * get the temperature information from hddtemp + * access is available through tcp or command + * + * @return array temperatures in array + */ + private function _temperature() + { + $ar_buf = array(); + switch (strtolower(PSI_HDD_TEMP)) { + case "tcp": + $lines = ''; + // Timo van Roermund: connect to the hddtemp daemon, use a 5 second timeout. + $fp = @fsockopen('localhost', 7634, $errno, $errstr, 5); + // if connected, read the output of the hddtemp daemon + if ($fp) { + while (!feof($fp)) { + $lines .= fread($fp, 1024); + } + fclose($fp); + } else { + $this->error->addError("HDDTemp error", $errno.", ".$errstr); + } + $lines = str_replace("||", "|\n|", $lines); + $ar_buf = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + break; + case "command": + $strDrives = ""; + $strContent = ""; + $hddtemp_value = ""; + if (CommonFunctions::rfts("/proc/diskstats", $strContent, 0, 4096, false)) { + $arrContent = preg_split("/\n/", $strContent, -1, PREG_SPLIT_NO_EMPTY); + foreach ($arrContent as $strLine) { + preg_match("/^\s(.*)\s([a-z]*)\s(.*)/", $strLine, $arrSplit); + if (! empty($arrSplit[2])) { + $strDrive = '/dev/'.$arrSplit[2]; + if (file_exists($strDrive)) { + $strDrives = $strDrives.$strDrive.' '; + } + } + } + } else { + if (CommonFunctions::rfts("/proc/partitions", $strContent, 0, 4096, false)) { + $arrContent = preg_split("/\n/", $strContent, -1, PREG_SPLIT_NO_EMPTY); + foreach ($arrContent as $strLine) { + if (!preg_match("/^\s(.*)\s([\/a-z0-9]*(\/disc))\s(.*)/", $strLine, $arrSplit)) { + preg_match("/^\s(.*)\s([a-z]*)\s(.*)/", $strLine, $arrSplit); + } + if (! empty($arrSplit[2])) { + $strDrive = '/dev/'.$arrSplit[2]; + if (file_exists($strDrive)) { + $strDrives = $strDrives.$strDrive.' '; + } + } + } + } + } + if (trim($strDrives) == "") { + break; + } + if (CommonFunctions::executeProgram("hddtemp", $strDrives, $hddtemp_value, PSI_DEBUG)) { + $hddtemp_value = preg_split("/\n/", $hddtemp_value, -1, PREG_SPLIT_NO_EMPTY); + foreach ($hddtemp_value as $line) { + $temp = preg_split("/:\s/", $line, 3); + if (count($temp) == 3 && preg_match("/^[0-9]/", $temp[2])) { + preg_match("/^([0-9]*)(.*)/", $temp[2], $ar_temp); + $temp[2] = trim($ar_temp[1]); + $temp[3] = trim($ar_temp[2]); + array_push($ar_buf, "|".implode("|", $temp)."|"); + } + } + } + break; + default: + $this->error->addConfigError("temperature()", "PSI_HDD_TEMP"); + break; + } + // Timo van Roermund: parse the info from the hddtemp daemon. + foreach ($ar_buf as $line) { + $data = array(); + if (preg_match("/\|(.*)\|(.*)\|(.*)\|(.*)\|/", $line, $data)) { + if (trim($data[3]) != "ERR") { + // get the info we need + $dev = new SensorDevice(); + $dev->setName($data[1] . ' (' . (strpos($data[2], " ")?substr($data[2], 0, strpos($data[2], " ")):$data[2]) . ')'); + if (is_numeric($data[3])) { + $dev->setValue($data[3]); + } + $dev->setMax(60); + $this->mbinfo->setMbTemp($dev); + } + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php b/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php new file mode 100644 index 0000000..dce6759 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.healthd.inc.php @@ -0,0 +1,159 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.healthd.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from healthd + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Healthd extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_lines = array(); + + /** + * fill the private content var through tcp or file access + */ + public function __construct() + { + parent::__construct(); + switch (strtolower(PSI_SENSOR_ACCESS)) { + case 'command': + $lines = ""; + CommonFunctions::executeProgram('healthdc', '-t', $lines); + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + break; + case 'file': + if (CommonFunctions::rfts(APP_ROOT.'/data/healthd.txt', $lines)) { + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + break; + default: + $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); + break; + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + $ar_buf = preg_split("/\t+/", $this->_lines); + $dev1 = new SensorDevice(); + $dev1->setName('temp1'); + $dev1->setValue($ar_buf[1]); + $dev1->setMax(70); + $this->mbinfo->setMbTemp($dev1); + $dev2 = new SensorDevice(); + $dev2->setName('temp1'); + $dev2->setValue($ar_buf[2]); + $dev2->setMax(70); + $this->mbinfo->setMbTemp($dev2); + $dev3 = new SensorDevice(); + $dev3->setName('temp1'); + $dev3->setValue($ar_buf[3]); + $dev3->setMax(70); + $this->mbinfo->setMbTemp($dev3); + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + $ar_buf = preg_split("/\t+/", $this->_lines); + $dev1 = new SensorDevice(); + $dev1->setName('fan1'); + $dev1->setValue($ar_buf[4]); + $dev1->setMin(3000); + $this->mbinfo->setMbFan($dev1); + $dev2 = new SensorDevice(); + $dev2->setName('fan2'); + $dev2->setValue($ar_buf[5]); + $dev2->setMin(3000); + $this->mbinfo->setMbFan($dev2); + $dev3 = new SensorDevice(); + $dev3->setName('fan3'); + $dev3->setValue($ar_buf[6]); + $dev3->setMin(3000); + $this->mbinfo->setMbFan($dev3); + } + + /** + * get voltage information + * + * @return array voltage in array with lable + */ + private function _voltage() + { + $ar_buf = preg_split("/\t+/", $this->_lines); + $dev1 = new SensorDevice(); + $dev1->setName('Vcore1'); + $dev1->setValue($ar_buf[7]); + $this->mbinfo->setMbVolt($dev1); + $dev2 = new SensorDevice(); + $dev2->setName('Vcore2'); + $dev2->setValue($ar_buf[8]); + $this->mbinfo->setMbVolt($dev2); + $dev3 = new SensorDevice(); + $dev3->setName('3volt'); + $dev3->setValue($ar_buf[9]); + $this->mbinfo->setMbVolt($dev3); + $dev4 = new SensorDevice(); + $dev4->setName('+5Volt'); + $dev4->setValue($ar_buf[10]); + $this->mbinfo->setMbVolt($dev4); + $dev5 = new SensorDevice(); + $dev5->setName('+12Volt'); + $dev5->setValue($ar_buf[11]); + $this->mbinfo->setMbVolt($dev5); + $dev6 = new SensorDevice(); + $dev6->setName('-12Volt'); + $dev6->setValue($ar_buf[12]); + $this->mbinfo->setMbVolt($dev6); + $dev7 = new SensorDevice(); + $dev7->setName('-5Volt'); + $dev7->setValue($ar_buf[13]); + $this->mbinfo->setMbVolt($dev7); + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + $this->_fans(); + $this->_voltage(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php b/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php new file mode 100644 index 0000000..948fba6 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.hwsensors.inc.php @@ -0,0 +1,156 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.hwsensors.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from hwsensors + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class HWSensors extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_lines = array(); + + /** + * fill the private content var through tcp or file access + */ + public function __construct() + { + parent::__construct(); + $lines = ""; +// CommonFunctions::executeProgram('sysctl', '-w hw.sensors', $lines); + CommonFunctions::executeProgram('sysctl', 'hw.sensors', $lines); + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + foreach ($this->_lines as $line) { + if (preg_match('/^hw\.sensors\.[0-9]+=[^\s,]+,\s+([^,]+),\s+temp,\s+([0-9\.]+)\s+degC.*$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[1]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbTemp($dev); + } elseif (preg_match('/^hw\.sensors\.[0-9]+=[^\s,]+,\s+([^,]+),\s+([0-9\.]+)\s+degC$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[1]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbTemp($dev); + } elseif (preg_match('/^hw\.sensors\.[^\.]+\.(.*)=([0-9\.]+)\s+degC\s+\((.*)\)$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[3]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbTemp($dev); + } elseif (preg_match('/^hw\.sensors\.[^\.]+\.(.*)=([0-9\.]+)\s+degC$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[1]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + foreach ($this->_lines as $line) { + if (preg_match('/^hw\.sensors\.[0-9]+=[^\s,]+,\s+([^,]+),\s+fanrpm,\s+([0-9\.]+)\s+RPM.*$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[1]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbFan($dev); + } elseif (preg_match('/^hw\.sensors\.[0-9]+=[^\s,]+,\s+([^,]+),\s+([0-9\.]+)\s+RPM$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[1]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbFan($dev); + } elseif (preg_match('/^hw\.sensors\.[^\.]+\.(.*)=([0-9\.]+)\s+RPM\s+\((.*)\)$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[3]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbFan($dev); + } elseif (preg_match('/^hw\.sensors\.[^\.]+\.(.*)=([0-9\.]+)\s+RPM$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[1]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbFan($dev); + } + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + foreach ($this->_lines as $line) { + if (preg_match('/^hw\.sensors\.[0-9]+=[^\s,]+,\s+([^,]+),\s+volts_dc,\s+([0-9\.]+)\s+V.*$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[1]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbVolt($dev); + } elseif (preg_match('/^hw\.sensors\.[0-9]+=[^\s,]+,\s+([^,]+),\s+([0-9\.]+)\s+V\sDC$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[1]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbVolt($dev); + } elseif (preg_match('/^hw\.sensors\.[^\.]+\.(.*)=([0-9\.]+)\s+VDC\s+\((.*)\)$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[3]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbVolt($dev); + } elseif (preg_match('/^hw\.sensors\.[^\.]+\.(.*)=([0-9\.]+)\s+VDC$/', $line, $ar_buf)) { + $dev = new SensorDevice(); + $dev->setName($ar_buf[1]); + $dev->setValue($ar_buf[2]); + $this->mbinfo->setMbVolt($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_fans(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.ipmi.inc.php b/root/opt/phpsysinfo/includes/mb/class.ipmi.inc.php new file mode 100644 index 0000000..1d16bde --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.ipmi.inc.php @@ -0,0 +1,197 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.ipmi.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from ipmitool + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class IPMI extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_lines = array(); + + /** + * fill the private content var through tcp or file access + */ + public function __construct() + { + parent::__construct(); + switch (strtolower(PSI_SENSOR_ACCESS)) { + case 'command': + CommonFunctions::executeProgram('ipmitool', 'sensor', $lines); + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + break; + case 'file': + if (CommonFunctions::rfts(APP_ROOT.'/data/ipmi.txt', $lines)) { + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + break; + default: + $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); + break; + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[2] == "degrees C" && $buffer[3] != "na") { + $dev = new SensorDevice(); + $dev->setName($buffer[0]); + $dev->setValue($buffer[1]); + if ($buffer[8] != "na") $dev->setMax($buffer[8]); + switch ($buffer[3]) { + case "nr": $dev->setEvent("Non-Recoverable"); break; + case "cr": $dev->setEvent("Critical"); break; + case "nc": $dev->setEvent("Non-Critical"); break; + } + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[2] == "Volts" && $buffer[3] != "na") { + $dev = new SensorDevice(); + $dev->setName($buffer[0]); + $dev->setValue($buffer[1]); + if ($buffer[5] != "na") $dev->setMin($buffer[5]); + if ($buffer[8] != "na") $dev->setMax($buffer[8]); + switch ($buffer[3]) { + case "nr": $dev->setEvent("Non-Recoverable"); break; + case "cr": $dev->setEvent("Critical"); break; + case "nc": $dev->setEvent("Non-Critical"); break; + } + $this->mbinfo->setMbVolt($dev); + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[2] == "RPM" && $buffer[3] != "na") { + $dev = new SensorDevice(); + $dev->setName($buffer[0]); + $dev->setValue($buffer[1]); + if ($buffer[8] != "na") { + $dev->setMin($buffer[8]); + } elseif (($buffer[5] != "na") && ($buffer[5]<$buffer[1])) { //max instead min issue + $dev->setMin($buffer[5]); + } + switch ($buffer[3]) { + case "nr": $dev->setEvent("Non-Recoverable"); break; + case "cr": $dev->setEvent("Critical"); break; + case "nc": $dev->setEvent("Non-Critical"); break; + } + $this->mbinfo->setMbFan($dev); + } + } + } + + /** + * get power information + * + * @return void + */ + private function _power() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[2] == "Watts" && $buffer[3] != "na") { + $dev = new SensorDevice(); + $dev->setName($buffer[0]); + $dev->setValue($buffer[1]); + if ($buffer[8] != "na") $dev->setMax($buffer[8]); + switch ($buffer[3]) { + case "nr": $dev->setEvent("Non-Recoverable"); break; + case "cr": $dev->setEvent("Critical"); break; + case "nc": $dev->setEvent("Non-Critical"); break; + } + $this->mbinfo->setMbPower($dev); + } + } + } + + /** + * get current information + * + * @return void + */ + private function _current() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if ($buffer[2] == "Amps" && $buffer[3] != "na") { + $dev = new SensorDevice(); + $dev->setName($buffer[0]); + $dev->setValue($buffer[1]); + if ($buffer[8] != "na") $dev->setMax($buffer[8]); + switch ($buffer[3]) { + case "nr": $dev->setEvent("Non-Recoverable"); break; + case "cr": $dev->setEvent("Critical"); break; + case "nc": $dev->setEvent("Non-Critical"); break; + } + $this->mbinfo->setMbCurrent($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_fans(); + $this->_power(); + $this->_current(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php b/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php new file mode 100644 index 0000000..68613c3 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.ipmiutil.inc.php @@ -0,0 +1,220 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.ipmiutil.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from ipmi-sensors + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class IPMIutil extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_lines = array(); + + /** + * fill the private content var through tcp or file access + */ + public function __construct() + { + parent::__construct(); + switch (strtolower(PSI_SENSOR_ACCESS)) { + case 'command': + CommonFunctions::executeProgram('ipmiutil', 'sensor -stw', $lines); + $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + break; + case 'file': + if (CommonFunctions::rfts(APP_ROOT.'/data/ipmiutil.txt', $lines)) { + $this->_lines = preg_split("/\r?\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + break; + default: + $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); + break; + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if (isset($buffer[2]) && $buffer[2] == "Temperature" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sC$/", $buffer[6], $value)) { + $dev = new SensorDevice(); + $dev->setName($buffer[4]); + $dev->setValue($value[1]); + if (isset($buffer[7]) && $buffer[7] == "Thresholds") { + if ((isset($buffer[8]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[8], $limits)) + ||(isset($buffer[9]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[9], $limits)) + ||(isset($buffer[10]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[10], $limits)) + ||(isset($buffer[11]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[11], $limits))) { + $dev->setMax($limits[1]); + } + } + if ($buffer[5] != "OK") $dev->setEvent($buffer[5]); + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if (isset($buffer[2]) && $buffer[2] == "Voltage" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sV$/", $buffer[6], $value)) { + $dev = new SensorDevice(); + $dev->setName($buffer[4]); + $dev->setValue($value[1]); + if (isset($buffer[7]) && $buffer[7] == "Thresholds") { + if ((isset($buffer[8]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[8], $limits)) + ||(isset($buffer[9]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[9], $limits)) + ||(isset($buffer[10]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[10], $limits)) + ||(isset($buffer[11]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[11], $limits))) { + $dev->setMin($limits[1]); + } + if ((isset($buffer[8]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[8], $limits)) + ||(isset($buffer[9]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[9], $limits)) + ||(isset($buffer[10]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[10], $limits)) + ||(isset($buffer[11]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[11], $limits))) { + $dev->setMax($limits[1]); + } + } + if ($buffer[5] != "OK") $dev->setEvent($buffer[5]); + $this->mbinfo->setMbVolt($dev); + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if (isset($buffer[2]) && $buffer[2] == "Fan" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sRPM$/", $buffer[6], $value)) { + $dev = new SensorDevice(); + $dev->setName($buffer[4]); + $dev->setValue($value[1]); + if (isset($buffer[7]) && $buffer[7] == "Thresholds") { + if ((isset($buffer[8]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[8], $limits)) + ||(isset($buffer[9]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[9], $limits)) + ||(isset($buffer[10]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[10], $limits)) + ||(isset($buffer[11]) && preg_match("/^lo-crit\s(\S+)\s*$/", $buffer[11], $limits))) { + $dev->setMin($limits[1]); + } elseif ((isset($buffer[8]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[8], $limits)) + ||(isset($buffer[9]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[9], $limits)) + ||(isset($buffer[10]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[10], $limits)) + ||(isset($buffer[11]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[11], $limits))) { + if ($limits[1]<$value[1]) {//max instead min issue + $dev->setMin($limits[1]); + } + } + } + if ($buffer[5] != "OK") $dev->setEvent($buffer[5]); + $this->mbinfo->setMbFan($dev); + } + } + } + + /** + * get power information + * + * @return void + */ + private function _power() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if (isset($buffer[2]) && $buffer[2] == "Current" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sW$/", $buffer[6], $value)) { + $dev = new SensorDevice(); + $dev->setName($buffer[4]); + $dev->setValue($value[1]); + if (isset($buffer[7]) && $buffer[7] == "Thresholds") { + if ((isset($buffer[8]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[8], $limits)) + ||(isset($buffer[9]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[9], $limits)) + ||(isset($buffer[10]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[10], $limits)) + ||(isset($buffer[11]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[11], $limits))) { + $dev->setMax($limits[1]); + } + } + if ($buffer[5] != "OK") $dev->setEvent($buffer[5]); + $this->mbinfo->setMbPower($dev); + } + } + } + + /** + * get current information + * + * @return void + */ + private function _current() + { + foreach ($this->_lines as $line) { + $buffer = preg_split("/\s*\|\s*/", $line); + if (isset($buffer[2]) && $buffer[2] == "Current" && $buffer[1] == "Full" && isset($buffer[6]) && preg_match("/^(\S+)\sA$/", $buffer[6], $value)) { + $dev = new SensorDevice(); + $dev->setName($buffer[4]); + $dev->setValue($value[1]); + if (isset($buffer[7]) && $buffer[7] == "Thresholds") { + if ((isset($buffer[8]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[8], $limits)) + ||(isset($buffer[9]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[9], $limits)) + ||(isset($buffer[10]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[10], $limits)) + ||(isset($buffer[11]) && preg_match("/^hi-crit\s(\S+)\s*$/", $buffer[11], $limits))) { + $dev->setMax($limits[1]); + } + } + if ($buffer[5] != "OK") $dev->setEvent($buffer[5]); + $this->mbinfo->setMbCurrent($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_fans(); + $this->_power(); + $this->_current(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php b/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php new file mode 100644 index 0000000..9383353 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.k8temp.inc.php @@ -0,0 +1,91 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.k8temp.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from k8temp + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class K8Temp extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_lines = array(); + + /** + * fill the private array + */ + public function __construct() + { + parent::__construct(); + switch (strtolower(PSI_SENSOR_ACCESS)) { + case 'command': + $lines = ""; + CommonFunctions::executeProgram('k8temp', '', $lines); + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + break; + case 'file': + if (CommonFunctions::rfts(APP_ROOT.'/data/k8temp.txt', $lines)) { + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + break; + default: + $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); + break; + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + foreach ($this->_lines as $line) { + if (preg_match('/(.*):\s*(\d*)/', $line, $data)) { + if ($data[2] > 0) { + $dev = new SensorDevice(); + $dev->setName($data[1]); + $dev->setMax('70.0'); + if ($data[2] < 250) { + $dev->setValue($data[2]); + } + $this->mbinfo->setMbTemp($dev); + } + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php b/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php new file mode 100644 index 0000000..e883c1e --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.lmsensors.inc.php @@ -0,0 +1,411 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.lmsensors.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from lmsensor + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class LMSensors extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_lines = array(); + + /** + * fill the private content var through tcp or file access + */ + public function __construct() + { + parent::__construct(); + switch (strtolower(PSI_SENSOR_ACCESS)) { + case 'command': + if (CommonFunctions::executeProgram("sensors", "", $lines)) { + // Martijn Stolk: Dirty fix for misinterpreted output of sensors, + // where info could come on next line when the label is too long. + $lines = str_replace(":\n", ":", $lines); + $lines = str_replace("\n\n", "\n", $lines); + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + break; + case 'file': + if (CommonFunctions::rfts(APP_ROOT.'/data/lmsensors.txt', $lines)) { + $lines = str_replace(":\n", ":", $lines); + $lines = str_replace("\n\n", "\n", $lines); + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + break; + default: + $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); + break; + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + $ar_buf = array(); + foreach ($this->_lines as $line) { + $data = array(); + if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) { + ; + } else { + preg_match("/(.*):(.*)/", $line, $data); + } + if (count($data) > 1) { + $temp = substr(trim($data[2]), -1); + switch ($temp) { + case "C": +// case "F": + array_push($ar_buf, $line); + } + } + } + foreach ($ar_buf as $line) { + $data = array(); + if (preg_match("/(.*):(.*).C[ ]*\((.*)=(.*).C,(.*)=(.*).C\)(.*)\)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*).C[ ]*\((.*)=(.*).C,(.*)=(.*).C\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*).C[ ]*\((.*)=(.*).C\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*).C[ \t]+/", $line, $data)) { + ; + } else { + preg_match("/(.*):(.*).C$/", $line, $data); + } + foreach ($data as $key=>$value) { + if (preg_match("/^\+?(-?[0-9\.]+).?$/", trim($value), $newvalue)) { + $data[$key] = 0+trim($newvalue[1]); + } else { + $data[$key] = trim($value); + } + } + $dev = new SensorDevice(); + + if (strlen($data[1]) == 4) { + if ($data[1][0] == "T") { + + if ($data[1][1] == "A") { + $data[1] = $data[1] . " Ambient"; + } elseif ($data[1][1] == "C") { + $data[1] = $data[1] . " CPU"; + } elseif ($data[1][1] == "G") { + $data[1] = $data[1] . " GPU"; + } elseif ($data[1][1] == "H") { + $data[1] = $data[1] . " Harddisk"; + } elseif ($data[1][1] == "L") { + $data[1] = $data[1] . " LCD"; + } elseif ($data[1][1] == "O") { + $data[1] = $data[1] . " ODD"; + } elseif ($data[1][1] == "B") { + $data[1] = $data[1] . " Battery"; + } + + if ($data[1][3] == "H") { + $data[1] = $data[1] . " Heatsink"; + } elseif ($data[1][3] == "P") { + $data[1] = $data[1] . " Proximity"; + } elseif ($data[1][3] == "D") { + $data[1] = $data[1] . " Die"; + } + } + } + + $dev->setName($data[1]); + $dev->setValue($data[2]); + + if (isset($data[6]) && $data[2] <= $data[6]) { + $dev->setMax(max($data[4], $data[6])); + } elseif (isset($data[4]) && $data[2] <= $data[4]) { + $dev->setMax($data[4]); + } + if (preg_match("/\sALARM(\s*)$/", $line)) { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbTemp($dev); + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + $ar_buf = array(); + foreach ($this->_lines as $line) { + $data = array(); + if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) { + ; + } else { + preg_match("/(.*):(.*)/", $line, $data); + } + if (count($data) > 1) { + $temp = substr(trim($data[2]), -4); + switch ($temp) { + case " RPM": + array_push($ar_buf, $line); + } + } + } + foreach ($ar_buf as $line) { + $data = array(); + if (preg_match("/(.*):(.*) RPM[ ]*\((.*)=(.*) RPM,(.*)=(.*)\)(.*)\)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*) RPM[ ]*\((.*)=(.*) RPM,(.*)=(.*)\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*) RPM[ ]*\((.*)=(.*) RPM\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*) RPM[ \t]+/", $line, $data)) { + ; + } else { + preg_match("/(.*):(.*) RPM$/", $line, $data); + } + $dev = new SensorDevice(); + $dev->setName(trim($data[1])); + $dev->setValue(trim($data[2])); + if (isset($data[4])) { + $dev->setMin(trim($data[4])); + } + if (preg_match("/\sALARM(\s*)$/", $line)) { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbFan($dev); + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + $ar_buf = array(); + foreach ($this->_lines as $line) { + $data = array(); + if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*)\(/", $line, $data)) { + ; + } else { + preg_match("/(.*):(.*)/", $line, $data); + } + if (count($data) > 1) { + $temp = substr(trim($data[2]), -2); + switch ($temp) { + case " V": + array_push($ar_buf, $line); + } + } + } + foreach ($ar_buf as $line) { + $data = array(); + if (preg_match("/(.*):(.*) V[ ]*\((.*)=(.*) V,(.*)=(.*) V\)(.*)\)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*) V[ ]*\((.*)=(.*) V,(.*)=(.*) V\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*) V[ \t]+/", $line, $data)) { + ; + } else { + preg_match("/(.*):(.*) V$/", $line, $data); + } + foreach ($data as $key=>$value) { + if (preg_match("/^\+?(-?[0-9\.]+)$/", trim($value), $newvalue)) { + $data[$key] = 0+trim($newvalue[1]); + } else { + $data[$key] = trim($value); + } + } + if (isset($data[1])) { + $dev = new SensorDevice(); + $dev->setName($data[1]); + $dev->setValue($data[2]); + if (isset($data[4])) { + $dev->setMin($data[4]); + } + if (isset($data[6])) { + $dev->setMax($data[6]); + } + if (preg_match("/\sALARM(\s*)$/", $line)) { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbVolt($dev); + } + } + } + + /** + * get power information + * + * @return void + */ + private function _power() + { + $ar_buf = array(); + foreach ($this->_lines as $line) { + $data = array(); + if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) { + ; + } else { + preg_match("/(.*):(.*)/", $line, $data); + } + if (count($data) > 1) { + $temp = substr(trim($data[2]), -2); + switch ($temp) { + case " W": + array_push($ar_buf, $line); + } + } + } + foreach ($ar_buf as $line) { + $data = array(); +/* not tested yet + if (preg_match("/(.*):(.*) W[ ]*\((.*)=(.*) W,(.*)=(.*) W\)(.*)\)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*) W[ ]*\((.*)=(.*) W,(.*)=(.*) W\)(.*)/", $line, $data)) { + ; + } else +*/ + if (preg_match("/(.*):(.*) W[ ]*\((.*)=(.*) W\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*) W[ \t]+/", $line, $data)) { + ; + } else { + preg_match("/(.*):(.*) W$/", $line, $data); + } + foreach ($data as $key=>$value) { + if (preg_match("/^\+?([0-9\.]+).?$/", trim($value), $newvalue)) { + $data[$key] = trim($newvalue[1]); + } else { + $data[$key] = trim($value); + } + } + $dev = new SensorDevice(); + $dev->setName($data[1]); + $dev->setValue($data[2]); + + if (isset($data[6]) && $data[2] <= $data[6]) { + $dev->setMax(max($data[4], $data[6])); + } elseif (isset($data[4]) && $data[2] <= $data[4]) { + $dev->setMax($data[4]); + } + if (preg_match("/\sALARM(\s*)$/", $line)) { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbPower($dev); + } + } + + /** + * get current information + * + * @return void + */ + private function _current() + { + $ar_buf = array(); + foreach ($this->_lines as $line) { + $data = array(); + if (preg_match("/(.*):(.*)\((.*)=(.*),(.*)=(.*)\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*)\((.*)=(.*)\)(.*)/", $line, $data)) { + ; + } else { + preg_match("/(.*):(.*)/", $line, $data); + } + if (count($data) > 1) { + $temp = substr(trim($data[2]), -2); + switch ($temp) { + case " A": + array_push($ar_buf, $line); + } + } + } + foreach ($ar_buf as $line) { + $data = array(); +/* not tested yet + if (preg_match("/(.*):(.*) A[ ]*\((.*)=(.*) A,(.*)=(.*) A\)(.*)\)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*) A[ ]*\((.*)=(.*) A,(.*)=(.*) A\)(.*)/", $line, $data)) { + ; + } else +*/ + if (preg_match("/(.*):(.*) A[ ]*\((.*)=(.*) A\)(.*)/", $line, $data)) { + ; + } elseif (preg_match("/(.*):(.*) A[ \t]+/", $line, $data)) { + ; + } else { + preg_match("/(.*):(.*) A$/", $line, $data); + } + foreach ($data as $key=>$value) { + if (preg_match("/^\+?([0-9\.]+).?$/", trim($value), $newvalue)) { + $data[$key] = trim($newvalue[1]); + } else { + $data[$key] = trim($value); + } + } + $dev = new SensorDevice(); + $dev->setName($data[1]); + $dev->setValue($data[2]); + + if (isset($data[6]) && $data[2] <= $data[6]) { + $dev->setMax(max($data[4], $data[6])); + } elseif (isset($data[4]) && $data[2] <= $data[4]) { + $dev->setMax($data[4]); + } + if (preg_match("/\sALARM(\s*)$/", $line)) { + $dev->setEvent("Alarm"); + } + $this->mbinfo->setMbCurrent($dev); + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_fans(); + $this->_power(); + $this->_current(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php b/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php new file mode 100644 index 0000000..bd22b40 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.mbm5.inc.php @@ -0,0 +1,138 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.mbm5.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from Motherboard Monitor 5 + * information retrival through csv file + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class MBM5 extends Sensors +{ + /** + * array with the names of the labels + * + * @var array + */ + private $_buf_label = array(); + + /** + * array withe the values + * + * @var array + */ + private $_buf_value = array(); + + /** + * read the MBM5.csv file and fill the private arrays + */ + public function __construct() + { + parent::__construct(); + switch (strtolower(PSI_SENSOR_ACCESS)) { + case 'file': + $delim = "/;/"; + CommonFunctions::rfts(APP_ROOT."/data/MBM5.csv", $buffer); + if (strpos($buffer, ";") === false) { + $delim = "/,/"; + } + $buffer = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY); + $this->_buf_label = preg_split($delim, substr($buffer[0], 0, -2), -1, PREG_SPLIT_NO_EMPTY); + $this->_buf_value = preg_split($delim, substr($buffer[1], 0, -2), -1, PREG_SPLIT_NO_EMPTY); + break; + default: + $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); + break; + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + for ($intPosi = 3; $intPosi < 6; $intPosi++) { + if ($this->_buf_value[$intPosi] == 0) { + continue; + } + preg_match("/([0-9\.])*/", str_replace(",", ".", $this->_buf_value[$intPosi]), $hits); + $dev = new SensorDevice(); + $dev->setName($this->_buf_label[$intPosi]); + $dev->setValue($hits[0]); + $dev->setMax(70); + $this->mbinfo->setMbTemp($dev); + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + for ($intPosi = 13; $intPosi < 16; $intPosi++) { + if (!isset($this->_buf_value[$intPosi])) { + continue; + } + preg_match("/([0-9\.])*/", str_replace(",", ".", $this->_buf_value[$intPosi]), $hits); + $dev = new SensorDevice(); + $dev->setName($this->_buf_label[$intPosi]); + $dev->setValue($hits[0]); + $dev->setMin(3000); + $this->mbinfo->setMbFan($dev); + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + for ($intPosi = 6; $intPosi < 13; $intPosi++) { + if ($this->_buf_value[$intPosi] == 0) { + continue; + } + preg_match("/([0-9\.])*/", str_replace(",", ".", $this->_buf_value[$intPosi]), $hits); + $dev = new SensorDevice(); + $dev->setName($this->_buf_label[$intPosi]); + $dev->setValue($hits[0]); + $this->mbinfo->setMbVolt($dev); + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_fans(); + $this->_temperature(); + $this->_voltage(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php b/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php new file mode 100644 index 0000000..351b0a8 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.mbmon.inc.php @@ -0,0 +1,143 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.mbmon.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from mbmon + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class MBMon extends Sensors +{ + /** + * content to parse + * + * @var array + */ + private $_lines = array(); + + /** + * fill the private content var through tcp or file access + */ + public function __construct() + { + parent::__construct(); + switch (strtolower(PSI_SENSOR_ACCESS)) { + case 'tcp': + $fp = fsockopen("localhost", 411, $errno, $errstr, 5); + if ($fp) { + $lines = ""; + while (!feof($fp)) { + $lines .= fread($fp, 1024); + } + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } else { + $this->error->addError("fsockopen()", $errno." ".$errstr); + } + break; + case 'command': + CommonFunctions::executeProgram('mbmon', '-c 1 -r', $lines, PSI_DEBUG); + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + break; + case 'file': + if (CommonFunctions::rfts(APP_ROOT.'/data/mbmon.txt', $lines)) { + $this->_lines = preg_split("/\n/", $lines, -1, PREG_SPLIT_NO_EMPTY); + } + break; + default: + $this->error->addConfigError('__construct()', 'PSI_SENSOR_ACCESS'); + break; + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + foreach ($this->_lines as $line) { + if (preg_match('/^(TEMP\d*)\s*:\s*(.*)$/D', $line, $data)) { + if ($data[2] <> '0') { + $dev = new SensorDevice(); + $dev->setName($data[1]); + $dev->setMax(70); + if ($data[2] < 250) { + $dev->setValue($data[2]); + } + $this->mbinfo->setMbTemp($dev); + } + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + foreach ($this->_lines as $line) { + if (preg_match('/^(FAN\d*)\s*:\s*(.*)$/D', $line, $data)) { + if ($data[2] <> '0') { + $dev = new SensorDevice(); + $dev->setName($data[1]); + $dev->setValue($data[2]); + $dev->setMax(3000); + $this->mbinfo->setMbFan($dev); + } + } + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + foreach ($this->_lines as $line) { + if (preg_match('/^(V.*)\s*:\s*(.*)$/D', $line, $data)) { + if ($data[2] <> '+0.00') { + $dev = new SensorDevice(); + $dev->setName($data[1]); + $dev->setValue($data[2]); + $this->mbinfo->setMbVolt($dev); + } + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return void + */ + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_fans(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php b/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php new file mode 100644 index 0000000..baed9bb --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.ohm.inc.php @@ -0,0 +1,145 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.ohm.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from Open Hardware Monitor + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class OHM extends Sensors +{ +/** + * holds the COM object that we pull all the WMI data from + * + * @var Object + */ + private $_buf = array(); + + /** + * fill the private content var + */ + public function __construct() + { + parent::__construct(); + $_wmi = null; + // don't set this params for local connection, it will not work + $strHostname = ''; + $strUser = ''; + $strPassword = ''; + try { + // initialize the wmi object + $objLocator = new COM('WbemScripting.SWbemLocator'); + if ($strHostname == "") { + $_wmi = $objLocator->ConnectServer($strHostname, 'root\OpenHardwareMonitor'); + + } else { + $_wmi = $objLocator->ConnectServer($strHostname, 'root\OpenHardwareMonitor', $strHostname.'\\'.$strUser, $strPassword); + } + } catch (Exception $e) { + $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for OpenHardwareMonitor data."); + } + if ($_wmi) { + $this->_buf = CommonFunctions::getWMI($_wmi, 'Sensor', array('Parent', 'Name', 'SensorType', 'Value')); + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + if ($this->_buf) foreach ($this->_buf as $buffer) { + if ($buffer['SensorType'] == "Temperature") { + $dev = new SensorDevice(); + $dev->setName($buffer['Parent'].' '.$buffer['Name']); + $dev->setValue($buffer['Value']); + $this->mbinfo->setMbTemp($dev); + } + } + } + + /** + * get voltage information + * + * @return void + */ + private function _voltage() + { + if ($this->_buf) foreach ($this->_buf as $buffer) { + if ($buffer['SensorType'] == "Voltage") { + $dev = new SensorDevice(); + $dev->setName($buffer['Parent'].' '.$buffer['Name']); + $dev->setValue($buffer['Value']); + $this->mbinfo->setMbVolt($dev); + } + } + } + + /** + * get fan information + * + * @return void + */ + private function _fans() + { + if ($this->_buf) foreach ($this->_buf as $buffer) { + if ($buffer['SensorType'] == "Fan") { + $dev = new SensorDevice(); + $dev->setName($buffer['Parent'].' '.$buffer['Name']); + $dev->setValue($buffer['Value']); + $this->mbinfo->setMbFan($dev); + } + } + } + + /** + * get power information + * + * @return void + */ + private function _power() + { + if ($this->_buf) foreach ($this->_buf as $buffer) { + if ($buffer['SensorType'] == "Power") { + $dev = new SensorDevice(); + $dev->setName($buffer['Parent'].' '.$buffer['Name']); + $dev->setValue($buffer['Value']); + $this->mbinfo->setMbPower($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_fans(); + $this->_power(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php b/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php new file mode 100644 index 0000000..1455ad5 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.pitemp.inc.php @@ -0,0 +1,62 @@ + + * @copyright 2012 Marc Hillesheim + * @link http://pi.no-ip.biz + */ +class PiTemp extends Sensors +{ + private function _temperature() + { + $temp = null; + $temp_max = null; + if (!CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input', $temp, 0, 4096, false)) { // Not Banana Pi + CommonFunctions::rfts('/sys/class/thermal/thermal_zone0/temp', $temp); + CommonFunctions::rfts('/sys/class/thermal/thermal_zone0/trip_point_0_temp', $temp_max, 0, 4096, PSI_DEBUG); + } + if (!is_null($temp) && (trim($temp) != "")) { + $dev = new SensorDevice(); + $dev->setName("CPU 1"); + $dev->setValue($temp / 1000); + if (!is_null($temp_max) && (trim($temp_max) != "") && ($temp_max > 0)) { + $dev->setMax($temp_max / 1000); + } + $this->mbinfo->setMbTemp($dev); + } + } + + private function _voltage() + { + $volt = null; + if (CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/voltage_now', $volt, 0, 4096, false) && !is_null($volt) && (trim($volt) != "")) { // Banana Pi + $dev = new SensorDevice(); + $dev->setName("Voltage 1"); + $dev->setValue($volt / 1000000); + $this->mbinfo->setMbVolt($dev); + } + } + + private function _current() + { + $current = null; + if (CommonFunctions::rfts('/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply/ac/current_now', $current, 0, 4096, false) && !is_null($current) && (trim($current) != "")) { // Banana Pi + $dev = new SensorDevice(); + $dev->setName("Current 1"); + $dev->setValue($current / 1000000); + $this->mbinfo->setMbCurrent($dev); + } + } + + public function build() + { + $this->_temperature(); + $this->_voltage(); + $this->_current(); + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php b/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php new file mode 100644 index 0000000..a37385b --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.sensors.inc.php @@ -0,0 +1,64 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.sensors.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * Basic OS functions for all OS classes + * + * @category PHP + * @package PSI sensors class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +abstract class Sensors implements PSI_Interface_Sensor +{ + /** + * object for error handling + * + * @var Error + */ + protected $error; + + /** + * object for the information + * + * @var MBInfo + */ + protected $mbinfo; + + /** + * build the global Error object + */ + public function __construct() + { + $this->error = Error::singleton(); + $this->mbinfo = new MBInfo(); + } + + /** + * get the filled or unfilled (with default values) MBInfo object + * + * @see PSI_Interface_Sensor::getMBInfo() + * + * @return MBInfo + */ + final public function getMBInfo() + { + $this->build(); + + return $this->mbinfo; + } +} diff --git a/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php b/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php new file mode 100644 index 0000000..6abd7c1 --- /dev/null +++ b/root/opt/phpsysinfo/includes/mb/class.thermalzone.inc.php @@ -0,0 +1,132 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.ohm.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting information from Thermal Zone WMI class + * + * @category PHP + * @package PSI_Sensor + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class ThermalZone extends Sensors +{ +/** + * holds the COM object that we pull all the WMI data from + * + * @var Object + */ + private $_buf = array(); + + /** + * fill the private content var + */ + public function __construct() + { + parent::__construct(); + if (PSI_OS == 'WINNT') { + $_wmi = null; + // don't set this params for local connection, it will not work + $strHostname = ''; + $strUser = ''; + $strPassword = ''; + try { + // initialize the wmi object + $objLocator = new COM('WbemScripting.SWbemLocator'); + if ($strHostname == "") { + $_wmi = $objLocator->ConnectServer($strHostname, 'root\WMI'); + + } else { + $_wmi = $objLocator->ConnectServer($strHostname, 'root\WMI', $strHostname.'\\'.$strUser, $strPassword); + } + } catch (Exception $e) { + $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for ThermalZone data."); + } + if ($_wmi) { + $this->_buf = CommonFunctions::getWMI($_wmi, 'MSAcpi_ThermalZoneTemperature', array('InstanceName', 'CriticalTripPoint', 'CurrentTemperature')); + } + } + } + + /** + * get temperature information + * + * @return void + */ + private function _temperature() + { + if (PSI_OS == 'WINNT') { + if ($this->_buf) foreach ($this->_buf as $buffer) { + if (isset($buffer['CurrentTemperature']) && (($value = ($buffer['CurrentTemperature'] - 2732)/10) > -100)) { + $dev = new SensorDevice(); + if (isset($buffer['InstanceName']) && preg_match("/([^\\\\ ]+)$/", $buffer['InstanceName'], $outbuf)) { + $dev->setName('ThermalZone '.$outbuf[1]); + } else { + $dev->setName('ThermalZone THM0_0'); + } + $dev->setValue($value); + if (isset($buffer['CriticalTripPoint']) && (($maxvalue = ($buffer['CriticalTripPoint'] - 2732)/10) > 0)) { + $dev->setMax($maxvalue); + } + $this->mbinfo->setMbTemp($dev); + } + } + } else { + foreach (glob('/sys/class/thermal/thermal_zone*/') as $thermalzone) { + $thermalzonetemp = $thermalzone.'temp'; + $temp = null; + if (CommonFunctions::rfts($thermalzonetemp, $temp, 0, 4096, false) && !is_null($temp) && (trim($temp) != "")) { + if ($temp >= 1000) { + $temp = $temp / 1000; + } + + if ($temp > -40) { + $dev = new SensorDevice(); + $dev->setValue($temp); + + $temp_type = null; + if (CommonFunctions::rfts($thermalzone.'type', $temp_type, 0, 4096, false) && !is_null($temp_type) && (trim($temp_type) != "")) { + $dev->setName($temp_type); + } + + $temp_max = null; + if (CommonFunctions::rfts($thermalzone.'trip_point_0_temp', $temp_max, 0, 4096, false) && !is_null($temp_max) && (trim($temp_max) != "") && ($temp_max > 0)) { + if ($temp_max >= 1000) { + $temp_max = $temp_max / 1000; + } + $dev->setMax($temp_max); + } + + $this->mbinfo->setMbTemp($dev); + } + } + } + } + } + + /** + * get the information + * + * @see PSI_Interface_Sensor::build() + * + * @return Void + */ + public function build() + { + $this->_temperature(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.AIX.inc.php b/root/opt/phpsysinfo/includes/os/class.AIX.inc.php new file mode 100644 index 0000000..61ce603 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.AIX.inc.php @@ -0,0 +1,381 @@ + + * @copyright 2011 Krzysztof Paz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.AIX.inc.php 287 2009-06-26 12:11:59Z Krzysztof Paz, IBM POLSKA + * @link http://phpsysinfo.sourceforge.net + */ +/** +* IBM AIX sysinfo class +* get all the required information from IBM AIX system +* +* @category PHP +* @package PSI AIX OS class +* @author Krzysztof Paz (kpaz@gazeta.pl) based on Michael Cramer +* @copyright 2011 Krzysztof Paz +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License +* @version Release: 3.0 +* @link http://phpsysinfo.sourceforge.net +*/ +class AIX extends OS +{ + + private $_aixdata = array(); + + /** + * Virtual Host Name + * @return void + */ + private function _hostname() + { + /* if (PSI_USE_VHOST === true) { + $this->sys->setHostname(getenv('SERVER_NAME')); + } else { + if (CommonFunctions::executeProgram('hostname', '', $ret)) { + $this->sys->setHostname($ret); + } + } */ + $this->sys->setHostname(getenv('SERVER_NAME')); + + } + + /** + * IP of the Virtual Host Name + * @return void + */ + private function _ip() + { + if (PSI_USE_VHOST === true) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + if (!($result = getenv('SERVER_ADDR'))) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + $this->sys->setIp($result); + } + } + } + + /** + * IBM AIX Version + * @return void + */ + private function _kernel() + { + if (CommonFunctions::executeProgram('oslevel', '', $ret1) && CommonFunctions::executeProgram('oslevel', '-s', $ret2)) { + $this->sys->setKernel($ret1 . ' (' . $ret2 . ')'); + } + } + + /** + * UpTime + * time the system is running + * @return void + */ + private function _uptime() + { + if (CommonFunctions::executeProgram('uptime', '', $buf)) { + if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $buf, $ar_buf) || preg_match("/up (\d+) day,\s*(\d+):(\d+),/", $buf, $ar_buf)) { + $min = $ar_buf[3]; + $hours = $ar_buf[2]; + $days = $ar_buf[1]; + $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60); + } + } + } + + /** + * Number of Users + * @return void + */ + private function _users() + { + if (CommonFunctions::executeProgram('who', '| wc -l', $buf, PSI_DEBUG)) { + $this->sys->setUsers($buf); + } + } + + /** + * Processor Load + * optionally create a loadbar + * @return void + */ + private function _loadavg() + { + if (CommonFunctions::executeProgram('uptime', '', $buf)) { + if (preg_match("/average: (.*), (.*), (.*)$/", $buf, $ar_buf)) { + $this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]); + } + } + } + + /** + * CPU information + * All of the tags here are highly architecture dependant + * @return void + */ + private function _cpuinfo() + { + $ncpu = 0; + $tcpu = ""; + $vcpu = ""; + $ccpu = ""; + $scpu = ""; + foreach ($this->readaixdata() as $line) { + if (preg_match("/^Number Of Processors:\s+(\d+)/", $line, $ar_buf)) { + $ncpu = $ar_buf[1]; + } + if (preg_match("/^Processor Type:\s+(.+)/", $line, $ar_buf)) { + $tcpu = $ar_buf[1]; + } + if (preg_match("/^Processor Version:\s+(.+)/", $line, $ar_buf)) { + $vcpu = $ar_buf[1]; + } + if (preg_match("/^CPU Type:\s+(.+)/", $line, $ar_buf)) { + $ccpu = $ar_buf[1]; + } + if (preg_match("/^Processor Clock Speed:\s+(\d+)\s/", $line, $ar_buf)) { + $scpu = $ar_buf[1]; + } + } + for ($i = 0; $i < $ncpu; $i++) { + $dev = new CpuDevice(); + if (trim($tcpu) != "") { + $cpu = trim($tcpu); + if (trim($vcpu) != "") $cpu .= " ".trim($vcpu); + if (trim($ccpu) != "") $cpu .= " ".trim($ccpu); + $dev->setModel($cpu); + } + if (trim($scpu) != "") { + $dev->setCpuSpeed(trim($scpu)); + } + $this->sys->setCpus($dev); + } + } + + /** + * PCI devices + * @return void + */ + private function _pci() + { + foreach ($this->readaixdata() as $line) { + if (preg_match("/^[\*\+]\s\S+\s+\S+\s+(.*PCI.*)/", $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName(trim($ar_buf[1])); + $this->sys->setPciDevices($dev); + } + } + } + + /** + * IDE devices + * @return void + */ + private function _ide() + { + foreach ($this->readaixdata() as $line) { + if (preg_match("/^[\*\+]\s\S+\s+\S+\s+(.*IDE.*)/", $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName(trim($ar_buf[1])); + $this->sys->setIdeDevices($dev); + } + } + } + + /** + * SCSI devices + * @return void + */ + private function _scsi() + { + foreach ($this->readaixdata() as $line) { + if (preg_match("/^[\*\+]\s\S+\s+\S+\s+(.*SCSI.*)/", $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName(trim($ar_buf[1])); + $this->sys->setScsiDevices($dev); + } + } + } + + /** + * USB devices + * @return void + */ + private function _usb() + { + foreach ($this->readaixdata() as $line) { + if (preg_match("/^[\*\+]\s\S+\s+\S+\s+(.*USB.*)/", $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName(trim($ar_buf[1])); + $this->sys->setUsbDevices($dev); + } + } + } + + /** + * Network devices + * includes also rx/tx bytes + * @return void + */ + private function _network() + { + if (CommonFunctions::executeProgram('netstat', '-ni | tail -n +2', $netstat)) { + $lines = preg_split("/\n/", $netstat, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $ar_buf = preg_split("/\s+/", $line); + if (! empty($ar_buf[0]) && ! empty($ar_buf[3])) { + $dev = new NetDevice(); + $dev->setName($ar_buf[0]); + $dev->setRxBytes($ar_buf[4]); + $dev->setTxBytes($ar_buf[6]); + $dev->setErrors($ar_buf[5] + $ar_buf[7]); + //$dev->setDrops($ar_buf[8]); + $this->sys->setNetDevices($dev); + } + } + } + } + + /** + * Physical memory information and Swap Space information + * @return void + */ + private function _memory() + { + $mems = ""; + $tswap = ""; + $pswap = ""; + foreach ($this->readaixdata() as $line) { + if (preg_match("/^Good Memory Size:\s+(\d+)\s+MB/", $line, $ar_buf)) { + $mems = $ar_buf[1]; + } + if (preg_match("/^\s*Total Paging Space:\s+(\d+)MB/", $line, $ar_buf)) { + $tswap = $ar_buf[1]; + } + if (preg_match("/^\s*Percent Used:\s+(\d+)%/", $line, $ar_buf)) { + $pswap = $ar_buf[1]; + } + } + if (trim($mems) != "") { + $mems = $mems*1024*1024; + $this->sys->setMemTotal($mems); + $memu = 0; + $memf = 0; + if (CommonFunctions::executeProgram('svmon', '-G', $buf)) { + if (preg_match("/^memory\s+\d+\s+(\d+)\s+/", $buf, $ar_buf)) { + $memu = $ar_buf[1]*1024*4; + $memf = $mems - $memu; + } + } + $this->sys->setMemUsed($memu); + $this->sys->setMemFree($memf); +// $this->sys->setMemApplication($mems); +// $this->sys->setMemBuffer($mems); +// $this->sys->setMemCache($mems); + } + if (trim($tswap) != "") { + $dev = new DiskDevice(); + $dev->setName("SWAP"); + $dev->setFsType('swap'); + $dev->setTotal($tswap * 1024 * 1024); + if (trim($pswap) != "") { + $dev->setUsed($dev->getTotal() * $pswap / 100); + } + $dev->setFree($dev->getTotal() - $dev->getUsed()); + $this->sys->setSwapDevices($dev); + } + } + + /** + * filesystem information + * + * @return void + */ + private function _filesystems() + { + if (CommonFunctions::executeProgram('df', '-kP', $df, PSI_DEBUG)) { + $mounts = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); + if (CommonFunctions::executeProgram('mount', '-v', $s, PSI_DEBUG)) { + $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); + while (list(, $line) = each($lines)) { + $a = preg_split('/ /', $line, -1, PREG_SPLIT_NO_EMPTY); + $fsdev[$a[0]] = $a[4]; + } + } + foreach ($mounts as $mount) { + $ar_buf = preg_split("/\s+/", $mount, 6); + $dev = new DiskDevice(); + $dev->setName($ar_buf[0]); + $dev->setTotal($ar_buf[1] * 1024); + $dev->setUsed($ar_buf[2] * 1024); + $dev->setFree($ar_buf[3] * 1024); + $dev->setMountPoint($ar_buf[5]); + if (isset($fsdev[$ar_buf[0]])) { + $dev->setFsType($fsdev[$ar_buf[0]]); + } + $this->sys->setDiskDevices($dev); + } + } + } + + /** + * Distribution + * + * @return void + */ + private function _distro() + { + $this->sys->setDistribution('IBM AIX'); + $this->sys->setDistributionIcon('AIX.png'); + } + + /** + * IBM AIX informations by K.PAZ + * @return void + */ + private function readaixdata() + { + if (count($this->_aixdata) === 0) { + if (CommonFunctions::executeProgram('prtconf', '', $bufr)) { + $this->_aixdata = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + } + } + + return $this->_aixdata; + } + + /** + * get the information + * + * @see PSI_Interface_OS::build() + * + * @return Void + */ + public function build() + { + $this->error->addError("WARN", "The AIX version of phpSysInfo is a work in progress, some things currently don't work"); + $this->_distro(); + $this->_hostname(); + $this->_ip(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + $this->_cpuinfo(); + $this->_pci(); + $this->_ide(); + $this->_scsi(); + $this->_usb(); + $this->_network(); + $this->_memory(); + $this->_filesystems(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.Android.inc.php b/root/opt/phpsysinfo/includes/os/class.Android.inc.php new file mode 100644 index 0000000..04c88e4 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.Android.inc.php @@ -0,0 +1,254 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.Linux.inc.php 712 2012-12-05 14:09:18Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * Android sysinfo class + * get all the required information from Android system + * + * @category PHP + * @package PSI Android OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Android extends Linux +{ + /** + * call parent constructor + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Kernel Version + * + * @return void + */ + private function _kernel() + { + if (CommonFunctions::rfts('/proc/version', $strBuf, 1)) { + if (preg_match('/version (.*?) /', $strBuf, $ar_buf)) { + $result = $ar_buf[1]; + if (preg_match('/SMP/', $strBuf)) { + $result .= ' (SMP)'; + } + $this->sys->setKernel($result); + } + } + } + + /** + * Number of Users + * + * @return void + */ + private function _users() + { + $this->sys->setUsers(1); + } + + /** + * filesystem information + * + * @return void + */ + private function _filesystems() + { + if (CommonFunctions::executeProgram('df', '2>/dev/null ', $df, PSI_DEBUG)) { + $df = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); + if (CommonFunctions::executeProgram('mount', '', $mount, PSI_DEBUG)) { + $mount = preg_split("/\n/", $mount, -1, PREG_SPLIT_NO_EMPTY); + foreach ($mount as $mount_line) { + $mount_buf = preg_split('/\s+/', $mount_line); + if (count($mount_buf) == 6) { + $mount_parm[$mount_buf[1]]['fstype'] = $mount_buf[2]; + if (PSI_SHOW_MOUNT_OPTION) $mount_parm[$mount_buf[1]]['options'] = $mount_buf[3]; + $mount_parm[$mount_buf[1]]['mountdev'] = $mount_buf[0]; + } + } + foreach ($df as $df_line) { + if ((preg_match("/^(\/\S+)(\s+)(([0-9\.]+)([KMGT])(\s+)([0-9\.]+)([KMGT])(\s+)([0-9\.]+)([KMGT])(\s+))/", $df_line, $df_buf) + || preg_match("/^(\/[^\s\:]+)\:(\s+)(([0-9\.]+)([KMGT])(\s+total\,\s+)([0-9\.]+)([KMGT])(\s+used\,\s+)([0-9\.]+)([KMGT])(\s+available))/", $df_line, $df_buf)) + && !preg_match('/^\/mnt\/asec\/com\./', $df_buf[1])) { + $dev = new DiskDevice(); + if (PSI_SHOW_MOUNT_POINT) $dev->setMountPoint($df_buf[1]); + + if ($df_buf[5] == 'K') $dev->setTotal($df_buf[4] * 1024); + elseif ($df_buf[5] == 'M') $dev->setTotal($df_buf[4] * 1024*1024); + elseif ($df_buf[5] == 'G') $dev->setTotal($df_buf[4] * 1024*1024*1024); + elseif ($df_buf[5] == 'T') $dev->setTotal($df_buf[4] * 1024*1024*1024*1024); + + if ($df_buf[8] == 'K') $dev->setUsed($df_buf[7] * 1024); + elseif ($df_buf[8] == 'M') $dev->setUsed($df_buf[7] * 1024*1024); + elseif ($df_buf[8] == 'G') $dev->setUsed($df_buf[7] * 1024*1024*1024); + elseif ($df_buf[8] == 'T') $dev->setUsed($df_buf[7] * 1024*1024*1024*1024); + + if ($df_buf[11] == 'K') $dev->setFree($df_buf[10] * 1024); + elseif ($df_buf[11] == 'M') $dev->setFree($df_buf[10] * 1024*1024); + elseif ($df_buf[11] == 'G') $dev->setFree($df_buf[10] * 1024*1024*1024); + elseif ($df_buf[11] == 'T') $dev->setFree($df_buf[10] * 1024*1024*1024*1024); + + if (isset($mount_parm[$df_buf[1]])) { + $dev->setFsType($mount_parm[$df_buf[1]]['fstype']); + $dev->setName($mount_parm[$df_buf[1]]['mountdev']); + + if (PSI_SHOW_MOUNT_OPTION) { + if (PSI_SHOW_MOUNT_CREDENTIALS) { + $dev->setOptions($mount_parm[$df_buf[1]]['options']); + } else { + $mpo=$mount_parm[$df_buf[1]]['options']; + + $mpo=preg_replace('/(^guest,)|(^guest$)|(,guest$)/i', '', $mpo); + $mpo=preg_replace('/,guest,/i', ',', $mpo); + + $mpo=preg_replace('/(^user=[^,]*,)|(^user=[^,]*$)|(,user=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,user=[^,]*,/i', ',', $mpo); + + $mpo=preg_replace('/(^username=[^,]*,)|(^username=[^,]*$)|(,username=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,username=[^,]*,/i', ',', $mpo); + + $mpo=preg_replace('/(^password=[^,]*,)|(^password=[^,]*$)|(,password=[^,]*$)/i', '', $mpo); + $mpo=preg_replace('/,password=[^,]*,/i', ',', $mpo); + + $dev->setOptions($mpo); + } + } + } + $this->sys->setDiskDevices($dev); + } + } + } + } + } + + /** + * Distribution + * + * @return void + */ + private function _distro() + { + $buf = ""; + if (CommonFunctions::rfts('/system/build.prop', $lines, 0, 4096, false) + && preg_match('/^ro\.build\.version\.release=([^\n]+)/m', $lines, $ar_buf)) { + $buf = trim($ar_buf[1]); + } + if (is_null($buf) || ($buf == "")) { + $this->sys->setDistribution('Android'); + } else { + if (preg_match('/^(\d+\.\d+)/', $buf, $ver) + && ($list = @parse_ini_file(APP_ROOT."/data/osnames.ini", true)) + && isset($list['Android'][$ver[1]])) { + $buf.=' '.$list['Android'][$ver[1]]; + } + $this->sys->setDistribution('Android '.$buf); + } + $this->sys->setDistributionIcon('Android.png'); + } + + /** + * Machine + * + * @return void + */ + private function _machine() + { + if (CommonFunctions::rfts('/system/build.prop', $lines, 0, 4096, false)) { + $buf = ""; + if (preg_match('/^ro\.product\.manufacturer=([^\n]+)/m', $lines, $ar_buf)) { + $buf .= ' '.trim($ar_buf[1]); + } + if (preg_match('/^ro\.product\.model=([^\n]+)/m', $lines, $ar_buf) && (trim($buf) !== trim($ar_buf[1]))) { + $buf .= ' '.trim($ar_buf[1]); + } + if (preg_match('/^ro\.semc\.product\.name=([^\n]+)/m', $lines, $ar_buf)) { + $buf .= ' '.trim($ar_buf[1]); + } + if (trim($buf) != "") { + $this->sys->setMachine(trim($buf)); + } + } + } + + /** + * PCI devices + * + * @return array + */ + private function _pci() + { + if (CommonFunctions::executeProgram('lspci', '', $bufr, false)) { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + $device = preg_split("/ /", $buf, 4); + if (isset($device[3]) && trim($device[3]) != "") { + $dev = new HWDevice(); + $dev->setName('Class '.trim($device[2]).' Device '.trim($device[3])); + $this->sys->setPciDevices($dev); + } + } + } + } + + /** + * USB devices + * + * @return array + */ + private function _usb() + { + if (file_exists('/dev/bus/usb') && CommonFunctions::executeProgram('lsusb', '', $bufr, false)) { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + $device = preg_split("/ /", $buf, 6); + if (isset($device[5]) && trim($device[5]) != "") { + $dev = new HWDevice(); + $dev->setName(trim($device[5])); + $this->sys->setUsbDevices($dev); + } + } + } + } + + /** + * get the information + * + * @see PSI_Interface_OS::build() + * + * @return Void + */ + public function build() + { + $this->_distro(); + $this->_hostname(); + $this->_ip(); + $this->_kernel(); + $this->_machine(); + $this->_uptime(); + $this->_users(); + $this->_cpuinfo(); + $this->_pci(); + $this->_usb(); + $this->_i2c(); + $this->_network(); + $this->_memory(); + $this->_filesystems(); + $this->_loadavg(); + $this->_processes(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php b/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php new file mode 100644 index 0000000..50bc2cf --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.BSDCommon.inc.php @@ -0,0 +1,592 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.BSDCommon.inc.php 621 2012-07-29 18:49:04Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * BSDCommon class + * get all the required information for BSD Like systems + * no need to implement in every class the same methods + * + * @category PHP + * @package PSI BSDCommon OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +abstract class BSDCommon extends OS +{ + /** + * content of the syslog + * + * @var array + */ + private $_dmesg = array(); + + /** + * regexp1 for cpu information out of the syslog + * + * @var string + */ + private $_CPURegExp1 = ""; + + /** + * regexp2 for cpu information out of the syslog + * + * @var string + */ + private $_CPURegExp2 = ""; + + /** + * regexp1 for scsi information out of the syslog + * + * @var string + */ + private $_SCSIRegExp1 = ""; + + /** + * regexp2 for scsi information out of the syslog + * + * @var string + */ + private $_SCSIRegExp2 = ""; + + /** + * regexp1 for pci information out of the syslog + * + * @var string + */ + private $_PCIRegExp1 = ""; + + /** + * regexp1 for pci information out of the syslog + * + * @var string + */ + private $_PCIRegExp2 = ""; + + /** + * call parent constructor + */ + public function __construct() + { + parent::__construct(); + } + + /** + * setter for cpuregexp1 + * + * @param string $value value to set + * + * @return void + */ + protected function setCPURegExp1($value) + { + $this->_CPURegExp1 = $value; + } + + /** + * setter for cpuregexp2 + * + * @param string $value value to set + * + * @return void + */ + protected function setCPURegExp2($value) + { + $this->_CPURegExp2 = $value; + } + + /** + * setter for scsiregexp1 + * + * @param string $value value to set + * + * @return void + */ + protected function setSCSIRegExp1($value) + { + $this->_SCSIRegExp1 = $value; + } + + /** + * setter for scsiregexp2 + * + * @param string $value value to set + * + * @return void + */ + protected function setSCSIRegExp2($value) + { + $this->_SCSIRegExp2 = $value; + } + + /** + * setter for pciregexp1 + * + * @param string $value value to set + * + * @return void + */ + protected function setPCIRegExp1($value) + { + $this->_PCIRegExp1 = $value; + } + + /** + * setter for pciregexp2 + * + * @param string $value value to set + * + * @return void + */ + protected function setPCIRegExp2($value) + { + $this->_PCIRegExp2 = $value; + } + + /** + * read /var/run/dmesg.boot, but only if we haven't already + * + * @return array + */ + protected function readdmesg() + { + if (count($this->_dmesg) === 0) { + if (PSI_OS != "Darwin") { + if (CommonFunctions::rfts('/var/run/dmesg.boot', $buf, 0, 4096, false) || CommonFunctions::rfts('/var/log/dmesg.boot', $buf, 0, 4096, false) || CommonFunctions::rfts('/var/run/dmesg.boot', $buf)) { // Once again but with debug + $parts = preg_split("/rebooting|Uptime/", $buf, -1, PREG_SPLIT_NO_EMPTY); + $this->_dmesg = preg_split("/\n/", $parts[count($parts) - 1], -1, PREG_SPLIT_NO_EMPTY); + } + } + } + + return $this->_dmesg; + } + + /** + * get a value from sysctl command + * + * @param string $key key for the value to get + * + * @return string + */ + protected function grabkey($key) + { + $buf = ""; + if (CommonFunctions::executeProgram('sysctl', "-n $key", $buf, PSI_DEBUG)) { + return $buf; + } else { + return ''; + } + } + + /** + * Virtual Host Name + * + * @return void + */ + protected function hostname() + { + if (PSI_USE_VHOST === true) { + $this->sys->setHostname(getenv('SERVER_NAME')); + } else { + if (CommonFunctions::executeProgram('hostname', '', $buf, PSI_DEBUG)) { + $this->sys->setHostname($buf); + } + } + } + + /** + * IP of the Canonical Host Name + * + * @return void + */ + protected function ip() + { + if (PSI_USE_VHOST === true) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + if (!($result = getenv('SERVER_ADDR'))) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + $this->sys->setIp($result); + } + } + } + + /** + * Kernel Version + * + * @return void + */ + protected function kernel() + { + $s = $this->grabkey('kern.version'); + $a = preg_split('/:/', $s); + $this->sys->setKernel($a[0].$a[1].':'.$a[2]); + } + + /** + * Number of Users + * + * @return void + */ + protected function users() + { + if (CommonFunctions::executeProgram('who', '| wc -l', $buf, PSI_DEBUG)) { + $this->sys->setUsers($buf); + } + } + + /** + * Processor Load + * optionally create a loadbar + * + * @return void + */ + protected function loadavg() + { + $s = $this->grabkey('vm.loadavg'); + $s = preg_replace('/{ /', '', $s); + $s = preg_replace('/ }/', '', $s); + $this->sys->setLoad($s); + if (PSI_LOAD_BAR && (PSI_OS != "Darwin")) { + if ($fd = $this->grabkey('kern.cp_time')) { + // Find out the CPU load + // user + sys = load + // total = total + preg_match($this->_CPURegExp2, $fd, $res); + $load = $res[2] + $res[3] + $res[4]; // cpu.user + cpu.sys + $total = $res[2] + $res[3] + $res[4] + $res[5]; // cpu.total + // we need a second value, wait 1 second befor getting (< 1 second no good value will occour) + sleep(1); + $fd = $this->grabkey('kern.cp_time'); + preg_match($this->_CPURegExp2, $fd, $res); + $load2 = $res[2] + $res[3] + $res[4]; + $total2 = $res[2] + $res[3] + $res[4] + $res[5]; + $this->sys->setLoadPercent((100 * ($load2 - $load)) / ($total2 - $total)); + } + } + } + + /** + * CPU information + * + * @return void + */ + protected function cpuinfo() + { + $dev = new CpuDevice(); + $dev->setModel($this->grabkey('hw.model')); + $notwas = true; + foreach ($this->readdmesg() as $line) { + if ($notwas) { + if (preg_match("/".$this->_CPURegExp1."/", $line, $ar_buf)) { + $dev->setCpuSpeed(round($ar_buf[2])); + $notwas = false; + } + } else { + if (preg_match("/ Origin| Features/", $line, $ar_buf)) { + if (preg_match("/ Features2[ ]*=.*<(.*)>/", $line, $ar_buf)) { + $feats = preg_split("/,/", strtolower(trim($ar_buf[1])), -1, PREG_SPLIT_NO_EMPTY); + foreach ($feats as $feat) { + if (($feat=="vmx") || ($feat=="svm")) { + $dev->setVirt($feat); + break 2; + } + } + break; + } + } else break; + } + } + $ncpu = $this->grabkey('hw.ncpu'); + if (is_null($ncpu) || (trim($ncpu) == "") || (!($ncpu >= 1))) + $ncpu = 1; + for ($ncpu ; $ncpu > 0 ; $ncpu--) { + $this->sys->setCpus($dev); + } + } + + /** + * SCSI devices + * get the scsi device information out of dmesg + * + * @return void + */ + protected function scsi() + { + foreach ($this->readdmesg() as $line) { + if (preg_match("/".$this->_SCSIRegExp1."/", $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1].": ".$ar_buf[2]); + $this->sys->setScsiDevices($dev); + } elseif (preg_match("/".$this->_SCSIRegExp2."/", $line, $ar_buf)) { + /* duplication security */ + $notwas = true; + foreach ($this->sys->getScsiDevices() as $finddev) { + if ($notwas && (substr($finddev->getName(), 0, strpos($finddev->getName(), ': ')) == $ar_buf[1])) { + $finddev->setCapacity($ar_buf[2] * 2048 * 1.049); + $notwas = false; + break; + } + } + if ($notwas) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1]); + $dev->setCapacity($ar_buf[2] * 2048 * 1.049); + $this->sys->setScsiDevices($dev); + } + } + } + /* cleaning */ + foreach ($this->sys->getScsiDevices() as $finddev) { + if (strpos($finddev->getName(), ': ') !== false) + $finddev->setName(substr(strstr($finddev->getName(), ': '), 2)); + } + } + + /** + * parsing the output of pciconf command + * + * @return Array + */ + protected function pciconf() + { + $arrResults = array(); + $intS = 0; + if (CommonFunctions::executeProgram("pciconf", "-lv", $strBuf, PSI_DEBUG)) { + $arrTemp = array(); + $arrBlocks = preg_split("/\n\S/", $strBuf, -1, PREG_SPLIT_NO_EMPTY); + foreach ($arrBlocks as $strBlock) { + $arrLines = preg_split("/\n/", $strBlock, -1, PREG_SPLIT_NO_EMPTY); + $vend = null; + foreach ($arrLines as $strLine) { + if (preg_match("/\sclass=0x([a-fA-F0-9]{4})[a-fA-F0-9]{2}\s.*\schip=0x([a-fA-F0-9]{4})([a-fA-F0-9]{4})\s/", $strLine, $arrParts)) { + $arrTemp[$intS] = 'Class '.$arrParts[1].': Device '.$arrParts[3].':'.$arrParts[2]; + $vend = ''; + } elseif (preg_match("/(.*) = '(.*)'/", $strLine, $arrParts)) { + if (trim($arrParts[1]) == "vendor") { + $vend = trim($arrParts[2]); + } elseif (trim($arrParts[1]) == "device") { + if (($vend !== null) && ($vend !== '')) { + $arrTemp[$intS] = $vend." - ".trim($arrParts[2]); + } else { + $arrTemp[$intS] = trim($arrParts[2]); + $vend = ''; + } + } + } + } + if ($vend !== null) { + $intS++; + } + } + foreach ($arrTemp as $name) { + $dev = new HWDevice(); + $dev->setName($name); + $arrResults[] = $dev; + } + } + + return $arrResults; + } + + /** + * PCI devices + * get the pci device information out of dmesg + * + * @return void + */ + protected function pci() + { + if (!is_array($results = Parser::lspci(false)) || !is_array($results = $this->pciconf())) { + foreach ($this->readdmesg() as $line) { + if (preg_match("/".$this->_PCIRegExp1."/", $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1].": ".$ar_buf[2]); + $results[] = $dev; + } elseif (preg_match("/".$this->_PCIRegExp2."/", $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1].": ".$ar_buf[2]); + $results[] = $dev; + } + } + } + foreach ($results as $dev) { + $this->sys->setPciDevices($dev); + } + } + + /** + * IDE devices + * get the ide device information out of dmesg + * + * @return void + */ + protected function ide() + { + foreach ($this->readdmesg() as $line) { + if (preg_match('/^(ad[0-9]+): (.*)MB <(.*)> (.*) (.*)/', $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1].": ".$ar_buf[3]); + $dev->setCapacity($ar_buf[2] * 1024); + $this->sys->setIdeDevices($dev); + } elseif (preg_match('/^(acd[0-9]+): (.*) <(.*)> (.*)/', $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1].": ".$ar_buf[3]); + $this->sys->setIdeDevices($dev); + } elseif (preg_match('/^(ada[0-9]+): <(.*)> (.*)/', $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1].": ".$ar_buf[2]); + $this->sys->setIdeDevices($dev); + } elseif (preg_match('/^(ada[0-9]+): (.*)MB \((.*)\)/', $line, $ar_buf)) { + /* duplication security */ + $notwas = true; + foreach ($this->sys->getIdeDevices() as $finddev) { + if ($notwas && (substr($finddev->getName(), 0, strpos($finddev->getName(), ': ')) == $ar_buf[1])) { + $finddev->setCapacity($ar_buf[2] * 1024); + $notwas = false; + break; + } + } + if ($notwas) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1]); + $dev->setCapacity($ar_buf[2] * 1024); + $this->sys->setIdeDevices($dev); + } + } + } + /* cleaning */ + foreach ($this->sys->getIdeDevices() as $finddev) { + if (strpos($finddev->getName(), ': ') !== false) + $finddev->setName(substr(strstr($finddev->getName(), ': '), 2)); + } + } + + /** + * Physical memory information and Swap Space information + * + * @return void + */ + protected function memory() + { + if (PSI_OS == 'FreeBSD' || PSI_OS == 'OpenBSD') { + // vmstat on fbsd 4.4 or greater outputs kbytes not hw.pagesize + // I should probably add some version checking here, but for now + // we only support fbsd 4.4 + $pagesize = 1024; + } else { + $pagesize = $this->grabkey('hw.pagesize'); + } + if (CommonFunctions::executeProgram('vmstat', '', $vmstat, PSI_DEBUG)) { + $lines = preg_split("/\n/", $vmstat, -1, PREG_SPLIT_NO_EMPTY); + $ar_buf = preg_split("/\s+/", trim($lines[2]), 19); + if (PSI_OS == 'NetBSD' || PSI_OS == 'DragonFly') { + $this->sys->setMemFree($ar_buf[4] * 1024); + } else { + $this->sys->setMemFree($ar_buf[4] * $pagesize); + } + $this->sys->setMemTotal($this->grabkey('hw.physmem')); + $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree()); + + if (((PSI_OS == 'OpenBSD' || PSI_OS == 'NetBSD') && CommonFunctions::executeProgram('swapctl', '-l -k', $swapstat, PSI_DEBUG)) || CommonFunctions::executeProgram('swapinfo', '-k', $swapstat, PSI_DEBUG)) { + $lines = preg_split("/\n/", $swapstat, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $ar_buf = preg_split("/\s+/", $line, 6); + if (($ar_buf[0] != 'Total') && ($ar_buf[0] != 'Device')) { + $dev = new DiskDevice(); + $dev->setMountPoint($ar_buf[0]); + $dev->setName("SWAP"); + $dev->setFsType('swap'); + $dev->setTotal($ar_buf[1] * 1024); + $dev->setUsed($ar_buf[2] * 1024); + $dev->setFree($dev->getTotal() - $dev->getUsed()); + $this->sys->setSwapDevices($dev); + } + } + } + } + } + + /** + * USB devices + * get the ide device information out of dmesg + * + * @return void + */ + protected function usb() + { + foreach ($this->readdmesg() as $line) { +// if (preg_match('/^(ugen[0-9\.]+): <(.*)> (.*) (.*)/', $line, $ar_buf)) { +// $dev->setName($ar_buf[1].": ".$ar_buf[2]); + if (preg_match('/^(u[a-z]+[0-9]+): <([^,]*)(.*)> on (usbus[0-9]+)/', $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName($ar_buf[2]); + $this->sys->setUSBDevices($dev); + } + } + } + + /** + * filesystem information + * + * @return void + */ + protected function filesystems() + { + $arrResult = Parser::df(); + foreach ($arrResult as $dev) { + $this->sys->setDiskDevices($dev); + } + } + + /** + * Distribution + * + * @return void + */ + protected function distro() + { + if (CommonFunctions::executeProgram('uname', '-s', $result, PSI_DEBUG)) { + $this->sys->setDistribution($result); + } + } + + /** + * get the information + * + * @see PSI_Interface_OS::build() + * + * @return Void + */ + public function build() + { + $this->distro(); + $this->memory(); + $this->ide(); + $this->pci(); + $this->cpuinfo(); + $this->filesystems(); + $this->kernel(); + $this->users(); + $this->loadavg(); + $this->hostname(); + $this->ip(); + $this->scsi(); + $this->usb(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php b/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php new file mode 100644 index 0000000..1ee9dd8 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.Darwin.inc.php @@ -0,0 +1,464 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.Darwin.inc.php 638 2012-08-24 09:40:48Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * Darwin sysinfo class + * get all the required information from Darwin system + * information may be incomplete + * + * @category PHP + * @package PSI Darwin OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Darwin extends BSDCommon +{ + /** + * define the regexp for log parser + */ + /* public function __construct() + { + parent::__construct(); + $this->error->addWarning("The Darwin version of phpSysInfo is a work in progress, some things currently don't work!"); + $this->setCPURegExp1("CPU: (.*) \((.*)-MHz (.*)\)"); + $this->setCPURegExp2("/(.*) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)/"); + $this->setSCSIRegExp1("^(.*): <(.*)> .*SCSI.*device"); + } */ + + /** + * get a value from sysctl command + * + * @param string $key key of the value to get + * + * @return string + */ + protected function grabkey($key) + { + if (CommonFunctions::executeProgram('sysctl', $key, $s, PSI_DEBUG)) { + $s = preg_replace('/'.$key.': /', '', $s); + $s = preg_replace('/'.$key.' = /', '', $s); + + return $s; + } else { + return ''; + } + } + + /** + * get a value from ioreg command + * + * @param string $key key of the value to get + * + * @return string + */ + private function _grabioreg($key) + { + if (CommonFunctions::executeProgram('ioreg', '-c "'.$key.'"', $s, PSI_DEBUG)) { + /* delete newlines */ + $s = preg_replace("/\s+/", " ", $s); + /* new newlines */ + $s = preg_replace("/[\|\t ]*\+\-o/", "\n", $s); + /* combine duplicate whitespaces and some chars */ + $s = preg_replace("/[\|\t ]+/", " ", $s); + + $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); + $out = ""; + foreach ($lines as $line) { + if (preg_match('/^([^<]*) sys->setUptime(time() - $data); + } else { /* kern.boottime= 1096732600 */ + $this->sys->setUptime(time() - $a); + } + } + } + + /** + * get CPU information + * + * @return void + */ + protected function cpuinfo() + { + $dev = new CpuDevice(); + if (CommonFunctions::executeProgram('hostinfo', '| grep "Processor type"', $buf, PSI_DEBUG)) { + $dev->setModel(preg_replace('/Processor type: /', '', $buf)); + $buf=$this->grabkey('hw.model'); + if (!is_null($buf) && (trim($buf) != "")) { + $this->sys->setMachine(trim($buf)); + if (CommonFunctions::rfts(APP_ROOT.'/data/ModelTranslation.txt', $buffer)) { + $buffer = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY); + foreach ($buffer as $line) { + $ar_buf = preg_split("/:/", $line, 3); + if (trim($buf) === trim($ar_buf[0])) { + $dev->setModel(trim($ar_buf[2])); + $this->sys->setMachine($this->sys->getMachine().' - '.trim($ar_buf[1])); + break; + } + } + } + } + $buf=$this->grabkey('machdep.cpu.brand_string'); + if (!is_null($buf) && (trim($buf) != "") && + ((trim($buf) != "i486 (Intel 80486)") || ($dev->getModel() == ""))) { + $dev->setModel(trim($buf)); + } + $buf=$this->grabkey('machdep.cpu.features'); + if (!is_null($buf) && (trim($buf) != "")) { + if (preg_match("/ VMX/", $buf)) { + $dev->setVirt("vmx"); + } elseif (preg_match("/ SVM/", $buf)) { + $dev->setVirt("svm"); + } + } + } + $dev->setCpuSpeed(round($this->grabkey('hw.cpufrequency') / 1000000)); + $dev->setBusSpeed(round($this->grabkey('hw.busfrequency') / 1000000)); + $bufn=$this->grabkey('hw.cpufrequency_min'); + $bufx=$this->grabkey('hw.cpufrequency_max'); + if (!is_null($bufn) && (trim($bufn) != "") && !is_null($bufx) && (trim($bufx) != "") && ($bufn != $bufx)) { + $dev->setCpuSpeedMin(round($bufn / 1000000)); + $dev->setCpuSpeedMax(round($bufx / 1000000)); + } + $buf=$this->grabkey('hw.l2cachesize'); + if (!is_null($buf) && (trim($buf) != "")) { + $dev->setCache(round($buf)); + } + $ncpu = $this->grabkey('hw.ncpu'); + if (is_null($ncpu) || (trim($ncpu) == "") || (!($ncpu >= 1))) + $ncpu = 1; + for ($ncpu ; $ncpu > 0 ; $ncpu--) { + $this->sys->setCpus($dev); + } + } + + /** + * get the pci device information out of ioreg + * + * @return void + */ + protected function pci() + { + if (!$arrResults = Parser::lspci(false)) { //no lspci port + $s = $this->_grabioreg('IOPCIDevice'); + $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $dev = new HWDevice(); + if (!preg_match('/"IOName" = "([^"]*)"/', $line, $ar_buf)) { + $ar_buf = preg_split("/[\s@]+/", $line, 19); + } + if (preg_match('/"model" = setName(trim($ar_buf[1]). ": ".trim($ar_buf2[1])); + } else { + $dev->setName(trim($ar_buf[1])); + } + $this->sys->setPciDevices($dev); + } + } else { + foreach ($arrResults as $dev) { + $this->sys->setPciDevices($dev); + } + } + } + + /** + * get the ide device information out of ioreg + * + * @return void + */ + protected function ide() + { + $s = $this->_grabioreg('IOATABlockStorageDevice'); + $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $dev = new HWDevice(); + if (!preg_match('/"Product Name"="([^"]*)"/', $line, $ar_buf)) + $ar_buf = preg_split("/[\s@]+/", $line, 19); + $dev->setName(trim($ar_buf[1])); + $this->sys->setIdeDevices($dev); + } + + $s = $this->_grabioreg('IOAHCIBlockStorageDevice'); + $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $dev = new HWDevice(); + if (!preg_match('/"Product Name"="([^"]*)"/', $line, $ar_buf)) + $ar_buf = preg_split("/[\s@]+/", $line, 19); + $dev->setName(trim($ar_buf[1])); + $this->sys->setIdeDevices($dev); + } + } + + /** + * get the usb device information out of ioreg + * + * @return void + */ + protected function usb() + { + $s = $this->_grabioreg('IOUSBDevice'); + $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $dev = new HWDevice(); + if (!preg_match('/"USB Product Name" = "([^"]*)"/', $line, $ar_buf)) + $ar_buf = preg_split("/[\s@]+/", $line, 19); + $dev->setName(trim($ar_buf[1])); + $this->sys->setUsbDevices($dev); + } + } + + /** + * get the scsi device information out of ioreg + * + * @return void + */ + protected function scsi() + { + $s = $this->_grabioreg('IOBlockStorageServices'); + $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $dev = new HWDevice(); + if (!preg_match('/"Product Name"="([^"]*)"/', $line, $ar_buf)) + $ar_buf = preg_split("/[\s@]+/", $line, 19); + $dev->setName(trim($ar_buf[1])); + $this->sys->setScsiDevices($dev); + } + } + + /** + * get memory and swap information + * + * @return void + */ + protected function memory() + { + $s = $this->grabkey('hw.memsize'); + if (CommonFunctions::executeProgram('vm_stat', '', $pstat, PSI_DEBUG)) { + // calculate free memory from page sizes (each page = 4096) + if (preg_match('/^Pages free:\s+(\S+)/m', $pstat, $free_buf)) { + if (preg_match('/^Anonymous pages:\s+(\S+)/m', $pstat, $anon_buf) + && preg_match('/^Pages wired down:\s+(\S+)/m', $pstat, $wire_buf) + && preg_match('/^File-backed pages:\s+(\S+)/m', $pstat, $fileb_buf)) { + // OS X 10.9 or never + $this->sys->setMemFree($free_buf[1] * 4 * 1024); + $this->sys->setMemApplication(($anon_buf[1]+$wire_buf[1]) * 4 * 1024); + $this->sys->setMemCache($fileb_buf[1] * 4 * 1024); + if (preg_match('/^Pages occupied by compressor:\s+(\S+)/m', $pstat, $compr_buf)) { + $this->sys->setMemBuffer($compr_buf[1] * 4 * 1024); + } + } else { + if (preg_match('/^Pages speculative:\s+(\S+)/m', $pstat, $spec_buf)) { + $this->sys->setMemFree(($free_buf[1]+$spec_buf[1]) * 4 * 1024); + } else { + $this->sys->setMemFree($free_buf[1] * 4 * 1024); + } + $appMemory = 0; + if (preg_match('/^Pages wired down:\s+(\S+)/m', $pstat, $wire_buf)) { + $appMemory += $wire_buf[1] * 4 * 1024; + } + if (preg_match('/^Pages active:\s+(\S+)/m', $pstat, $active_buf)) { + $appMemory += $active_buf[1] * 4 * 1024; + } + $this->sys->setMemApplication($appMemory); + + if (preg_match('/^Pages inactive:\s+(\S+)/m', $pstat, $inactive_buf)) { + $this->sys->setMemCache($inactive_buf[1] * 4 * 1024); + } + } + } else { + $lines = preg_split("/\n/", $pstat, -1, PREG_SPLIT_NO_EMPTY); + $ar_buf = preg_split("/\s+/", $lines[1], 19); + $this->sys->setMemFree($ar_buf[2] * 4 * 1024); + } + + $this->sys->setMemTotal($s); + $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree()); + + if (CommonFunctions::executeProgram('sysctl', 'vm.swapusage | colrm 1 22', $swapBuff, PSI_DEBUG)) { + $swap1 = preg_split('/M/', $swapBuff); + $swap2 = preg_split('/=/', $swap1[1]); + $swap3 = preg_split('/=/', $swap1[2]); + $dev = new DiskDevice(); + $dev->setName('SWAP'); + $dev->setMountPoint('SWAP'); + $dev->setFsType('swap'); + $dev->setTotal($swap1[0] * 1024 * 1024); + $dev->setUsed($swap2[1] * 1024 * 1024); + $dev->setFree($swap3[1] * 1024 * 1024); + $this->sys->setSwapDevices($dev); + } + } + } + + /** + * get the thunderbolt device information out of ioreg + * + * @return void + */ + protected function _tb() + { + $s = $this->_grabioreg('IOThunderboltPort'); + $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $dev = new HWDevice(); + if (!preg_match('/"Description" = "([^"]*)"/', $line, $ar_buf)) + $ar_buf = preg_split("/[\s@]+/", $line, 19); + $dev->setName(trim($ar_buf[1])); + $this->sys->setTbDevices($dev); + } + } + + /** + * get network information + * + * @return void + */ + private function _network() + { + if (CommonFunctions::executeProgram('netstat', '-nbdi | cut -c1-24,42- | grep Link', $netstat, PSI_DEBUG)) { + $lines = preg_split("/\n/", $netstat, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $ar_buf = preg_split("/\s+/", $line, 10); + if (! empty($ar_buf[0])) { + $dev = new NetDevice(); + $dev->setName($ar_buf[0]); + $dev->setTxBytes($ar_buf[8]); + $dev->setRxBytes($ar_buf[5]); + $dev->setErrors($ar_buf[4] + $ar_buf[7]); + if (isset($ar_buf[10])) { + $dev->setDrops($ar_buf[10]); + } + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' 2>/dev/null', $bufr2, PSI_DEBUG))) { + $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe2 as $buf2) { + if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); + elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet6\s+([^\s%]+)%\S+\s+prefixlen/i', $buf2, $ar_buf2)) + && !preg_match('/^fe80::/i', $ar_buf2[1])) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } + $this->sys->setNetDevices($dev); + } + } + } + } + + /** + * get icon name + * + * @return void + */ + protected function distro() + { + $this->sys->setDistributionIcon('Darwin.png'); + if (!CommonFunctions::executeProgram('system_profiler', 'SPSoftwareDataType', $buffer, PSI_DEBUG)) { + parent::distro(); + } else { + $arrBuff = preg_split("/\n/", $buffer, -1, PREG_SPLIT_NO_EMPTY); + foreach ($arrBuff as $line) { + $arrLine = preg_split("/:/", $line, -1, PREG_SPLIT_NO_EMPTY); + if (trim($arrLine[0]) === "System Version") { + $distro = trim($arrLine[1]); + + if (preg_match('/(^Mac OS)|(^OS X)/', $distro)) { + $this->sys->setDistributionIcon('Apple.png'); + if (preg_match('/((^Mac OS X Server)|(^Mac OS X)|(^OS X Server)|(^OS X)) (\d+\.\d+)/', $distro, $ver) + && ($list = @parse_ini_file(APP_ROOT."/data/osnames.ini", true)) + && isset($list['OS X'][$ver[6]])) { + $distro.=' '.$list['OS X'][$ver[6]]; + } + } + + $this->sys->setDistribution($distro); + + return; + } + } + } + } + + /** + * Processes + * + * @return void + */ + protected function _processes() + { + if (CommonFunctions::executeProgram('ps', 'aux', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $processes['*'] = 0; + foreach ($lines as $line) { + if (preg_match("/^\S+\s+\d+\s+\S+\s+\S+\s+\d+\s+\d+\s+\S+\s+(\w)/", $line, $ar_buf)) { + $processes['*']++; + $state = $ar_buf[1]; + if ($state == 'U') $state = 'D'; //linux format + elseif ($state == 'I') $state = 'S'; + elseif ($state == 'D') $state = 'd'; //invalid + if (isset($processes[$state])) { + $processes[$state]++; + } else { + $processes[$state] = 1; + } + } + } + if ($processes['*'] > 0) { + $this->sys->setProcesses($processes); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_OS::build() + * + * @return Void + */ + public function build() + { + parent::build(); + $this->_uptime(); + $this->_network(); + $this->_processes(); + $this->_tb(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php b/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php new file mode 100644 index 0000000..9e9f946 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.DragonFly.inc.php @@ -0,0 +1,153 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.DragonFly.inc.php 287 2009-06-26 12:11:59Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * DragonFly sysinfo class + * get all the required information from DragonFly system + * + * @category PHP + * @package PSI DragonFly OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class DragonFly extends BSDCommon +{ + /** + * define the regexp for log parser + */ + public function __construct() + { + parent::__construct(); + $this->setCPURegExp1("^cpu(.*)\, (.*) MHz"); + $this->setCPURegExp2("^(.*) at scsibus.*: <(.*)> .*"); + $this->setSCSIRegExp2("^(da[0-9]): (.*)MB "); + $this->setPCIRegExp1("/(.*): <(.*)>(.*) (pci|legacypci)[0-9]$/"); + $this->setPCIRegExp2("/(.*): <(.*)>.* at [0-9\.]+$/"); + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + private function _uptime() + { + $a = $this->grab_key('kern.boottime'); + preg_match("/sec = ([0-9]+)/", $a, $buf); + $this->sys->setUptime(time() - $buf[1]); + } + + /** + * get network information + * + * @return array + */ + private function _network() + { + CommonFunctions::executeProgram('netstat', '-nbdi | cut -c1-25,44- | grep "^[a-z]*[0-9][ \t].*Link"', $netstat_b); + CommonFunctions::executeProgram('netstat', '-ndi | cut -c1-25,44- | grep "^[a-z]*[0-9][ \t].*Link"', $netstat_n); + $lines_b = preg_split("/\n/", $netstat_b, -1, PREG_SPLIT_NO_EMPTY); + $lines_n = preg_split("/\n/", $netstat_n, -1, PREG_SPLIT_NO_EMPTY); + for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) { + $ar_buf_b = preg_split("/\s+/", $lines_b[$i]); + $ar_buf_n = preg_split("/\s+/", $lines_n[$i]); + if (! empty($ar_buf_b[0]) && ! empty($ar_buf_n[3])) { + $dev = new NetDevice(); + $dev->setName($ar_buf_b[0]); + $dev->setTxBytes($ar_buf_b[8]); + $dev->setRxBytes($ar_buf_b[5]); + $dev->setErrors($ar_buf_n[4] + $ar_buf_n[6]); + $dev->setDrops($ar_buf_n[8]); + $this->sys->setNetDevices($dev); + } + } + } + + /** + * get the ide information + * + * @return array + */ + protected function ide() + { + foreach ($this->readdmesg() as $line) { + if (preg_match('/^(.*): (.*) <(.*)> at (ata[0-9]\-(.*)) (.*)/', $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1]); + if (!preg_match("/^acd[0-9](.*)/", $ar_buf[1])) { + $dev->setCapacity($ar_buf[2] * 1024); + } + $this->sys->setIdeDevices($dev); + } + } + } + + /** + * get icon name + * + * @return void + */ + private function _distroicon() + { + $this->sys->setDistributionIcon('DragonFly.png'); + } + + /** + * Processes + * + * @return void + */ + protected function _processes() + { + if (CommonFunctions::executeProgram('ps', 'aux', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $processes['*'] = 0; + foreach ($lines as $line) { + if (preg_match("/^\S+\s+\d+\s+\S+\s+\S+\s+\d+\s+\d+\s+\S+\s+(\w)/", $line, $ar_buf)) { + $processes['*']++; + $state = $ar_buf[1]; + if ($state == 'I') $state = 'S'; //linux format + if (isset($processes[$state])) { + $processes[$state]++; + } else { + $processes[$state] = 1; + } + } + } + if ($processes['*'] > 0) { + $this->sys->setProcesses($processes); + } + } + } + + /** + * get the information + * + * @see BSDCommon::build() + * + * @return Void + */ + public function build() + { + parent::build(); + $this->_distroicon(); + $this->_network(); + $this->_uptime(); + $this->_processes(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php b/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php new file mode 100644 index 0000000..d602a60 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.FreeBSD.inc.php @@ -0,0 +1,190 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.FreeBSD.inc.php 696 2012-09-09 11:24:04Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * FreeBSD sysinfo class + * get all the required information from FreeBSD system + * + * @category PHP + * @package PSI FreeBSD OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class FreeBSD extends BSDCommon +{ + /** + * define the regexp for log parser + */ + public function __construct() + { + parent::__construct(); + $this->setCPURegExp1("CPU: (.*) \((.*)-MHz (.*)\)"); + $this->setCPURegExp2("/(.*) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)/"); + $this->setSCSIRegExp1("^(.*): <(.*)> .*SCSI.*device"); + $this->setSCSIRegExp2("^(da[0-9]): (.*)MB "); + $this->setPCIRegExp1("/(.*): <(.*)>(.*) pci[0-9]$/"); + $this->setPCIRegExp2("/(.*): <(.*)>.* at [.0-9]+ irq/"); + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + private function _uptime() + { + $s = preg_split('/ /', $this->grabkey('kern.boottime')); + $a = preg_replace('/,/', '', $s[3]); + $this->sys->setUptime(time() - $a); + } + + /** + * get network information + * + * @return void + */ + private function _network() + { + $dev = null; + if (CommonFunctions::executeProgram('netstat', '-nibd', $netstat, PSI_DEBUG)) { + $lines = preg_split("/\n/", $netstat, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $ar_buf = preg_split("/\s+/", $line); + if (! empty($ar_buf[0])) { + if (preg_match('/^setName($ar_buf[0]); + if (strlen($ar_buf[3]) < 17) { /* no Address */ + if (isset($ar_buf[11]) && (trim($ar_buf[11]) != '')) { /* Idrop column exist*/ + $dev->setTxBytes($ar_buf[9]); + $dev->setRxBytes($ar_buf[6]); + $dev->setErrors($ar_buf[4] + $ar_buf[8]); + $dev->setDrops($ar_buf[11] + $ar_buf[5]); + } else { + $dev->setTxBytes($ar_buf[8]); + $dev->setRxBytes($ar_buf[5]); + $dev->setErrors($ar_buf[4] + $ar_buf[7]); + $dev->setDrops($ar_buf[10]); + } + } else { + if (isset($ar_buf[12]) && (trim($ar_buf[12]) != '')) { /* Idrop column exist*/ + $dev->setTxBytes($ar_buf[10]); + $dev->setRxBytes($ar_buf[7]); + $dev->setErrors($ar_buf[5] + $ar_buf[9]); + $dev->setDrops($ar_buf[12] + $ar_buf[6]); + } else { + $dev->setTxBytes($ar_buf[9]); + $dev->setRxBytes($ar_buf[6]); + $dev->setErrors($ar_buf[5] + $ar_buf[8]); + $dev->setDrops($ar_buf[11]); + } + } + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' 2>/dev/null', $bufr2, PSI_DEBUG))) { + $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe2 as $buf2) { + if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); + elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + elseif ((preg_match('/^\s+inet6\s+([^\s%]+)\s+prefixlen/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet6\s+([^\s%]+)%\S+\s+prefixlen/i', $buf2, $ar_buf2)) + && !preg_match('/^fe80::/i', $ar_buf2[1])) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } + $this->sys->setNetDevices($dev); + } + } + } + } + } + + /** + * get icon name and distro extended check + * + * @return void + */ + private function _distroicon() + { + if (extension_loaded('pfSense') && CommonFunctions::rfts('/etc/version', $version, 1, 4096, false) && (trim($version) != '')) { // pfSense detection + $this->sys->setDistribution('pfSense '. trim($version)); + $this->sys->setDistributionIcon('pfSense.png'); + } else { + $this->sys->setDistributionIcon('FreeBSD.png'); + } + } + + /** + * extend the memory information with additional values + * + * @return void + */ + private function _memoryadditional() + { + $pagesize = $this->grabkey("hw.pagesize"); + $this->sys->setMemCache($this->grabkey("vm.stats.vm.v_cache_count") * $pagesize); + $this->sys->setMemApplication(($this->grabkey("vm.stats.vm.v_active_count") + $this->grabkey("vm.stats.vm.v_wire_count")) * $pagesize); + $this->sys->setMemBuffer($this->sys->getMemUsed() - $this->sys->getMemApplication() - $this->sys->getMemCache()); + } + + /** + * Processes + * + * @return void + */ + protected function _processes() + { + if (CommonFunctions::executeProgram('ps', 'aux', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $processes['*'] = 0; + foreach ($lines as $line) { + if (preg_match("/^\S+\s+\d+\s+\S+\s+\S+\s+\d+\s+\d+\s+\S+\s+(\w)/", $line, $ar_buf)) { + $processes['*']++; + $state = $ar_buf[1]; + if ($state == 'L') $state = 'D'; //linux format + elseif ($state == 'I') $state = 'S'; + if (isset($processes[$state])) { + $processes[$state]++; + } else { + $processes[$state] = 1; + } + } + } + if ($processes['*'] > 0) { + $this->sys->setProcesses($processes); + } + } + } + + /** + * get the information + * + * @see BSDCommon::build() + * + * @return Void + */ + public function build() + { + parent::build(); + $this->_memoryadditional(); + $this->_distroicon(); + $this->_network(); + $this->_uptime(); + $this->_processes(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php b/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php new file mode 100644 index 0000000..02626ca --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.HPUX.inc.php @@ -0,0 +1,404 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.HPUX.inc.php 596 2012-07-05 19:37:48Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * HP-UX sysinfo class + * get all the required information from HP-UX system + * + * @category PHP + * @package PSI HPUX OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class HPUX extends OS +{ + /** + * Virtual Host Name + * + * @return void + */ + private function _hostname() + { + if (PSI_USE_VHOST === true) { + $this->sys->setHostname(getenv('SERVER_NAME')); + } else { + if (CommonFunctions::executeProgram('hostname', '', $ret)) { + $this->sys->setHostname($ret); + } + } + } + + /** + * IP of the Virtual Host Name + * + * @return void + */ + private function _ip() + { + if (PSI_USE_VHOST === true) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + if (!($result = getenv('SERVER_ADDR'))) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + $this->sys->setIp($result); + } + } + } + + /** + * HP-UX Version + * + * @return void + */ + private function _kernel() + { + if (CommonFunctions::executeProgram('uname', '-srvm', $ret)) { + $this->sys->setKernel($ret); + } + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + private function _uptime() + { + if (CommonFunctions::executeProgram('uptime', '', $buf)) { + if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $buf, $ar_buf)) { + $min = $ar_buf[3]; + $hours = $ar_buf[2]; + $days = $ar_buf[1]; + $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60); + } + } + } + + /** + * Number of Users + * + * @return void + */ + private function _users() + { + if (CommonFunctions::executeProgram('who', '-q', $ret)) { + $who = preg_split('/=/', $ret, -1, PREG_SPLIT_NO_EMPTY); + $this->sys->setUsers($who[1]); + } + } + + /** + * Processor Load + * optionally create a loadbar + * + * @return void + */ + private function _loadavg() + { + if (CommonFunctions::executeProgram('uptime', '', $buf)) { + if (preg_match("/average: (.*), (.*), (.*)$/", $buf, $ar_buf)) { + $this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]); + } + } + } + + /** + * CPU information + * All of the tags here are highly architecture dependant + * + * @return void + */ + private function _cpuinfo() + { + if (CommonFunctions::rfts('/proc/cpuinfo', $bufr)) { + $processors = preg_split('/\s?\n\s?\n/', trim($bufr)); + foreach ($processors as $processor) { + $dev = new CpuDevice(); + $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY); + foreach ($details as $detail) { + $arrBuff = preg_split('/\s+:\s+/', trim($detail)); + if (count($arrBuff) == 2) { + switch (strtolower($arrBuff[0])) { + case 'model name': + case 'cpu': + $dev->setModel($arrBuff[1]); + break; + case 'cpu mhz': + case 'clock': + $dev->setCpuSpeed($arrBuff[1]); + break; + case 'cycle frequency [hz]': + $dev->setCpuSpeed($arrBuff[1] / 1000000); + break; + case 'cpu0clktck': + $dev->setCpuSpeed(hexdec($arrBuff[1]) / 1000000); // Linux sparc64 + break; + case 'l2 cache': + case 'cache size': + $dev->setCache(preg_replace("/[a-zA-Z]/", "", $arrBuff[1]) * 1024); + break; + case 'bogomips': + case 'cpu0bogo': + $dev->setBogomips($arrBuff[1]); + break; + } + } + } + } + } + } + + /** + * PCI devices + * + * @return void + */ + private function _pci() + { + if (CommonFunctions::rfts('/proc/pci', $bufr)) { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + if (preg_match('/Bus/', $buf)) { + $device = true; + continue; + } + if ($device) { + list($key, $value) = preg_split('/: /', $buf, 2); + if (!preg_match('/bridge/i', $key) && !preg_match('/USB/i', $key)) { + $dev = new HWDevice(); + $dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($value))); + $this->sys->setPciDevices($dev); + } + $device = false; + } + } + } + } + + /** + * IDE devices + * + * @return void + */ + private function _ide() + { + $bufd = CommonFunctions::gdc('/proc/ide', false); + foreach ($bufd as $file) { + if (preg_match('/^hd/', $file)) { + $dev = new HWDevice(); + $dev->setName(trim($file)); + if (CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) { + if (trim($buf) == 'disk') { + if (CommonFunctions::rfts("/proc/ide/".$file."/capacity", $buf, 1, 4096, false)) { + $dev->setCapacity(trim($buf) * 512 / 1024); + } + } + } + $this->sys->setIdeDevices($dev); + } + } + } + + /** + * SCSI devices + * + * @return void + */ + private function _scsi() + { + $get_type = false; + if (CommonFunctions::rfts('/proc/scsi/scsi', $bufr, 0, 4096, PSI_DEBUG)) { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + if (preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $dev)) { + $get_type = true; + continue; + } + if ($get_type) { + preg_match('/Type:\s+(\S+)/i', $buf, $dev_type); + $dev = new HWDevice(); + $dev->setName($dev[1].' '.$dev[2].' ('.$dev_type[1].')'); + $this->sys->setScsiDevices($dev); + $get_type = false; + } + } + } + } + + /** + * USB devices + * + * @return void + */ + private function _usb() + { + if (CommonFunctions::rfts('/proc/bus/usb/devices', $bufr, 0, 4096, false)) { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + if (preg_match('/^T/', $buf)) { + $devnum += 1; + $results[$devnum] = ""; + } elseif (preg_match('/^S:/', $buf)) { + list($key, $value) = preg_split('/: /', $buf, 2); + list($key, $value2) = preg_split('/=/', $value, 2); + if (trim($key) != "SerialNumber") { + $results[$devnum] .= " ".trim($value2); + } + } + } + foreach ($results as $var) { + $dev = new HWDevice(); + $dev->setName($var); + $this->sys->setUsbDevices($dev); + } + } + } + + /** + * Network devices + * includes also rx/tx bytes + * + * @return void + */ + private function _network() + { + if (CommonFunctions::executeProgram('netstat', '-ni | tail -n +2', $netstat)) { + $lines = preg_split("/\n/", $netstat, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $ar_buf = preg_split("/\s+/", $line); + if (! empty($ar_buf[0]) && ! empty($ar_buf[3])) { + $dev = new NetDevice(); + $dev->setName($ar_buf[0]); + $dev->setRxBytes($ar_buf[4]); + $dev->setTxBytes($ar_buf[6]); + $dev->setErrors($ar_buf[5] + $ar_buf[7]); + $dev->setDrops($ar_buf[8]); + $this->sys->setNetDevices($dev); + } + } + } + } + + /** + * Physical memory information and Swap Space information + * + * @return void + */ + private function _memory() + { + if (CommonFunctions::rfts('/proc/meminfo', $bufr)) { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + if (preg_match('/Mem:\s+(.*)$/', $buf, $ar_buf)) { + $ar_buf = preg_split('/\s+/', $ar_buf[1], 6); + $this->sys->setMemTotal($ar_buf[0]); + $this->sys->setMemUsed($ar_buf[1]); + $this->sys->setMemFree($ar_buf[2]); + $this->sys->setMemApplication($ar_buf[3]); + $this->sys->setMemBuffer($ar_buf[4]); + $this->sys->setMemCache($ar_buf[5]); + } + // Get info on individual swap files + if (CommonFunctions::rfts('/proc/swaps', $swaps)) { + $swapdevs = preg_split("/\n/", $swaps, -1, PREG_SPLIT_NO_EMPTY); + for ($i = 1, $max = (sizeof($swapdevs) - 1); $i < $max; $i++) { + $ar_buf = preg_split('/\s+/', $swapdevs[$i], 6); + $dev = new DiskDevice(); + $dev->setMountPoint($ar_buf[0]); + $dev->setName("SWAP"); + $dev->setFsType('swap'); + $dev->setTotal($ar_buf[2] * 1024); + $dev->setUsed($ar_buf[3] * 1024); + $dev->setFree($dev->getTotal() - $dev->getUsed()); + $this->sys->setSwapDevices($dev); + } + } + } + } + } + + /** + * filesystem information + * + * @return void + */ + private function _filesystems() + { + if (CommonFunctions::executeProgram('df', '-kP', $df, PSI_DEBUG)) { + $mounts = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); + if (CommonFunctions::executeProgram('mount', '-v', $s, PSI_DEBUG)) { + $lines = preg_split("/\n/", $s, -1, PREG_SPLIT_NO_EMPTY); + while (list(, $line) = each($lines)) { + $a = preg_split('/ /', $line, -1, PREG_SPLIT_NO_EMPTY); + $fsdev[$a[0]] = $a[4]; + } + } + foreach ($mounts as $mount) { + $ar_buf = preg_split("/\s+/", $mount, 6); + $dev = new DiskDevice(); + $dev->setName($ar_buf[0]); + $dev->setTotal($ar_buf[1] * 1024); + $dev->setUsed($ar_buf[2] * 1024); + $dev->setFree($ar_buf[3] * 1024); + $dev->setMountPoint($ar_buf[5]); + if (isset($fsdev[$ar_buf[0]])) { + $dev->setFsType($fsdev[$ar_buf[0]]); + } + $this->sys->setDiskDevices($dev); + } + } + } + + /** + * Distribution + * + * @return void + */ + private function _distro() + { + $this->sys->setDistribution('HP-UX'); + $this->sys->setDistributionIcon('HPUX.png'); + } + + /** + * get the information + * + * @see PSI_Interface_OS::build() + * + * @return Void + */ + public function build() + { + $this->_distro(); + $this->_hostname(); + $this->_ip(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + $this->_cpuinfo(); + $this->_pci(); + $this->_ide(); + $this->_scsi(); + $this->_usb(); + $this->_network(); + $this->_memory(); + $this->_filesystems(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php b/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php new file mode 100644 index 0000000..c803156 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.Haiku.inc.php @@ -0,0 +1,403 @@ + + * @copyright 2012 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.Haiku.inc.php 687 2012-09-06 20:54:49Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * Haiku sysinfo class + * get all the required information from Haiku system + * + * @category PHP + * @package PSI Haiku OS class + * @author Mieczyslaw Nalewaj + * @copyright 2012 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Haiku extends OS +{ + /** + * call parent constructor + */ + public function __construct() + { + parent::__construct(); + } + + /** + * get the cpu information + * + * @return array + */ + protected function _cpuinfo() + { + + if (CommonFunctions::executeProgram('sysinfo', '-cpu', $bufr, PSI_DEBUG)) { + $cpus = preg_split("/\nCPU #\d+/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $cpuspeed = ""; + foreach ($cpus as $cpu) { + if (preg_match("/^.*running at (\d+)MHz/", $cpu, $ar_buf)) { + $cpuspeed = $ar_buf[1]; + } elseif (preg_match("/^: \"(.*)\"/", $cpu, $ar_buf)) { + $dev = new CpuDevice(); + $dev->setModel($ar_buf[1]); + $arrLines = preg_split("/\n/", $cpu, -1, PREG_SPLIT_NO_EMPTY); + foreach ($arrLines as $Line) { + if (preg_match("/^\s+Data TLB:\s+(.*)K-byte/", $Line, $Line_buf)) { + $dev->setCache(max($Line_buf[1]*1024, $dev->getCache())); + } elseif (preg_match("/^\s+Data TLB:\s+(.*)M-byte/", $Line, $Line_buf)) { + $dev->setCache(max($Line_buf[1]*1024*1024, $dev->getCache())); + } elseif (preg_match("/^\s+Data TLB:\s+(.*)G-byte/", $Line, $Line_buf)) { + $dev->setCache(max($Line_buf[1]*1024*1024*1024, $dev->getCache())); + } elseif (preg_match("/\s+VMX/", $Line, $Line_buf)) { + $dev->setVirt("vmx"); + } elseif (preg_match("/\s+SVM/", $Line, $Line_buf)) { + $dev->setVirt("svm"); + } + } + if ($cpuspeed != "")$dev->setCpuSpeed($cpuspeed); + $this->sys->setCpus($dev); + //echo ">>>>>".$cpu; + } + } + } + } + + /** + * PCI devices + * get the pci device information + * + * @return void + */ + protected function _pci() + { + if (CommonFunctions::executeProgram('listdev', '', $bufr, PSI_DEBUG)) { +// $devices = preg_split("/^device |\ndevice /", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $devices = preg_split("/^device /m", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($devices as $device) { + $ar_buf = preg_split("/\n/", $device); + if (count($ar_buf) >= 3) { + if (preg_match("/^([^\(\[\n]*)/", $device, $ar_buf2)) { + if (preg_match("/^[^\(]*\((.*)\)/", $device, $ar_buf3)) { + $ar_buf2[1] = $ar_buf3[1]; + } + $name = trim($ar_buf2[1]).": "; + + if (preg_match("/^\s+vendor\s+[0-9a-fA-F]{4}:\s+(.*)/", $ar_buf[1], $ar_buf3)) { + $name .=$ar_buf3[1]." "; + } + if (preg_match("/^\s+device\s+[0-9a-fA-F]{4}:\s+(.*)/", $ar_buf[2], $ar_buf3)) { + $name .=$ar_buf3[1]." "; + } + $dev = new HWDevice(); + $dev->setName(trim($name)); + $this->sys->setPciDevices($dev); + } + } + } + } + } + + /** + * USB devices + * get the usb device information + * + * @return void + */ + protected function _usb() + { + if (CommonFunctions::executeProgram('listusb', '', $bufr, PSI_DEBUG)) { + $devices = preg_split("/\n/", $bufr); + foreach ($devices as $device) { + if (preg_match("/^\S+\s+\S+\s+\"(.*)\"\s+\"(.*)\"/", $device, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName(trim($ar_buf[1]." ".$ar_buf[2])); + $this->sys->setUSBDevices($dev); + } + } + } + } + + /** + * Haiku Version + * + * @return void + */ + private function _kernel() + { + if (CommonFunctions::executeProgram('uname', '-rvm', $ret)) { + $this->sys->setKernel($ret); + } + } + + /** + * Distribution + * + * @return void + */ + protected function _distro() + { + if (CommonFunctions::executeProgram('uname', '-sr', $ret)) + $this->sys->setDistribution($ret); + else + $this->sys->setDistribution('Haiku'); + + $this->sys->setDistributionIcon('Haiku.png'); + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + private function _uptime() + { + if (CommonFunctions::executeProgram('uptime', '-u', $buf)) { + if (preg_match("/^up (\d+) minute[s]?/", $buf, $ar_buf)) { + $min = $ar_buf[1]; + $this->sys->setUptime($min * 60); + } elseif (preg_match("/^up (\d+) hour[s]?, (\d+) minute[s]?/", $buf, $ar_buf)) { + $min = $ar_buf[2]; + $hours = $ar_buf[1]; + $this->sys->setUptime($hours * 3600 + $min * 60); + } elseif (preg_match("/^up (\d+) day[s]?, (\d+) hour[s]?, (\d+) minute[s]?/", $buf, $ar_buf)) { + $min = $ar_buf[3]; + $hours = $ar_buf[2]; + $days = $ar_buf[1]; + $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60); + } + } + } + + /** + * Processor Load + * optionally create a loadbar + * + * @return void + */ + private function _loadavg() + { + if (CommonFunctions::executeProgram('top', '-n 1 -i 1', $buf)) { + if (preg_match("/\s+(\S+)%\s+TOTAL\s+\(\S+%\s+idle time/", $buf, $ar_buf)) { + $this->sys->setLoad($ar_buf[1]); + if (PSI_LOAD_BAR) { + $this->sys->setLoadPercent(round($ar_buf[1])); + } + } + } + } + + /** + * Number of Users + * + * @return void + */ + private function _users() + { + $this->sys->setUsers(1); + } + + /** + * Virtual Host Name + * + * @return void + */ + private function _hostname() + { + if (PSI_USE_VHOST === true) { + $this->sys->setHostname(getenv('SERVER_NAME')); + } else { + if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) { + $ip = gethostbyname($result); + if ($ip != $result) { + $this->sys->setHostname(gethostbyaddr($ip)); + } + } + } + } + + /** + * IP of the Virtual Host Name + * + * @return void + */ + private function _ip() + { + if (PSI_USE_VHOST === true) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + if (!($result = getenv('SERVER_ADDR'))) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + $this->sys->setIp($result); + } + } + } + + /** + * Physical memory information and Swap Space information + * + * @return void + */ + private function _memory() + { + if (CommonFunctions::executeProgram('sysinfo', '-mem', $bufr, PSI_DEBUG)) { + if (preg_match("/(.*)bytes free\s+\(used\/max\s+(.*)\s+\/\s+(.*)\)\s*\n\s+\(cached\s+(.*)\)/", $bufr, $ar_buf)) { + $this->sys->setMemTotal($ar_buf[3]); + $this->sys->setMemFree($ar_buf[1]); + $this->sys->setMemCache($ar_buf[4]); + $this->sys->setMemUsed($ar_buf[2]); + } + } + if (CommonFunctions::executeProgram('vmstat', '', $bufr, PSI_DEBUG)) { + if (preg_match("/max swap space:\s+(.*)\nfree swap space:\s+(.*)\n/", $bufr, $ar_buf)) { + if ($ar_buf[1]>0) { + $dev = new DiskDevice(); + $dev->setMountPoint("/boot/common/var/swap"); + $dev->setName("SWAP"); + $dev->setTotal($ar_buf[1]); + $dev->setFree($ar_buf[2]); + $dev->setUSed($ar_buf[1]-$ar_buf[2]); + $this->sys->setSwapDevices($dev); + } + } + } + } + + /** + * filesystem information + * + * @return void + */ + private function _filesystems() + { + if (CommonFunctions::executeProgram('df', '-b', $df, PSI_DEBUG)) { + $df = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); + foreach ($df as $df_line) { + $ar_buf = preg_split("/\s+/", $df_line); + if ((substr($df_line, 0, 1) == "/") && (count($ar_buf) == 6)) { + $dev = new DiskDevice(); + $dev->setMountPoint($ar_buf[0]); + $dev->setName($ar_buf[5]); + $dev->setFsType($ar_buf[1]); + $dev->setOptions($ar_buf[4]); + $dev->setTotal($ar_buf[2] * 1024); + $dev->setFree($ar_buf[3] * 1024); + $dev->setUsed($dev->getTotal() - $dev->getFree()); + $this->sys->setDiskDevices($dev); + } + } + } + } + + /** + * network information + * + * @return void + */ + private function _network() + { + if (CommonFunctions::executeProgram('ifconfig', '', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $notwas = true; + foreach ($lines as $line) { + if (preg_match("/^(\S+)/", $line, $ar_buf)) { + if (!$notwas) { + $dev->setErrors($errors); + $dev->setDrops($drops); + $this->sys->setNetDevices($dev); + } + $errors = 0; + $drops = 0; + $dev = new NetDevice(); + $dev->setName($ar_buf[1]); + $notwas = false; + } else { + if (!$notwas) { + if (preg_match('/\sReceive:\s\d+\spackets,\s(\d+)\serrors,\s(\d+)\sbytes,\s\d+\smcasts,\s(\d+)\sdropped/i', $line, $ar_buf2)) { + $errors +=$ar_buf2[1]; + $drops +=$ar_buf2[3]; + $dev->setRxBytes($ar_buf2[2]); + } elseif (preg_match('/\sTransmit:\s\d+\spackets,\s(\d+)\serrors,\s(\d+)\sbytes,\s\d+\smcasts,\s(\d+)\sdropped/i', $line, $ar_buf2)) { + $errors +=$ar_buf2[1]; + $drops +=$ar_buf2[3]; + $dev->setTxBytes($ar_buf2[2]); + } + + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + if (preg_match('/\sEthernet,\s+Address:\s(\S*)/i', $line, $ar_buf2)) + $dev->setInfo(preg_replace('/:/', '-', $ar_buf2[1])); + elseif (preg_match('/^\s+inet\saddr:\s(\S*),/i', $line, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + elseif (preg_match('/^\s+inet6\saddr:\s(\S*),/i', $line, $ar_buf2)) + if (!preg_match('/^fe80::/i', $ar_buf2[1])) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } + } + } + if (!$notwas) { + $dev->setErrors($errors); + $dev->setDrops($drops); + $this->sys->setNetDevices($dev); + } + } + } + + /** + * Processes + * + * @return void + */ + protected function _processes() + { + if (CommonFunctions::executeProgram('ps', '', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $processes['*'] = 0; + foreach ($lines as $line) { + if (preg_match("/^(kernel_team|\/)/", $line, $ar_buf)) { + $processes['*']++; + } + } + if ($processes['*'] > 0) { + $processes[' '] = $processes['*']; + $this->sys->setProcesses($processes); + } + } + } + + /** + * get the information + * + * @return Void + */ + public function build() + { + $this->error->addError("WARN", "The Haiku version of phpSysInfo is a work in progress, some things currently don't work"); + $this->_distro(); + $this->_hostname(); + $this->_ip(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + $this->_pci(); + $this->_usb(); + $this->_cpuinfo(); + $this->_memory(); + $this->_filesystems(); + $this->_network(); + $this->_processes(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.Linux.inc.php b/root/opt/phpsysinfo/includes/os/class.Linux.inc.php new file mode 100644 index 0000000..96abbbf --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.Linux.inc.php @@ -0,0 +1,1096 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.Linux.inc.php 712 2012-12-05 14:09:18Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * Linux sysinfo class + * get all the required information from Linux system + * + * @category PHP + * @package PSI Linux OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Linux extends OS +{ + /** + * Assoc array of all CPUs loads. + */ + protected $_cpu_loads; + + /** + * call parent constructor + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Machine + * + * @return void + */ + private function _machine() + { + if ((CommonFunctions::rfts('/var/log/dmesg', $result, 0, 4096, false) + && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.*)/m', $result, $ar_buf)) + ||(CommonFunctions::executeProgram('dmesg', '', $result, false) + && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.*)/m', $result, $ar_buf))) { + $this->sys->setMachine(trim($ar_buf[1])); + } else { //data from /sys/devices/virtual/dmi/id/ + $machine = ""; + $product = ""; + $board = ""; + $bios = ""; + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) { + $machine = trim($buf); + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) { + $product = trim($buf); + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_name', $buf, 1, 4096, false) && (trim($buf)!="")) { + $board = trim($buf); + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_version', $buf, 1, 4096, false) && (trim($buf)!="")) { + $bios = trim($buf); + } + if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_date', $buf, 1, 4096, false) && (trim($buf)!="")) { + $bios = trim($bios." ".trim($buf)); + } + if ($product != "") { + $machine .= " ".$product; + } + if ($board != "") { + $machine .= "/".$board; + } + if ($bios != "") { + $machine .= ", BIOS ".$bios; + } + + if ($machine != "") { + $this->sys->setMachine(trim($machine)); + } + } + } + + /** + * Hostname + * + * @return void + */ + protected function _hostname() + { + if (PSI_USE_VHOST === true) { + $this->sys->setHostname(getenv('SERVER_NAME')); + } else { + if (CommonFunctions::rfts('/proc/sys/kernel/hostname', $result, 1)) { + $result = trim($result); + $ip = gethostbyname($result); + if ($ip != $result) { + $this->sys->setHostname(gethostbyaddr($ip)); + } + } + } + } + + /** + * IP + * + * @return void + */ + protected function _ip() + { + if (PSI_USE_VHOST === true) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + if (!isset($_SERVER['SERVER_ADDR']) || !($result = $_SERVER['SERVER_ADDR'])) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + $this->sys->setIp($result); + } + } + } + + /** + * Kernel Version + * + * @return void + */ + private function _kernel() + { + $result = ""; + if (CommonFunctions::executeProgram($uname="uptrack-uname", '-r', $strBuf, false) || // show effective kernel if ksplice uptrack is installed + CommonFunctions::executeProgram($uname="uname", '-r', $strBuf, PSI_DEBUG)) { + $result = trim($strBuf); + if (CommonFunctions::executeProgram($uname, '-v', $strBuf, PSI_DEBUG)) { + if (preg_match('/SMP/', $strBuf)) { + $result .= ' (SMP)'; + } + } + if (CommonFunctions::executeProgram($uname, '-m', $strBuf, PSI_DEBUG)) { + $result .= ' '.trim($strBuf); + } + } elseif (CommonFunctions::rfts('/proc/version', $strBuf, 1) && preg_match('/version (.*?) /', $strBuf, $ar_buf)) { + $result = $ar_buf[1]; + if (preg_match('/SMP/', $strBuf)) { + $result .= ' (SMP)'; + } + } + if ($result != "") { + if (CommonFunctions::rfts('/proc/self/cgroup', $strBuf2, 0, 4096, false)) { + if (preg_match('/:\/lxc\//m', $strBuf2)) { + $result .= ' [lxc]'; + } elseif (preg_match('/:\/docker\//m', $strBuf2)) { + $result .= ' [docker]'; + } elseif (preg_match('/:\/system\.slice\/docker\-/m', $strBuf2)) { + $result .= ' [docker]'; + } + } + $this->sys->setKernel($result); + } + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + protected function _uptime() + { + CommonFunctions::rfts('/proc/uptime', $buf, 1); + $ar_buf = preg_split('/ /', $buf); + $this->sys->setUptime(trim($ar_buf[0])); + } + + /** + * Number of Users + * + * @return void + */ + private function _users() + { + if (CommonFunctions::executeProgram('who', '', $strBuf, PSI_DEBUG)) { + if (strlen(trim($strBuf)) > 0) { + $lines = preg_split('/\n/', $strBuf); + $this->sys->setUsers(count($lines)); + } + } + } + + /** + * Processor Load + * optionally create a loadbar + * + * @return void + */ + protected function _loadavg() + { + if (CommonFunctions::rfts('/proc/loadavg', $buf)) { + $result = preg_split("/\s/", $buf, 4); + // don't need the extra values, only first three + unset($result[3]); + $this->sys->setLoad(implode(' ', $result)); + } + if (PSI_LOAD_BAR) { + $this->sys->setLoadPercent($this->_parseProcStat('cpu')); + } + } + + /** + * fill the load for a individual cpu, through parsing /proc/stat for the specified cpu + * + * @param String $cpuline cpu for which load should be meassured + * + * @return Integer + */ + protected function _parseProcStat($cpuline) + { + if (is_null($this->_cpu_loads)) { + $this->_cpu_loads = array(); + + if (CommonFunctions::rfts('/proc/stat', $buf)) { + if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) { + foreach ($matches as $line) { + $cpu = $line[1]; + $buf2 = $line[2]; + + $this->_cpu_loads[$cpu] = array(); + + $ab = 0; + $ac = 0; + $ad = 0; + $ae = 0; + sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae); + $this->_cpu_loads[$cpu]['load'] = $ab + $ac + $ad; // cpu.user + cpu.sys + $this->_cpu_loads[$cpu]['total'] = $ab + $ac + $ad + $ae; // cpu.total + } + } + } + // we need a second value, wait 1 second befor getting (< 1 second no good value will occour) + if (PSI_LOAD_BAR) { + sleep(1); + } + if (CommonFunctions::rfts('/proc/stat', $buf)) { + if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) { + foreach ($matches as $line) { + $cpu = $line[1]; + $buf2 = $line[2]; + + $ab = 0; + $ac = 0; + $ad = 0; + $ae = 0; + sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae); + $load2 = $ab + $ac + $ad; // cpu.user + cpu.sys + $total2 = $ab + $ac + $ad + $ae; // cpu.total + $total = $this->_cpu_loads[$cpu]['total']; + $load = $this->_cpu_loads[$cpu]['load']; + $this->_cpu_loads[$cpu] = 0; + if ($total > 0 && $total2 > 0 && $load > 0 && $load2 > 0 && $total2 != $total && $load2 != $load) { + $this->_cpu_loads[$cpu] = (100 * ($load2 - $load)) / ($total2 - $total); + } + } + } + } + } + + if (isset($this->_cpu_loads[$cpuline])) { + return $this->_cpu_loads[$cpuline]; + } + + return 0; + } + + /** + * CPU information + * All of the tags here are highly architecture dependant. + * + * @return void + */ + protected function _cpuinfo() + { + if (CommonFunctions::rfts('/proc/cpuinfo', $bufr)) { + $processors = preg_split('/\s?\n\s?\n/', trim($bufr)); + $procname = null; + foreach ($processors as $processor) { + $proc = null; + $arch = null; + $dev = new CpuDevice(); + $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY); + foreach ($details as $detail) { + $arrBuff = preg_split('/\s*:\s*/', trim($detail)); + if (count($arrBuff) == 2) { + switch (strtolower($arrBuff[0])) { + case 'processor': + $proc = trim($arrBuff[1]); + if (is_numeric($proc)) { + if (strlen($procname)>0) { + $dev->setModel($procname); + } + } else { + $procname = $proc; + $dev->setModel($procname); + } + break; + case 'model name': + case 'cpu model': + case 'cpu type': + case 'cpu': + $dev->setModel($arrBuff[1]); + break; + case 'cpu mhz': + case 'clock': + if ($arrBuff[1] > 0) { //openSUSE fix + $dev->setCpuSpeed($arrBuff[1]); + } + break; + case 'cycle frequency [hz]': + $dev->setCpuSpeed($arrBuff[1] / 1000000); + break; + case 'cpu0clktck': + $dev->setCpuSpeed(hexdec($arrBuff[1]) / 1000000); // Linux sparc64 + break; + case 'l2 cache': + case 'cache size': + $dev->setCache(preg_replace("/[a-zA-Z]/", "", $arrBuff[1]) * 1024); + break; + case 'initial bogomips': + case 'bogomips': + case 'cpu0bogo': + $dev->setBogomips($arrBuff[1]); + break; + case 'flags': + if (preg_match("/ vmx/", $arrBuff[1])) { + $dev->setVirt("vmx"); + } elseif (preg_match("/ svm/", $arrBuff[1])) { + $dev->setVirt("svm"); + } elseif (preg_match("/ hypervisor/", $arrBuff[1])) { + $dev->setVirt("hypervisor"); + } + break; + case 'i size': + case 'd size': + if ($dev->getCache() === null) { + $dev->setCache($arrBuff[1] * 1024); + } else { + $dev->setCache($dev->getCache() + ($arrBuff[1] * 1024)); + } + break; + case 'cpu architecture': + $arch = trim($arrBuff[1]); + break; + } + } + } + // sparc64 specific code follows + // This adds the ability to display the cache that a CPU has + // Originally made by Sven Blumenstein in 2004 + // Modified by Tom Weustink in 2004 + $sparclist = array('SUNW,UltraSPARC@0,0', 'SUNW,UltraSPARC-II@0,0', 'SUNW,UltraSPARC@1c,0', 'SUNW,UltraSPARC-IIi@1c,0', 'SUNW,UltraSPARC-II@1c,0', 'SUNW,UltraSPARC-IIe@0,0'); + foreach ($sparclist as $name) { + if (CommonFunctions::rfts('/proc/openprom/'.$name.'/ecache-size', $buf, 1, 32, false)) { + $dev->setCache(base_convert($buf, 16, 10)); + } + } + // sparc64 specific code ends + + // XScale detection code + if (($arch === "5TE") && ($dev->getBogomips() != null)) { + $dev->setCpuSpeed($dev->getBogomips()); //BogoMIPS are not BogoMIPS on this CPU, it's the speed + $dev->setBogomips(null); // no BogoMIPS available, unset previously set BogoMIPS + } + + if ($proc != null) { + if (!is_numeric($proc)) { + $proc = 0; + } + // variable speed processors specific code follows + if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_cur_freq', $buf, 1, 4096, false)) { + $dev->setCpuSpeed($buf / 1000); + } elseif (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_cur_freq', $buf, 1, 4096, false)) { + $dev->setCpuSpeed($buf / 1000); + } + if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_max_freq', $buf, 1, 4096, false)) { + $dev->setCpuSpeedMax($buf / 1000); + } + if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_min_freq', $buf, 1, 4096, false)) { + $dev->setCpuSpeedMin($buf / 1000); + } + // variable speed processors specific code ends + if (PSI_LOAD_BAR) { + $dev->setLoad($this->_parseProcStat('cpu'.$proc)); + } + + if (CommonFunctions::rfts('/proc/acpi/thermal_zone/THRM/temperature', $buf, 1, 4096, false)) { + $dev->setTemp(substr($buf, 25, 2)); + } + if ($dev->getModel() === "") { + $dev->setModel("unknown"); + } + $this->sys->setCpus($dev); + } + } + } + } + + /** + * PCI devices + * + * @return void + */ + private function _pci() + { + if (!$arrResults = Parser::lspci()) { + if (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) { + $booDevice = false; + $arrBuf = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY); + foreach ($arrBuf as $strLine) { + if (preg_match('/Bus/', $strLine)) { + $booDevice = true; + continue; + } + if ($booDevice) { + list($strKey, $strValue) = preg_split('/: /', $strLine, 2); + if (!preg_match('/bridge/i', $strKey) && !preg_match('/USB/i ', $strKey)) { + $dev = new HWDevice(); + $dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($strValue))); + $this->sys->setPciDevices($dev); + } + $booDevice = false; + } + } + } + } else { + foreach ($arrResults as $dev) { + $this->sys->setPciDevices($dev); + } + } + } + + /** + * IDE devices + * + * @return void + */ + private function _ide() + { + $bufd = CommonFunctions::gdc('/proc/ide', false); + foreach ($bufd as $file) { + if (preg_match('/^hd/', $file)) { + $dev = new HWDevice(); + $dev->setName(trim($file)); + if (CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) { + if (trim($buf) == 'disk') { + if (CommonFunctions::rfts("/proc/ide/".$file."/capacity", $buf, 1, 4096, false) || CommonFunctions::rfts("/sys/block/".$file."/size", $buf, 1, 4096, false)) { + $dev->setCapacity(trim($buf) * 512 / 1024); + } + } + } + if (CommonFunctions::rfts("/proc/ide/".$file."/model", $buf, 1)) { + $dev->setName($dev->getName().": ".trim($buf)); + } + $this->sys->setIdeDevices($dev); + } + } + } + + /** + * SCSI devices + * + * @return void + */ + private function _scsi() + { + $get_type = false; + $device = null; + if (CommonFunctions::executeProgram('lsscsi', '-c', $bufr, PSI_DEBUG) || CommonFunctions::rfts('/proc/scsi/scsi', $bufr, 0, 4096, PSI_DEBUG)) { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + if (preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $devices)) { + $get_type = true; + $device = $devices; + continue; + } + if ($get_type) { + preg_match('/Type:\s+(\S+)/i', $buf, $dev_type); + $dev = new HWDevice(); + $dev->setName($device[1].' '.$device[2].' ('.$dev_type[1].')'); + $this->sys->setScsiDevices($dev); + $get_type = false; + } + } + } + } + + /** + * USB devices + * + * @return array + */ + private function _usb() + { + $devnum = -1; + if (!CommonFunctions::executeProgram('lsusb', '', $bufr, PSI_DEBUG)) { + if (CommonFunctions::rfts('/proc/bus/usb/devices', $bufr, 0, 4096, false)) { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + if (preg_match('/^T/', $buf)) { + $devnum += 1; + $results[$devnum] = ""; + } elseif (preg_match('/^S:/', $buf)) { + list($key, $value) = preg_split('/: /', $buf, 2); + list($key, $value2) = preg_split('/=/', $value, 2); + if (trim($key) != "SerialNumber") { + $results[$devnum] .= " ".trim($value2); + } + } + } + foreach ($results as $var) { + $dev = new HWDevice(); + $dev->setName($var); + $this->sys->setUsbDevices($dev); + } + } + } else { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + $device = preg_split("/ /", $buf, 7); + if (isset($device[6]) && trim($device[6]) != "") { + $dev = new HWDevice(); + $dev->setName(trim($device[6])); + $this->sys->setUsbDevices($dev); + } elseif (isset($device[5]) && trim($device[5]) != "") { + $dev = new HWDevice(); + $dev->setName("unknown"); + $this->sys->setUsbDevices($dev); + } + } + } + } + + /** + * I2C devices + * + * @return void + */ + protected function _i2c() + { + $i2cdevices = glob('/sys/bus/i2c/devices/*/name', GLOB_NOSORT); + if (($total = count($i2cdevices)) > 0) { + $buf = ""; + for ($i = 0; $i < $total; $i++) { + if (CommonFunctions::rfts($i2cdevices[$i], $buf, 1, 4096, false)) { + if (trim($buf) != "") { + $dev = new HWDevice(); + $dev->setName(trim($buf)); + $this->sys->setI2cDevices($dev); + } + } + } + } + } + + /** + * Network devices + * includes also rx/tx bytes + * + * @return void + */ + protected function _network() + { + if (CommonFunctions::rfts('/proc/net/dev', $bufr, 0, 4096, PSI_DEBUG)) { + $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + if (preg_match('/:/', $buf)) { + list($dev_name, $stats_list) = preg_split('/:/', $buf, 2); + $stats = preg_split('/\s+/', trim($stats_list)); + $dev = new NetDevice(); + $dev->setName(trim($dev_name)); + $dev->setRxBytes($stats[0]); + $dev->setTxBytes($stats[8]); + $dev->setErrors($stats[2] + $stats[10]); + $dev->setDrops($stats[3] + $stats[11]); + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS) && (CommonFunctions::executeProgram('ifconfig', trim($dev_name).' 2>/dev/null', $bufr2, PSI_DEBUG))) { + $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe2 as $buf2) { +// if (preg_match('/^'.trim($dev_name).'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2) + if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2) + || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $buf2, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); + elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $buf2, $ar_buf2)) { + if ($ar_buf2[1] != $ar_buf2[2]) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]); + } else { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } elseif (preg_match('/^\s+inet\saddr:(\S+)/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2) + || preg_match('/^'.trim($dev_name).':\s+ip\s+(\S+)\s+mask/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet6\saddr:\s([^\/]+)(.+)\s+Scope:[GH]/i', $buf2, $ar_buf2) + || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)(()|())/i', $buf2, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } + $this->sys->setNetDevices($dev); + } + } + } elseif (CommonFunctions::executeProgram('ifconfig', '', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $notwas = true; + foreach ($lines as $line) { + if (preg_match("/^([^\s:]+)/", $line, $ar_buf)) { + if (!$notwas) { + $dev->setErrors($errors); + $dev->setDrops($drops); + $this->sys->setNetDevices($dev); + } + $errors = 0; + $drops = 0; + $dev = new NetDevice(); + $dev->setName($ar_buf[1]); + $notwas = false; + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + if (preg_match('/^'.$ar_buf[1].'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); + elseif (preg_match('/^'.$ar_buf[1].':\s+ip\s+(\S+)\s+mask/i', $line, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } else { + if (!$notwas) { + if (preg_match('/\sRX bytes:(\d+)\s/i', $line, $ar_buf2)) { + $dev->setRxBytes($ar_buf2[1]); + } + if (preg_match('/\sTX bytes:(\d+)\s/i', $line, $ar_buf2)) { + $dev->setTxBytes($ar_buf2[1]); + } + + if (preg_match('/\sRX packets:\d+\serrors:(\d+)\sdropped:(\d+)/i', $line, $ar_buf2)) { + $errors +=$ar_buf2[1]; + $drops +=$ar_buf2[2]; + } elseif (preg_match('/\sTX packets:\d+\serrors:(\d+)\sdropped:(\d+)/i', $line, $ar_buf2)) { + $errors +=$ar_buf2[1]; + $drops +=$ar_buf2[2]; + } + + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2) + || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $line, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); + elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $line, $ar_buf2) + || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $line, $ar_buf2)) { + if ($ar_buf2[1] != $ar_buf2[2]) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]); + } else { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } elseif (preg_match('/^\s+inet\saddr:(\S+)/i', $line, $ar_buf2) + || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $line, $ar_buf2) + || preg_match('/^\s+inet6\saddr:\s([^\/]+)(.+)\s+Scope:[GH]/i', $line, $ar_buf2) + || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)(()|())/i', $line, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + + } + } + } + } + if (!$notwas) { + $dev->setErrors($errors); + $dev->setDrops($drops); + $this->sys->setNetDevices($dev); + } + } + } + + /** + * Physical memory information and Swap Space information + * + * @return void + */ + protected function _memory() + { + if (CommonFunctions::rfts('/proc/meminfo', $mbuf)) { + $bufe = preg_split("/\n/", $mbuf, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe as $buf) { + if (preg_match('/^MemTotal:\s+(.*)\s*kB/i', $buf, $ar_buf)) { + $this->sys->setMemTotal($ar_buf[1] * 1024); + } elseif (preg_match('/^MemFree:\s+(.*)\s*kB/i', $buf, $ar_buf)) { + $this->sys->setMemFree($ar_buf[1] * 1024); + } elseif (preg_match('/^Cached:\s+(.*)\s*kB/i', $buf, $ar_buf)) { + $this->sys->setMemCache($ar_buf[1] * 1024); + } elseif (preg_match('/^Buffers:\s+(.*)\s*kB/i', $buf, $ar_buf)) { + $this->sys->setMemBuffer($ar_buf[1] * 1024); + } + } + $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree()); + // values for splitting memory usage + if ($this->sys->getMemCache() !== null && $this->sys->getMemBuffer() !== null) { + $this->sys->setMemApplication($this->sys->getMemUsed() - $this->sys->getMemCache() - $this->sys->getMemBuffer()); + } + if (CommonFunctions::rfts('/proc/swaps', $sbuf, 0, 4096, false)) { + $swaps = preg_split("/\n/", $sbuf, -1, PREG_SPLIT_NO_EMPTY); + unset($swaps[0]); + foreach ($swaps as $swap) { + $ar_buf = preg_split('/\s+/', $swap, 5); + $dev = new DiskDevice(); + $dev->setMountPoint($ar_buf[0]); + $dev->setName("SWAP"); + $dev->setTotal($ar_buf[2] * 1024); + $dev->setUsed($ar_buf[3] * 1024); + $dev->setFree($dev->getTotal() - $dev->getUsed()); + $this->sys->setSwapDevices($dev); + } + } + } + } + + /** + * filesystem information + * + * @return void + */ + private function _filesystems() + { + $df_args = ""; + $hideFstypes = array(); + if (defined('PSI_HIDE_FS_TYPES') && is_string(PSI_HIDE_FS_TYPES)) { + if (preg_match(ARRAY_EXP, PSI_HIDE_FS_TYPES)) { + $hideFstypes = eval(PSI_HIDE_FS_TYPES); + } else { + $hideFstypes = array(PSI_HIDE_FS_TYPES); + } + } + foreach ($hideFstypes as $Fstype) { + $df_args .= "-x $Fstype "; + } + if ($df_args !== "") { + $df_args = trim($df_args); //trim spaces + $arrResult = Parser::df("-P $df_args 2>/dev/null"); + } else { + $arrResult = Parser::df("-P 2>/dev/null"); + } + foreach ($arrResult as $dev) { + $this->sys->setDiskDevices($dev); + } + } + + /** + * Distribution + * + * @return void + */ + private function _distro() + { + $this->sys->setDistribution("Linux"); + $list = @parse_ini_file(APP_ROOT."/data/distros.ini", true); + if (!$list) { + return; + } + // We have the '2>/dev/null' because Ubuntu gives an error on this command which causes the distro to be unknown + if (CommonFunctions::executeProgram('lsb_release', '-a 2>/dev/null', $distro_info, PSI_DEBUG) && (strlen(trim($distro_info)) > 0)) { + $distro_tmp = preg_split("/\n/", $distro_info, -1, PREG_SPLIT_NO_EMPTY); + foreach ($distro_tmp as $info) { + $info_tmp = preg_split('/:/', $info, 2); + if (isset($distro_tmp[0]) && !is_null($distro_tmp[0]) && (trim($distro_tmp[0]) != "") && + isset($distro_tmp[1]) && !is_null($distro_tmp[1]) && (trim($distro_tmp[1]) != "")) { + $distro[trim($info_tmp[0])] = trim($info_tmp[1]); + } + } + if (!isset($distro['Distributor ID']) && !isset($distro['Description'])) { // Systems like StartOS + if (isset($distro_tmp[0]) && !is_null($distro_tmp[0]) && (trim($distro_tmp[0]) != "")) { + $this->sys->setDistribution(trim($distro_tmp[0])); + if (preg_match('/^(\S+)\s*/', $distro_tmp[0], $id_buf) + && isset($list[trim($id_buf[1])]['Image'])) { + $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); + } + } + } else { + if (isset($distro['Description']) + && preg_match('/^NAME=\s*(.+)\s*$/', $distro['Description'], $name_tmp)) { + $distro['Description'] = $name_tmp[1]; + } + if (isset($distro['Description']) + && ($distro['Description'] != "n/a") + && !isset($distro['Distributor ID'])) { + $this->sys->setDistribution($distro['Description']); + } elseif (isset($distro['Description']) + && ($distro['Description'] != "n/a") + && isset($distro['Distributor ID']) + && ($distro['Distributor ID'] != "n/a") + && ($distro['Description'] != $distro['Distributor ID'])) { + $this->sys->setDistribution($distro['Description']); + } elseif (isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a")) { + $this->sys->setDistribution($distro['Distributor ID']); + if (isset($distro['Release']) && ($distro['Release'] != "n/a")) { + $this->sys->setDistribution($this->sys->getDistribution()." ".$distro['Release']); + } + if (isset($distro['Codename']) && ($distro['Codename'] != "n/a")) { + $this->sys->setDistribution($this->sys->getDistribution()." (".$distro['Codename'].")"); + } + } + if (isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a") && isset($list[$distro['Distributor ID']]['Image'])) { + $this->sys->setDistributionIcon($list[$distro['Distributor ID']]['Image']); + } + } + } else { + /* default error handler */ + if (function_exists('errorHandlerPsi')) { + restore_error_handler(); + } + /* fatal errors only */ + $old_err_rep = error_reporting(); + error_reporting(E_ERROR); + + // Fall back in case 'lsb_release' does not exist but exist /etc/lsb-release + if (CommonFunctions::fileexists($filename="/etc/lsb-release") + && CommonFunctions::rfts($filename, $buf, 0, 4096, false) + && preg_match('/^DISTRIB_ID="?([^"\n]+)"?/m', $buf, $id_buf)) { + if (preg_match('/^DISTRIB_DESCRIPTION="?([^"\n]+)"?/m', $buf, $desc_buf) + && (trim($desc_buf[1])!=trim($id_buf[1]))) { + $this->sys->setDistribution(trim($desc_buf[1])); + } else { + if (isset($list[trim($id_buf[1])]['Name'])) { + $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name'])); + } else { + $this->sys->setDistribution(trim($id_buf[1])); + } + if (preg_match('/^DISTRIB_RELEASE="?([^"\n]+)"?/m', $buf, $vers_buf)) { + $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); + } + if (preg_match('/^DISTRIB_CODENAME="?([^"\n]+)"?/m', $buf, $vers_buf)) { + $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")"); + } + } + if (isset($list[trim($id_buf[1])]['Image'])) { + $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); + } + } else { // otherwise find files specific for distribution + foreach ($list as $section=>$distribution) { + if (!isset($distribution['Files'])) { + continue; + } else { + foreach (preg_split("/;/", $distribution['Files'], -1, PREG_SPLIT_NO_EMPTY) as $filename) { + if (CommonFunctions::fileexists($filename)) { + $distro = $distribution; + if (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="detection")) { + $buf = ""; + } elseif (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="execute")) { + if (!CommonFunctions::executeProgram($filename, '2>/dev/null', $buf, PSI_DEBUG)) { + $buf = ""; + } + } else { + if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) { + $buf = ""; + } elseif (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="analyse")) { + if (preg_match('/^(\S+)\s*/', preg_replace('/^Red\s+/', 'Red', $buf), $id_buf) + && isset($list[trim($id_buf[1])]['Image'])) { + $distro = $list[trim($id_buf[1])]; + } + } + } + if (isset($distro['Image'])) { + $this->sys->setDistributionIcon($distro['Image']); + } + if (isset($distribution['Name'])) { + if (is_null($buf) || (trim($buf) == "")) { + $this->sys->setDistribution($distribution['Name']); + } else { + $this->sys->setDistribution($distribution['Name']." ".trim($buf)); + } + } else { + if (is_null($buf) || (trim($buf) == "")) { + $this->sys->setDistribution($section); + } else { + $this->sys->setDistribution(trim($buf)); + } + } + if (isset($distribution['Files2'])) { + foreach (preg_split("/;/", $distribution['Files2'], -1, PREG_SPLIT_NO_EMPTY) as $filename2) { + if (CommonFunctions::fileexists($filename2) && CommonFunctions::rfts($filename2, $buf, 0, 4096, false)) { + if (preg_match('/^majorversion="?([^"\n]+)"?/m', $buf, $maj_buf) + && preg_match('/^minorversion="?([^"\n]+)"?/m', $buf, $min_buf)) { + $distr2=$maj_buf[1].'.'.$min_buf[1]; + if (preg_match('/^buildphase="?([^"\n]+)"?/m', $buf, $pha_buf) && ($pha_buf[1]!=="0")) { + $distr2.='.'.$pha_buf[1]; + } + if (preg_match('/^buildnumber="?([^"\n]+)"?/m', $buf, $num_buf)) { + $distr2.='-'.$num_buf[1]; + } + if (preg_match('/^builddate="?([^"\n]+)"?/m', $buf, $dat_buf)) { + $distr2.=' ('.$dat_buf[1].')'; + } + $this->sys->setDistribution($this->sys->getDistribution()." ".$distr2); + } else { + $distr2=trim(substr($buf, 0, strpos($buf, "\n"))); + if (!is_null($distr2) && ($distr2 != "")) { + $this->sys->setDistribution($this->sys->getDistribution()." ".$distr2); + } + } + break; + } + } + } + break 2; + } + } + } + } + } + // if the distribution is still unknown + if ($this->sys->getDistribution() == "Linux") { + if (CommonFunctions::fileexists($filename="/etc/DISTRO_SPECS") + && CommonFunctions::rfts($filename, $buf, 0, 4096, false) + && preg_match('/^DISTRO_NAME=\'(.+)\'/m', $buf, $id_buf)) { + if (isset($list[trim($id_buf[1])]['Name'])) { + $dist = trim($list[trim($id_buf[1])]['Name']); + } else { + $dist = trim($id_buf[1]); + } + if (preg_match('/^DISTRO_VERSION=(.+)/m', $buf, $vers_buf)) { + $this->sys->setDistribution(trim($dist." ".trim($vers_buf[1]))); + } else { + $this->sys->setDistribution($dist); + } + if (isset($list[trim($id_buf[1])]['Image'])) { + $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); + } else { + if (isset($list['Puppy']['Image'])) { + $this->sys->setDistributionIcon($list['Puppy']['Image']); + } + } + } elseif ((CommonFunctions::fileexists($filename="/etc/distro-release") + && CommonFunctions::rfts($filename, $buf, 1, 4096, false) + && !is_null($buf) && (trim($buf) != "")) + || (CommonFunctions::fileexists($filename="/etc/system-release") + && CommonFunctions::rfts($filename, $buf, 1, 4096, false) + && !is_null($buf) && (trim($buf) != ""))) { + $this->sys->setDistribution(trim($buf)); + if (preg_match('/^(\S+)\s*/', preg_replace('/^Red\s+/', 'Red', $buf), $id_buf) + && isset($list[trim($id_buf[1])]['Image'])) { + $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); + } + } elseif (CommonFunctions::fileexists($filename="/etc/solydxk/info") + && CommonFunctions::rfts($filename, $buf, 0, 4096, false) + && preg_match('/^DISTRIB_ID="?([^"\n]+)"?/m', $buf, $id_buf)) { + if (preg_match('/^DESCRIPTION="?([^"\n]+)"?/m', $buf, $desc_buf) + && (trim($desc_buf[1])!=trim($id_buf[1]))) { + $this->sys->setDistribution(trim($desc_buf[1])); + } else { + if (isset($list[trim($id_buf[1])]['Name'])) { + $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name'])); + } else { + $this->sys->setDistribution(trim($id_buf[1])); + } + if (preg_match('/^RELEASE="?([^"\n]+)"?/m', $buf, $vers_buf)) { + $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); + } + if (preg_match('/^CODENAME="?([^"\n]+)"?/m', $buf, $vers_buf)) { + $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")"); + } + } + if (isset($list[trim($id_buf[1])]['Image'])) { + $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); + } else { + $this->sys->setDistributionIcon($list['SolydXK']['Image']); + } + } elseif (CommonFunctions::fileexists($filename="/etc/os-release") + && CommonFunctions::rfts($filename, $buf, 0, 4096, false) + && (preg_match('/^TAILS_VERSION_ID="?([^"\n]+)"?/m', $buf, $tid_buf) + || preg_match('/^NAME="?([^"\n]+)"?/m', $buf, $id_buf))) { + if (preg_match('/^TAILS_VERSION_ID="?([^"\n]+)"?/m', $buf, $tid_buf)) { + if (preg_match('/^TAILS_PRODUCT_NAME="?([^"\n]+)"?/m', $buf, $desc_buf)) { + $this->sys->setDistribution(trim($desc_buf[1])." ".trim($tid_buf[1])); + } else { + if (isset($list['Tails']['Name'])) { + $this->sys->setDistribution(trim($list['Tails']['Name'])." ".trim($tid_buf[1])); + } else { + $this->sys->setDistribution('Tails'." ".trim($tid_buf[1])); + } + } + $this->sys->setDistributionIcon($list['Tails']['Image']); + } else { + if (preg_match('/^PRETTY_NAME="?([^"\n]+)"?/m', $buf, $desc_buf) + && !preg_match('/\$/', $desc_buf[1])) { //if is not defined by variable + $this->sys->setDistribution(trim($desc_buf[1])); + } else { + if (isset($list[trim($id_buf[1])]['Name'])) { + $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name'])); + } else { + $this->sys->setDistribution(trim($id_buf[1])); + } + if (preg_match('/^VERSION="?([^"\n]+)"?/m', $buf, $vers_buf)) { + $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); + } elseif (preg_match('/^VERSION_ID="?([^"\n]+)"?/m', $buf, $vers_buf)) { + $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1])); + } + } + if (isset($list[trim($id_buf[1])]['Image'])) { + $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']); + } + } + } elseif (CommonFunctions::fileexists($filename="/etc/debian_version")) { + if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) { + $buf = ""; + } + if (isset($list['Debian']['Image'])) { + $this->sys->setDistributionIcon($list['Debian']['Image']); + } + if (isset($list['Debian']['Name'])) { + if (is_null($buf) || (trim($buf) == "")) { + $this->sys->setDistribution($list['Debian']['Name']); + } else { + $this->sys->setDistribution($list['Debian']['Name']." ".trim($buf)); + } + } else { + if (is_null($buf) || (trim($buf) == "")) { + $this->sys->setDistribution('Debian'); + } else { + $this->sys->setDistribution(trim($buf)); + } + } + } + } + /* restore error level */ + error_reporting($old_err_rep); + /* restore error handler */ + if (function_exists('errorHandlerPsi')) { + set_error_handler('errorHandlerPsi'); + } + } + } + + /** + * Processes + * + * @return void + */ + protected function _processes() + { + $process = glob('/proc/*/status', GLOB_NOSORT); + if (($total = count($process)) > 0) { + + $processes['*'] = 0; + $buf = ""; + for ($i = 0; $i < $total; $i++) { + if (CommonFunctions::rfts($process[$i], $buf, 0, 4096, false)) { + $processes['*']++; //current total + if (preg_match('/^State:\s+(\w)/m', $buf, $state)) { + if (isset($processes[$state[1]])) { + $processes[$state[1]]++; + } else { + $processes[$state[1]] = 1; + } + } + } + } + if (!($processes['*'] > 0)) { + $processes['*'] = $processes[' '] = $total; //all unknown + } + $this->sys->setProcesses($processes); + } + } + + /** + * get the information + * + * @see PSI_Interface_OS::build() + * + * @return Void + */ + public function build() + { + $this->_distro(); + $this->_hostname(); + $this->_ip(); + $this->_kernel(); + $this->_machine(); + $this->_uptime(); + $this->_users(); + $this->_cpuinfo(); + $this->_pci(); + $this->_ide(); + $this->_scsi(); + $this->_usb(); + $this->_i2c(); + $this->_network(); + $this->_memory(); + $this->_filesystems(); + $this->_loadavg(); + $this->_processes(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.Minix.inc.php b/root/opt/phpsysinfo/includes/os/class.Minix.inc.php new file mode 100644 index 0000000..43fd4bf --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.Minix.inc.php @@ -0,0 +1,382 @@ + + * @copyright 2012 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.Minix.inc.php 687 2012-09-06 20:54:49Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * Minix sysinfo class + * get all the required information from Minix system + * + * @category PHP + * @package PSI Minix OS class + * @author Mieczyslaw Nalewaj + * @copyright 2012 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Minix extends OS +{ + /** + * content of the syslog + * + * @var array + */ + private $_dmesg = array(); + + /** + * call parent constructor + */ + public function __construct() + { + parent::__construct(); + } + + /** + * read /var/log/messages, but only if we haven't already + * + * @return array + */ + protected function readdmesg() + { + if (count($this->_dmesg) === 0) { + if (CommonFunctions::rfts('/var/log/messages', $buf)) { + $parts = preg_split("/kernel: APIC/", $buf, -1, PREG_SPLIT_NO_EMPTY); +// $parts = preg_split("/ syslogd: restart\n/", $buf, -1, PREG_SPLIT_NO_EMPTY); + $this->_dmesg = preg_split("/\n/", $parts[count($parts) - 1], -1, PREG_SPLIT_NO_EMPTY); + } + } + + return $this->_dmesg; + } + + /** + * get the cpu information + * + * @return array + */ + protected function _cpuinfo() + { + if (CommonFunctions::rfts('/proc/cpuinfo', $bufr, 0, 4096, false)) { + $processors = preg_split('/\s?\n\s?\n/', trim($bufr)); + foreach ($processors as $processor) { + $_n = ""; $_f = ""; $_m = ""; $_s = ""; + $dev = new CpuDevice(); + $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY); + foreach ($details as $detail) { + $arrBuff = preg_split('/\s+:\s+/', trim($detail)); + if (count($arrBuff) == 2) { + switch (strtolower($arrBuff[0])) { + case 'model name': + $_n = $arrBuff[1]; + break; + case 'cpu mhz': + $dev->setCpuSpeed($arrBuff[1]); + break; + case 'cpu family': + $_f = $arrBuff[1]; + break; + case 'model': + $_m = $arrBuff[1]; + break; + case 'stepping': + $_s = $arrBuff[1]; + break; + case 'flags': + if (preg_match("/ vmx/", $arrBuff[1])) { + $dev->setVirt("vmx"); + } elseif (preg_match("/ svm/", $arrBuff[1])) { + $dev->setVirt("svm"); + } + break; + } + } + } + if ($_n == "") $_n="CPU"; + if ($_f != "") $_n.=" Family ".$_f; + if ($_m != "") $_n.=" Model ".$_m; + if ($_s != "") $_n.=" Stepping ".$_s; + $dev->SetModel($_n); + $this->sys->setCpus($dev); + } + } else + foreach ($this->readdmesg() as $line) { + if (preg_match('/kernel: (CPU .*) freq (.*) MHz/', $line, $ar_buf)) { + $dev = new CpuDevice(); + $dev->setModel($ar_buf[1]); + $dev->setCpuSpeed($ar_buf[2]); + $this->sys->setCpus($dev); + } + } + } + + /** + * PCI devices + * get the pci device information out of dmesg + * + * @return void + */ + protected function _pci() + { + if (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) { + $arrLines = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY); + foreach ($arrLines as $strLine) { + $arrParams = preg_split('/\s+/', trim($strLine), 4); + if (count($arrParams) == 4) + $strName = $arrParams[3]; + else + $strName = "unknown"; + $strName = preg_replace('/\(.*\)/', '', $strName); + $dev = new HWDevice(); + $dev->setName($strName); + $arrResults[] = $dev; + } + foreach ($arrResults as $dev) { + $this->sys->setPciDevices($dev); + } + } + if (!(isset($arrResults) && is_array($arrResults)) && is_array($results = Parser::lspci())) { + /* if access error: chmod 4755 /usr/bin/lspci */ + foreach ($results as $dev) { + $this->sys->setPciDevices($dev); + } + } + } + + /** + * Minix Version + * + * @return void + */ + private function _kernel() + { + foreach ($this->readdmesg() as $line) { + if (preg_match('/kernel: MINIX (.*) \((.*)\)/', $line, $ar_buf)) { + $branch = $ar_buf[2]; + } + } + if (CommonFunctions::executeProgram('uname', '-rvm', $ret)) { + if (isset($branch)) + $this->sys->setKernel($ret.' ('.$branch.')'); + else + $this->sys->setKernel($ret); + } + } + + /** + * Distribution + * + * @return void + */ + protected function _distro() + { + if (CommonFunctions::executeProgram('uname', '-sr', $ret)) + $this->sys->setDistribution($ret); + else + $this->sys->setDistribution('Minix'); + + $this->sys->setDistributionIcon('Minix.png'); + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + private function _uptime() + { + if (CommonFunctions::executeProgram('uptime', '', $buf)) { + if (preg_match("/up (\d+) days,\s*(\d+):(\d+),/", $buf, $ar_buf)) { + $min = $ar_buf[3]; + $hours = $ar_buf[2]; + $days = $ar_buf[1]; + $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60); + } elseif (preg_match("/up (\d+):(\d+),/", $buf, $ar_buf)) { + $min = $ar_buf[2]; + $hours = $ar_buf[1]; + $this->sys->setUptime($hours * 3600 + $min * 60); + } + } + } + + /** + * Processor Load + * optionally create a loadbar + * + * @return void + */ + private function _loadavg() + { + if (CommonFunctions::executeProgram('uptime', '', $buf)) { + if (preg_match("/load averages: (.*), (.*), (.*)$/", $buf, $ar_buf)) { + $this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]); + } + } + } + + /** + * Number of Users + * + * @return void + */ + private function _users() + { + if (CommonFunctions::executeProgram('uptime', '', $buf)) { + if (preg_match("/, (.*) users, load averages: (.*), (.*), (.*)$/", $buf, $ar_buf)) { + $this->sys->setUsers($ar_buf[1]); + } + } + } + + /** + * Virtual Host Name + * + * @return void + */ + private function _hostname() + { + if (PSI_USE_VHOST === true) { + $this->sys->setHostname(getenv('SERVER_NAME')); + } else { + if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) { + $ip = gethostbyname($result); + if ($ip != $result) { + $this->sys->setHostname(gethostbyaddr($ip)); + } + } + } + } + + /** + * IP of the Virtual Host Name + * + * @return void + */ + private function _ip() + { + if (PSI_USE_VHOST === true) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + if (!($result = getenv('SERVER_ADDR'))) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + $this->sys->setIp($result); + } + } + } + + /** + * Physical memory information and Swap Space information + * + * @return void + */ + private function _memory() + { + if (CommonFunctions::rfts('/proc/meminfo', $bufr, 1, 4096, false)) { + $ar_buf = preg_split('/\s+/', trim($bufr)); + if (count($ar_buf) >= 5) { + $this->sys->setMemTotal($ar_buf[0]*$ar_buf[1]); + $this->sys->setMemFree($ar_buf[0]*$ar_buf[2]); + $this->sys->setMemCache($ar_buf[0]*$ar_buf[4]); + $this->sys->setMemUsed($ar_buf[0]*($ar_buf[1]-$ar_buf[2])); + } + } + } + + /** + * filesystem information + * + * @return void + */ + private function _filesystems() + { + $arrResult = Parser::df("-P 2>/dev/null"); + foreach ($arrResult as $dev) { + $this->sys->setDiskDevices($dev); + } + } + + /** + * network information + * + * @return void + */ + private function _network() + { + if (CommonFunctions::executeProgram('ifconfig', '-a', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + if (preg_match("/^([^\s:]+):\saddress\s(\S+)\snetmask/", $line, $ar_buf)) { + $dev = new NetDevice(); + $dev->setName($ar_buf[1]); + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + $dev->setInfo($ar_buf[2]); + } + $this->sys->setNetDevices($dev); + } + } + } + } + + /** + * Processes + * + * @return void + */ + protected function _processes() + { + if (CommonFunctions::executeProgram('ps', 'alx', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $processes['*'] = 0; + foreach ($lines as $line) { + if (preg_match("/^\s(\w)\s/", $line, $ar_buf)) { + $processes['*']++; + $state = $ar_buf[1]; + if ($state == 'W') $state = 'D'; //linux format + elseif ($state == 'D') $state = 'd'; //invalid + if (isset($processes[$state])) { + $processes[$state]++; + } else { + $processes[$state] = 1; + } + } + } + if ($processes['*'] > 0) { + $this->sys->setProcesses($processes); + } + } + } + + /** + * get the information + * + * @return Void + */ + public function build() + { + $this->error->addError("WARN", "The Minix version of phpSysInfo is a work in progress, some things currently don't work"); + $this->_distro(); + $this->_hostname(); + $this->_ip(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + $this->_pci(); + $this->_cpuinfo(); + $this->_memory(); + $this->_filesystems(); + $this->_network(); + $this->_processes(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php b/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php new file mode 100644 index 0000000..d43e79c --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.NetBSD.inc.php @@ -0,0 +1,159 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.NetBSD.inc.php 287 2009-06-26 12:11:59Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * NetBSD sysinfo class + * get all the required information from NetBSD systems + * + * @category PHP + * @package PSI NetBSD OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class NetBSD extends BSDCommon +{ + /** + * define the regexp for log parser + */ + public function __construct() + { + parent::__construct(); + $this->setCPURegExp1("^cpu(.*)\, (.*) MHz"); + $this->setCPURegExp2("/user = (.*), nice = (.*), sys = (.*), intr = (.*), idle = (.*)/"); + $this->setSCSIRegExp1("^(.*) at scsibus.*: <(.*)> .*"); + $this->setSCSIRegExp2("^(da[0-9]): (.*)MB "); + $this->setPCIRegExp1("/(.*) at pci[0-9] dev [0-9]* function [0-9]*: (.*)$/"); + $this->setPCIRegExp2("/\"(.*)\" (.*).* at [.0-9]+ irq/"); + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + private function _uptime() + { + $a = $this->grabkey('kern.boottime'); + $this->sys->setUptime(time() - $a); + } + + /** + * get network information + * + * @return void + */ + private function _network() + { + CommonFunctions::executeProgram('netstat', '-nbdi | cut -c1-25,44- | grep "^[a-z]*[0-9][ \t].*Link"', $netstat_b); + CommonFunctions::executeProgram('netstat', '-ndi | cut -c1-25,44- | grep "^[a-z]*[0-9][ \t].*Link"', $netstat_n); + $lines_b = preg_split("/\n/", $netstat_b, -1, PREG_SPLIT_NO_EMPTY); + $lines_n = preg_split("/\n/", $netstat_n, -1, PREG_SPLIT_NO_EMPTY); + for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) { + $ar_buf_b = preg_split("/\s+/", $lines_b[$i]); + $ar_buf_n = preg_split("/\s+/", $lines_n[$i]); + if (! empty($ar_buf_b[0]) && ! empty($ar_buf_n[3])) { + $dev = new NetDevice(); + $dev->setName($ar_buf_b[0]); + $dev->setTxBytes($ar_buf_b[4]); + $dev->setRxBytes($ar_buf_b[3]); + $dev->setDrops($ar_buf_n[8]); + $dev->setErrors($ar_buf_n[4] + $ar_buf_n[6]); + $this->sys->setNetDevices($dev); + } + } + } + + /** + * IDE information + * + * @return void + */ + protected function ide() + { + foreach ($this->readdmesg() as $line) { + if (preg_match('/^(.*) at (pciide|wdc|atabus|atapibus)[0-9] (.*): <(.*)>/', $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName($ar_buf[1]); + // now loop again and find the capacity + foreach ($this->readdmesg() as $line2) { + if (preg_match("/^(".$ar_buf[1]."): (.*), (.*), (.*)MB, .*$/", $line2, $ar_buf_n)) { + $dev->setCapacity($ar_buf_n[4] * 2048 * 1.049); + } elseif (preg_match("/^(".$ar_buf[1]."): (.*) MB, (.*), (.*), .*$/", $line2, $ar_buf_n)) { + $dev->setCapacity($ar_buf_n[2] * 2048); + } + } + $this->sys->setIdeDevices($dev); + } + } + } + + /** + * get icon name + * + * @return void + */ + private function _distroicon() + { + $this->sys->setDistributionIcon('NetBSD.png'); + } + + /** + * Processes + * + * @return void + */ + protected function _processes() + { + if (CommonFunctions::executeProgram('ps', 'aux', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $processes['*'] = 0; + foreach ($lines as $line) { + if (preg_match("/^\S+\s+\d+\s+\S+\s+\S+\s+\d+\s+\d+\s+\S+\s+(\w)/", $line, $ar_buf)) { + $processes['*']++; + $state = $ar_buf[1]; + if ($state == 'O') $state = 'R'; //linux format + elseif ($state == 'I') $state = 'S'; + if (isset($processes[$state])) { + $processes[$state]++; + } else { + $processes[$state] = 1; + } + } + } + if ($processes['*'] > 0) { + $this->sys->setProcesses($processes); + } + } + } + + /** + * get the information + * + * @see BSDCommon::build() + * + * @return Void + */ + public function build() + { + parent::build(); + $this->_distroicon(); + $this->_network(); + $this->_uptime(); + $this->_processes(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.OS.inc.php b/root/opt/phpsysinfo/includes/os/class.OS.inc.php new file mode 100644 index 0000000..eadf92b --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.OS.inc.php @@ -0,0 +1,85 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.OS.inc.php 699 2012-09-15 11:57:13Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * Basic OS functions for all OS classes + * + * @category PHP + * @package PSI OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +abstract class OS implements PSI_Interface_OS +{ + /** + * object for error handling + * + * @var Error + */ + protected $error; + + /** + * @var System + */ + protected $sys; + + /** + * build the global Error object + */ + public function __construct() + { + $this->error = Error::singleton(); + $this->sys = new System(); + } + + /** + * get os specific encoding + * + * @see PSI_Interface_OS::getEncoding() + * + * @return string + */ + public function getEncoding() + { + return PSI_SYSTEM_CODEPAGE; + } + /** + * get os specific language + * + * @see PSI_Interface_OS::getLanguage() + * + * @return string + */ + public function getLanguage() + { + return PSI_SYSTEM_LANG; + } + + /** + * get the filled or unfilled (with default values) System object + * + * @see PSI_Interface_OS::getSys() + * + * @return System + */ + final public function getSys() + { + $this->build(); + + return $this->sys; + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php b/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php new file mode 100644 index 0000000..e642d42 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.OpenBSD.inc.php @@ -0,0 +1,174 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.OpenBSD.inc.php 621 2012-07-29 18:49:04Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * OpenBSD sysinfo class + * get all the required information from OpenBSD systems + * + * @category PHP + * @package PSI OpenBSD OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class OpenBSD extends BSDCommon +{ + /** + * define the regexp for log parser + */ + public function __construct() + { + parent::__construct(); + $this->setCPURegExp1("^cpu(.*) (.*) MHz"); + $this->setCPURegExp2("/(.*),(.*),(.*),(.*),(.*)/"); + $this->setSCSIRegExp1("^(.*) at scsibus.*: <(.*)> .*"); + $this->setSCSIRegExp2("^(da[0-9]): (.*)MB "); + $this->setPCIRegExp1("/(.*) at pci[0-9] .* \"(.*)\"/"); + $this->setPCIRegExp2("/\"(.*)\" (.*).* at [.0-9]+ irq/"); + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + private function _uptime() + { + $a = $this->grabkey('kern.boottime'); + $this->sys->setUptime(time() - $a); + } + + /** + * get network information + * + * @return void + */ + private function _network() + { + CommonFunctions::executeProgram('netstat', '-nbdi | cut -c1-25,44- | grep Link | grep -v \'* \'', $netstat_b, PSI_DEBUG); + CommonFunctions::executeProgram('netstat', '-ndi | cut -c1-25,44- | grep Link | grep -v \'* \'', $netstat_n, PSI_DEBUG); + $lines_b = preg_split("/\n/", $netstat_b, -1, PREG_SPLIT_NO_EMPTY); + $lines_n = preg_split("/\n/", $netstat_n, -1, PREG_SPLIT_NO_EMPTY); + for ($i = 0, $max = sizeof($lines_b); $i < $max; $i++) { + $ar_buf_b = preg_split("/\s+/", $lines_b[$i]); + $ar_buf_n = preg_split("/\s+/", $lines_n[$i]); + if (! empty($ar_buf_b[0]) && ! empty($ar_buf_n[3])) { + $dev = new NetDevice(); + $dev->setName($ar_buf_b[0]); + $dev->setTxBytes($ar_buf_b[4]); + $dev->setRxBytes($ar_buf_b[3]); + $dev->setErrors($ar_buf_n[4] + $ar_buf_n[6]); + $dev->setDrops($ar_buf_n[8]); + $this->sys->setNetDevices($dev); + } + } + } + + /** + * IDE information + * + * @return void + */ + protected function ide() + { + foreach ($this->readdmesg() as $line) { + if (preg_match('/^(.*) at pciide[0-9] (.*): <(.*)>/', $line, $ar_buf)) { + $dev = new HWDevice(); + $dev->setName($ar_buf[0]); + // now loop again and find the capacity + foreach ($this->readdmesg() as $line2) { + if (preg_match("/^(".$ar_buf[0]."): (.*), (.*), (.*)MB, .*$/", $line2, $ar_buf_n)) { + $dev->setCapacity($ar_buf_n[4] * 2048 * 1.049); + } + } + $this->sys->setIdeDevices($dev); + } + } + } + + /** + * get CPU information + * + * @return void + */ + protected function cpuinfo() + { + $dev = new CpuDevice(); + $dev->setModel($this->grabkey('hw.model')); + $dev->setCpuSpeed($this->grabkey('hw.cpuspeed')); + $ncpu = $this->grabkey('hw.ncpu'); + if (is_null($ncpu) || (trim($ncpu) == "") || (!($ncpu >= 1))) + $ncpu = 1; + for ($ncpu ; $ncpu > 0 ; $ncpu--) { + $this->sys->setCpus($dev); + } + } + + /** + * get icon name + * + * @return void + */ + private function _distroicon() + { + $this->sys->setDistributionIcon('OpenBSD.png'); + } + + /** + * Processes + * + * @return void + */ + protected function _processes() + { + if (CommonFunctions::executeProgram('ps', 'aux', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $processes['*'] = 0; + foreach ($lines as $line) { + if (preg_match("/^\S+\s+\d+\s+\S+\s+\S+\s+\d+\s+\d+\s+\S+\s+(\w)/", $line, $ar_buf)) { + $processes['*']++; + $state = $ar_buf[1]; + if ($state == 'I') $state = 'S'; //linux format + if (isset($processes[$state])) { + $processes[$state]++; + } else { + $processes[$state] = 1; + } + } + } + if ($processes['*'] > 0) { + $this->sys->setProcesses($processes); + } + } + } + + /** + * get the information + * + * @see BSDCommon::build() + * + * @return Void + */ + public function build() + { + parent::build(); + $this->_distroicon(); + $this->_network(); + $this->_uptime(); + $this->_processes(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.QNX.inc.php b/root/opt/phpsysinfo/includes/os/class.QNX.inc.php new file mode 100644 index 0000000..203dae3 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.QNX.inc.php @@ -0,0 +1,256 @@ + + * @copyright 2012 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.QNX.inc.php 687 2012-09-06 20:54:49Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * QNX sysinfo class + * get all the required information from QNX system + * + * @category PHP + * @package PSI QNX OS class + * @author Mieczyslaw Nalewaj + * @copyright 2012 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class QNX extends OS +{ + /** + * content of the syslog + * + * @var array + */ + private $_dmesg = array(); + + /** + * call parent constructor + */ + public function __construct() + { + parent::__construct(); + } + + /** + * get the cpu information + * + * @return array + */ + protected function _cpuinfo() + { + if (CommonFunctions::executeProgram('pidin', 'info', $buf) + && preg_match('/^Processor\d+: (.*)/m', $buf)) { + $lines = preg_split("/\n/", $buf, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + if (preg_match('/^Processor\d+: (.+)/', $line, $proc)) { + $dev = new CpuDevice(); + $dev->SetModel(trim($proc[1])); + if (preg_match('/(\d+)MHz/', $proc[1], $mhz)) { + $dev->setCpuSpeed($mhz[1]); + } + $this->sys->setCpus($dev); + } + } + } + } + + /** + * QNX Version + * + * @return void + */ + private function _kernel() + { + if (CommonFunctions::executeProgram('uname', '-rvm', $ret)) { + $this->sys->setKernel($ret); + } + } + + /** + * Distribution + * + * @return void + */ + protected function _distro() + { + if (CommonFunctions::executeProgram('uname', '-sr', $ret)) + $this->sys->setDistribution($ret); + else + $this->sys->setDistribution('QNX'); + + $this->sys->setDistributionIcon('QNX.png'); + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + private function _uptime() + { + + if (CommonFunctions::executeProgram('pidin', 'info', $buf) + && preg_match('/^.* BootTime:(.*)/', $buf, $bstart) + && CommonFunctions::executeProgram('date', '', $bstop)) { + /* default error handler */ + if (function_exists('errorHandlerPsi')) { + restore_error_handler(); + } + /* fatal errors only */ + $old_err_rep = error_reporting(); + error_reporting(E_ERROR); + + $uptime = strtotime($bstop)-strtotime($bstart[1]); + if ($uptime > 0) $this->sys->setUptime($uptime); + + /* restore error level */ + error_reporting($old_err_rep); + /* restore error handler */ + if (function_exists('errorHandlerPsi')) { + set_error_handler('errorHandlerPsi'); + } + } + } + + /** + * Number of Users + * + * @return void + */ + private function _users() + { + $this->sys->setUsers(1); + } + + /** + * Virtual Host Name + * + * @return void + */ + private function _hostname() + { + if (PSI_USE_VHOST === true) { + $this->sys->setHostname(getenv('SERVER_NAME')); + } else { + if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) { + $ip = gethostbyname($result); + if ($ip != $result) { + $this->sys->setHostname(gethostbyaddr($ip)); + } + } + } + } + + /** + * IP of the Virtual Host Name + * + * @return void + */ + private function _ip() + { + if (PSI_USE_VHOST === true) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + if (!($result = getenv('SERVER_ADDR'))) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + $this->sys->setIp($result); + } + } + } + + /** + * Physical memory information and Swap Space information + * + * @return void + */ + private function _memory() + { + if (CommonFunctions::executeProgram('pidin', 'info', $buf) + && preg_match('/^.* FreeMem:(\S+)Mb\/(\S+)Mb/', $buf, $memm)) { + $this->sys->setMemTotal(1024*1024*$memm[2]); + $this->sys->setMemFree(1024*1024*$memm[1]); + $this->sys->setMemUsed(1024*1024*($memm[2]-$memm[1])); + } + } + + /** + * filesystem information + * + * @return void + */ + private function _filesystems() + { + $arrResult = Parser::df("-P 2>/dev/null"); + foreach ($arrResult as $dev) { + $this->sys->setDiskDevices($dev); + } + } + + /** + * network information + * + * @return void + */ + private function _network() + { + if (CommonFunctions::executeProgram('ifconfig', '', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $notwas = true; + foreach ($lines as $line) { + if (preg_match("/^([^\s:]+)/", $line, $ar_buf)) { + if (!$notwas) { + $this->sys->setNetDevices($dev); + } + $dev = new NetDevice(); + $dev->setName($ar_buf[1]); + $notwas = false; + } else { + if (!$notwas) { + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + if (preg_match('/^\s+address:\s*(\S+)/i', $line, $ar_buf2)) { + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $line, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + + } + } + } + } + if (!$notwas) { + $this->sys->setNetDevices($dev); + } + } + } + + /** + * get the information + * + * @return Void + */ + public function build() + { + $this->error->addError("WARN", "The QNX version of phpSysInfo is a work in progress, some things currently don't work"); + $this->_distro(); + $this->_hostname(); + $this->_ip(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_cpuinfo(); + $this->_memory(); + $this->_filesystems(); + $this->_network(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php b/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php new file mode 100644 index 0000000..e9dee30 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.SunOS.inc.php @@ -0,0 +1,349 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.SunOS.inc.php 687 2012-09-06 20:54:49Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * SunOS sysinfo class + * get all the required information from SunOS systems + * + * @category PHP + * @package PSI SunOS OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class SunOS extends OS +{ + /** + * Extract kernel values via kstat() interface + * + * @param string $key key for kstat programm + * + * @return string + */ + private function _kstat($key) + { + if (CommonFunctions::executeProgram('kstat', '-p d '.$key, $m, PSI_DEBUG) && + !is_null($m) && (trim($m)!=="")) { + list($key, $value) = preg_split("/\t/", trim($m), 2); + + return $value; + } else { + return ''; + } + } + + /** + * Virtual Host Name + * + * @return void + */ + private function _hostname() + { + if (PSI_USE_VHOST === true) { + $this->sys->setHostname(getenv('SERVER_NAME')); + } else { + if (CommonFunctions::executeProgram('uname', '-n', $result, PSI_DEBUG)) { + $ip = gethostbyname($result); + if ($ip != $result) { + $this->sys->setHostname(gethostbyaddr($ip)); + } + } + } + } + + /** + * IP of the Virtual Host Name + * + * @return void + */ + private function _ip() + { + if (PSI_USE_VHOST === true) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + if (!($result = getenv('SERVER_ADDR'))) { + $this->sys->setIp(gethostbyname($this->sys->getHostname())); + } else { + $this->sys->setIp($result); + } + } + } + + /** + * Kernel Version + * + * @return void + */ + private function _kernel() + { + if (CommonFunctions::executeProgram('uname', '-s', $os, PSI_DEBUG)) { + if (CommonFunctions::executeProgram('uname', '-r', $version, PSI_DEBUG)) { + $this->sys->setKernel($os.' '.$version); + } else { + $this->sys->setKernel($os); + } + } + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + private function _uptime() + { + $this->sys->setUptime(time() - $this->_kstat('unix:0:system_misc:boot_time')); + } + + /** + * Number of Users + * + * @return void + */ + private function _users() + { + if (CommonFunctions::executeProgram('who', '-q', $buf, PSI_DEBUG)) { + $who = preg_split('/=/', $buf); + $this->sys->setUsers($who[1]); + } + } + + /** + * Processor Load + * optionally create a loadbar + * + * @return void + */ + private function _loadavg() + { + $load1 = $this->_kstat('unix:0:system_misc:avenrun_1min'); + $load5 = $this->_kstat('unix:0:system_misc:avenrun_5min'); + $load15 = $this->_kstat('unix:0:system_misc:avenrun_15min'); + $this->sys->setLoad(round($load1 / 256, 2).' '.round($load5 / 256, 2).' '.round($load15 / 256, 2)); + } + + /** + * CPU information + * + * @return void + */ + private function _cpuinfo() + { + $dev = new CpuDevice(); + if (CommonFunctions::executeProgram('uname', '-i', $buf, PSI_DEBUG)) { + $dev->setModel(trim($buf)); + } + $dev->setCpuSpeed($this->_kstat('cpu_info:0:cpu_info0:clock_MHz')); + $dev->setCache($this->_kstat('cpu_info:0:cpu_info0:cpu_type') * 1024); + $this->sys->setCpus($dev); + } + + /** + * Network devices + * + * @return void + */ + private function _network() + { + if (CommonFunctions::executeProgram('netstat', '-ni | awk \'(NF ==10){print;}\'', $netstat, PSI_DEBUG)) { + $lines = preg_split("/\n/", $netstat, -1, PREG_SPLIT_NO_EMPTY); + foreach ($lines as $line) { + $ar_buf = preg_split("/\s+/", $line); + if (!empty($ar_buf[0]) && $ar_buf[0] !== 'Name') { + $dev = new NetDevice(); + $dev->setName($ar_buf[0]); + $results[$ar_buf[0]]['errs'] = $ar_buf[5] + $ar_buf[7]; + if (preg_match('/^(\D+)(\d+)$/', $ar_buf[0], $intf)) { + $prefix = $intf[1].':'.$intf[2].':'.$intf[1].$intf[2].':'; + } elseif (preg_match('/^(\D.*)(\d+)$/', $ar_buf[0], $intf)) { + $prefix = $intf[1].':'.$intf[2].':mac:'; + } else { + $prefix = ""; + } + if ($prefix !== "") { + $cnt = $this->_kstat($prefix.'drop'); + if ($cnt > 0) { + $dev->setDrops($cnt); + } + $cnt = $this->_kstat($prefix.'obytes64'); + if ($cnt > 0) { + $dev->setTxBytes($cnt); + } + $cnt = $this->_kstat($prefix.'rbytes64'); + if ($cnt > 0) { + $dev->setRxBytes($cnt); + } + } + if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) { + if (CommonFunctions::executeProgram('ifconfig', $ar_buf[0], $bufr2, PSI_DEBUG) + && !is_null($bufr2) && (trim($bufr2) !== "")) { + $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe2 as $buf2) { + if (preg_match('/^\s+ether\s+(\S+)/i', $buf2, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').preg_replace('/:/', '-', $ar_buf2[1])); + elseif (preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } + if (CommonFunctions::executeProgram('ifconfig', $ar_buf[0].' inet6', $bufr2, PSI_DEBUG) + && !is_null($bufr2) && (trim($bufr2) !== "")) { + $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY); + foreach ($bufe2 as $buf2) { + if (preg_match('/^\s+inet6\s+([^\s\/]+)/i', $buf2, $ar_buf2) + && !preg_match('/^fe80::/i', $ar_buf2[1])) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]); + } + } + } + + $this->sys->setNetDevices($dev); + } + } + } + } + + /** + * Physical memory information and Swap Space information + * + * @return void + */ + private function _memory() + { + $pagesize = $this->_kstat('unix:0:seg_cache:slab_size'); + $this->sys->setMemTotal($this->_kstat('unix:0:system_pages:pagestotal') * $pagesize); + $this->sys->setMemUsed($this->_kstat('unix:0:system_pages:pageslocked') * $pagesize); + $this->sys->setMemFree($this->_kstat('unix:0:system_pages:pagesfree') * $pagesize); + $dev = new DiskDevice(); + $dev->setName('SWAP'); + $dev->setFsType('swap'); + $dev->setMountPoint('SWAP'); + $dev->setTotal($this->_kstat('unix:0:vminfo:swap_avail') / 1024); + $dev->setUsed($this->_kstat('unix:0:vminfo:swap_alloc') / 1024); + $dev->setFree($this->_kstat('unix:0:vminfo:swap_free') / 1024); + $this->sys->setSwapDevices($dev); + } + + /** + * filesystem information + * + * @return void + */ + private function _filesystems() + { + if (CommonFunctions::executeProgram('df', '-k', $df, PSI_DEBUG)) { + $df = preg_replace('/\n\s/m', ' ', $df); + $mounts = preg_split("/\n/", $df, -1, PREG_SPLIT_NO_EMPTY); + foreach ($mounts as $mount) { + $ar_buf = preg_split('/\s+/', $mount, 6); + if (!empty($ar_buf[0]) && $ar_buf[0] !== 'Filesystem') { + $dev = new DiskDevice(); + $dev->setName($ar_buf[0]); + $dev->setTotal($ar_buf[1] * 1024); + $dev->setUsed($ar_buf[2] * 1024); + $dev->setFree($ar_buf[3] * 1024); + $dev->setMountPoint($ar_buf[5]); + if (CommonFunctions::executeProgram('df', '-n', $dftypes, PSI_DEBUG)) { + $mounttypes = preg_split("/\n/", $dftypes, -1, PREG_SPLIT_NO_EMPTY); + foreach ($mounttypes as $type) { + $ty_buf = preg_split('/:/', $type, 2); + if (trim($ty_buf[0]) == $dev->getMountPoint()) { + $dev->setFsType($ty_buf[1]); + break; + } + } + } elseif (CommonFunctions::executeProgram('df', '-T', $dftypes, PSI_DEBUG)) { + $dftypes = preg_replace('/\n\s/m', ' ', $dftypes); + $mounttypes = preg_split("/\n/", $dftypes, -1, PREG_SPLIT_NO_EMPTY); + foreach ($mounttypes as $type) { + $ty_buf = preg_split("/\s+/", $type, 3); + if ($ty_buf[0] == $dev->getName()) { + $dev->setFsType($ty_buf[1]); + break; + } + } + } + $this->sys->setDiskDevices($dev); + } + } + } + } + + /** + * Distribution Icon + * + * @return void + */ + private function _distro() + { + $this->sys->setDistribution('SunOS'); + $this->sys->setDistributionIcon('SunOS.png'); + } + + /** + * Processes + * + * @return void + */ + protected function _processes() + { + if (CommonFunctions::executeProgram('ps', 'aux', $bufr, PSI_DEBUG)) { + $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY); + $processes['*'] = 0; + foreach ($lines as $line) { + if (preg_match("/^\S+\s+\d+\s+\S+\s+\S+\s+\d+\s+\d+\s+\S+\s+(\w)/", $line, $ar_buf)) { + $processes['*']++; + $state = $ar_buf[1]; + if ($state == 'O') $state = 'R'; //linux format + elseif ($state == 'W') $state = 'D'; + elseif ($state == 'D') $state = 'd'; //invalid + if (isset($processes[$state])) { + $processes[$state]++; + } else { + $processes[$state] = 1; + } + } + } + if ($processes['*'] > 0) { + $this->sys->setProcesses($processes); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_OS::build() + * + * @return Void + */ + public function build() + { + $this->error->addError("WARN", "The SunOS version of phpSysInfo is a work in progress, some things currently don't work"); + $this->_distro(); + $this->_hostname(); + $this->_ip(); + $this->_kernel(); + $this->_uptime(); + $this->_users(); + $this->_loadavg(); + $this->_cpuinfo(); + $this->_network(); + $this->_memory(); + $this->_filesystems(); + $this->_processes(); + } +} diff --git a/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php b/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php new file mode 100644 index 0000000..ff5eac5 --- /dev/null +++ b/root/opt/phpsysinfo/includes/os/class.WINNT.inc.php @@ -0,0 +1,609 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.WINNT.inc.php 699 2012-09-15 11:57:13Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * WINNT sysinfo class + * get all the required information from WINNT systems + * information are retrieved through the WMI interface + * + * @category PHP + * @package PSI WINNT OS class + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class WINNT extends OS +{ + /** + * holds the COM object that we pull all the WMI data from + * + * @var Object + */ + private $_wmi = null; + + /** + * holds all devices, which are in the system + * + * @var array + */ + private $_wmidevices; + + /** + * store language encoding of the system to convert some output to utf-8 + * + * @var string + */ + private $_codepage = null; + + /** + * store language of the system + * + * @var string + */ + private $_syslang = null; + + /** + * build the global Error object and create the WMI connection + */ + public function __construct() + { + parent::__construct(); + // don't set this params for local connection, it will not work + $strHostname = ''; + $strUser = ''; + $strPassword = ''; + try { + // initialize the wmi object + $objLocator = new COM('WbemScripting.SWbemLocator'); + if ($strHostname == "") { + $this->_wmi = $objLocator->ConnectServer(); + + } else { + $this->_wmi = $objLocator->ConnectServer($strHostname, 'root\CIMv2', $strHostname.'\\'.$strUser, $strPassword); + } + } catch (Exception $e) { + $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for security reasons.\nCheck an authentication mechanism for the directory where phpSysInfo is installed."); + } + $this->_getCodeSet(); + } + + /** + * store the codepage of the os for converting some strings to utf-8 + * + * @return void + */ + private function _getCodeSet() + { + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_OperatingSystem', array('CodeSet', 'OSLanguage')); + if ($buffer) { + $this->_codepage = 'windows-'.$buffer[0]['CodeSet']; + $lang = ""; + if (is_readable(APP_ROOT.'/data/languages.ini') && ($langdata = @parse_ini_file(APP_ROOT.'/data/languages.ini', true))) { + if (isset($langdata['WINNT'][$buffer[0]['OSLanguage']])) { + $lang = $langdata['WINNT'][$buffer[0]['OSLanguage']]; + } + } + if ($lang == "") { + $lang = 'Unknown'; + } + $this->_syslang = $lang.' ('.$buffer[0]['OSLanguage'].')'; + } + } + + /** + * retrieve different device types from the system based on selector + * + * @param string $strType type of the devices that should be returned + * + * @return array list of devices of the specified type + */ + private function _devicelist($strType) + { + if (empty($this->_wmidevices)) { + $this->_wmidevices = CommonFunctions::getWMI($this->_wmi, 'Win32_PnPEntity', array('Name', 'PNPDeviceID')); + } + $list = array(); + foreach ($this->_wmidevices as $device) { + if (substr($device['PNPDeviceID'], 0, strpos($device['PNPDeviceID'], "\\") + 1) == ($strType."\\")) { + $list[] = $device['Name']; + } + } + + return $list; + } + + /** + * Host Name + * + * @return void + */ + private function _hostname() + { + if (PSI_USE_VHOST === true) { + if ($hnm = getenv('SERVER_NAME')) $this->sys->setHostname($hnm); + } else { + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_ComputerSystem', array('Name')); + if ($buffer) { + $result = $buffer[0]['Name']; + $ip = gethostbyname($result); + if ($ip != $result) { + $long = ip2long($ip); + if (($long >= 167772160 && $long <= 184549375) || + ($long >= -1408237568 && $long <= -1407188993) || + ($long >= -1062731776 && $long <= -1062666241) || + ($long >= 2130706432 && $long <= 2147483647) || $long == -1) { + $this->sys->setHostname($result); //internal ip + } else { + $this->sys->setHostname(gethostbyaddr($ip)); + } + } + } else { + if ($hnm = getenv('COMPUTERNAME')) $this->sys->setHostname($hnm); + } + } + } + + /** + * IP of the Canonical Host Name + * + * @return void + */ + private function _ip() + { + if (PSI_USE_VHOST === true) { + if ((($hnm=$this->sys->getHostname()) != 'localhost') && + (($hip=gethostbyname($hnm)) != $hnm)) $this->sys->setIp($hip); + } else { + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_ComputerSystem', array('Name')); + if ($buffer) { + $result = $buffer[0]['Name']; + $this->sys->setIp(gethostbyname($result)); + } else { + if ((($hnm=$this->sys->getHostname()) != 'localhost') && + (($hip=gethostbyname($hnm)) != $hnm)) $this->sys->setIp($hip); + } + } + } + + /** + * UpTime + * time the system is running + * + * @return void + */ + private function _uptime() + { + $result = 0; + date_default_timezone_set('UTC'); + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_OperatingSystem', array('LastBootUpTime', 'LocalDateTime')); + if ($buffer) { + $byear = intval(substr($buffer[0]['LastBootUpTime'], 0, 4)); + $bmonth = intval(substr($buffer[0]['LastBootUpTime'], 4, 2)); + $bday = intval(substr($buffer[0]['LastBootUpTime'], 6, 2)); + $bhour = intval(substr($buffer[0]['LastBootUpTime'], 8, 2)); + $bminute = intval(substr($buffer[0]['LastBootUpTime'], 10, 2)); + $bseconds = intval(substr($buffer[0]['LastBootUpTime'], 12, 2)); + $lyear = intval(substr($buffer[0]['LocalDateTime'], 0, 4)); + $lmonth = intval(substr($buffer[0]['LocalDateTime'], 4, 2)); + $lday = intval(substr($buffer[0]['LocalDateTime'], 6, 2)); + $lhour = intval(substr($buffer[0]['LocalDateTime'], 8, 2)); + $lminute = intval(substr($buffer[0]['LocalDateTime'], 10, 2)); + $lseconds = intval(substr($buffer[0]['LocalDateTime'], 12, 2)); + $boottime = mktime($bhour, $bminute, $bseconds, $bmonth, $bday, $byear); + $localtime = mktime($lhour, $lminute, $lseconds, $lmonth, $lday, $lyear); + $result = $localtime - $boottime; + $this->sys->setUptime($result); + } + } + + /** + * Number of Users + * + * @return void + */ + private function _users() + { + if (CommonFunctions::executeProgram("quser", "", $strBuf, false) && (strlen(trim($strBuf)) > 0)) { + $lines = preg_split('/\n/', $strBuf); + $users = count($lines)-1; + } else { + $users = 0; + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_Process', array('Caption')); + foreach ($buffer as $process) { + if (strtoupper($process['Caption']) == strtoupper('explorer.exe')) { + $users++; + } + } + } + $this->sys->setUsers($users); + } + + /** + * Distribution + * + * @return void + */ + private function _distro() + { + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_OperatingSystem', array('Version', 'ServicePackMajorVersion', 'Caption', 'OSArchitecture')); + if ($buffer) { + $kernel = $buffer[0]['Version']; + if ($buffer[0]['ServicePackMajorVersion'] > 0) { + $kernel .= ' SP'.$buffer[0]['ServicePackMajorVersion']; + } + if (isset($buffer[0]['OSArchitecture']) && preg_match("/^(\d+)/", $buffer[0]['OSArchitecture'], $bits)) { + $this->sys->setKernel($kernel.' ('.$bits[1].'-bit)'); + } elseif (($allCpus = CommonFunctions::getWMI($this->_wmi, 'Win32_Processor', array('AddressWidth'))) && isset($allCpus[0]['AddressWidth'])) { + $this->sys->setKernel($kernel.' ('.$allCpus[0]['AddressWidth'].'-bit)'); + } else { + $this->sys->setKernel($kernel); + } + $this->sys->setDistribution($buffer[0]['Caption']); + + if ((($kernel[1] == ".") && ($kernel[0] <5)) || (substr($kernel, 0, 4) == "5.0.")) + $icon = 'Win2000.png'; + elseif ((substr($kernel, 0, 4) == "6.0.") || (substr($kernel, 0, 4) == "6.1.")) + $icon = 'WinVista.png'; + elseif ((substr($kernel, 0, 4) == "6.2.") || (substr($kernel, 0, 4) == "6.3.") || (substr($kernel, 0, 4) == "6.4.") || (substr($kernel, 0, 5) == "10.0.")) + $icon = 'Win8.png'; + else + $icon = 'WinXP.png'; + $this->sys->setDistributionIcon($icon); + } elseif (CommonFunctions::executeProgram("cmd", "/c ver 2>nul", $ver_value, false)) { + if (preg_match("/ReactOS\r?\nVersion\s+(.+)/", $ver_value, $ar_temp)) { + $this->sys->setDistribution("ReactOS"); + $this->sys->setKernel($ar_temp[1]); + $this->sys->setDistributionIcon('ReactOS.png'); + } elseif (preg_match("/^(Microsoft [^\[]*)\s*\[\D*\s*(.+)\]/", $ver_value, $ar_temp)) { + $this->sys->setDistribution($ar_temp[1]); + $this->sys->setKernel($ar_temp[2]); + $this->sys->setDistributionIcon('Win2000.png'); + } else { + $this->sys->setDistribution("WinNT"); + $this->sys->setDistributionIcon('Win2000.png'); + } + } else { + $this->sys->setDistribution("WinNT"); + $this->sys->setDistributionIcon('Win2000.png'); + } + } + + /** + * Processor Load + * optionally create a loadbar + * + * @return void + */ + private function _loadavg() + { + $loadavg = ""; + $sum = 0; + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_Processor', array('LoadPercentage')); + if ($buffer) { + foreach ($buffer as $load) { + $value = $load['LoadPercentage']; + $loadavg .= $value.' '; + $sum += $value; + } + $this->sys->setLoad(trim($loadavg)); + if (PSI_LOAD_BAR) { + $this->sys->setLoadPercent($sum / count($buffer)); + } + } + } + + /** + * CPU information + * + * @return void + */ + private function _cpuinfo() + { + $allCpus = CommonFunctions::getWMI($this->_wmi, 'Win32_Processor', array('Name', 'L2CacheSize', 'CurrentClockSpeed', 'ExtClock', 'NumberOfCores', 'MaxClockSpeed')); + foreach ($allCpus as $oneCpu) { + $coreCount = 1; + if (isset($oneCpu['NumberOfCores'])) { + $coreCount = $oneCpu['NumberOfCores']; + } + for ($i = 0; $i < $coreCount; $i++) { + $cpu = new CpuDevice(); + $cpu->setModel($oneCpu['Name']); + $cpu->setCache($oneCpu['L2CacheSize'] * 1024); + $cpu->setCpuSpeed($oneCpu['CurrentClockSpeed']); + $cpu->setBusSpeed($oneCpu['ExtClock']); + if ($oneCpu['CurrentClockSpeed'] < $oneCpu['MaxClockSpeed']) $cpu->setCpuSpeedMax($oneCpu['MaxClockSpeed']); + $this->sys->setCpus($cpu); + } + } + } + + /** + * Machine information + * + * @return void + */ + private function _machine() + { + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_ComputerSystem', array('Manufacturer', 'Model')); + if ($buffer) { + $buf = ""; + if (isset($buffer[0]['Manufacturer'])) { + $buf .= ' '.$buffer[0]['Manufacturer']; + } + if (isset($buffer[0]['Model'])) { + $buf .= ' '.$buffer[0]['Model']; + } + if (trim($buf) != "") { + $this->sys->setMachine(trim($buf)); + } + } + } + + /** + * Hardwaredevices + * + * @return void + */ + private function _hardware() + { + foreach ($this->_devicelist('PCI') as $pciDev) { + $dev = new HWDevice(); + $dev->setName($pciDev); + $this->sys->setPciDevices($dev); + } + + foreach ($this->_devicelist('IDE') as $ideDev) { + $dev = new HWDevice(); + $dev->setName($ideDev); + $this->sys->setIdeDevices($dev); + } + + foreach ($this->_devicelist('SCSI') as $scsiDev) { + $dev = new HWDevice(); + $dev->setName($scsiDev); + $this->sys->setScsiDevices($dev); + } + + foreach ($this->_devicelist('USB') as $usbDev) { + $dev = new HWDevice(); + $dev->setName($usbDev); + $this->sys->setUsbDevices($dev); + } + } + + /** + * Network devices + * + * @return void + */ + private function _network() + { + $allDevices = CommonFunctions::getWMI($this->_wmi, 'Win32_PerfRawData_Tcpip_NetworkInterface', array('Name', 'BytesSentPersec', 'BytesTotalPersec', 'BytesReceivedPersec', 'PacketsReceivedErrors', 'PacketsReceivedDiscarded')); + $allNetworkAdapterConfigurations = CommonFunctions::getWMI($this->_wmi, 'Win32_NetworkAdapterConfiguration', array('Description', 'MACAddress', 'IPAddress', 'SettingID')); + + foreach ($allDevices as $device) { + $dev = new NetDevice(); + $name=$device['Name']; + + if (preg_match('/^isatap\.({[A-Fa-f0-9\-]*})/', $name, $ar_name)) { //isatap device + foreach ($allNetworkAdapterConfigurations as $NetworkAdapterConfiguration) { + if ($ar_name[1]==$NetworkAdapterConfiguration['SettingID']) { + $dev->setName($NetworkAdapterConfiguration['Description']); + if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) { + $dev->setInfo(preg_replace('/:/', '-', $NetworkAdapterConfiguration['MACAddress'])); + if (isset($NetworkAdapterConfiguration['IPAddress'])) + foreach($NetworkAdapterConfiguration['IPAddress'] as $ipaddres) + if (($ipaddres!="0.0.0.0") && !preg_match('/^fe80::/i', $ipaddres)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ipaddres); + } + + break; + } + } + } + if ($dev->getName() == "") { //no isatap or no isatap description + $cname=preg_replace('/[^A-Za-z0-9]/', '_', $name); //convert to canonical + if (preg_match('/\s-\s([^-]*)$/', $name, $ar_name)) + $name=substr($name, 0, strlen($name)-strlen($ar_name[0])); + $dev->setName($name); + + if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) foreach ($allNetworkAdapterConfigurations as $NetworkAdapterConfiguration) { + if (preg_replace('/[^A-Za-z0-9]/', '_', $NetworkAdapterConfiguration['Description']) == $cname) { + if (!is_null($dev->getInfo())) { + $dev->setInfo(''); //multiple with the same name + } else { + $dev->setInfo(preg_replace('/:/', '-', $NetworkAdapterConfiguration['MACAddress'])); + if (isset($NetworkAdapterConfiguration['IPAddress'])) + foreach($NetworkAdapterConfiguration['IPAddress'] as $ipaddres) + if (($ipaddres!="0.0.0.0") && !preg_match('/^fe80::/i', $ipaddres)) + $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ipaddres); + } + } + } + } + + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_perfrawdata_tcpip_networkinterface.asp + // there is a possible bug in the wmi interfaceabout uint32 and uint64: http://www.ureader.com/message/1244948.aspx, so that + // magative numbers would occour, try to calculate the nagative value from total - positive number + $txbytes = $device['BytesSentPersec']; + $rxbytes = $device['BytesReceivedPersec']; + if (($txbytes < 0) && ($rxbytes < 0)) { + $txbytes += 4294967296; + $rxbytes += 4294967296; + } elseif ($txbytes < 0) { + if ($device['BytesTotalPersec'] > $rxbytes) + $txbytes = $device['BytesTotalPersec'] - $rxbytes; + else + $txbytes += 4294967296; + } elseif ($rxbytes < 0) { + if ($device['BytesTotalPersec'] > $txbytes) + $rxbytes = $device['BytesTotalPersec'] - $txbytes; + else + $rxbytes += 4294967296; + } + $dev->setTxBytes($txbytes); + $dev->setRxBytes($rxbytes); + $dev->setErrors($device['PacketsReceivedErrors']); + $dev->setDrops($device['PacketsReceivedDiscarded']); + + $this->sys->setNetDevices($dev); + } + } + + /** + * Physical memory information and Swap Space information + * + * @link http://msdn2.microsoft.com/En-US/library/aa394239.aspx + * @link http://msdn2.microsoft.com/en-us/library/aa394246.aspx + * @return void + */ + private function _memory() + { + $buffer = CommonFunctions::getWMI($this->_wmi, "Win32_OperatingSystem", array('TotalVisibleMemorySize', 'FreePhysicalMemory')); + if ($buffer) { + $this->sys->setMemTotal($buffer[0]['TotalVisibleMemorySize'] * 1024); + $this->sys->setMemFree($buffer[0]['FreePhysicalMemory'] * 1024); + $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree()); + } + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_PageFileUsage'); + foreach ($buffer as $swapdevice) { + $dev = new DiskDevice(); + $dev->setName("SWAP"); + $dev->setMountPoint($swapdevice['Name']); + $dev->setTotal($swapdevice['AllocatedBaseSize'] * 1024 * 1024); + $dev->setUsed($swapdevice['CurrentUsage'] * 1024 * 1024); + $dev->setFree($dev->getTotal() - $dev->getUsed()); + $dev->setFsType('swap'); + $this->sys->setSwapDevices($dev); + } + } + + /** + * filesystem information + * + * @return void + */ + private function _filesystems() + { + $typearray = array('Unknown', 'No Root Directory', 'Removable Disk', 'Local Disk', 'Network Drive', 'Compact Disc', 'RAM Disk'); + $floppyarray = array('Unknown', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', 'Other', 'HD', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '8 in.'); + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_LogicalDisk', array('Name', 'Size', 'FreeSpace', 'FileSystem', 'DriveType', 'MediaType')); + foreach ($buffer as $filesystem) { + $dev = new DiskDevice(); + $dev->setMountPoint($filesystem['Name']); + $dev->setFsType($filesystem['FileSystem']); + if ($filesystem['Size'] > 0) { + $dev->setTotal($filesystem['Size']); + $dev->setFree($filesystem['FreeSpace']); + $dev->setUsed($filesystem['Size'] - $filesystem['FreeSpace']); + } + if ($filesystem['MediaType'] != "" && $filesystem['DriveType'] == 2) { + $dev->setName($typearray[$filesystem['DriveType']]." (".$floppyarray[$filesystem['MediaType']].")"); + } else { + $dev->setName($typearray[$filesystem['DriveType']]); + } + $this->sys->setDiskDevices($dev); + } + if (!$buffer && ($this->sys->getDistribution()=="ReactOS")) { + // test for command 'free' on current disk + if (CommonFunctions::executeProgram("cmd", "/c free 2>nul", $out_value, true)) { + for ($letter='A'; $letter!='AA'; $letter++) if (CommonFunctions::executeProgram("cmd", "/c free ".$letter.": 2>nul", $out_value, false)) { + if (preg_match('/\n\s*([\d\.\,]+).*\n\s*([\d\.\,]+).*\n\s*([\d\.\,]+).*$/', $out_value, $out_dig)) { + $size = preg_replace('/(\.)|(\,)/', '', $out_dig[1]); + $used = preg_replace('/(\.)|(\,)/', '', $out_dig[2]); + $free = preg_replace('/(\.)|(\,)/', '', $out_dig[3]); + if ($used + $free == $size) { + $dev = new DiskDevice(); + $dev->setMountPoint($letter.":"); + $dev->setFsType('Unknown'); + $dev->setTotal($size); + $dev->setFree($free); + $dev->setUsed($used); + $this->sys->setDiskDevices($dev); + } + } + } + } + } + } + + /** + * get os specific encoding + * + * @see OS::getEncoding() + * + * @return string + */ + public function getEncoding() + { + return $this->_codepage; + } + + /** + * get os specific language + * + * @see OS::getLanguage() + * + * @return string + */ + public function getLanguage() + { + return $this->_syslang; + } + + public function _processes() + { + $processes['*'] = 0; + if (CommonFunctions::executeProgram("qprocess", "*", $strBuf, false) && (strlen(trim($strBuf)) > 0)) { + $lines = preg_split('/\n/', $strBuf); + $processes['*'] = (count($lines)-1) - 3 ; //correction for process "qprocess *" + } + if ($processes['*'] <= 0) { + $buffer = CommonFunctions::getWMI($this->_wmi, 'Win32_Process', array('Caption')); + $processes['*'] = count($buffer); + } + $processes[' '] = $processes['*']; + $this->sys->setProcesses($processes); + } + + + /** + * get the information + * + * @see PSI_Interface_OS::build() + * + * @return Void + */ + public function build() + { + $this->_distro(); + if ($this->sys->getDistribution()=="ReactOS") { + $this->error->addError("WARN", "The ReactOS version of phpSysInfo is a work in progress, some things currently don't work"); + } + $this->_hostname(); + $this->_ip(); + $this->_users(); + $this->_machine(); + $this->_uptime(); + $this->_cpuinfo(); + $this->_network(); + $this->_hardware(); + $this->_filesystems(); + $this->_memory(); + $this->_loadavg(); + $this->_processes(); + } +} diff --git a/root/opt/phpsysinfo/includes/output/class.Output.inc.php b/root/opt/phpsysinfo/includes/output/class.Output.inc.php new file mode 100644 index 0000000..4d561e3 --- /dev/null +++ b/root/opt/phpsysinfo/includes/output/class.Output.inc.php @@ -0,0 +1,60 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.Output.inc.php 569 2012-04-16 06:08:18Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * basic output functions for all output formats + * + * @category PHP + * @package PSI_Output + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +abstract class Output +{ + /** + * error object for logging errors + * + * @var Error + */ + protected $error; + + /** + * call the parent constructor and check for needed extensions + */ + public function __construct() + { + $this->error = Error::singleton(); + $this->_checkConfig(); + CommonFunctions::checkForExtensions(); +// $this->error = Error::singleton(); +// $this->_checkConfig(); + } + + /** + * read the config file and check for existence + * + * @return void + */ + private function _checkConfig() + { + include_once APP_ROOT.'/read_config.php'; + + if ($this->error->errorsExist()) { + $this->error->errorsAsXML(); + } + } +} diff --git a/root/opt/phpsysinfo/includes/output/class.Template.inc.php b/root/opt/phpsysinfo/includes/output/class.Template.inc.php new file mode 100644 index 0000000..3fa71ce --- /dev/null +++ b/root/opt/phpsysinfo/includes/output/class.Template.inc.php @@ -0,0 +1,93 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.Output.inc.php 315 2009-09-02 15:48:31Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ +/** + * basic output functions for all output formats + * + * @category PHP + * @package PSI_Output + * @author Damien Roth + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Template +{ + /** + * Vars used in the template + * + * @Array + */ + private $_vars; + + /** + * Template file + * + * @String + */ + private $_file; + + /** + * Constructor + * + * @param String $file the template file name + */ + public function __construct($file=null) + { + $this->_file = $file; + $this->_vars = array(); + } + + /** + * Set a template variable. + * + * @param string variable name + * @param string variable value + */ + public function set($name, $value) + { + $this->_vars[$name] = is_object($value) ? $value->fetch() : $value; + } + + /** + * Open, parse, and return the template file. + * + * @param string $file + * + * @return string + */ + public function fetch($file=null) + { + if (!$file) { + $file = $this->_file; + } + + // Extract the vars to local namespace + extract($this->_vars); + + // Start output buffering + ob_start(); + + include(APP_ROOT.$file); + + // Get the contents of the buffer + $contents = ob_get_contents(); + + // End buffering and discard + ob_end_clean(); + + return $contents; + } +} diff --git a/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php b/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php new file mode 100644 index 0000000..2d27fea --- /dev/null +++ b/root/opt/phpsysinfo/includes/output/class.Webpage.inc.php @@ -0,0 +1,139 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.Webpage.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * generate the dynamic webpage + * + * @category PHP + * @package PSI_Web + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Webpage extends Output implements PSI_Interface_Output +{ + /** + * configured language + * + * @var String + */ + private $_language; + + /** + * configured template + * + * @var String + */ + private $_template; + + /** + * all available templates + * + * @var Array + */ + private $_templates = array(); + + /** + * all available languages + * + * @var Array + */ + private $_languages = array(); + + /** + * check for all extensions that are needed, initialize needed vars and read phpsysinfo.ini + */ + public function __construct() + { + parent::__construct(); + $this->_getTemplateList(); + $this->_getLanguageList(); + } + + /** + * checking phpsysinfo.ini setting for template, if not supportet set phpsysinfo.css as default + * checking phpsysinfo.ini setting for language, if not supported set en as default + * + * @return void + */ + private function _checkTemplateLanguage() + { + $this->_template = trim(strtolower(PSI_DEFAULT_TEMPLATE)); + if (!file_exists(APP_ROOT.'/templates/'.$this->_template.".css")) { + $this->_template = 'phpsysinfo'; + } + + $this->_language = trim(strtolower(PSI_DEFAULT_LANG)); + if (!file_exists(APP_ROOT.'/language/'.$this->_language.".xml")) { + $this->_language = 'en'; + } + } + + /** + * get all available tamplates and store them in internal array + * + * @return void + */ + private function _getTemplateList() + { + $dirlist = CommonFunctions::gdc(APP_ROOT.'/templates/'); + sort($dirlist); + foreach ($dirlist as $file) { + $tpl_ext = substr($file, strlen($file) - 4); + $tpl_name = substr($file, 0, strlen($file) - 4); + if (($tpl_ext === ".css") && ($tpl_name !== "phpsysinfo_bootstrap")) { + array_push($this->_templates, $tpl_name); + } + } + } + + /** + * get all available translations and store them in internal array + * + * @return void + */ + private function _getLanguageList() + { + $dirlist = CommonFunctions::gdc(APP_ROOT.'/language/'); + sort($dirlist); + foreach ($dirlist as $file) { + $lang_ext = substr($file, strlen($file) - 4); + $lang_name = substr($file, 0, strlen($file) - 4); + if ($lang_ext == ".xml") { + array_push($this->_languages, $lang_name); + } + } + } + + /** + * render the page + * + * @return void + */ + public function run() + { + $this->_checkTemplateLanguage(); + + $tpl = new Template("/templates/html/index_dynamic.html"); + + $tpl->set("template", $this->_template); + $tpl->set("templates", $this->_templates); + $tpl->set("language", $this->_language); + $tpl->set("languages", $this->_languages); + + echo $tpl->fetch(); + } +} diff --git a/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php b/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php new file mode 100644 index 0000000..43c226d --- /dev/null +++ b/root/opt/phpsysinfo/includes/output/class.WebpageXML.inc.php @@ -0,0 +1,189 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.WebpageXML.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * class for xml output + * + * @category PHP + * @package PSI_XML + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class WebpageXML extends Output implements PSI_Interface_Output +{ + /** + * xml object that holds the generated xml + * + * @var XML + */ + private $_xml; + + /** + * only plugin xml + * + * @var boolean + */ + private $_pluginRequest = false; + + /** + * complete xml + * + * @var boolean + */ + private $_completeXML = false; + + /** + * name of the plugin + * + * @var string + */ + private $_pluginName = null; + + /** + * generate the output + * + * @return void + */ + private function _prepare() + { + if (!$this->_pluginRequest) { + // Figure out which OS we are running on, and detect support + if (!file_exists(APP_ROOT.'/includes/os/class.'.PSI_OS.'.inc.php')) { + $this->error->addError("file_exists(class.".PSI_OS.".inc.php)", PSI_OS." is not currently supported"); + } + + // check if there is a valid sensor configuration in phpsysinfo.ini + $foundsp = array(); + if (defined('PSI_SENSOR_PROGRAM') && is_string(PSI_SENSOR_PROGRAM)) { + if (preg_match(ARRAY_EXP, PSI_SENSOR_PROGRAM)) { + $sensorprograms = eval(strtolower(PSI_SENSOR_PROGRAM)); + } else { + $sensorprograms = array(strtolower(PSI_SENSOR_PROGRAM)); + } + foreach ($sensorprograms as $sensorprogram) { + if (!file_exists(APP_ROOT.'/includes/mb/class.'.$sensorprogram.'.inc.php')) { + $this->error->addError("file_exists(class.".htmlspecialchars($sensorprogram).".inc.php)", "specified sensor program is not supported"); + } else { + $foundsp[] = $sensorprogram; + } + } + } + + /** + * motherboard information + * + * @var serialized array + */ + define('PSI_MBINFO', serialize($foundsp)); + + // check if there is a valid hddtemp configuration in phpsysinfo.ini + $found = false; + if (PSI_HDD_TEMP !== false) { + $found = true; + } + /** + * hddtemp information available or not + * + * @var boolean + */ + define('PSI_HDDTEMP', $found); + + // check if there is a valid ups configuration in phpsysinfo.ini + $foundup = array(); + if (defined('PSI_UPS_PROGRAM') && is_string(PSI_UPS_PROGRAM)) { + if (preg_match(ARRAY_EXP, PSI_UPS_PROGRAM)) { + $upsprograms = eval(strtolower(PSI_UPS_PROGRAM)); + } else { + $upsprograms = array(strtolower(PSI_UPS_PROGRAM)); + } + foreach ($upsprograms as $upsprogram) { + if (!file_exists(APP_ROOT.'/includes/ups/class.'.$upsprogram.'.inc.php')) { + $this->error->addError("file_exists(class.".htmlspecialchars($upsprogram).".inc.php)", "specified UPS program is not supported"); + } else { + $foundup[] = $upsprogram; + } + } + } + /** + * ups information + * + * @var serialized array + */ + define('PSI_UPSINFO', serialize($foundup)); + + // if there are errors stop executing the script until they are fixed + if ($this->error->errorsExist()) { + $this->error->errorsAsXML(); + } + } + + // Create the XML + if ($this->_pluginRequest) { + $this->_xml = new XML(false, $this->_pluginName); + } else { + $this->_xml = new XML($this->_completeXML); + } + } + + /** + * render the output + * + * @return void + */ + public function run() + { + header("Cache-Control: no-cache, must-revalidate\n"); + header("Content-Type: text/xml\n\n"); + $xml = $this->_xml->getXml(); + echo $xml->asXML(); + } + + /** + * get XML as pure string + * + * @return string + */ + public function getXMLString() + { + $xml = $this->_xml->getXml(); + + return $xml->asXML(); + } + + /** + * set parameters for the XML generation process + * + * @param boolean $completeXML switch for complete xml with all plugins + * @param string $plugin name of the plugin + * + * @return void + */ + public function __construct($completeXML, $plugin = null) + { + parent::__construct(); + if ($completeXML) { + $this->_completeXML = true; + } + if ($plugin) { + if (in_array(strtolower($plugin), CommonFunctions::getPlugins())) { + $this->_pluginName = $plugin; + $this->_pluginRequest = true; + } + } + $this->_prepare(); + } +} diff --git a/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php b/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php new file mode 100644 index 0000000..284498c --- /dev/null +++ b/root/opt/phpsysinfo/includes/output/class.WebpageXSLT.inc.php @@ -0,0 +1,54 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.WebpageXSLT.inc.php 569 2012-04-16 06:08:18Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * generate a static webpage with xslt trasformation of the xml + * + * @category PHP + * @package PSI_Web + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class WebpageXSLT extends WebpageXML implements PSI_Interface_Output +{ + /** + * call the parent constructor + */ + public function __construct() + { + parent::__construct(false, null); + } + + /** + * generate the static page + * + * @return void + */ + public function run() + { + CommonFunctions::checkForExtensions(array('xsl')); + $xmlfile = $this->getXMLString(); + $xslfile = "phpsysinfo.xslt"; + $domxml = new DOMDocument(); + $domxml->loadXML($xmlfile); + $domxsl = new DOMDocument(); + $domxsl->load($xslfile); + $xsltproc = new XSLTProcessor; + $xsltproc->importStyleSheet($domxsl); + echo $xsltproc->transformToXML($domxml); + } +} diff --git a/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php b/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php new file mode 100644 index 0000000..583ef8c --- /dev/null +++ b/root/opt/phpsysinfo/includes/plugin/class.PSI_Plugin.inc.php @@ -0,0 +1,134 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.PSI_Plugin.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * basic functions to get a plugin working in phpSysinfo + * every plugin must implement this abstract class to be a valid plugin, main tasks + * of this class are reading the configuration file and check for the required files + * (*.js, lang/en.xml) to get everything working, if we have errors here we log them + * to our global error object + * + * @category PHP + * @package PSI_Plugin + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +abstract class PSI_Plugin implements PSI_Interface_Plugin +{ + /** + * name of the plugin (classname) + * + * @var string + */ + private $_plugin_name = ""; + + /** + * full directory path of the plugin + * + * @var string + */ + private $_plugin_base = ""; + + /** + * global object for error handling + * + * @var Error + */ + protected $global_error = ""; + + /** + * xml tamplate with header + * + * @var SimpleXMLExtended + */ + protected $xml; + + /** + * build the global Error object, read the configuration and check if all files are available + * for a minimalistic function of the plugin + * + * @param String $plugin_name name of the plugin + * @param String $enc target encoding + * + * @return void + */ + public function __construct($plugin_name, $enc) + { + $this->global_error = Error::Singleton(); + if (trim($plugin_name) != "") { + $this->_plugin_name = $plugin_name; + $this->_plugin_base = APP_ROOT."/plugins/".strtolower($this->_plugin_name)."/"; + $this->_checkfiles(); + $this->_getconfig(); + } else { + $this->global_error->addError("__construct()", "Parent constructor called without Plugin-Name!"); + } + $this->_createXml($enc); + } + + /** + * read the plugin configuration file, if we have one in the plugin directory + * + * @return void + */ + private function _getconfig() + { + if ((!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_ACCESS')) && + (!defined('PSI_PLUGIN_'.strtoupper($this->_plugin_name).'_FILE'))) { + $this->global_error->addError("config.ini", "Config for plugin ".$this->_plugin_name." not exist!"); + } + } + + /** + * check if there is a default translation file availabe and also the required js file for + * appending the content of the plugin to the main webpage + * + * @return void + */ + private function _checkfiles() + { + if (!file_exists($this->_plugin_base."js/".strtolower($this->_plugin_name).".js")) { + $this->global_error->addError("file_exists(".$this->_plugin_base."js/".strtolower($this->_plugin_name).".js)", "JS-File for Plugin '".$this->_plugin_name."' is missing!"); + } else { + if (!is_readable($this->_plugin_base."js/".strtolower($this->_plugin_name).".js")) { + $this->global_error->addError("is_readable(".$this->_plugin_base."js/".strtolower($this->_plugin_name).".js)", "JS-File for Plugin '".$this->_plugin_name."' is not readable but present!"); + } + } + if (!file_exists($this->_plugin_base."lang/en.xml")) { + $this->global_error->addError("file_exists(".$this->_plugin_base."lang/en.xml)", "At least an english translation must exist for the plugin!"); + } else { + if (!is_readable($this->_plugin_base."lang/en.xml")) { + $this->global_error->addError("is_readable(".$this->_plugin_base."js/".$this->_plugin_name.".js)", "The english translation can't be read but is present!"); + } + } + } + + /** + * create the xml template where plugin information are added to + * + * @param String $enc target encoding + * + * @return Void + */ + private function _createXml($enc) + { + $dom = new DOMDocument('1.0', 'UTF-8'); + $root = $dom->createElement("Plugin_".$this->_plugin_name); + $dom->appendChild($root); + $this->xml = new SimpleXMLExtended(simplexml_import_dom($dom), $enc); + } +} diff --git a/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php b/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php new file mode 100644 index 0000000..07c254c --- /dev/null +++ b/root/opt/phpsysinfo/includes/to/class.MBInfo.inc.php @@ -0,0 +1,201 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.MBInfo.inc.php 253 2009-06-17 13:07:50Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * MBInfo TO class + * + * @category PHP + * @package PSI_TO + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class MBInfo +{ + /** + * array with SensorDevices for temperatures + * + * @see SensorDevice + * + * @var Array + */ + private $_mbTemp = array(); + + /** + * array with SensorDevices for fans + * + * @see SensorDevice + * + * @var Array + */ + private $_mbFan = array(); + + /** + * array with SensorDevices for voltages + * + * @see SensorDevice + * + * @var Array + */ + private $_mbVolt = array(); + + /** + * array with SensorDevices for power + * + * @see SensorDevice + * + * @var Array + */ + private $_mbPower = array(); + + /** + * array with SensorDevices for apmers + * + * @see SensorDevice + * + * @var Array + */ + private $_mbCurrent = array(); + + /** + * Returns $_mbFan. + * + * @see System::$_mbFan + * + * @return Array + */ + public function getMbFan() + { + return $this->_mbFan; + } + + /** + * Sets $_mbFan. + * + * @param SensorDevice $mbFan fan device + * + * @see System::$_mbFan + * + * @return Void + */ + public function setMbFan($mbFan) + { + array_push($this->_mbFan, $mbFan); + } + + /** + * Returns $_mbTemp. + * + * @see System::$_mbTemp + * + * @return Array + */ + public function getMbTemp() + { + return $this->_mbTemp; + } + + /** + * Sets $_mbTemp. + * + * @param Sensor $mbTemp temp device + * + * @see System::$_mbTemp + * + * @return Void + */ + public function setMbTemp($mbTemp) + { + array_push($this->_mbTemp, $mbTemp); + } + + /** + * Returns $_mbVolt. + * + * @see System::$_mbVolt + * + * @return Array + */ + public function getMbVolt() + { + return $this->_mbVolt; + } + + /** + * Sets $_mbVolt. + * + * @param Sensor $mbVolt voltage device + * + * @see System::$_mbVolt + * + * @return Void + */ + public function setMbVolt($mbVolt) + { + array_push($this->_mbVolt, $mbVolt); + } + + /** + * Returns $_mbPower. + * + * @see System::$_mbPower + * + * @return Array + */ + public function getMbPower() + { + return $this->_mbPower; + } + + /** + * Sets $_mbPower. + * + * @param Sensor $mbPower power device + * + * @see System::$_mbPower + * + * @return Void + */ + public function setMbPower($mbPower) + { + array_push($this->_mbPower, $mbPower); + } + /** + * Returns $_mbCurrent. + * + * @see System::$_mbCurrent + * + * @return Array + */ + public function getMbCurrent() + { + return $this->_mbCurrent; + } + + /** + * Sets $_mbCurrent. + * + * @param Sensor $mbCurrent current device + * + * @see System::$_mbCurrent + * + * @return Void + */ + public function setMbCurrent($mbCurrent) + { + array_push($this->_mbCurrent, $mbCurrent); + } +} diff --git a/root/opt/phpsysinfo/includes/to/class.System.inc.php b/root/opt/phpsysinfo/includes/to/class.System.inc.php new file mode 100644 index 0000000..938139e --- /dev/null +++ b/root/opt/phpsysinfo/includes/to/class.System.inc.php @@ -0,0 +1,1167 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.System.inc.php 255 2009-06-17 13:39:41Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * System TO class + * + * @category PHP + * @package PSI_TO + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class System +{ + /** + * name of the host where phpSysInfo runs + * + * @var String + */ + private $_hostname = "localhost"; + + /** + * ip of the host where phpSysInfo runs + * + * @var String + */ + private $_ip = "127.0.0.1"; + + /** + * detailed Information about the kernel + * + * @var String + */ + private $_kernel = "Unknown"; + + /** + * name of the distribution + * + * @var String + */ + private $_distribution = "Unknown"; + + /** + * icon of the distribution (must be available in phpSysInfo) + * + * @var String + */ + private $_distributionIcon = "unknown.png"; + + /** + * detailed Information about the machine name + * + * @var String + */ + private $_machine = ""; + + /** + * time in sec how long the system is running + * + * @var Integer + */ + private $_uptime = 0; + + /** + * count of users that are currently logged in + * + * @var Integer + */ + private $_users = 0; + + /** + * load of the system + * + * @var String + */ + private $_load = ""; + + /** + * load of the system in percent (all cpus, if more than one) + * + * @var Integer + */ + private $_loadPercent = null; + + /** + * array with cpu devices + * + * @see CpuDevice + * + * @var Array + */ + private $_cpus = array(); + + /** + * array with network devices + * + * @see NetDevice + * + * @var Array + */ + private $_netDevices = array(); + + /** + * array with pci devices + * + * @see HWDevice + * + * @var Array + */ + private $_pciDevices = array(); + + /** + * array with ide devices + * + * @see HWDevice + * + * @var Array + */ + private $_ideDevices = array(); + + /** + * array with scsi devices + * + * @see HWDevice + * + * @var Array + */ + private $_scsiDevices = array(); + + /** + * array with usb devices + * + * @see HWDevice + * + * @var Array + */ + private $_usbDevices = array(); + + /** + * array with thunderbolt devices + * + * @see HWDevice + * + * @var Array + */ + private $_tbDevices = array(); + + /** + * array with I2C devices + * + * @see HWDevice + * + * @var Array + */ + private $_i2cDevices = array(); + + /** + * array with disk devices + * + * @see DiskDevice + * + * @var Array + */ + private $_diskDevices = array(); + + /** + * free memory in bytes + * + * @var Integer + */ + private $_memFree = 0; + + /** + * total memory in bytes + * + * @var Integer + */ + private $_memTotal = 0; + + /** + * used memory in bytes + * + * @var Integer + */ + private $_memUsed = 0; + + /** + * used memory by applications in bytes + * + * @var Integer + */ + private $_memApplication = null; + + /** + * used memory for buffers in bytes + * + * @var Integer + */ + private $_memBuffer = null; + + /** + * used memory for cache in bytes + * + * @var Integer + */ + private $_memCache = null; + + /** + * array with swap devices + * + * @see DiskDevice + * + * @var Array + */ + private $_swapDevices = array(); + + /** + * array of types of processes + * + * @var Array + */ + private $_processes = array(); + + /** + * remove duplicate Entries and Count + * + * @param Array $arrDev list of HWDevices + * + * @see HWDevice + * + * @return Array + */ + public static function removeDupsAndCount($arrDev) + { + $result = array(); + foreach ($arrDev as $dev) { + if (count($result) === 0) { + array_push($result, $dev); + } else { + $found = false; + foreach ($result as $tmp) { + if ($dev->equals($tmp)) { + $tmp->setCount($tmp->getCount() + 1); + $found = true; + break; + } + } + if (!$found) { + array_push($result, $dev); + } + } + } + + return $result; + } + + /** + * return percent of used memory + * + * @see System::_memUsed + * @see System::_memTotal + * + * @return Integer + */ + public function getMemPercentUsed() + { + if ($this->_memTotal > 0) { + return round($this->_memUsed / $this->_memTotal * 100); + } else { + return 0; + } + } + + /** + * return percent of used memory for applications + * + * @see System::_memApplication + * @see System::_memTotal + * + * @return Integer + */ + public function getMemPercentApplication() + { + if ($this->_memApplication !== null) { + if (($this->_memApplication > 0) && ($this->_memTotal > 0)) { + return round($this->_memApplication / $this->_memTotal * 100); + } else { + return 0; + } + } else { + return null; + } + } + + /** + * return percent of used memory for cache + * + * @see System::_memCache + * @see System::_memTotal + * + * @return Integer + */ + public function getMemPercentCache() + { + if ($this->_memCache !== null) { + if (($this->_memCache > 0) && ($this->_memTotal > 0)) { + if (($this->_memApplication !== null) && ($this->_memApplication > 0)) { + return round(($this->_memCache + $this->_memApplication) / $this->_memTotal * 100) - $this->getMemPercentApplication(); + } else { + return round($this->_memCache / $this->_memTotal * 100); + } + } else { + return 0; + } + } else { + return null; + } + } + + /** + * return percent of used memory for buffer + * + * @see System::_memBuffer + * @see System::_memTotal + * + * @return Integer + */ + public function getMemPercentBuffer() + { + if ($this->_memBuffer !== null) { + if (($this->_memBuffer > 0) && ($this->_memTotal > 0)) { + if (($this->_memCache !== null) && ($this->_memCache > 0)) { + if (($this->_memApplication !== null) && ($this->_memApplication > 0)) { + return round(($this->_memBuffer + $this->_memApplication + $this->_memCache) / $this->_memTotal * 100) - $this->getMemPercentApplication() - $this->getMemPercentCache(); + } else { + return round(($this->_memBuffer + $this->_memCache) / $this->_memTotal * 100) - $this->getMemPercentCache(); + } + } elseif (($this->_memApplication !== null) && ($this->_memApplication > 0)) { + return round(($this->_memBuffer + $this->_memApplication) / $this->_memTotal * 100) - $this->getMemPercentApplication(); + } else { + return round($this->_memBuffer / $this->_memTotal * 100); + } + } else { + return 0; + } + } else { + return null; + } + } + + /** + * Returns total free swap space + * + * @see System::_swapDevices + * @see DiskDevice::getFree() + * + * @return Integer + */ + public function getSwapFree() + { + if (count($this->_swapDevices) > 0) { + $free = 0; + foreach ($this->_swapDevices as $dev) { + $free += $dev->getFree(); + } + + return $free; + } + + return null; + } + + /** + * Returns total swap space + * + * @see System::_swapDevices + * @see DiskDevice::getTotal() + * + * @return Integer + */ + public function getSwapTotal() + { + if (count($this->_swapDevices) > 0) { + $total = 0; + foreach ($this->_swapDevices as $dev) { + $total += $dev->getTotal(); + } + + return $total; + } else { + return null; + } + } + + /** + * Returns total used swap space + * + * @see System::_swapDevices + * @see DiskDevice::getUsed() + * + * @return Integer + */ + public function getSwapUsed() + { + if (count($this->_swapDevices) > 0) { + $used = 0; + foreach ($this->_swapDevices as $dev) { + $used += $dev->getUsed(); + } + + return $used; + } else { + return null; + } + } + + /** + * return percent of total swap space used + * + * @see System::getSwapUsed() + * @see System::getSwapTotal() + * + * @return Integer + */ + public function getSwapPercentUsed() + { + if ($this->getSwapTotal() !== null) { + if ($this->getSwapTotal() > 0) { + return round($this->getSwapUsed() / $this->getSwapTotal() * 100); + } else { + return 0; + } + } else { + return null; + } + } + + /** + * Returns $_distribution. + * + * @see System::$_distribution + * + * @return String + */ + public function getDistribution() + { + return $this->_distribution; + } + + /** + * Sets $_distribution. + * + * @param String $distribution distributionname + * + * @see System::$_distribution + * + * @return Void + */ + public function setDistribution($distribution) + { + $this->_distribution = $distribution; + } + + /** + * Returns $_distributionIcon. + * + * @see System::$_distributionIcon + * + * @return String + */ + public function getDistributionIcon() + { + return $this->_distributionIcon; + } + + /** + * Sets $_distributionIcon. + * + * @param String $distributionIcon distribution icon + * + * @see System::$_distributionIcon + * + * @return Void + */ + public function setDistributionIcon($distributionIcon) + { + $this->_distributionIcon = $distributionIcon; + } + + /** + * Returns $_hostname. + * + * @see System::$_hostname + * + * @return String + */ + public function getHostname() + { + return $this->_hostname; + } + + /** + * Sets $_hostname. + * + * @param String $hostname hostname + * + * @see System::$_hostname + * + * @return Void + */ + public function setHostname($hostname) + { + $this->_hostname = $hostname; + } + + /** + * Returns $_ip. + * + * @see System::$_ip + * + * @return String + */ + public function getIp() + { + return $this->_ip; + } + + /** + * Sets $_ip. + * + * @param String $ip IP + * + * @see System::$_ip + * + * @return Void + */ + public function setIp($ip) + { + $this->_ip = $ip; + } + + /** + * Returns $_kernel. + * + * @see System::$_kernel + * + * @return String + */ + public function getKernel() + { + return $this->_kernel; + } + + /** + * Sets $_kernel. + * + * @param String $kernel kernelname + * + * @see System::$_kernel + * + * @return Void + */ + public function setKernel($kernel) + { + $this->_kernel = $kernel; + } + + /** + * Returns $_load. + * + * @see System::$_load + * + * @return String + */ + public function getLoad() + { + return $this->_load; + } + + /** + * Sets $_load. + * + * @param String $load current system load + * + * @see System::$_load + * + * @return Void + */ + public function setLoad($load) + { + $this->_load = $load; + } + + /** + * Returns $_loadPercent. + * + * @see System::$_loadPercent + * + * @return Integer + */ + public function getLoadPercent() + { + return $this->_loadPercent; + } + + /** + * Sets $_loadPercent. + * + * @param Integer $loadPercent load percent + * + * @see System::$_loadPercent + * + * @return Void + */ + public function setLoadPercent($loadPercent) + { + $this->_loadPercent = $loadPercent; + } + + /** + * Returns $_machine. + * + * @see System::$_machine + * + * @return String + */ + public function getMachine() + { + return $this->_machine; + } + + /** + * Sets $_machine. + * + * @param Interger $machine machine + * + * @see System::$_machine + * + * @return Void + */ + public function setMachine($machine) + { + $this->_machine = $machine; + } + + /** + * Returns $_uptime. + * + * @see System::$_uptime + * + * @return Integer + */ + public function getUptime() + { + return $this->_uptime; + } + + /** + * Sets $_uptime. + * + * @param Interger $uptime uptime + * + * @see System::$_uptime + * + * @return Void + */ + public function setUptime($uptime) + { + $this->_uptime = $uptime; + } + + /** + * Returns $_users. + * + * @see System::$_users + * + * @return Integer + */ + public function getUsers() + { + return $this->_users; + } + + /** + * Sets $_users. + * + * @param Integer $users user count + * + * @see System::$_users + * + * @return Void + */ + public function setUsers($users) + { + $this->_users = $users; + } + + /** + * Returns $_cpus. + * + * @see System::$_cpus + * + * @return Array + */ + public function getCpus() + { + return $this->_cpus; + } + + /** + * Sets $_cpus. + * + * @param Cpu $cpus cpu device + * + * @see System::$_cpus + * @see CpuDevice + * + * @return Void + */ + public function setCpus($cpus) + { + array_push($this->_cpus, $cpus); + } + + /** + * Returns $_netDevices. + * + * @see System::$_netDevices + * + * @return Array + */ + public function getNetDevices() + { + return $this->_netDevices; + } + + /** + * Sets $_netDevices. + * + * @param NetDevice $netDevices network device + * + * @see System::$_netDevices + * @see NetDevice + * + * @return Void + */ + public function setNetDevices($netDevices) + { + array_push($this->_netDevices, $netDevices); + } + + /** + * Returns $_pciDevices. + * + * @see System::$_pciDevices + * + * @return Array + */ + public function getPciDevices() + { + return $this->_pciDevices; + } + + /** + * Sets $_pciDevices. + * + * @param HWDevice $pciDevices pci device + * + * @see System::$_pciDevices + * @see HWDevice + * + * @return Void + */ + public function setPciDevices($pciDevices) + { + array_push($this->_pciDevices, $pciDevices); + } + + /** + * Returns $_ideDevices. + * + * @see System::$_ideDevices + * + * @return Array + */ + public function getIdeDevices() + { + return $this->_ideDevices; + } + + /** + * Sets $_ideDevices. + * + * @param HWDevice $ideDevices ide device + * + * @see System::$_ideDevices + * @see HWDevice + * + * @return Void + */ + public function setIdeDevices($ideDevices) + { + array_push($this->_ideDevices, $ideDevices); + } + + /** + * Returns $_scsiDevices. + * + * @see System::$_scsiDevices + * + * @return Array + */ + public function getScsiDevices() + { + return $this->_scsiDevices; + } + + /** + * Sets $_scsiDevices. + * + * @param HWDevice $scsiDevices scsi devices + * + * @see System::$_scsiDevices + * @see HWDevice + * + * @return Void + */ + public function setScsiDevices($scsiDevices) + { + array_push($this->_scsiDevices, $scsiDevices); + } + + /** + * Returns $_usbDevices. + * + * @see System::$_usbDevices + * + * @return Array + */ + public function getUsbDevices() + { + return $this->_usbDevices; + } + + /** + * Sets $_usbDevices. + * + * @param HWDevice $usbDevices usb device + * + * @see System::$_usbDevices + * @see HWDevice + * + * @return Void + */ + public function setUsbDevices($usbDevices) + { + array_push($this->_usbDevices, $usbDevices); + } + + /** + * Returns $_tbDevices. + * + * @see System::$_tbDevices + * + * @return Array + */ + public function getTbDevices() + { + return $this->_tbDevices; + } + + /** + * Sets $_tbDevices. + * + * @param HWDevice $tbDevices thunderbolt device + * + * @see System::$_tbDevices + * @see HWDevice + * + * @return Void + */ + public function setTbDevices($tbDevices) + { + array_push($this->_tbDevices, $tbDevices); + } + + /** + * Returns $_i2cDevices. + * + * @see System::$_i2cDevices + * + * @return Array + */ + public function getI2cDevices() + { + return $this->_i2cDevices; + } + + /** + * Sets $_i2cDevices. + * + * @param HWDevice $i2cDevices I2C device + * + * @see System::$_i2cDevices + * @see HWDevice + * + * @return Void + */ + public function setI2cDevices($i2cDevices) + { + array_push($this->_i2cDevices, $i2cDevices); + } + + /** + * Returns $_diskDevices. + * + * @see System::$_diskDevices + * + * @return Array + */ + public function getDiskDevices() + { + return $this->_diskDevices; + } + + /** + * Sets $_diskDevices. + * + * @param DiskDevice $diskDevices disk device + * + * @see System::$_diskDevices + * @see DiskDevice + * + * @return void + */ + public function setDiskDevices($diskDevices) + { + array_push($this->_diskDevices, $diskDevices); + } + + /** + * Returns $_memApplication. + * + * @see System::$_memApplication + * + * @return Integer + */ + public function getMemApplication() + { + return $this->_memApplication; + } + + /** + * Sets $_memApplication. + * + * @param Integer $memApplication application memory + * + * @see System::$_memApplication + * + * @return Void + */ + public function setMemApplication($memApplication) + { + $this->_memApplication = $memApplication; + } + + /** + * Returns $_memBuffer. + * + * @see System::$_memBuffer + * + * @return Integer + */ + public function getMemBuffer() + { + return $this->_memBuffer; + } + + /** + * Sets $_memBuffer. + * + * @param Integer $memBuffer buffer memory + * + * @see System::$_memBuffer + * + * @return Void + */ + public function setMemBuffer($memBuffer) + { + $this->_memBuffer = $memBuffer; + } + + /** + * Returns $_memCache. + * + * @see System::$_memCache + * + * @return Integer + */ + public function getMemCache() + { + return $this->_memCache; + } + + /** + * Sets $_memCache. + * + * @param Integer $memCache cache memory + * + * @see System::$_memCache + * + * @return Void + */ + public function setMemCache($memCache) + { + $this->_memCache = $memCache; + } + + /** + * Returns $_memFree. + * + * @see System::$_memFree + * + * @return Integer + */ + public function getMemFree() + { + return $this->_memFree; + } + + /** + * Sets $_memFree. + * + * @param Integer $memFree free memory + * + * @see System::$_memFree + * + * @return Void + */ + public function setMemFree($memFree) + { + $this->_memFree = $memFree; + } + + /** + * Returns $_memTotal. + * + * @see System::$_memTotal + * + * @return Integer + */ + public function getMemTotal() + { + return $this->_memTotal; + } + + /** + * Sets $_memTotal. + * + * @param Integer $memTotal total memory + * + * @see System::$_memTotal + * + * @return Void + */ + public function setMemTotal($memTotal) + { + $this->_memTotal = $memTotal; + } + + /** + * Returns $_memUsed. + * + * @see System::$_memUsed + * + * @return Integer + */ + public function getMemUsed() + { + return $this->_memUsed; + } + + /** + * Sets $_memUsed. + * + * @param Integer $memUsed used memory + * + * @see System::$_memUsed + * + * @return Void + */ + public function setMemUsed($memUsed) + { + $this->_memUsed = $memUsed; + } + + /** + * Returns $_swapDevices. + * + * @see System::$_swapDevices + * + * @return Array + */ + public function getSwapDevices() + { + return $this->_swapDevices; + } + + /** + * Sets $_swapDevices. + * + * @param DiskDevice $swapDevices swap devices + * + * @see System::$_swapDevices + * @see DiskDevice + * + * @return Void + */ + public function setSwapDevices($swapDevices) + { + array_push($this->_swapDevices, $swapDevices); + } + + /** + * Returns $_processes. + * + * @see System::$_processes + * + * @return Array + */ + public function getProcesses() + { + return $this->_processes; + } + + /** + * Sets $_proceses. + * + * @param $processes array of types of processes + * + * @see System::$_processes + * + * @return Void + */ + public function setProcesses($processes) + { + $this->_processes = $processes; +/* + foreach ($processes as $proc_type=>$proc_count) { + $this->_processes[$proc_type] = $proc_count; + } +*/ + } +} diff --git a/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php b/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php new file mode 100644 index 0000000..26b81cf --- /dev/null +++ b/root/opt/phpsysinfo/includes/to/class.UPSInfo.inc.php @@ -0,0 +1,62 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.UPSInfo.inc.php 329 2009-09-07 11:21:44Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * MBInfo TO class + * + * @category PHP + * @package PSI_TO + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class UPSInfo +{ + /** + * array with upsdivices + * + * @see UPSDevice + * + * @var Array + */ + private $_upsDevices = array(); + + /** + * Returns $_upsDevices. + * + * @see UPSInfo::$_upsDevices + * + * @return Array + */ + public function getUpsDevices() + { + return $this->_upsDevices; + } + + /** + * Sets $_upsDevices. + * + * @param UPSDevice $upsDevices upsdevice + * + * @see UPSInfo::$_upsDevices + * + * @return Void + */ + public function setUpsDevices($upsDevices) + { + array_push($this->_upsDevices, $upsDevices); + } +} diff --git a/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php new file mode 100644 index 0000000..e690ef2 --- /dev/null +++ b/root/opt/phpsysinfo/includes/to/device/class.CpuDevice.inc.php @@ -0,0 +1,357 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.CpuDevice.inc.php 411 2010-12-28 22:32:52Z Jacky672 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * CpuDevice TO class + * + * @category PHP + * @package PSI_TO + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class CpuDevice +{ + /** + * model of the cpu + * + * @var String + */ + private $_model = ""; + + /** + * speed of the cpu in hertz + * + * @var Integer + */ + private $_cpuSpeed = 0; + + /** + * max speed of the cpu in hertz + * + * @var Integer + */ + private $_cpuSpeedMax = 0; + + /** + * min speed of the cpu in hertz + * + * @var Integer + */ + private $_cpuSpeedMin = 0; + + /** + * cache size in bytes, if available + * + * @var Integer + */ + private $_cache = null; + + /** + * virtualization, if available + * + * @var String + */ + private $_virt = null; + + /** + * busspeed in hertz, if available + * + * @var Integer + */ + private $_busSpeed = null; + + /** + * temperature of the cpu, if available + * + * @var Integer + */ + private $_temp = null; + + /** + * bogomips of the cpu, if available + * + * @var Integer + */ + private $_bogomips = null; + + /** + * current load in percent of the cpu, if available + * + * @var Integer + */ + private $_load = null; + + /** + * Returns $_bogomips. + * + * @see Cpu::$_bogomips + * + * @return Integer + */ + public function getBogomips() + { + return $this->_bogomips; + } + + /** + * Sets $_bogomips. + * + * @param Integer $bogomips bogompis + * + * @see Cpu::$_bogomips + * + * @return Void + */ + public function setBogomips($bogomips) + { + $this->_bogomips = $bogomips; + } + + /** + * Returns $_busSpeed. + * + * @see Cpu::$_busSpeed + * + * @return Integer + */ + public function getBusSpeed() + { + return $this->_busSpeed; + } + + /** + * Sets $_busSpeed. + * + * @param Integer $busSpeed busspeed + * + * @see Cpu::$_busSpeed + * + * @return Void + */ + public function setBusSpeed($busSpeed) + { + $this->_busSpeed = $busSpeed; + } + + /** + * Returns $_cache. + * + * @see Cpu::$_cache + * + * @return Integer + */ + public function getCache() + { + return $this->_cache; + } + + /** + * Sets $_cache. + * + * @param Integer $cache cache size + * + * @see Cpu::$_cache + * + * @return Void + */ + public function setCache($cache) + { + $this->_cache = $cache; + } + + /** + * Returns $_virt. + * + * @see Cpu::$_virt + * + * @return String + */ + public function getVirt() + { + return $this->_virt; + } + + /** + * Sets $_virt. + * + * @param String $_virt + * + * @see Cpu::$_virt + * + * @return Void + */ + public function setVirt($virt) + { + $this->_virt = $virt; + } + + /** + * Returns $_cpuSpeed. + * + * @see Cpu::$_cpuSpeed + * + * @return Integer + */ + public function getCpuSpeed() + { + return $this->_cpuSpeed; + } + + /** + * Returns $_cpuSpeedMax. + * + * @see Cpu::$_cpuSpeedMAx + * + * @return Integer + */ + public function getCpuSpeedMax() + { + return $this->_cpuSpeedMax; + } + + /** + * Returns $_cpuSpeedMin. + * + * @see Cpu::$_cpuSpeedMin + * + * @return Integer + */ + public function getCpuSpeedMin() + { + return $this->_cpuSpeedMin; + } + + /** + * Sets $_cpuSpeed. + * + * @param Integer $cpuSpeed cpuspeed + * + * @see Cpu::$_cpuSpeed + * + * @return Void + */ + public function setCpuSpeed($cpuSpeed) + { + $this->_cpuSpeed = $cpuSpeed; + } + + /** + * Sets $_cpuSpeedMax. + * + * @param Integer $cpuSpeedMax cpuspeedmax + * + * @see Cpu::$_cpuSpeedMax + * + * @return Void + */ + public function setCpuSpeedMax($cpuSpeedMax) + { + $this->_cpuSpeedMax = $cpuSpeedMax; + } + + /** + * Sets $_cpuSpeedMin. + * + * @param Integer $cpuSpeedMin cpuspeedmin + * + * @see Cpu::$_cpuSpeedMin + * + * @return Void + */ + public function setCpuSpeedMin($cpuSpeedMin) + { + $this->_cpuSpeedMin = $cpuSpeedMin; + } + + /** + * Returns $_model. + * + * @see Cpu::$_model + * + * @return String + */ + public function getModel() + { + return $this->_model; + } + + /** + * Sets $_model. + * + * @param String $model cpumodel + * + * @see Cpu::$_model + * + * @return Void + */ + public function setModel($model) + { + $this->_model = $model; + } + + /** + * Returns $_temp. + * + * @see Cpu::$_temp + * + * @return Integer + */ + public function getTemp() + { + return $this->_temp; + } + + /** + * Sets $_temp. + * + * @param Integer $temp temperature + * + * @see Cpu::$_temp + * + * @return Void + */ + public function setTemp($temp) + { + $this->_temp = $temp; + } + + /** + * Returns $_load. + * + * @see CpuDevice::$_load + * + * @return Integer + */ + public function getLoad() + { + return $this->_load; + } + + /** + * Sets $_load. + * + * @param Integer $load load percent + * + * @see CpuDevice::$_load + * + * @return Void + */ + public function setLoad($load) + { + $this->_load = $load; + } +} diff --git a/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php new file mode 100644 index 0000000..32e5b73 --- /dev/null +++ b/root/opt/phpsysinfo/includes/to/device/class.DiskDevice.inc.php @@ -0,0 +1,308 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.DiskDevice.inc.php 252 2009-06-17 13:06:44Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * DiskDevice TO class + * + * @category PHP + * @package PSI_TO + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class DiskDevice +{ + /** + * name of the disk device + * + * @var String + */ + private $_name = ""; + + /** + * type of the filesystem on the disk device + * + * @var String + */ + private $_fsType = ""; + + /** + * diskspace that is free in bytes + * + * @var Integer + */ + private $_free = 0; + + /** + * diskspace that is used in bytes + * + * @var Integer + */ + private $_used = 0; + + /** + * total diskspace + * + * @var Integer + */ + private $_total = 0; + + /** + * mount point of the disk device if available + * + * @var String + */ + private $_mountPoint = null; + + /** + * additional options of the device, like mount options + * + * @var String + */ + private $_options = null; + + /** + * inodes usage in percent if available + * + * @var + */ + private $_percentInodesUsed = null; + + /** + * Returns PercentUsed calculated when function is called from internal values + * + * @see DiskDevice::$_total + * @see DiskDevice::$_used + * + * @return Integer + */ + public function getPercentUsed() + { + if ($this->_total > 0) { + return round($this->_used / $this->_total * 100); + } else { + return 0; + } + } + + /** + * Returns $_PercentInodesUsed. + * + * @see DiskDevice::$_PercentInodesUsed + * + * @return Integer + */ + public function getPercentInodesUsed() + { + return $this->_percentInodesUsed; + } + + /** + * Sets $_PercentInodesUsed. + * + * @param Integer $percentInodesUsed inodes percent + * + * @see DiskDevice::$_PercentInodesUsed + * + * @return Void + */ + public function setPercentInodesUsed($percentInodesUsed) + { + $this->_percentInodesUsed = $percentInodesUsed; + } + + /** + * Returns $_free. + * + * @see DiskDevice::$_free + * + * @return Integer + */ + public function getFree() + { + return $this->_free; + } + + /** + * Sets $_free. + * + * @param Integer $free free bytes + * + * @see DiskDevice::$_free + * + * @return Void + */ + public function setFree($free) + { + $this->_free = $free; + } + + /** + * Returns $_fsType. + * + * @see DiskDevice::$_fsType + * + * @return String + */ + public function getFsType() + { + return $this->_fsType; + } + + /** + * Sets $_fsType. + * + * @param String $fsType filesystemtype + * + * @see DiskDevice::$_fsType + * + * @return Void + */ + public function setFsType($fsType) + { + $this->_fsType = $fsType; + } + + /** + * Returns $_mountPoint. + * + * @see DiskDevice::$_mountPoint + * + * @return String + */ + public function getMountPoint() + { + return $this->_mountPoint; + } + + /** + * Sets $_mountPoint. + * + * @param String $mountPoint mountpoint + * + * @see DiskDevice::$_mountPoint + * + * @return Void + */ + public function setMountPoint($mountPoint) + { + $this->_mountPoint = $mountPoint; + } + + /** + * Returns $_name. + * + * @see DiskDevice::$_name + * + * @return String + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets $_name. + * + * @param String $name device name + * + * @see DiskDevice::$_name + * + * @return Void + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Returns $_options. + * + * @see DiskDevice::$_options + * + * @return String + */ + public function getOptions() + { + return $this->_options; + } + + /** + * Sets $_options. + * + * @param String $options additional options + * + * @see DiskDevice::$_options + * + * @return Void + */ + public function setOptions($options) + { + $this->_options = $options; + } + + /** + * Returns $_total. + * + * @see DiskDevice::$_total + * + * @return Integer + */ + public function getTotal() + { + return $this->_total; + } + + /** + * Sets $_total. + * + * @param Integer $total total bytes + * + * @see DiskDevice::$_total + * + * @return Void + */ + public function setTotal($total) + { + $this->_total = $total; + } + + /** + * Returns $_used. + * + * @see DiskDevice::$_used + * + * @return Integer + */ + public function getUsed() + { + return $this->_used; + } + + /** + * Sets $_used. + * + * @param Integer $used used bytes + * + * @see DiskDevice::$_used + * + * @return Void + */ + public function setUsed($used) + { + $this->_used = $used; + } +} diff --git a/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php new file mode 100644 index 0000000..3a2b0f1 --- /dev/null +++ b/root/opt/phpsysinfo/includes/to/device/class.HWDevice.inc.php @@ -0,0 +1,142 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.HWDevice.inc.php 255 2009-06-17 13:39:41Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * HWDevice TO class + * + * @category PHP + * @package PSI_TO + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class HWDevice +{ + /** + * name of the device + * + * @var String + */ + private $_name = ""; + + /** + * capacity of the device, if not available it will be null + * + * @var Integer + */ + private $_capacity = null; + + /** + * count of the device + * + * @var Integer + */ + private $_count = 1; + + /** + * compare a given device with the internal one + * + * @param HWDevice $dev device that should be compared + * + * @return boolean + */ + public function equals(HWDevice $dev) + { + if ($dev->getName() === $this->_name && $dev->getCapacity() === $this->_capacity) { + return true; + } else { + return false; + } + } + + /** + * Returns $_capacity. + * + * @see HWDevice::$_capacity + * + * @return Integer + */ + public function getCapacity() + { + return $this->_capacity; + } + + /** + * Sets $_capacity. + * + * @param Integer $capacity device capacity + * + * @see HWDevice::$_capacity + * + * @return Void + */ + public function setCapacity($capacity) + { + $this->_capacity = $capacity; + } + + /** + * Returns $_name. + * + * @see HWDevice::$_name + * + * @return String + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets $_name. + * + * @param String $name device name + * + * @see HWDevice::$_name + * + * @return Void + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Returns $_count. + * + * @see HWDevice::$_count + * + * @return Integer + */ + public function getCount() + { + return $this->_count; + } + + /** + * Sets $_count. + * + * @param Integer $count device count + * + * @see HWDevice::$_count + * + * @return Void + */ + public function setCount($count) + { + $this->_count = $count; + } +} diff --git a/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php new file mode 100644 index 0000000..6f8d3b9 --- /dev/null +++ b/root/opt/phpsysinfo/includes/to/device/class.NetDevice.inc.php @@ -0,0 +1,225 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.NetDevice.inc.php 547 2012-03-22 09:44:38Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * NetDevice TO class + * + * @category PHP + * @package PSI_TO + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class NetDevice +{ + /** + * name of the device + * + * @var String + */ + private $_name = ""; + + /** + * transmitted bytes + * + * @var Integer + */ + private $_txBytes = 0; + + /** + * received bytes + * + * @var Integer + */ + private $_rxBytes = 0; + + /** + * counted error packages + * + * @var Integer + */ + private $_errors = 0; + + /** + * counted droped packages + * + * @var Integer + */ + private $_drops = 0; + + /** + * string with info + * + * @var String + */ + private $_info = null; + + /** + * Returns $_drops. + * + * @see NetDevice::$_drops + * + * @return Integer + */ + public function getDrops() + { + return $this->_drops; + } + + /** + * Sets $_drops. + * + * @param Integer $drops dropped packages + * + * @see NetDevice::$_drops + * + * @return Void + */ + public function setDrops($drops) + { + $this->_drops = $drops; + } + + /** + * Returns $_errors. + * + * @see NetDevice::$_errors + * + * @return Integer + */ + public function getErrors() + { + return $this->_errors; + } + + /** + * Sets $_errors. + * + * @param Integer $errors error packages + * + * @see NetDevice::$_errors + * + * @return Void + */ + public function setErrors($errors) + { + $this->_errors = $errors; + } + + /** + * Returns $_name. + * + * @see NetDevice::$_name + * + * @return String + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets $_name. + * + * @param String $name device name + * + * @see NetDevice::$_name + * + * @return Void + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Returns $_rxBytes. + * + * @see NetDevice::$_rxBytes + * + * @return Integer + */ + public function getRxBytes() + { + return $this->_rxBytes; + } + + /** + * Sets $_rxBytes. + * + * @param Integer $rxBytes received bytes + * + * @see NetDevice::$_rxBytes + * + * @return Void + */ + public function setRxBytes($rxBytes) + { + $this->_rxBytes = $rxBytes; + } + + /** + * Returns $_txBytes. + * + * @see NetDevice::$_txBytes + * + * @return Integer + */ + public function getTxBytes() + { + return $this->_txBytes; + } + + /** + * Sets $_txBytes. + * + * @param Integer $txBytes transmitted bytes + * + * @see NetDevice::$_txBytes + * + * @return Void + */ + public function setTxBytes($txBytes) + { + $this->_txBytes = $txBytes; + } + + /** + * Returns $_info. + * + * @see NetDevice::$_info + * + * @return String + */ + public function getInfo() + { + return $this->_info; + } + + /** + * Sets $_info. + * + * @param String $info info string + * + * @see NetDevice::$_info + * + * @return Void + */ + public function setInfo($info) + { + $this->_info = $info; + } +} diff --git a/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php new file mode 100644 index 0000000..65c2f6c --- /dev/null +++ b/root/opt/phpsysinfo/includes/to/device/class.SensorDevice.inc.php @@ -0,0 +1,192 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.SensorDevice.inc.php 592 2012-07-03 10:55:51Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * SensorDevice TO class + * + * @category PHP + * @package PSI_TO + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class SensorDevice +{ + /** + * name of the sensor + * + * @var String + */ + private $_name = ""; + + /** + * current value of the sensor + * + * @var Integer + */ + private $_value = 0; + + /** + * maximum value of the sensor + * + * @var Integer + */ + private $_max = null; + + /** + * minimum value of the sensor + * + * @var Integer + */ + private $_min = null; + + /** + * event of the sensor + * + * @var String + */ + private $_event = ""; + + /** + * Returns $_max. + * + * @see Sensor::$_max + * + * @return Integer + */ + public function getMax() + { + return $this->_max; + } + + /** + * Sets $_max. + * + * @param Integer $max maximum value + * + * @see Sensor::$_max + * + * @return Void + */ + public function setMax($max) + { + $this->_max = $max; + } + + /** + * Returns $_min. + * + * @see Sensor::$_min + * + * @return Integer + */ + public function getMin() + { + return $this->_min; + } + + /** + * Sets $_min. + * + * @param Integer $min minimum value + * + * @see Sensor::$_min + * + * @return Void + */ + public function setMin($min) + { + $this->_min = $min; + } + + /** + * Returns $_name. + * + * @see Sensor::$_name + * + * @return String + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets $_name. + * + * @param String $name sensor name + * + * @see Sensor::$_name + * + * @return Void + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Returns $_value. + * + * @see Sensor::$_value + * + * @return Integer + */ + public function getValue() + { + return $this->_value; + } + + /** + * Sets $_value. + * + * @param Integer $value current value + * + * @see Sensor::$_value + * + * @return Void + */ + public function setValue($value) + { + $this->_value = $value; + } + + /** + * Returns $_event. + * + * @see Sensor::$_event + * + * @return String + */ + public function getEvent() + { + return $this->_event; + } + + /** + * Sets $_event. + * + * @param String $event sensor event + * + * @see Sensor::$_event + * + * @return Void + */ + public function setEvent($event) + { + $this->_event = $event; + } +} diff --git a/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php b/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php new file mode 100644 index 0000000..f72e30a --- /dev/null +++ b/root/opt/phpsysinfo/includes/to/device/class.UPSDevice.inc.php @@ -0,0 +1,555 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.UPSDevice.inc.php 262 2009-06-22 10:48:33Z bigmichi1 $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * UPSDevice TO class + * + * @category PHP + * @package PSI_TO + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class UPSDevice +{ + /** + * name of the ups + * + * @var String + */ + private $_name = ""; + + /** + * model of the ups + * + * @var String + */ + private $_model = ""; + + /** + * mode of the ups + * + * @var String + */ + private $_mode = ""; + + /** + * last start time + * + * @var String + */ + private $_startTime = ""; + + /** + * status of the ups + * + * @var String + */ + private $_status = ""; + + /** + * temperature of the ups + * + * @var Integer + */ + private $_temperatur = null; + + /** + * outages count + * + * @var Integer + */ + private $_outages = null; + + /** + * date of last outtage + * + * @var String + */ + private $_lastOutage = null; + + /** + * date of last outage finish + * + * @var String + */ + private $_lastOutageFinish = null; + + /** + * line volt + * + * @var Integer + */ + private $_lineVoltage = null; + + /** + * line freq + * + * @var Integer + */ + private $_lineFrequency = null; + + /** + * current load of the ups in percent + * + * @var Integer + */ + private $_load = null; + + /** + * battery installation date + * + * @var String + */ + private $_batteryDate = null; + + /** + * current battery volt + * + * @var Integer + */ + private $_batteryVoltage = null; + + /** + * current charge in percent of the battery + * + * @var Integer + */ + private $_batterCharge = null; + + /** + * time left + * + * @var String + */ + private $_timeLeft = null; + + /** + * Returns $_batterCharge. + * + * @see UPSDevice::$_batterCharge + * + * @return integer + */ + public function getBatterCharge() + { + return $this->_batterCharge; + } + + /** + * Sets $_batterCharge. + * + * @param Integer $batterCharge battery charge + * + * @see UPSDevice::$_batterCharge + * + * @return void + */ + public function setBatterCharge($batterCharge) + { + $this->_batterCharge = $batterCharge; + } + + /** + * Returns $_batteryDate. + * + * @see UPSDevice::$_batteryDate + * + * @return String + */ + public function getBatteryDate() + { + return $this->_batteryDate; + } + + /** + * Sets $_batteryDate. + * + * @param object $batteryDate battery date + * + * @see UPSDevice::$_batteryDate + * + * @return Void + */ + public function setBatteryDate($batteryDate) + { + $this->_batteryDate = $batteryDate; + } + + /** + * Returns $_batteryVoltage. + * + * @see UPSDevice::$_batteryVoltage + * + * @return Integer + */ + public function getBatteryVoltage() + { + return $this->_batteryVoltage; + } + + /** + * Sets $_batteryVoltage. + * + * @param object $batteryVoltage battery volt + * + * @see UPSDevice::$_batteryVoltage + * + * @return Void + */ + public function setBatteryVoltage($batteryVoltage) + { + $this->_batteryVoltage = $batteryVoltage; + } + + /** + * Returns $_lastOutage. + * + * @see UPSDevice::$_lastOutage + * + * @return String + */ + public function getLastOutage() + { + return $this->_lastOutage; + } + + /** + * Sets $_lastOutage. + * + * @param String $lastOutage last Outage + * + * @see UPSDevice::$lastOutage + * + * @return Void + */ + public function setLastOutage($lastOutage) + { + $this->_lastOutage = $lastOutage; + } + + /** + * Returns $_lastOutageFinish. + * + * @see UPSDevice::$_lastOutageFinish + * + * @return String + */ + public function getLastOutageFinish() + { + return $this->_lastOutageFinish; + } + + /** + * Sets $_lastOutageFinish. + * + * @param String $lastOutageFinish last outage finish + * + * @see UPSDevice::$_lastOutageFinish + * + * @return Void + */ + public function setLastOutageFinish($lastOutageFinish) + { + $this->_lastOutageFinish = $lastOutageFinish; + } + + /** + * Returns $_lineVoltage. + * + * @see UPSDevice::$_lineVoltage + * + * @return Integer + */ + public function getLineVoltage() + { + return $this->_lineVoltage; + } + + /** + * Sets $_lineVoltage. + * + * @param Integer $lineVoltage line voltage + * + * @see UPSDevice::$_lineVoltage + * + * @return Void + */ + public function setLineVoltage($lineVoltage) + { + $this->_lineVoltage = $lineVoltage; + } + + /** + * Returns $_lineFrequency. + * + * @see UPSDevice::$_lineFrequency + * + * @return Integer + */ + public function getLineFrequency() + { + return $this->_lineFrequency; + } + + /** + * Sets $_lineFrequency. + * + * @param Integer $lineFrequency line frequency + * + * @see UPSDevice::$_lineFrequency + * + * @return Void + */ + public function setLineFrequency($lineFrequency) + { + $this->_lineFrequency = $lineFrequency; + } + + /** + * Returns $_load. + * + * @see UPSDevice::$_load + * + * @return Integer + */ + public function getLoad() + { + return $this->_load; + } + + /** + * Sets $_load. + * + * @param Integer $load current load + * + * @see UPSDevice::$_load + * + * @return Void + */ + public function setLoad($load) + { + $this->_load = $load; + } + + /** + * Returns $_mode. + * + * @see UPSDevice::$_mode + * + * @return String + */ + public function getMode() + { + return $this->_mode; + } + + /** + * Sets $_mode. + * + * @param String $mode mode + * + * @see UPSDevice::$_mode + * + * @return Void + */ + public function setMode($mode) + { + $this->_mode = $mode; + } + + /** + * Returns $_model. + * + * @see UPSDevice::$_model + * + * @return String + */ + public function getModel() + { + return $this->_model; + } + + /** + * Sets $_model. + * + * @param String $model model + * + * @see UPSDevice::$_model + * + * @return Void + */ + public function setModel($model) + { + $this->_model = $model; + } + + /** + * Returns $_name. + * + * @see UPSDevice::$_name + * + * @return String + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets $_name. + * + * @param String $name name + * + * @see UPSDevice::$_name + * + * @return Void + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Returns $_outages. + * + * @see UPSDevice::$_outages + * + * @return Integer + */ + public function getOutages() + { + return $this->_outages; + } + + /** + * Sets $_outages. + * + * @param Integer $outages outages count + * + * @see UPSDevice::$_outages + * + * @return Void + */ + public function setOutages($outages) + { + $this->_outages = $outages; + } + + /** + * Returns $_startTime. + * + * @see UPSDevice::$_startTime + * + * @return String + */ + public function getStartTime() + { + return $this->_startTime; + } + + /** + * Sets $_startTime. + * + * @param String $startTime startTime + * + * @see UPSDevice::$_startTime + * + * @return Void + */ + public function setStartTime($startTime) + { + $this->_startTime = $startTime; + } + + /** + * Returns $_status. + * + * @see UPSDevice::$_status + * + * @return String + */ + public function getStatus() + { + return $this->_status; + } + + /** + * Sets $_status. + * + * @param String $status status + * + * @see UPSDevice::$_status + * + * @return Void + */ + public function setStatus($status) + { + $this->_status = $status; + } + + /** + * Returns $_temperatur. + * + * @see UPSDevice::$_temperatur + * + * @return Integer + */ + public function getTemperatur() + { + return $this->_temperatur; + } + + /** + * Sets $_temperatur. + * + * @param Integer $temperatur temperature + * + * @see UPSDevice::$_temperatur + * + * @return Void + */ + public function setTemperatur($temperatur) + { + $this->_temperatur = $temperatur; + } + + /** + * Returns $_timeLeft. + * + * @see UPSDevice::$_timeLeft + * + * @return String + */ + public function getTimeLeft() + { + return $this->_timeLeft; + } + + /** + * Sets $_timeLeft. + * + * @param String $timeLeft time left + * + * @see UPSDevice::$_timeLeft + * + * @return Void + */ + public function setTimeLeft($timeLeft) + { + $this->_timeLeft = $timeLeft; + } +} diff --git a/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php b/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php new file mode 100644 index 0000000..0a0744a --- /dev/null +++ b/root/opt/phpsysinfo/includes/ups/class.apcupsd.inc.php @@ -0,0 +1,145 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.apcupsd.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting ups information from apcupsd program + * + * @category PHP + * @package PSI_UPS + * @author Michael Cramer + * @author Artem Volk + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Apcupsd extends UPS +{ + /** + * internal storage for all gathered data + * + * @var Array + */ + private $_output = array(); + + /** + * get all information from all configured ups in phpsysinfo.ini and store output in internal array + */ + public function __construct() + { + parent::__construct(); + if (defined('PSI_UPS_APCUPSD_LIST') && is_string(PSI_UPS_APCUPSD_LIST)) { + if (preg_match(ARRAY_EXP, PSI_UPS_APCUPSD_LIST)) { + $upses = eval(PSI_UPS_APCUPSD_LIST); + } else { + $upses = array(PSI_UPS_APCUPSD_LIST); + } + foreach ($upses as $ups) { + CommonFunctions::executeProgram('apcaccess', 'status '.trim($ups), $temp); + if (! empty($temp)) { + $this->_output[] = $temp; + } + } + } else { //use default if address and port not defined + CommonFunctions::executeProgram('apcaccess', 'status', $temp); + if (! empty($temp)) { + $this->_output[] = $temp; + } + } + } + + /** + * parse the input and store data in resultset for xml generation + * + * @return Void + */ + private function _info() + { + foreach ($this->_output as $ups) { + + $dev = new UPSDevice(); + + // General info + if (preg_match('/^UPSNAME\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setName(trim($data[1])); + } + if (preg_match('/^MODEL\s*:\s*(.*)$/m', $ups, $data)) { + $model=trim($data[1]); + if (preg_match('/^APCMODEL\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setModel($model.' ('.trim($data[1]).')'); + } else { + $dev->setModel($model); + } + } + if (preg_match('/^UPSMODE\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setMode(trim($data[1])); + } + if (preg_match('/^STARTTIME\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setStartTime(trim($data[1])); + } + if (preg_match('/^STATUS\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setStatus(trim($data[1])); + } + if (preg_match('/^ITEMP\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setTemperatur(trim($data[1])); + } + // Outages + if (preg_match('/^NUMXFERS\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setOutages(trim($data[1])); + } + if (preg_match('/^LASTXFER\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setLastOutage(trim($data[1])); + } + if (preg_match('/^XOFFBATT\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setLastOutageFinish(trim($data[1])); + } + // Line + if (preg_match('/^LINEV\s*:\s*(\d*\.\d*)(.*)$/m', $ups, $data)) { + $dev->setLineVoltage(trim($data[1])); + } + if (preg_match('/^LINEFREQ\s*:\s*(\d*\.\d*)(.*)$/m', $ups, $data)) { + $dev->setLineFrequency(trim($data[1])); + } + if (preg_match('/^LOADPCT\s*:\s*(\d*\.\d*)(.*)$/m', $ups, $data)) { + $dev->setLoad(trim($data[1])); + } + // Battery + if (preg_match('/^BATTDATE\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setBatteryDate(trim($data[1])); + } + if (preg_match('/^BATTV\s*:\s*(\d*\.\d*)(.*)$/m', $ups, $data)) { + $dev->setBatteryVoltage(trim($data[1])); + } + if (preg_match('/^BCHARGE\s*:\s*(\d*\.\d*)(.*)$/m', $ups, $data)) { + $dev->setBatterCharge(trim($data[1])); + } + if (preg_match('/^TIMELEFT\s*:\s*(\d*\.\d*)(.*)$/m', $ups, $data)) { + $dev->setTimeLeft(trim($data[1])); + } + $this->upsinfo->setUpsDevices($dev); + } + } + + /** + * get the information + * + * @see PSI_Interface_UPS::build() + * + * @return Void + */ + public function build() + { + $this->_info(); + } +} diff --git a/root/opt/phpsysinfo/includes/ups/class.nut.inc.php b/root/opt/phpsysinfo/includes/ups/class.nut.inc.php new file mode 100644 index 0000000..b9b86a9 --- /dev/null +++ b/root/opt/phpsysinfo/includes/ups/class.nut.inc.php @@ -0,0 +1,142 @@ + + * @author Anders Häggström + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.nut.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting ups information from upsc program + * + * @category PHP + * @package PSI_UPS + * @author Artem Volk + * @author Anders Häggström + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Nut extends UPS +{ + /** + * internal storage for all gathered data + * + * @var array + */ + private $_output = array(); + + /** + * get all information from all configured ups and store output in internal array + */ + public function __construct() + { + parent::__construct(); + if (defined('PSI_UPS_NUT_LIST') && is_string(PSI_UPS_NUT_LIST)) { + if (preg_match(ARRAY_EXP, PSI_UPS_NUT_LIST)) { + $upses = eval(PSI_UPS_NUT_LIST); + } else { + $upses = array(PSI_UPS_NUT_LIST); + } + foreach ($upses as $ups) { + CommonFunctions::executeProgram('upsc', '-l '.trim($ups), $output); + $ups_names = preg_split("/\n/", $output, -1, PREG_SPLIT_NO_EMPTY); + foreach ($ups_names as $ups_name) { + CommonFunctions::executeProgram('upsc', trim($ups_name).'@'.trim($ups), $temp); + if (! empty($temp)) { + $this->_output[trim($ups_name).'@'.trim($ups)] = $temp; + } + } + } + } else { //use default if address and port not defined + CommonFunctions::executeProgram('upsc', '-l', $output); + $ups_names = preg_split("/\n/", $output, -1, PREG_SPLIT_NO_EMPTY); + foreach ($ups_names as $ups_name) { + CommonFunctions::executeProgram('upsc', trim($ups_name), $temp); + if (! empty($temp)) { + $this->_output[trim($ups_name)] = $temp; + } + } + } + } + + /** + * parse the input and store data in resultset for xml generation + * + * @return array + */ + private function _info() + { + if (! empty($this->_output)) { + foreach ($this->_output as $name=>$value) { + $temp = preg_split("/\n/", $value, -1, PREG_SPLIT_NO_EMPTY); + $ups_data = array(); + foreach ($temp as $value) { + $line = preg_split('/: /', $value, 2); + $ups_data[$line[0]] = isset($line[1]) ? trim($line[1]) : ''; + } + $dev = new UPSDevice(); + //General + $dev->setName($name); + if (isset($ups_data['ups.model'])) { + $dev->setModel($ups_data['ups.model']); + } + if (isset($ups_data['driver.name'])) { + $dev->setMode($ups_data['driver.name']); + } + if (isset($ups_data['ups.status'])) { + $dev->setStatus($ups_data['ups.status']); + } + + //Line + if (isset($ups_data['input.voltage'])) { + $dev->setLineVoltage($ups_data['input.voltage']); + } + if (isset($ups_data['input.frequency'])) { + $dev->setLineFrequency($ups_data['input.frequency']); + } + if (isset($ups_data['ups.load'])) { + $dev->setLoad($ups_data['ups.load']); + } + + //Battery + if (isset($ups_data['battery.voltage'])) { + $dev->setBatteryVoltage($ups_data['battery.voltage']); + } + if (isset($ups_data['battery.charge'])) { + $dev->setBatterCharge($ups_data['battery.charge']); + } + if (isset($ups_data['battery.runtime'])) { + $dev->setTimeLeft(round($ups_data['battery.runtime']/60, 2)); + } + + //Temperature + if (isset($ups_data['ups.temperature'])) { + $dev->setTemperatur($ups_data['ups.temperature']); + } + + $this->upsinfo->setUpsDevices($dev); + } + } + } + + /** + * get the information + * + * @see PSI_Interface_UPS::build() + * + * @return Void + */ + public function build() + { + $this->_info(); + } +} diff --git a/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php b/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php new file mode 100644 index 0000000..b334eb9 --- /dev/null +++ b/root/opt/phpsysinfo/includes/ups/class.pmset.inc.php @@ -0,0 +1,90 @@ + + * @copyright 2014 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.nut.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * getting ups information from pmset program + * + * @category PHP + * @package PSI_UPS + * @author Robert Pelletier + * @copyright 2014 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class Pmset extends UPS +{ + /** + * internal storage for all gathered data + * + * @var array + */ + private $_output = array(); + + /** + * get all information from all configured ups and store output in internal array + */ + public function __construct() + { + parent::__construct(); + CommonFunctions::executeProgram('pmset', '-g batt', $temp); + if (! empty($temp)) { + $this->_output[] = $temp; + } + } + + /** + * parse the input and store data in resultset for xml generation + * + * @return array + */ + private function _info() + { + $model = array(); + $percCharge = array(); + $lines = explode(PHP_EOL, implode($this->_output)); + $dev = new UPSDevice(); + $model = explode('FW:', $lines[1]); + if (strpos($model[0], 'InternalBattery') === false) { + $percCharge = explode(';', $lines[1]); + $dev->setName('UPS'); + if ($model !== false) { + $dev->setModel(substr(trim($model[0]), 1)); + } + if ($percCharge !== false) { + $dev->setBatterCharge(trim(substr($percCharge[0], -4, 3))); + $dev->setStatus(trim($percCharge[1])); + if (isset($percCharge[2])) { + $time = explode(':', $percCharge[2]); + $hours = $time[0]; + $minutes = $hours*60+substr($time[1], 0, 2); + $dev->setTimeLeft($minutes); + } + } + $this->upsinfo->setUpsDevices($dev); + } + } + + /** + * get the information + * + * @see PSI_Interface_UPS::build() + * + * @return Void + */ + public function build() + { + $this->_info(); + } +} diff --git a/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php b/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php new file mode 100644 index 0000000..b43ac34 --- /dev/null +++ b/root/opt/phpsysinfo/includes/ups/class.powersoftplus.inc.php @@ -0,0 +1,115 @@ + + * @copyright 2014 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.powersoftplus.inc.php 661 2014-06-13 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net +*/ +/** + * getting ups information from powersoftplus program + * + * @category PHP + * @package PSI_UPS + * @author Mieczyslaw Nalewaj + * @copyright 2014 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net +*/ +class PowerSoftPlus extends UPS +{ + /** + * internal storage for all gathered data + * + * @var Array + */ + private $_output = array(); + + /** + * get all information from all configured ups in phpsysinfo.ini and store output in internal array + */ + public function __construct() + { + parent::__construct(); + CommonFunctions::executeProgram('powersoftplus', '-p', $temp); + if (! empty($temp)) { + $this->_output[] = $temp; + } + } + + /** + * parse the input and store data in resultset for xml generation + * + * @return Void + */ + private function _info() + { + foreach ($this->_output as $ups) { + + $dev = new UPSDevice(); + + // General info + $dev->setName("EVER"); + $dev->setMode("PowerSoftPlus"); + $maxpwr = 0; + $load = null; + if (preg_match('/^Identifier: UPS Model\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setModel(trim($data[1])); + if (preg_match('/\s(\d*)[^\d]*$/', trim($data[1]), $number)) { + $maxpwr=$number[1]*0.65; + } + } + if (preg_match('/^Current UPS state\s*:\s*(.*)$/m', $ups, $data)) { + $dev->setStatus(trim($data[1])); + } + if (preg_match('/^Output load\s*:\s*(.*)\s\[\%\]$/m', $ups, $data)) { + $load = trim($data[1]); + } + //wrong Output load issue + if (($load == 0) && ($maxpwr != 0) && preg_match('/^Effective power\s*:\s*(.*)\s\[W\]$/m', $ups, $data)) { + $load = 100.0*trim($data[1])/$maxpwr; + } + if ($load != null) { + $dev->setLoad($load); + } + // Battery + if (preg_match('/^Battery voltage\s*:\s*(.*)\s\[Volt\]$/m', $ups, $data)) { + $dev->setBatteryVoltage(trim($data[1])); + } + if (preg_match('/^Battery state\s*:\s*(.*)$/m', $ups, $data)) { + if (preg_match('/^At full capacity$/', trim($data[1]))) { + $dev->setBatterCharge(100); + } elseif (preg_match('/^(Discharged)|(Depleted)$/', trim($data[1]))) { + $dev->setBatterCharge(0); + } + } + // Line + if (preg_match('/^Input voltage\s*:\s*(.*)\s\[Volt\]$/m', $ups, $data)) { + $dev->setLineVoltage(trim($data[1])); + } + if (preg_match('/^Input frequency\s*:\s*(.*)\s\[Hz\]$/m', $ups, $data)) { + $dev->setLineFrequency(trim($data[1])); + } + $this->upsinfo->setUpsDevices($dev); + } + } + + /** + * get the information + * + * @see PSI_Interface_UPS::build() + * + * @return Void + */ + public function build() + { + $this->_info(); + } +} diff --git a/root/opt/phpsysinfo/includes/ups/class.ups.inc.php b/root/opt/phpsysinfo/includes/ups/class.ups.inc.php new file mode 100644 index 0000000..c0970b4 --- /dev/null +++ b/root/opt/phpsysinfo/includes/ups/class.ups.inc.php @@ -0,0 +1,64 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.ups.inc.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * Basic UPS functions for all UPS classes + * + * @category PHP + * @package PSI_UPS + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +abstract class UPS implements PSI_Interface_UPS +{ + /** + * object for error handling + * + * @var Error + */ + protected $error; + + /** + * main object for ups information + * + * @var UPSInfo + */ + protected $upsinfo; + + /** + * build the global Error object + */ + public function __construct() + { + $this->error = Error::singleton(); + $this->upsinfo = new UPSInfo(); + } + + /** + * build and return the ups information + * + * @see PSI_Interface_UPS::getUPSInfo() + * + * @return UPSInfo + */ + final public function getUPSInfo() + { + $this->build(); + + return $this->upsinfo; + } +} diff --git a/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php b/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php new file mode 100644 index 0000000..a05ff2c --- /dev/null +++ b/root/opt/phpsysinfo/includes/xml/class.SimpleXMLExtended.inc.php @@ -0,0 +1,212 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.SimpleXMLExtended.inc.php 610 2012-07-11 19:12:12Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * class extends the SimpleXML element for including some special functions, like encoding stuff and cdata support + * + * @category PHP + * @package PSI_XML + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class SimpleXMLExtended +{ + /** + * store the encoding that is used for conversation to utf8 + * + * @var String base encoding + */ + private $_encoding = null; + + /** + * SimpleXMLElement to which every call is delegated + * + * @var SimpleXMLElement delegated SimpleXMLElement + */ + private $_SimpleXmlElement = null; + + /** + * _CP437toUTF8Table for code page conversion for CP437 + * + * @var _CP437toUTF8Table array + */ + private static $_CP437toUTF8Table = array( + "\xC3\x87","\xC3\xBC","\xC3\xA9","\xC3\xA2", + "\xC3\xA4","\xC3\xA0","\xC3\xA5","\xC3\xA7", + "\xC3\xAA","\xC3\xAB","\xC3\xA8","\xC3\xAF", + "\xC3\xAE","\xC3\xAC","\xC3\x84","\xC3\x85", + "\xC3\x89","\xC3\xA6","\xC3\x86","\xC3\xB4", + "\xC3\xB6","\xC3\xB2","\xC3\xBB","\xC3\xB9", + "\xC3\xBF","\xC3\x96","\xC3\x9C","\xC3\xA2", + "\xC2\xA3","\xC3\xA5","\xE2\x82\xA7","\xC6\x92", + "\xC3\xA1","\xC3\xAD","\xC3\xB3","\xC3\xBA", + "\xC3\xB1","\xC3\x91","\xC2\xAA","\xC2\xBA", + "\xC2\xBF","\xE2\x8C\x90","\xC2\xAC","\xC2\xBD", + "\xC2\xBC","\xC2\xA1","\xC2\xAB","\xC2\xBB", + "\xE2\x96\x91","\xE2\x96\x92","\xE2\x96\x93","\xE2\x94\x82", + "\xE2\x94\xA4","\xE2\x95\xA1","\xE2\x95\xA2","\xE2\x95\x96", + "\xE2\x95\x95","\xE2\x95\xA3","\xE2\x95\x91","\xE2\x95\x97", + "\xE2\x95\x9D","\xE2\x95\x9C","\xE2\x95\x9B","\xE2\x94\x90", + "\xE2\x94\x94","\xE2\x94\xB4","\xE2\x94\xAC","\xE2\x94\x9C", + "\xE2\x94\x80","\xE2\x94\xBC","\xE2\x95\x9E","\xE2\x95\x9F", + "\xE2\x95\x9A","\xE2\x95\x94","\xE2\x95\xA9","\xE2\x95\xA6", + "\xE2\x95\xA0","\xE2\x95\x90","\xE2\x95\xAC","\xE2\x95\xA7", + "\xE2\x95\xA8","\xE2\x95\xA4","\xE2\x95\xA5","\xE2\x95\x99", + "\xE2\x95\x98","\xE2\x95\x92","\xE2\x95\x93","\xE2\x95\xAB", + "\xE2\x95\xAA","\xE2\x94\x98","\xE2\x94\x8C","\xE2\x96\x88", + "\xE2\x96\x84","\xE2\x96\x8C","\xE2\x96\x90","\xE2\x96\x80", + "\xCE\xB1","\xC3\x9F","\xCE\x93","\xCF\x80", + "\xCE\xA3","\xCF\x83","\xC2\xB5","\xCF\x84", + "\xCE\xA6","\xCE\x98","\xCE\xA9","\xCE\xB4", + "\xE2\x88\x9E","\xCF\x86","\xCE\xB5","\xE2\x88\xA9", + "\xE2\x89\xA1","\xC2\xB1","\xE2\x89\xA5","\xE2\x89\xA4", + "\xE2\x8C\xA0","\xE2\x8C\xA1","\xC3\xB7","\xE2\x89\x88", + "\xC2\xB0","\xE2\x88\x99","\xC2\xB7","\xE2\x88\x9A", + "\xE2\x81\xBF","\xC2\xB2","\xE2\x96\xA0","\xC2\xA0"); + + /** + * create a new extended SimpleXMLElement and set encoding if specified + * + * @param SimpleXMLElement $xml base xml element + * @param String $encoding base encoding that should be used for conversation to utf8 + * + * @return void + */ + public function __construct($xml, $encoding = null) + { + if ($encoding != null) { + $this->_encoding = $encoding; + } + $this->_SimpleXmlElement = $xml; + } + + /** + * insert a child element with or without a value, also doing conversation of name and if value is set to utf8 + * + * @param String $name name of the child element + * @param String $value a value that should be insert to the child + * + * @return SimpleXMLExtended extended child SimpleXMLElement + */ + public function addChild($name, $value = null) + { + $nameUtf8 = $this->_toUTF8($name); + if ($value == null) { + return new SimpleXMLExtended($this->_SimpleXmlElement->addChild($nameUtf8), $this->_encoding); + } else { + $valueUtf8 = htmlspecialchars($this->_toUTF8($value)); + + return new SimpleXMLExtended($this->_SimpleXmlElement->addChild($nameUtf8, $valueUtf8), $this->_encoding); + } + } + + /** + * insert a child with cdata section + * + * @param String $name name of the child element + * @param String $cdata data for CDATA section + * + * @return SimpleXMLExtended extended child SimpleXMLElement + */ + public function addCData($name, $cdata) + { + $nameUtf8 = $this->_toUTF8($name); + $node = $this->_SimpleXmlElement->addChild($nameUtf8); + $domnode = dom_import_simplexml($node); + $no = $domnode->ownerDocument; + $domnode->appendChild($no->createCDATASection($cdata)); + + return new SimpleXMLExtended($node, $this->_encoding); + } + + /** + * add a attribute to a child and convert name and value to utf8 + * + * @param String $name name of the attribute + * @param String $value value of the attribute + * + * @return Void + */ + public function addAttribute($name, $value) + { + $nameUtf8 = $this->_toUTF8($name); + $valueUtf8 = htmlspecialchars($this->_toUTF8($value)); + $this->_SimpleXmlElement->addAttribute($nameUtf8, $valueUtf8); + } + + /** + * append a xml-tree to another xml-tree + * + * @param SimpleXMLElement $new_child child that should be appended + * + * @return Void + */ + public function combinexml(SimpleXMLElement $new_child) + { + $node1 = dom_import_simplexml($this->_SimpleXmlElement); + $dom_sxe = dom_import_simplexml($new_child); + $node2 = $node1->ownerDocument->importNode($dom_sxe, true); + $node1->appendChild($node2); + } + + /** + * convert a string into an UTF-8 string + * + * @param String $str string to convert + * + * @return String UTF-8 string + */ + private function _toUTF8($str) + { + if ($this->_encoding != null) { + if (strcasecmp($this->_encoding, "UTF-8") == 0) { + return trim($str); + } elseif (strcasecmp($this->_encoding, "CP437") == 0) { + $str = trim($str); + $strr = ""; + if (($strl = strlen($str)) > 0) for ($i = 0; $i < $strl; $i++) { + $strc = substr($str, $i, 1); + if ($strc < 128) $strr.=$strc; + else $strr.=$_CP437toUTF8Table[$strc-128]; + } + + return $strr; + } else { + $enclist = mb_list_encodings(); + if (in_array($this->_encoding, $enclist)) { + return mb_convert_encoding(trim($str), 'UTF-8', $this->_encoding); + } elseif (function_exists("iconv")) { + return iconv($this->_encoding, 'UTF-8', trim($str)); + } else { + return mb_convert_encoding(trim($str), 'UTF-8'); + } + } + } else { + return mb_convert_encoding(trim($str), 'UTF-8'); + } + } + + /** + * Returns the SimpleXmlElement + * + * @return SimpleXmlElement entire xml as SimpleXmlElement + */ + public function getSimpleXmlElement() + { + return $this->_SimpleXmlElement; + } +} diff --git a/root/opt/phpsysinfo/includes/xml/class.XML.inc.php b/root/opt/phpsysinfo/includes/xml/class.XML.inc.php new file mode 100644 index 0000000..b46330a --- /dev/null +++ b/root/opt/phpsysinfo/includes/xml/class.XML.inc.php @@ -0,0 +1,742 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: class.XML.inc.php 699 2012-09-15 11:57:13Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ + /** + * class for generation of the xml + * + * @category PHP + * @package PSI_XML + * @author Michael Cramer + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version Release: 3.0 + * @link http://phpsysinfo.sourceforge.net + */ +class XML +{ + /** + * Sysinfo object where the information retrieval methods are included + * + * @var PSI_Interface_OS + */ + private $_sysinfo; + + /** + * @var System + */ + private $_sys = null; + + /** + * xml object with the xml content + * + * @var SimpleXMLExtended + */ + private $_xml; + + /** + * object for error handling + * + * @var Error + */ + private $_errors; + + /** + * array with all enabled plugins (name) + * + * @var array + */ + private $_plugins; + + /** + * plugin name if pluginrequest + * + * @var string + */ + private $_plugin = ''; + + /** + * generate a xml for a plugin or for the main app + * + * @var boolean + */ + private $_plugin_request = false; + + /** + * generate the entire xml with all plugins or only a part of the xml (main or plugin) + * + * @var boolean + */ + private $_complete_request = false; + + /** + * doing some initial tasks + * - generate the xml structure with the right header elements + * - get the error object for error output + * - get a instance of the sysinfo object + * + * @param boolean $complete generate xml with all plugins or not + * @param string $pluginname name of the plugin + * + * @return void + */ + public function __construct($complete = false, $pluginname = "") + { + $this->_errors = Error::singleton(); + if ($pluginname == "") { + $this->_plugin_request = false; + $this->_plugin = ''; + } else { + $this->_plugin_request = true; + $this->_plugin = $pluginname; + } + if ($complete) { + $this->_complete_request = true; + } else { + $this->_complete_request = false; + } + $os = PSI_OS; + $this->_sysinfo = new $os(); + $this->_plugins = CommonFunctions::getPlugins(); + $this->_xmlbody(); + } + + /** + * generate common information + * + * @return void + */ + private function _buildVitals() + { + $vitals = $this->_xml->addChild('Vitals'); + $vitals->addAttribute('Hostname', $this->_sys->getHostname()); + $vitals->addAttribute('IPAddr', $this->_sys->getIp()); + $vitals->addAttribute('Kernel', $this->_sys->getKernel()); + $vitals->addAttribute('Distro', $this->_sys->getDistribution()); + $vitals->addAttribute('Distroicon', $this->_sys->getDistributionIcon()); + $vitals->addAttribute('Uptime', $this->_sys->getUptime()); + $vitals->addAttribute('Users', $this->_sys->getUsers()); + $vitals->addAttribute('LoadAvg', $this->_sys->getLoad()); + if ($this->_sys->getLoadPercent() !== null) { + $vitals->addAttribute('CPULoad', $this->_sys->getLoadPercent()); + } + if ($this->_sysinfo->getLanguage() !== null) { + $vitals->addAttribute('SysLang', $this->_sysinfo->getLanguage()); + } + if ($this->_sysinfo->getEncoding() !== null) { + $vitals->addAttribute('CodePage', $this->_sysinfo->getEncoding()); + } + + //processes + if (($procss = $this->_sys->getProcesses()) !== null) { + if (isset($procss['*']) && (($procall = $procss['*']) > 0)) { + $vitals->addAttribute('Processes', $procall); + if (!isset($procss[' ']) || !($procss[' '] > 0)) { // not unknown + $procsum = 0; + if (isset($procss['R']) && (($proctmp = $procss['R']) > 0)) { + $vitals->addAttribute('ProcessesRunning', $proctmp); + $procsum += $proctmp; + } + if (isset($procss['S']) && (($proctmp = $procss['S']) > 0)) { + $vitals->addAttribute('ProcessesSleeping', $proctmp); + $procsum += $proctmp; + } + if (isset($procss['T']) && (($proctmp = $procss['T']) > 0)) { + $vitals->addAttribute('ProcessesStopped', $proctmp); + $procsum += $proctmp; + } + if (isset($procss['Z']) && (($proctmp = $procss['Z']) > 0)) { + $vitals->addAttribute('ProcessesZombie', $proctmp); + $procsum += $proctmp; + } + if (isset($procss['D']) && (($proctmp = $procss['D']) > 0)) { + $vitals->addAttribute('ProcessesWaiting', $proctmp); + $procsum += $proctmp; + } + if (($proctmp = $procall - $procsum) > 0) { + $vitals->addAttribute('ProcessesOther', $proctmp); + } + } + } + } + $vitals->addAttribute('OS', PSI_OS); + } + + /** + * generate the network information + * + * @return void + */ + private function _buildNetwork() + { + $hideDevices = array(); + $network = $this->_xml->addChild('Network'); + if (defined('PSI_HIDE_NETWORK_INTERFACE')) { + if (is_string(PSI_HIDE_NETWORK_INTERFACE)) { + if (preg_match(ARRAY_EXP, PSI_HIDE_NETWORK_INTERFACE)) { + $hideDevices = eval(PSI_HIDE_NETWORK_INTERFACE); + } else { + $hideDevices = array(PSI_HIDE_NETWORK_INTERFACE); + } + } elseif (PSI_HIDE_NETWORK_INTERFACE === true) { + return; + } + } + foreach ($this->_sys->getNetDevices() as $dev) { + if (!in_array(trim($dev->getName()), $hideDevices)) { + $device = $network->addChild('NetDevice'); + $device->addAttribute('Name', $dev->getName()); + $device->addAttribute('RxBytes', $dev->getRxBytes()); + $device->addAttribute('TxBytes', $dev->getTxBytes()); + $device->addAttribute('Err', $dev->getErrors()); + $device->addAttribute('Drops', $dev->getDrops()); + if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS && $dev->getInfo()) + $device->addAttribute('Info', $dev->getInfo()); + } + } + } + + /** + * generate the hardware information + * + * @return void + */ + private function _buildHardware() + { + $dev = new HWDevice(); + $hardware = $this->_xml->addChild('Hardware'); + if ($this->_sys->getMachine() != "") { + $hardware->addAttribute('Name', $this->_sys->getMachine()); + } + $pci = null; + foreach (System::removeDupsAndCount($this->_sys->getPciDevices()) as $dev) { + if ($pci === null) $pci = $hardware->addChild('PCI'); + $tmp = $pci->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + $tmp->addAttribute('Count', $dev->getCount()); + } + $usb = null; + foreach (System::removeDupsAndCount($this->_sys->getUsbDevices()) as $dev) { + if ($usb === null) $usb = $hardware->addChild('USB'); + $tmp = $usb->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + $tmp->addAttribute('Count', $dev->getCount()); + } + $ide = null; + foreach (System::removeDupsAndCount($this->_sys->getIdeDevices()) as $dev) { + if ($ide === null) $ide = $hardware->addChild('IDE'); + $tmp = $ide->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + $tmp->addAttribute('Count', $dev->getCount()); + if ($dev->getCapacity() !== null) { + $tmp->addAttribute('Capacity', $dev->getCapacity()); + } + } + $scsi = null; + foreach (System::removeDupsAndCount($this->_sys->getScsiDevices()) as $dev) { + if ($scsi === null) $scsi = $hardware->addChild('SCSI'); + $tmp = $scsi->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + $tmp->addAttribute('Count', $dev->getCount()); + if ($dev->getCapacity() !== null) { + $tmp->addAttribute('Capacity', $dev->getCapacity()); + } + } + $tb = null; + foreach (System::removeDupsAndCount($this->_sys->getTbDevices()) as $dev) { + if ($tb === null) $tb = $hardware->addChild('TB'); + $tmp = $tb->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + $tmp->addAttribute('Count', $dev->getCount()); + } + $i2c = null; + foreach (System::removeDupsAndCount($this->_sys->getI2cDevices()) as $dev) { + if ($i2c === null) $i2c = $hardware->addChild('I2C'); + $tmp = $i2c->addChild('Device'); + $tmp->addAttribute('Name', $dev->getName()); + $tmp->addAttribute('Count', $dev->getCount()); + } + + $cpu = null; + foreach ($this->_sys->getCpus() as $oneCpu) { + if ($cpu === null) $cpu = $hardware->addChild('CPU'); + $tmp = $cpu->addChild('CpuCore'); + $tmp->addAttribute('Model', $oneCpu->getModel()); + if ($oneCpu->getCpuSpeed() !== 0) { + $tmp->addAttribute('CpuSpeed', $oneCpu->getCpuSpeed()); + } + if ($oneCpu->getCpuSpeedMax() !== 0) { + $tmp->addAttribute('CpuSpeedMax', $oneCpu->getCpuSpeedMax()); + } + if ($oneCpu->getCpuSpeedMin() !== 0) { + $tmp->addAttribute('CpuSpeedMin', $oneCpu->getCpuSpeedMin()); + } + if ($oneCpu->getTemp() !== null) { + $tmp->addAttribute('CpuTemp', $oneCpu->getTemp()); + } + if ($oneCpu->getBusSpeed() !== null) { + $tmp->addAttribute('BusSpeed', $oneCpu->getBusSpeed()); + } + if ($oneCpu->getCache() !== null) { + $tmp->addAttribute('Cache', $oneCpu->getCache()); + } + if ($oneCpu->getVirt() !== null) { + $tmp->addAttribute('Virt', $oneCpu->getVirt()); + } + if ($oneCpu->getBogomips() !== null) { + $tmp->addAttribute('Bogomips', $oneCpu->getBogomips()); + } + if ($oneCpu->getLoad() !== null) { + $tmp->addAttribute('Load', $oneCpu->getLoad()); + } + } + } + + /** + * generate the memory information + * + * @return void + */ + private function _buildMemory() + { + $memory = $this->_xml->addChild('Memory'); + $memory->addAttribute('Free', $this->_sys->getMemFree()); + $memory->addAttribute('Used', $this->_sys->getMemUsed()); + $memory->addAttribute('Total', $this->_sys->getMemTotal()); + $memory->addAttribute('Percent', $this->_sys->getMemPercentUsed()); + if (($this->_sys->getMemApplication() !== null) || ($this->_sys->getMemBuffer() !== null) || ($this->_sys->getMemCache() !== null)) { + $details = $memory->addChild('Details'); + if ($this->_sys->getMemApplication() !== null) { + $details->addAttribute('App', $this->_sys->getMemApplication()); + $details->addAttribute('AppPercent', $this->_sys->getMemPercentApplication()); + } + if ($this->_sys->getMemBuffer() !== null) { + $details->addAttribute('Buffers', $this->_sys->getMemBuffer()); + $details->addAttribute('BuffersPercent', $this->_sys->getMemPercentBuffer()); + } + if ($this->_sys->getMemCache() !== null) { + $details->addAttribute('Cached', $this->_sys->getMemCache()); + $details->addAttribute('CachedPercent', $this->_sys->getMemPercentCache()); + } + } + if (count($this->_sys->getSwapDevices()) > 0) { + $swap = $memory->addChild('Swap'); + $swap->addAttribute('Free', $this->_sys->getSwapFree()); + $swap->addAttribute('Used', $this->_sys->getSwapUsed()); + $swap->addAttribute('Total', $this->_sys->getSwapTotal()); + $swap->addAttribute('Percent', $this->_sys->getSwapPercentUsed()); + $i = 1; + foreach ($this->_sys->getSwapDevices() as $dev) { + $swapMount = $swap->addChild('Mount'); + $this->_fillDevice($swapMount, $dev, $i++); + } + } + } + + /** + * fill a xml element with atrributes from a disk device + * + * @param SimpleXmlExtended $mount Xml-Element + * @param DiskDevice $dev DiskDevice + * @param Integer $i counter + * + * @return Void + */ + private function _fillDevice(SimpleXMLExtended $mount, DiskDevice $dev, $i) + { + $mount->addAttribute('MountPointID', $i); + $mount->addAttribute('FSType', $dev->getFsType()); + $mount->addAttribute('Name', $dev->getName()); + $mount->addAttribute('Free', sprintf("%.0f", $dev->getFree())); + $mount->addAttribute('Used', sprintf("%.0f", $dev->getUsed())); + $mount->addAttribute('Total', sprintf("%.0f", $dev->getTotal())); + $mount->addAttribute('Percent', $dev->getPercentUsed()); + if (PSI_SHOW_MOUNT_OPTION === true) { + if ($dev->getOptions() !== null) { + $mount->addAttribute('MountOptions', preg_replace("/,/", ", ", $dev->getOptions())); + } + } + if ($dev->getPercentInodesUsed() !== null) { + $mount->addAttribute('Inodes', $dev->getPercentInodesUsed()); + } + if (PSI_SHOW_MOUNT_POINT === true) { + $mount->addAttribute('MountPoint', $dev->getMountPoint()); + } + } + + /** + * generate the filesysteminformation + * + * @return void + */ + private function _buildFilesystems() + { + $hideMounts = $hideFstypes = $hideDisks = array(); + $i = 1; + if (defined('PSI_HIDE_MOUNTS') && is_string(PSI_HIDE_MOUNTS)) { + if (preg_match(ARRAY_EXP, PSI_HIDE_MOUNTS)) { + $hideMounts = eval(PSI_HIDE_MOUNTS); + } else { + $hideMounts = array(PSI_HIDE_MOUNTS); + } + } + if (defined('PSI_HIDE_FS_TYPES') && is_string(PSI_HIDE_FS_TYPES)) { + if (preg_match(ARRAY_EXP, PSI_HIDE_FS_TYPES)) { + $hideFstypes = eval(PSI_HIDE_FS_TYPES); + } else { + $hideFstypes = array(PSI_HIDE_FS_TYPES); + } + } + if (defined('PSI_HIDE_DISKS')) { + if (is_string(PSI_HIDE_DISKS)) { + if (preg_match(ARRAY_EXP, PSI_HIDE_DISKS)) { + $hideDisks = eval(PSI_HIDE_DISKS); + } else { + $hideDisks = array(PSI_HIDE_DISKS); + } + } elseif (PSI_HIDE_DISKS === true) { + return; + } + } + $fs = $this->_xml->addChild('FileSystem'); + foreach ($this->_sys->getDiskDevices() as $disk) { + if (!in_array($disk->getMountPoint(), $hideMounts, true) && !in_array($disk->getFsType(), $hideFstypes, true) && !in_array($disk->getName(), $hideDisks, true)) { + $mount = $fs->addChild('Mount'); + $this->_fillDevice($mount, $disk, $i++); + } + } + } + + /** + * generate the motherboard information + * + * @return void + */ + private function _buildMbinfo() + { + $mbinfo = $this->_xml->addChild('MBInfo'); + $temp = $fan = $volt = $power = $current = null; + + if (sizeof(unserialize(PSI_MBINFO))>0) { + foreach (unserialize(PSI_MBINFO) as $mbinfoclass) { + $mbinfo_data = new $mbinfoclass(); + $mbinfo_detail = $mbinfo_data->getMBInfo(); + + foreach ($mbinfo_detail->getMbTemp() as $dev) { + if ($temp == null) { + $temp = $mbinfo->addChild('Temperature'); + } + $item = $temp->addChild('Item'); + $item->addAttribute('Label', $dev->getName()); + $item->addAttribute('Value', $dev->getValue()); + if ($dev->getMax() !== null) { + $item->addAttribute('Max', $dev->getMax()); + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { + $item->addAttribute('Event', $dev->getEvent()); + } + } + + foreach ($mbinfo_detail->getMbFan() as $dev) { + if ($fan == null) { + $fan = $mbinfo->addChild('Fans'); + } + $item = $fan->addChild('Item'); + $item->addAttribute('Label', $dev->getName()); + $item->addAttribute('Value', $dev->getValue()); + if ($dev->getMin() !== null) { + $item->addAttribute('Min', $dev->getMin()); + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { + $item->addAttribute('Event', $dev->getEvent()); + } + } + + foreach ($mbinfo_detail->getMbVolt() as $dev) { + if ($volt == null) { + $volt = $mbinfo->addChild('Voltage'); + } + $item = $volt->addChild('Item'); + $item->addAttribute('Label', $dev->getName()); + $item->addAttribute('Value', $dev->getValue()); + if ($dev->getMin() !== null) { + $item->addAttribute('Min', $dev->getMin()); + } + if ($dev->getMax() !== null) { + $item->addAttribute('Max', $dev->getMax()); + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { + $item->addAttribute('Event', $dev->getEvent()); + } + } + + foreach ($mbinfo_detail->getMbPower() as $dev) { + if ($power == null) { + $power = $mbinfo->addChild('Power'); + } + $item = $power->addChild('Item'); + $item->addAttribute('Label', $dev->getName()); + $item->addAttribute('Value', $dev->getValue()); + if ($dev->getMax() !== null) { + $item->addAttribute('Max', $dev->getMax()); + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { + $item->addAttribute('Event', $dev->getEvent()); + } + } + + foreach ($mbinfo_detail->getMbCurrent() as $dev) { + if ($current == null) { + $current = $mbinfo->addChild('Current'); + } + $item = $current->addChild('Item'); + $item->addAttribute('Label', $dev->getName()); + $item->addAttribute('Value', $dev->getValue()); + if ($dev->getMax() !== null) { + $item->addAttribute('Max', $dev->getMax()); + } + if (defined('PSI_SENSOR_EVENTS') && PSI_SENSOR_EVENTS && $dev->getEvent() !== "") { + $item->addAttribute('Event', $dev->getEvent()); + } + } + } + } + + if (PSI_HDDTEMP) { + $hddtemp = new HDDTemp(); + $hddtemp_data = $hddtemp->getMBInfo(); + foreach ($hddtemp_data->getMbTemp() as $dev) { + if ($temp == null) { + $temp = $mbinfo->addChild('Temperature'); + } + $item = $temp->addChild('Item'); + $item->addAttribute('Label', $dev->getName()); + $item->addAttribute('Value', $dev->getValue()); + if ($dev->getMax() !== null) { + $item->addAttribute('Max', $dev->getMax()); + } + } + } + } + + /** + * generate the ups information + * + * @return void + */ + private function _buildUpsinfo() + { + $upsinfo = $this->_xml->addChild('UPSInfo'); + if (defined('PSI_UPS_APCUPSD_CGI_ENABLE') && PSI_UPS_APCUPSD_CGI_ENABLE) { + $upsinfo->addAttribute('ApcupsdCgiLinks', true); + } + if (sizeof(unserialize(PSI_UPSINFO))>0) { + foreach (unserialize(PSI_UPSINFO) as $upsinfoclass) { + $upsinfo_data = new $upsinfoclass(); + $upsinfo_detail = $upsinfo_data->getUPSInfo(); + foreach ($upsinfo_detail->getUpsDevices() as $ups) { + $item = $upsinfo->addChild('UPS'); + $item->addAttribute('Name', $ups->getName()); + if ($ups->getModel() !== "") { + $item->addAttribute('Model', $ups->getModel()); + } + $item->addAttribute('Mode', $ups->getMode()); + if ($ups->getStartTime() !== "") { + $item->addAttribute('StartTime', $ups->getStartTime()); + } + $item->addAttribute('Status', $ups->getStatus()); + if ($ups->getTemperatur() !== null) { + $item->addAttribute('Temperature', $ups->getTemperatur()); + } + if ($ups->getOutages() !== null) { + $item->addAttribute('OutagesCount', $ups->getOutages()); + } + if ($ups->getLastOutage() !== null) { + $item->addAttribute('LastOutage', $ups->getLastOutage()); + } + if ($ups->getLastOutageFinish() !== null) { + $item->addAttribute('LastOutageFinish', $ups->getLastOutageFinish()); + } + if ($ups->getLineVoltage() !== null) { + $item->addAttribute('LineVoltage', $ups->getLineVoltage()); + } + if ($ups->getLineFrequency() !== null) { + $item->addAttribute('LineFrequency', $ups->getLineFrequency()); + } + if ($ups->getLoad() !== null) { + $item->addAttribute('LoadPercent', $ups->getLoad()); + } + if ($ups->getBatteryDate() !== null) { + $item->addAttribute('BatteryDate', $ups->getBatteryDate()); + } + if ($ups->getBatteryVoltage() !== null) { + $item->addAttribute('BatteryVoltage', $ups->getBatteryVoltage()); + } + if ($ups->getBatterCharge() !== null) { + $item->addAttribute('BatteryChargePercent', $ups->getBatterCharge()); + } + if ($ups->getTimeLeft() !== null) { + $item->addAttribute('TimeLeftMinutes', $ups->getTimeLeft()); + } + } + } + } + } + + /** + * generate the xml document + * + * @return void + */ + private function _buildXml() + { + if (!$this->_plugin_request || $this->_complete_request) { + if ($this->_sys === null) { + if (PSI_DEBUG === true) { + // Safe mode check + $safe_mode = @ini_get("safe_mode") ? true : false; + if ($safe_mode) { + $this->_errors->addError("WARN", "PhpSysInfo requires to set off 'safe_mode' in 'php.ini'"); + } + // Include path check + $include_path = @ini_get("include_path"); + if ($include_path && ($include_path!="")) { + $include_path = preg_replace("/(:)|(;)/", "\n", $include_path); + if (preg_match("/^\.$/m", $include_path)) { + $include_path = "."; + } + } + if ($include_path != ".") { + $this->_errors->addError("WARN", "PhpSysInfo requires '.' inside the 'include_path' in php.ini"); + } + // popen mode check + if (defined("PSI_MODE_POPEN") && PSI_MODE_POPEN === true) { + $this->_errors->addError("WARN", "Installed version of PHP does not support proc_open() function, popen() is used"); + } + } + $this->_sys = $this->_sysinfo->getSys(); + } + $this->_buildVitals(); + $this->_buildNetwork(); + $this->_buildHardware(); + $this->_buildMemory(); + $this->_buildFilesystems(); + $this->_buildMbinfo(); + $this->_buildUpsinfo(); + } + $this->_buildPlugins(); + $this->_xml->combinexml($this->_errors->errorsAddToXML($this->_sysinfo->getEncoding())); + } + + /** + * get the xml object + * + * @return string + */ + public function getXml() + { + $this->_buildXml(); + + return $this->_xml->getSimpleXmlElement(); + } + + /** + * include xml-trees of the plugins to the main xml + * + * @return void + */ + private function _buildPlugins() + { + $pluginroot = $this->_xml->addChild("Plugins"); + if (($this->_plugin_request || $this->_complete_request) && count($this->_plugins) > 0) { + $plugins = array(); + if ($this->_complete_request) { + $plugins = $this->_plugins; + } + if ($this->_plugin_request) { + $plugins = array($this->_plugin); + } + foreach ($plugins as $plugin) { + $object = new $plugin($this->_sysinfo->getEncoding()); + $object->execute(); + $oxml = $object->xml(); + if (sizeof($oxml) > 0) { + $pluginroot->combinexml($oxml); + } + } + } + } + + /** + * build the xml structure where the content can be inserted + * + * @return void + */ + private function _xmlbody() + { + $dom = new DOMDocument('1.0', 'UTF-8'); + $root = $dom->createElement("tns:phpsysinfo"); + $root->setAttribute('xmlns:tns', 'http://phpsysinfo.sourceforge.net/'); + $root->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + $root->setAttribute('xsi:schemaLocation', 'http://phpsysinfo.sourceforge.net/ phpsysinfo3.xsd'); + $dom->appendChild($root); + $this->_xml = new SimpleXMLExtended(simplexml_import_dom($dom), $this->_sysinfo->getEncoding()); + + $generation = $this->_xml->addChild('Generation'); + $generation->addAttribute('version', PSI_VERSION_STRING); + $generation->addAttribute('timestamp', time()); + $options = $this->_xml->addChild('Options'); + $options->addAttribute('tempFormat', defined('PSI_TEMP_FORMAT') ? strtolower(PSI_TEMP_FORMAT) : 'c'); + $options->addAttribute('byteFormat', defined('PSI_BYTE_FORMAT') ? strtolower(PSI_BYTE_FORMAT) : 'auto_binary'); + if (defined('PSI_REFRESH')) { + if (PSI_REFRESH === false) { + $options->addAttribute('refresh', 0); + } elseif (PSI_REFRESH === true) { + $options->addAttribute('refresh', 1); + } else { + $options->addAttribute('refresh', PSI_REFRESH); + } + } else { + $options->addAttribute('refresh', 60000); + } + if (defined('PSI_FS_USAGE_THRESHOLD')) { + if (PSI_FS_USAGE_THRESHOLD === true) { + $options->addAttribute('threshold', 1); + } elseif ((PSI_FS_USAGE_THRESHOLD !== false) && (PSI_FS_USAGE_THRESHOLD >= 1) && (PSI_FS_USAGE_THRESHOLD <= 99)) { + $options->addAttribute('threshold', PSI_FS_USAGE_THRESHOLD); + } + } else { + $options->addAttribute('threshold', 90); + } + $options->addAttribute('showPickListTemplate', defined('PSI_SHOW_PICKLIST_TEMPLATE') ? (PSI_SHOW_PICKLIST_TEMPLATE ? 'true' : 'false') : 'false'); + $options->addAttribute('showPickListLang', defined('PSI_SHOW_PICKLIST_LANG') ? (PSI_SHOW_PICKLIST_LANG ? 'true' : 'false') : 'false'); + $options->addAttribute('showCPUListExpanded', defined('PSI_SHOW_CPULIST_EXPANDED') ? (PSI_SHOW_CPULIST_EXPANDED ? 'true' : 'false') : 'true'); + $options->addAttribute('showCPUInfoExpanded', defined('PSI_SHOW_CPUINFO_EXPANDED') ? (PSI_SHOW_CPUINFO_EXPANDED ? 'true' : 'false') : 'false'); + if (count($this->_plugins) > 0) { + if ($this->_plugin_request) { + $plug = $this->_xml->addChild('UsedPlugins'); + $plug->addChild('Plugin')->addAttribute('name', $this->_plugin); + } elseif ($this->_complete_request) { + $plug = $this->_xml->addChild('UsedPlugins'); + foreach ($this->_plugins as $plugin) { + $plug->addChild('Plugin')->addAttribute('name', $plugin); + } + } else { + $plug = $this->_xml->addChild('UnusedPlugins'); + foreach ($this->_plugins as $plugin) { + $plug->addChild('Plugin')->addAttribute('name', $plugin); + } + } + } + } +} diff --git a/root/opt/phpsysinfo/index.php b/root/opt/phpsysinfo/index.php new file mode 100644 index 0000000..2314548 --- /dev/null +++ b/root/opt/phpsysinfo/index.php @@ -0,0 +1,71 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: index.php 687 2012-09-06 20:54:49Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ +/** + * define the application root path on the webserver + * @var string + */ +define('APP_ROOT', dirname(__FILE__)); + +/** + * internal xml or external + * external is needed when running in static mode + * + * @var boolean + */ +define('PSI_INTERNAL_XML', false); + +if (version_compare("5.2", PHP_VERSION, ">")) { + die("PHP 5.2 or greater is required!!!"); +} +if (!extension_loaded("pcre")) { + die("phpSysInfo requires the pcre extension to php in order to work properly."); +} + +require_once APP_ROOT.'/includes/autoloader.inc.php'; + +// Load configuration +require_once APP_ROOT.'/read_config.php'; + +if (!defined('PSI_CONFIG_FILE') || !defined('PSI_DEBUG')) { + $tpl = new Template("/templates/html/error_config.html"); + echo $tpl->fetch(); + die(); +} + +// redirect to page with and without javascript +$display = isset($_GET['disp']) ? $_GET['disp'] : strtolower(PSI_DEFAULT_DISPLAY_MODE); +switch ($display) { +case "static": + $webpage = new WebpageXSLT(); + $webpage->run(); + break; +case "dynamic": + $webpage = new Webpage(); + $webpage->run(); + break; +case "xml": + $webpage = new WebpageXML(true, null); + $webpage->run(); + break; +case "bootstrap": + $tpl = new Template("/templates/html/index_bootstrap.html"); + echo $tpl->fetch(); + break; +default: + $tpl = new Template("/templates/html/index_all.html"); + echo $tpl->fetch(); + break; +} diff --git a/root/opt/phpsysinfo/js.php b/root/opt/phpsysinfo/js.php new file mode 100644 index 0000000..375cb99 --- /dev/null +++ b/root/opt/phpsysinfo/js.php @@ -0,0 +1,85 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: js.php 661 2012-08-27 11:26:39Z namiltd $ + * @link http://phpsysinfo.sourceforge.net + */ +/** + * application root path + * + * @var string + */ +define('APP_ROOT', dirname(__FILE__)); + +require_once APP_ROOT.'/includes/autoloader.inc.php'; + +require_once APP_ROOT.'/read_config.php'; + +$file = isset($_GET['name']) ? basename(htmlspecialchars($_GET['name'])) : null; +$plugin = isset($_GET['plugin']) ? basename(htmlspecialchars($_GET['plugin'])) : null; +$script = null; + +if ($file != null && $plugin == null) { + if (strtolower(substr($file, 0, 6)) == 'jquery') { + $script = APP_ROOT.'/js/jQuery/'.$file; + } elseif (strtolower(substr($file, 0, 10)) == 'phpsysinfo') { + $script = APP_ROOT.'/js/phpSysInfo/'.$file; + } else { + $script = APP_ROOT.'/js/vendor/'.$file; + } +} elseif ($file == null && $plugin != null) { + $script = APP_ROOT.'/plugins/'.strtolower($plugin).'/js/'.strtolower($plugin); +} elseif ($file != null && $plugin != null) { + $script = APP_ROOT.'/plugins/'.strtolower($plugin).'/js/'.strtolower($file); +} + +if ($script != null) { + $scriptjs = $script.'.js'; + $scriptmin = $script.'.min.js'; + $compression = false; + + header("content-type: application/x-javascript"); + + if ((!defined("PSI_DEBUG") || (PSI_DEBUG !== true)) && defined("PSI_JS_COMPRESSION")) { + $compression = strtolower(PSI_JS_COMPRESSION); + } + switch ($compression) { + case "normal": + if (file_exists($scriptmin) && is_readable($scriptmin)) { + $filecontent = file_get_contents($scriptmin); + echo $filecontent; + } elseif (file_exists($scriptjs) && is_readable($scriptjs)) { + $filecontent = file_get_contents($scriptjs); + $packer = new JavaScriptPacker($filecontent); + echo $packer->pack(); + } + break; + case "none": + if (file_exists($scriptjs) && is_readable($scriptjs)) { + $filecontent = file_get_contents($scriptjs); + $packer = new JavaScriptPacker($filecontent, 0); + echo $packer->pack(); + } elseif (file_exists($scriptmin) && is_readable($scriptmin)) { + $filecontent = file_get_contents($scriptmin); + echo $filecontent; + } + break; + default: + if (file_exists($scriptjs) && is_readable($scriptjs)) { + $filecontent = file_get_contents($scriptjs); + } elseif (file_exists($scriptmin) && is_readable($scriptmin)) { + $filecontent = file_get_contents($scriptmin); + } else break; + + echo $filecontent; + break; + } +} diff --git a/root/opt/phpsysinfo/js/jQuery/README b/root/opt/phpsysinfo/js/jQuery/README new file mode 100644 index 0000000..5e80578 --- /dev/null +++ b/root/opt/phpsysinfo/js/jQuery/README @@ -0,0 +1,58 @@ +versions, links and simple description of used jquery files +=========================================================== + +jquery.js +--------- +VERSION : 2.1.4 +URL : http://jquery.com/ +DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle + events, perform animations, and add Ajax interactions to your web pages. +USED : used for the entire userinterface + +jquery-1.js +--------- +VERSION : 1.11.3 +URL : http://jquery.com/ +DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle + events, perform animations, and add Ajax interactions to your web pages. +USED : used for the entire userinterface + + +jquery.dataTables.js +-------------------- +VERSION : 1.8.2 +URL : http://plugins.jquery.com/project/DataTables +DESC : dataTables is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable + table without page refreshes. +USED : provide tablesorting for the filesystem table + +jquery.nyroModal.js +------------------- +VERSION : 1.6.2+jquery1.8fix +URL : http://plugins.jquery.com/project/nyroModal +DESC : nyroModal is a high customizable modal window plugin. +USED : provide a modal dialog, that is shown when errors are found during execution of the php parsers, or lets say + in this way: if there are error elements in the xml file + +jquery.timers.js +---------------- +VERSION : 0.1 +URL : http://plugins.jquery.com/project/Timer +DESC : provides a cleaner way to handle intervals +USED : automatic reloading of the entire page + +jquery.jgrowl.js +---------------- +VERSION : 1.2.6 +URL : http://plugins.jquery.com/project/jGrowl +DESC : jGrowl is a jQuery plugin that raises unobtrusive messages within the browser, similar to the way that OS X's Growl Framework works +USED : show alert and error message + +jquery.treeTable.js +------------------- +VERSION : 2009-06-22+statefix +URL : http://plugins.jquery.com/project/jQTreeTable; http://www.hanpau.com/index.php?page=jqtreetable +DESC : Take a plain html table, wrap the rows you want collapsing/expanding in a tbody tag with an id of treetable, map each row to it's parent row, set some options, and let jQTreeTable take it from there. +USED : Hardware, Memory, UPS blocks + +$Id: README 702 2012-09-21 16:52:32Z namiltd $ diff --git a/root/opt/phpsysinfo/js/jQuery/README_bootstrap b/root/opt/phpsysinfo/js/jQuery/README_bootstrap new file mode 100644 index 0000000..18e9b93 --- /dev/null +++ b/root/opt/phpsysinfo/js/jQuery/README_bootstrap @@ -0,0 +1,25 @@ +versions, links and simple description of used jquery files +=========================================================== + +jquery.js +--------- +VERSION : 2.1.4 +URL : http://jquery.com/ +DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle + events, perform animations, and add Ajax interactions to your web pages. +USED : used for the entire userinterface + +jquery-1.js +--------- +VERSION : 1.11.3 +URL : http://jquery.com/ +DESC : jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle + events, perform animations, and add Ajax interactions to your web pages. +USED : used for the entire userinterface + +jquery.treegrid.js +------------------- +VERSION : 0.3.0 +URL : http://plugins.jquery.com/treegrid/; http://maxazan.github.io/jquery-treegrid/ +DESC : TreeGrid is a lightweight and flexible jQuery plugin to create a tree grid component that renders hierarchical, nested and flat data in a table. +USED : Hardware, Memory, UPS blocks diff --git a/root/opt/phpsysinfo/js/jQuery/jquery-1.js b/root/opt/phpsysinfo/js/jQuery/jquery-1.js new file mode 100644 index 0000000..6feb110 --- /dev/null +++ b/root/opt/phpsysinfo/js/jQuery/jquery-1.js @@ -0,0 +1,10351 @@ +/*! + * jQuery JavaScript Library v1.11.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-04-28T16:19Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var deletedIds = []; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "1.11.3", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1, IE<9 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( support.ownLast ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1, IE<9 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( indexOf ) { + return indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: function() { + return +( new Date() ); + }, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.0-pre + * http://sizzlejs.com/ + * + * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-12-16 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + nodeType = context.nodeType; + + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + if ( !seed && documentIsHTML ) { + + // Try to shortcut find operations when possible (e.g., not under DocumentFragment) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType !== 1 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + parent = doc.defaultView; + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Support tests + ---------------------------------------------------------------------- */ + documentIsHTML = !isXML( doc ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + + } else if ( !(--remaining) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + + +var strundefined = typeof undefined; + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownLast = i !== "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +// Execute ASAP in case we need to set body.style.zoom +jQuery(function() { + // Minified: var a,b,c,d + var val, div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Return for frameset docs that don't have a body + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; + + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; + if ( val ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); +}); + + + + +(function() { + var div = document.createElement( "div" ); + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( elem ) { + var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute("classid") === noData; +}; + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties + noData: { + "applet ": true, + "embed ": true, + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[0], + attrs = elem && elem.attributes; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; +}; +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + // Minified: var a,b,c + var input = document.createElement( "input" ), + div = document.createElement( "div" ), + fragment = document.createDocumentFragment(); + + // Setup + div.innerHTML = "
a"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + div.innerHTML = ""; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + support.noCloneEvent = true; + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } +})(); + + +(function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) + for ( i in { submit: true, change: true, focusin: true }) { + eventName = "on" + i; + + if ( !(support[ i + "Bubbles" ] = eventName in window) ) { + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: IE < 9, Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!support.noCloneEvent || !support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + deletedIds.push( id ); + } + } + } + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "'); + $('iframe', modal.tmp) + .css({ + width: currentSettings.width, + height: currentSettings.height + }) + .error(loadingError) + .load(formDataLoaded); + debug('Form Data Load: '+jFrom.attr('action')); + showModal(); + showContentOrLoading(); + } else if (currentSettings.type == 'image') { + debug('Image Load: '+url); + var title = jFrom.attr('title') || currentSettings.defaultImgAlt; + initModal(); + modal.tmp.html('').find('img').attr('alt', title); + modal.tmp.css({lineHeight: 0}); + $('img', modal.tmp) + .error(loadingError) + .load(function() { + debug('Image Loaded: '+this.src); + $(this).unbind('load'); + var w = modal.tmp.width(); + var h = modal.tmp.height(); + modal.tmp.css({lineHeight: ''}); + resized.width = w; + resized.height = h; + setCurrentSettings({ + width: w, + height: h, + imgWidth: w, + imgHeight: h + }); + initSettingsSize.width = w; + initSettingsSize.height = h; + setCurrentSettings({overflow: 'visible'}, 'cssOpt', 'content'); + modal.dataReady = true; + if (modal.loadingShown || modal.transition) + showContentOrLoading(); + }) + .attr('src', url); + showModal(); + } else if (currentSettings.type == 'iframeForm') { + initModal(); + modal.tmp.html(''); + debug('Iframe Form Load: '+url); + $('iframe', modal.tmp).eq(0) + .css({ + width: '100%', + height: $.support.boxModel? '99%' : '100%' + }) + .load(iframeLoaded); + modal.dataReady = true; + showModal(); + } else if (currentSettings.type == 'iframe') { + initModal(); + modal.tmp.html(''); + debug('Iframe Load: '+url); + $('iframe', modal.tmp).eq(0) + .css({ + width: '100%', + height: $.support.boxModel? '99%' : '100%' + }) + .load(iframeLoaded); + modal.dataReady = true; + showModal(); + } else if (currentSettings.type) { + // Could be every other kind of type or a dom selector + debug('Content: '+currentSettings.type); + initModal(); + modal.tmp.html(currentSettings.content); + var w = modal.tmp.width(); + var h = modal.tmp.height(); + var div = $(currentSettings.type); + if (div.length) { + setCurrentSettings({type: 'div'}); + w = div.width(); + h = div.height(); + if (contentElt) + contentEltLast = contentElt; + contentElt = div; + modal.tmp.append(div.contents()); + } + initSettingsSize.width = w; + initSettingsSize.height = h; + setCurrentSettings({ + width: w, + height: h + }); + if (modal.tmp.html()) + modal.dataReady = true; + else + loadingError(); + if (!modal.ready) + showModal(); + else + endHideContent(); + } else { + debug('Ajax Load: '+url); + setCurrentSettings({type: 'ajax'}); + var data = currentSettings.ajax.data || {}; + if (currentSettings.selector) { + if (typeof data == "string") { + data+= '&'+currentSettings.selIndicator+'='+currentSettings.selector.substring(1); + } else { + data[currentSettings.selIndicator] = currentSettings.selector.substring(1); + } + } + showModal(); + $.ajax($.extend(true, currentSettings.ajax, { + url: url, + success: ajaxLoaded, + error: loadingError, + data: data + })); + } + } else if (currentSettings.content) { + // Raw content not from a DOM element + debug('Content: '+currentSettings.type); + setCurrentSettings({type: 'manual'}); + initModal(); + modal.tmp.html($('
').html(currentSettings.content).contents()); + if (modal.tmp.html()) + modal.dataReady = true; + else + loadingError(); + showModal(); + } else { + // What should we show here? nothing happen + } + } + + // Update the current settings + // object settings + // string deep1 first key where overwrite the settings + // string deep2 second key where overwrite the settings + function setDefaultCurrentSettings(settings) { + debug('setDefaultCurrentSettings'); + currentSettings = $.extend(true, {}, $.fn.nyroModal.settings, settings); + setMargin(); + } + + function setCurrentSettings(settings, deep1, deep2) { + if (modal.started) { + if (deep1 && deep2) { + $.extend(true, currentSettings[deep1][deep2], settings); + } else if (deep1) { + $.extend(true, currentSettings[deep1], settings); + } else { + if (modal.animContent) { + if ('width' in settings) { + if (!modal.resizing) { + settings.setWidth = settings.width; + shouldResize = true; + } + delete settings['width']; + } + if ('height' in settings) { + if (!modal.resizing) { + settings.setHeight = settings.height; + shouldResize = true; + } + delete settings['height']; + } + } + $.extend(true, currentSettings, settings); + } + } else { + if (deep1 && deep2) { + $.extend(true, $.fn.nyroModal.settings[deep1][deep2], settings); + } else if (deep1) { + $.extend(true, $.fn.nyroModal.settings[deep1], settings); + } else { + $.extend(true, $.fn.nyroModal.settings, settings); + } + } + } + + // Set the margin for postionning the element. Useful for IE6 + function setMarginScroll() { + if (isIE6 && !modal.blocker) { + if (document.documentElement) { + currentSettings.marginScrollLeft = document.documentElement.scrollLeft; + currentSettings.marginScrollTop = document.documentElement.scrollTop; + } else { + currentSettings.marginScrollLeft = document.body.scrollLeft; + currentSettings.marginScrollTop = document.body.scrollTop; + } + } else { + currentSettings.marginScrollLeft = 0; + currentSettings.marginScrollTop = 0; + } + } + + // Set the margin for the content + function setMargin() { + setMarginScroll(); + currentSettings.marginLeft = -(currentSettings.width+currentSettings.borderW)/2; + currentSettings.marginTop = -(currentSettings.height+currentSettings.borderH)/2; + if (!modal.blocker) { + currentSettings.marginLeft+= currentSettings.marginScrollLeft; + currentSettings.marginTop+= currentSettings.marginScrollTop; + } + } + + // Set the margin for the current loading + function setMarginLoading() { + setMarginScroll(); + var outer = getOuter(modal.loading); + currentSettings.marginTopLoading = -(modal.loading.height() + outer.h.border + outer.h.padding)/2; + currentSettings.marginLeftLoading = -(modal.loading.width() + outer.w.border + outer.w.padding)/2; + if (!modal.blocker) { + currentSettings.marginLeftLoading+= currentSettings.marginScrollLeft; + currentSettings.marginTopLoading+= currentSettings.marginScrollTop; + } + } + + // Set the modal Title + function setTitle() { + var title = $('h1#nyroModalTitle', modal.contentWrapper); + if (title.length) + title.text(currentSettings.title); + else + modal.contentWrapper.prepend('

'+currentSettings.title+'

'); + } + + // Init the nyroModal div by settings the CSS elements and hide needed elements + function initModal() { + debug('initModal'); + if (!modal.full) { + if (currentSettings.debug) + setCurrentSettings({color: 'white'}, 'cssOpt', 'bg'); + + var full = { + zIndex: currentSettings.zIndexStart, + position: 'fixed', + top: 0, + left: 0, + width: '100%', + height: '100%' + }; + + var contain = body; + var iframeHideIE = ''; + if (currentSettings.blocker) { + modal.blocker = contain = $(currentSettings.blocker); + var pos = modal.blocker.offset(); + var w = modal.blocker.outerWidth(); + var h = modal.blocker.outerHeight(); + if (isIE6) { + setCurrentSettings({ + height: '100%', + width: '100%', + top: 0, + left: 0 + }, 'cssOpt', 'bg'); + } + modal.blockerVars = { + top: pos.top, + left: pos.left, + width: w, + height: h + }; + var plusTop = (/msie/.test(userAgent) ?0:getCurCSS(body.get(0), 'borderTopWidth')); + var plusLeft = (/msie/.test(userAgent) ?0:getCurCSS(body.get(0), 'borderLeftWidth')); + full = { + position: 'absolute', + top: pos.top + plusTop, + left: pos.left + plusLeft, + width: w, + height: h + }; + } else if (isIE6) { + body.css({ + marginLeft: 0, + marginRight: 0 + }); + var w = body.width(); + var h = $(window).height()+'px'; + if ($(window).height() >= body.outerHeight()) { + h = body.outerHeight()+'px'; + } else + w+= 20; + w += 'px'; + body.css({ + width: w, + height: h, + position: 'static', + overflow: 'hidden' + }); + $('html').css({overflow: 'hidden'}); + setCurrentSettings({ + cssOpt: { + bg: { + position: 'absolute', + zIndex: currentSettings.zIndexStart+1, + height: '110%', + width: '110%', + top: currentSettings.marginScrollTop+'px', + left: currentSettings.marginScrollLeft+'px' + }, + wrapper: { zIndex: currentSettings.zIndexStart+2 }, + loading: { zIndex: currentSettings.zIndexStart+3 } + } + }); + + iframeHideIE = $('') + .css($.extend({}, + currentSettings.cssOpt.bg, { + opacity: 0, + zIndex: 50, + border: 'none' + })); + } + + contain.append($('
').hide()); + + modal.full = $('#nyroModalFull') + .css(full) + .show(); + modal.bg = $('#nyroModalBg') + .css($.extend({ + backgroundColor: currentSettings.bgColor + }, currentSettings.cssOpt.bg)) + .before(iframeHideIE); + modal.bg.bind('click.nyroModal', clickBg); + modal.loading = $('#nyroModalLoading') + .css(currentSettings.cssOpt.loading) + .hide(); + modal.contentWrapper = $('#nyroModalWrapper') + .css(currentSettings.cssOpt.wrapper) + .hide(); + modal.content = $('#nyroModalContent'); + modal.tmp = $('#nyrModalTmp').hide(); + + // To stop the mousewheel if the the plugin is available + if ($.isFunction($.fn.mousewheel)) { + modal.content.mousewheel(function(e, d) { + var elt = modal.content.get(0); + if ((d > 0 && elt.scrollTop == 0) || + (d < 0 && elt.scrollHeight - elt.scrollTop == elt.clientHeight)) { + e.preventDefault(); + e.stopPropagation(); + } + }); + } + + $(document).bind('keydown.nyroModal', keyHandler); + modal.content.css({width: 'auto', height: 'auto'}); + modal.contentWrapper.css({width: 'auto', height: 'auto'}); + + if (!currentSettings.blocker && currentSettings.windowResize) { + $(window).bind('resize.nyroModal', function() { + window.clearTimeout(windowResizeTimeout); + windowResizeTimeout = window.setTimeout(windowResizeHandler, 200); + }); + } + } + } + + function windowResizeHandler() { + $.nyroModalSettings(initSettingsSize); + } + + // Show the modal (ie: the background and then the loading if needed or the content directly) + function showModal() { + debug('showModal'); + if (!modal.ready) { + initModal(); + modal.anim = true; + currentSettings.showBackground(modal, currentSettings, endBackground); + } else { + modal.anim = true; + modal.transition = true; + currentSettings.showTransition(modal, currentSettings, function(){endHideContent();modal.anim=false;showContentOrLoading();}); + } + } + + // Called when user click on background + function clickBg(e) { + if (!currentSettings.modal) + removeModal(); + } + + // Used for the escape key or the arrow in the gallery type + function keyHandler(e) { + if (e.keyCode == 27) { + if (!currentSettings.modal) + removeModal(); + } else if (currentSettings.gallery && modal.ready && modal.dataReady && !modal.anim && !modal.transition) { + if (e.keyCode == 39 || e.keyCode == 40) { + e.preventDefault(); + $.nyroModalNext(); + return false; + } else if (e.keyCode == 37 || e.keyCode == 38) { + e.preventDefault(); + $.nyroModalPrev(); + return false; + } + } + } + + // Determine the filetype regarding the link DOM element + function fileType() { + var from = currentSettings.from; + + var url; + + if (from && from.nodeName) { + var jFrom = $(from); + + url = jFrom.attr(from.nodeName.toLowerCase() == 'form' ? 'action' : 'href'); + if (!url) + url = location.href.substring(window.location.host.length+7); + currentSettings.url = url; + + if (jFrom.attr('rev') == 'modal') + currentSettings.modal = true; + + currentSettings.title = jFrom.attr('title'); + + if (from && from.rel && from.rel.toLowerCase() != 'nofollow') { + var indexSpace = from.rel.indexOf(' '); + currentSettings.gallery = indexSpace > 0 ? from.rel.substr(0, indexSpace) : from.rel; + } + + var imgType = imageType(url, from); + if (imgType) + return imgType; + + if (isSwf(url)) + return 'swf'; + + var iframe = false; + if (from.target && from.target.toLowerCase() == '_blank' || (from.hostname && from.hostname.replace(/:\d*$/,'') != window.location.hostname.replace(/:\d*$/,''))) { + iframe = true; + } + if (from.nodeName.toLowerCase() == 'form') { + if (iframe) + return 'iframeForm'; + setCurrentSettings(extractUrlSel(url)); + if (jFrom.attr('enctype') == 'multipart/form-data') + return 'formData'; + return 'form'; + } + if (iframe) + return 'iframe'; + } else { + url = currentSettings.url; + if (!currentSettings.content) + currentSettings.from = true; + + if (!url) + return null; + + if (isSwf(url)) + return 'swf'; + + var reg1 = new RegExp("^http://|https://", "g"); + if (url.match(reg1)) + return 'iframe'; + } + + var imgType = imageType(url, from); + if (imgType) + return imgType; + + var tmp = extractUrlSel(url); + setCurrentSettings(tmp); + + if (!tmp.url) + return tmp.selector; + } + + function imageType(url, from) { + var image = new RegExp(currentSettings.regexImg, 'i'); + if (image.test(url)) { + return 'image'; + } + } + + function isSwf(url) { + var swf = new RegExp('[^\.]\.(swf)\s*$', 'i'); + return swf.test(url); + } + + function extractUrlSel(url) { + var ret = { + url: null, + selector: null + }; + + if (url) { + var hash = getHash(url); + var hashLoc = getHash(window.location.href); + var curLoc = window.location.href.substring(0, window.location.href.length - hashLoc.length); + var req = url.substring(0, url.length - hash.length); + + if (req == curLoc || req == $('base').attr('href')) { + ret.selector = hash; + } else { + ret.url = req; + ret.selector = hash; + } + } + return ret; + } + + // Called when the content cannot be loaded or tiemout reached + function loadingError() { + debug('loadingError'); + + modal.error = true; + + if (!modal.ready) + return; + + if ($.isFunction(currentSettings.handleError)) + currentSettings.handleError(modal, currentSettings); + + modal.loading + .addClass(currentSettings.errorClass) + .html(currentSettings.contentError); + $(currentSettings.closeSelector, modal.loading) + .unbind('click.nyroModal') + .bind('click.nyroModal', removeModal); + setMarginLoading(); + modal.loading + .css({ + marginTop: currentSettings.marginTopLoading+'px', + marginLeft: currentSettings.marginLeftLoading+'px' + }); + } + + // Put the content from modal.tmp to modal.content + function fillContent() { + debug('fillContent'); + if (!modal.tmp.html()) + return; + + modal.content.html(modal.tmp.contents()); + modal.tmp.empty(); + wrapContent(); + + if (currentSettings.type == 'iframeForm') { + $(currentSettings.from) + .attr('target', 'nyroModalIframe') + .data('nyroModalprocessing', 1) + .submit() + .attr('target', '_blank') + .removeData('nyroModalprocessing'); + } + + if (!currentSettings.modal) + modal.wrapper.prepend(currentSettings.closeButton); + + if ($.isFunction(currentSettings.endFillContent)) + currentSettings.endFillContent(modal, currentSettings); + + modal.content.append(modal.scripts); + + $(currentSettings.closeSelector, modal.contentWrapper) + .unbind('click.nyroModal') + .bind('click.nyroModal', removeModal); + $(currentSettings.openSelector, modal.contentWrapper).nyroModal(getCurrentSettingsNew()); + } + + // Get the current settings to be used in new links + function getCurrentSettingsNew() { + return callingSettings; + var currentSettingsNew = $.extend(true, {}, currentSettings); + if (resized.width) + currentSettingsNew.width = null; + else + currentSettingsNew.width = initSettingsSize.width; + if (resized.height) + currentSettingsNew.height = null; + else + currentSettingsNew.height = initSettingsSize.height; + currentSettingsNew.cssOpt.content.overflow = 'auto'; + return currentSettingsNew; + } + + // Wrap the content and update the modal size if needed + function wrapContent() { + debug('wrapContent'); + + var wrap = $(currentSettings.wrap[currentSettings.type]); + modal.content.append(wrap.children().remove()); + modal.contentWrapper.wrapInner(wrap); + + if (currentSettings.gallery) { + // Set the action for the next and prev button (or remove them) + modal.content.append(currentSettings.galleryLinks); + + gallery.links = $('[rel="'+currentSettings.gallery+'"], [rel^="'+currentSettings.gallery+' "]'); + gallery.index = gallery.links.index(currentSettings.from); + + if (currentSettings.galleryCounts && $.isFunction(currentSettings.galleryCounts)) + currentSettings.galleryCounts(gallery.index + 1, gallery.links.length, modal, currentSettings); + + var currentSettingsNew = getCurrentSettingsNew(); + + var linkPrev = getGalleryLink(-1); + if (linkPrev) { + var prev = $('.nyroModalPrev', modal.contentWrapper) + .attr('href', linkPrev.attr('href')) + .click(function(e) { + e.preventDefault(); + $.nyroModalPrev(); + return false; + }); + if (isIE6 && currentSettings.type == 'swf') { + prev.before($('').css({ + position: prev.css('position'), + top: prev.css('top'), + left: prev.css('left'), + width: prev.width(), + height: prev.height(), + opacity: 0, + border: 'none' + })); + } + } else { + $('.nyroModalPrev', modal.contentWrapper).remove(); + } + var linkNext = getGalleryLink(1); + if (linkNext) { + var next = $('.nyroModalNext', modal.contentWrapper) + .attr('href', linkNext.attr('href')) + .click(function(e) { + e.preventDefault(); + $.nyroModalNext(); + return false; + }); + if (isIE6 && currentSettings.type == 'swf') { + next.before($('') + .css($.extend({}, { + position: next.css('position'), + top: next.css('top'), + left: next.css('left'), + width: next.width(), + height: next.height(), + opacity: 0, + border: 'none' + }))); + } + } else { + $('.nyroModalNext', modal.contentWrapper).remove(); + } + } + + calculateSize(); + } + + function getGalleryLink(dir) { + if (currentSettings.gallery) { + if (!currentSettings.ltr) + dir *= -1; + var index = gallery.index + dir; + if (index >= 0 && index < gallery.links.length) + return gallery.links.eq(index); + else if (currentSettings.galleryLoop) { + if (index < 0) + return gallery.links.eq(gallery.links.length-1); + else + return gallery.links.eq(0); + } + } + return false; + } + + // Calculate the size for the contentWrapper + function calculateSize(resizing) { + debug('calculateSize'); + + modal.wrapper = modal.contentWrapper.children('div:first'); + + resized.width = false; + resized.height = false; + if (false && !currentSettings.windowResizing) { + initSettingsSize.width = currentSettings.width; + initSettingsSize.height = currentSettings.height; + } + + if (currentSettings.autoSizable && (!currentSettings.width || !currentSettings.height)) { + modal.contentWrapper + .css({ + opacity: 0, + width: 'auto', + height: 'auto' + }) + .show(); + var tmp = { + width: 'auto', + height: 'auto' + }; + if (currentSettings.width) { + tmp.width = currentSettings.width; + } else if (currentSettings.type == 'iframe') { + tmp.width = currentSettings.minWidth; + } + + if (currentSettings.height) { + tmp.height = currentSettings.height; + } else if (currentSettings.type == 'iframe') { + tmp.height = currentSettings.minHeight; + } + + modal.content.css(tmp); + if (!currentSettings.width) { + currentSettings.width = modal.content.outerWidth(true); + resized.width = true; + } + if (!currentSettings.height) { + currentSettings.height = modal.content.outerHeight(true); + resized.height = true; + } + modal.contentWrapper.css({opacity: 1}); + if (!resizing) + modal.contentWrapper.hide(); + } + + if (currentSettings.type != 'image' && currentSettings.type != 'swf') { + currentSettings.width = Math.max(currentSettings.width, currentSettings.minWidth); + currentSettings.height = Math.max(currentSettings.height, currentSettings.minHeight); + } + + var outerWrapper = getOuter(modal.contentWrapper); + var outerWrapper2 = getOuter(modal.wrapper); + var outerContent = getOuter(modal.content); + + var tmp = { + content: { + width: currentSettings.width, + height: currentSettings.height + }, + wrapper2: { + width: currentSettings.width + outerContent.w.total, + height: currentSettings.height + outerContent.h.total + }, + wrapper: { + width: currentSettings.width + outerContent.w.total + outerWrapper2.w.total, + height: currentSettings.height + outerContent.h.total + outerWrapper2.h.total + } + }; + + if (currentSettings.resizable) { + var maxHeight = modal.blockerVars? modal.blockerVars.height : $(window).height() + - outerWrapper.h.border + - (tmp.wrapper.height - currentSettings.height); + var maxWidth = modal.blockerVars? modal.blockerVars.width : $(window).width() + - outerWrapper.w.border + - (tmp.wrapper.width - currentSettings.width); + maxHeight-= currentSettings.padding*2; + maxWidth-= currentSettings.padding*2; + + if (tmp.content.height > maxHeight || tmp.content.width > maxWidth) { + // We're gonna resize the modal as it will goes outside the view port + if (currentSettings.type == 'image' || currentSettings.type == 'swf') { + // An image is resized proportionnaly + var useW = currentSettings.imgWidth?currentSettings.imgWidth : currentSettings.width; + var useH = currentSettings.imgHeight?currentSettings.imgHeight : currentSettings.height; + var diffW = tmp.content.width - useW; + var diffH = tmp.content.height - useH; + if (diffH < 0) diffH = 0; + if (diffW < 0) diffW = 0; + var calcH = maxHeight - diffH; + var calcW = maxWidth - diffW; + var ratio = Math.min(calcH/useH, calcW/useW); + calcW = Math.floor(useW*ratio); + calcH = Math.floor(useH*ratio); + tmp.content.height = calcH + diffH; + tmp.content.width = calcW + diffW; + } else { + // For an HTML content, we simply decrease the size + tmp.content.height = Math.min(tmp.content.height, maxHeight); + tmp.content.width = Math.min(tmp.content.width, maxWidth); + } + tmp.wrapper2 = { + width: tmp.content.width + outerContent.w.total, + height: tmp.content.height + outerContent.h.total + }; + tmp.wrapper = { + width: tmp.content.width + outerContent.w.total + outerWrapper2.w.total, + height: tmp.content.height + outerContent.h.total + outerWrapper2.h.total + }; + } + } + + if (currentSettings.type == 'swf') { + $('object, embed', modal.content) + .attr('width', tmp.content.width) + .attr('height', tmp.content.height); + } else if (currentSettings.type == 'image') { + $('img', modal.content).css({ + width: tmp.content.width, + height: tmp.content.height + }); + } + + modal.content.css($.extend({}, tmp.content, currentSettings.cssOpt.content)); + modal.wrapper.css($.extend({}, tmp.wrapper2, currentSettings.cssOpt.wrapper2)); + + if (!resizing) + modal.contentWrapper.css($.extend({}, tmp.wrapper, currentSettings.cssOpt.wrapper)); + + if (currentSettings.type == 'image' && currentSettings.addImageDivTitle) { + // Adding the title for the image + $('img', modal.content).removeAttr('alt'); + var divTitle = $('div', modal.content); + if (currentSettings.title != currentSettings.defaultImgAlt && currentSettings.title) { + if (divTitle.length == 0) { + divTitle = $('
'+currentSettings.title+'
'); + modal.content.append(divTitle); + } + if (currentSettings.setWidthImgTitle) { + var outerDivTitle = getOuter(divTitle); + divTitle.css({width: (tmp.content.width + outerContent.w.padding - outerDivTitle.w.total)+'px'}); + } + } else if (divTitle.length = 0) { + divTitle.remove(); + } + } + + if (currentSettings.title) + setTitle(); + + tmp.wrapper.borderW = outerWrapper.w.border; + tmp.wrapper.borderH = outerWrapper.h.border; + + setCurrentSettings(tmp.wrapper); + setMargin(); + } + + function removeModal(e) { + debug('removeModal'); + if (e) + e.preventDefault(); + if (modal.full && modal.ready) { + $(document).unbind('keydown.nyroModal'); + if (!currentSettings.blocker) + $(window).unbind('resize.nyroModal'); + modal.ready = false; + modal.anim = true; + modal.closing = true; + if (modal.loadingShown || modal.transition) { + currentSettings.hideLoading(modal, currentSettings, function() { + modal.loading.hide(); + modal.loadingShown = false; + modal.transition = false; + currentSettings.hideBackground(modal, currentSettings, endRemove); + }); + } else { + if (fixFF) + modal.content.css({position: ''}); // Fix Issue #10, remove the attribute + modal.wrapper.css({overflow: 'hidden'}); // Used to fix a visual issue when hiding + modal.content.css({overflow: 'hidden'}); // Used to fix a visual issue when hiding + $('iframe', modal.content).hide(); // Fix issue 359 + if ($.isFunction(currentSettings.beforeHideContent)) { + currentSettings.beforeHideContent(modal, currentSettings, function() { + currentSettings.hideContent(modal, currentSettings, function() { + endHideContent(); + currentSettings.hideBackground(modal, currentSettings, endRemove); + }); + }); + } else { + currentSettings.hideContent(modal, currentSettings, function() { + endHideContent(); + currentSettings.hideBackground(modal, currentSettings, endRemove); + }); + } + } + } + if (e) + return false; + } + + function showContentOrLoading() { + debug('showContentOrLoading'); + if (modal.ready && !modal.anim) { + if (modal.dataReady) { + if (modal.tmp.html()) { + modal.anim = true; + if (modal.transition) { + fillContent(); + modal.animContent = true; + currentSettings.hideTransition(modal, currentSettings, function() { + modal.loading.hide(); + modal.transition = false; + modal.loadingShown = false; + endShowContent(); + }); + } else { + currentSettings.hideLoading(modal, currentSettings, function() { + modal.loading.hide(); + modal.loadingShown = false; + fillContent(); + setMarginLoading(); + setMargin(); + modal.animContent = true; + currentSettings.showContent(modal, currentSettings, endShowContent); + }); + } + } + } else if (!modal.loadingShown && !modal.transition) { + modal.anim = true; + modal.loadingShown = true; + if (modal.error) + loadingError(); + else + modal.loading.html(currentSettings.contentLoading); + $(currentSettings.closeSelector, modal.loading) + .unbind('click.nyroModal') + .bind('click.nyroModal', removeModal); + setMarginLoading(); + currentSettings.showLoading(modal, currentSettings, function(){modal.anim=false;showContentOrLoading();}); + } + } + } + + // ------------------------------------------------------- + // Private Data Loaded callback + // ------------------------------------------------------- + + function ajaxLoaded(data) { + debug('AjaxLoaded: '+this.url); + + if (currentSettings.selector) { + var tmp = {}; + var i = 0; + // Looking for script to store them + data = data + .replace(/\r\n/gi,'nyroModalLN') + .replace(//gi, function(x) { + tmp[i] = x; + return ''; + }); + data = $('
'+data+'
').find(currentSettings.selector).html() + .replace(/
\n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += "
" + genlang(31, false) + "" + genlang(34, false) + "" + genlang(32, false) + "" + genlang(33, false) + "" + genlang(35, true) + "" + genlang(36, true) + "" + genlang(37, true) + "
  " + genlang(38, false) + "
\n"; + + $("#filesystem").append(html); + + filesystemTable = $("#filesystemTable").dataTable({ + "bPaginate": false, + "bLengthChange": false, + "bFilter": false, + "bSort": true, + "bInfo": false, + "bProcessing": true, + "bAutoWidth": false, + "bStateSave": true, + "aoColumns": [{ + "sType": 'span-string', + "sWidth": "100px" + }, { + "sType": 'span-string', + "sWidth": "50px" + }, { + "sType": 'span-string', + "sWidth": "200px" + }, { + "sType": 'span-number' + }, { + "sType": 'span-number', + "sWidth": "80px", + "sClass": "right" + }, { + "sType": 'span-number', + "sWidth": "80px", + "sClass": "right" + }, { + "sType": 'span-number', + "sWidth": "80px", + "sClass": "right" + }] + }); +} + +/** + * fill all errors from the xml in the error div element in the document and show the error icon + * @param {jQuery} xml phpSysInfo-XML + */ +function populateErrors(xml) { + var values = false; + $("Errors Error", xml).each(function getError(id) { +// $("#errorlist").append("" + $(this).attr("Function") + "

" + $(this).text() + "

"); + $("#errorlist").append("" + $(this).attr("Function") + "

" + $(this).attr("Message") + "

"); + values = true; + }); + if (values) { + $("#warn").css("display", "inline"); + } +} + +/** + * show the page + * @param {jQuery} xml phpSysInfo-XML + */ +function displayPage(xml) { + var versioni = ""; + if (cookie_template !== null) { + $("#template").val(cookie_template); + } + if (cookie_language !== null) { + $("#lang").val(cookie_language); + } + $("#loader").hide(); + $("#container").fadeIn("slow"); + versioni = $("Generation", xml).attr("version").toString(); + $("#version").html(versioni); + + $("Options", xml).each(function getOptions(id) { + var showPickListLang = "", showPickListTemplate = ""; + showPickListLang = $(this).attr("showPickListLang"); + showPickListTemplate = $(this).attr("showPickListTemplate"); + if (showPickListTemplate === 'false') { + $('#template').hide(); + $('span[id=lang_044]').hide(); + } + if (showPickListLang === 'false') { + $('#lang').hide(); + $('span[id=lang_045]').hide(); + } + }); +} + +/** + * format seconds to a better readable statement with days, hours and minutes + * @param {Number} sec seconds that should be formatted + * @return {String} html string with no breaking spaces and translation statements + */ +function formatUptime(sec) { + var txt = "", intMin = 0, intHours = 0, intDays = 0; + intMin = sec / 60; + intHours = intMin / 60; + intDays = Math.floor(intHours / 24); + intHours = Math.floor(intHours - (intDays * 24)); + intMin = Math.floor(intMin - (intDays * 60 * 24) - (intHours * 60)); + if (intDays) { + txt += intDays.toString() + " " + genlang(48, false) + " "; + } + if (intHours) { + txt += intHours.toString() + " " + genlang(49, false) + " "; + } + return txt + intMin.toString() + " " + genlang(50, false); +} + +/** + * format a given MHz value to a better readable statement with the right suffix + * @param {Number} mhertz mhertz value that should be formatted + * @return {String} html string with no breaking spaces and translation statements + */ +function formatHertz(mhertz) { + if (mhertz && mhertz < 1000) { + return mhertz.toString() + " " + genlang(92, true); + } + else { + if (mhertz && mhertz >= 1000) { + return round(mhertz / 1000, 2) + " " + genlang(93, true); + } + else { + return ""; + } + } +} + +/** + * format the byte values into a user friendly value with the corespondenting unit expression
support is included + * for binary and decimal output
user can specify a constant format for all byte outputs or the output is formated + * automatically so that every value can be read in a user friendly way + * @param {Number} bytes value that should be converted in the corespondenting format, which is specified in the phpsysinfo.ini + * @param {jQuery} xml phpSysInfo-XML + * @return {String} string of the converted bytes with the translated unit expression + */ +function formatBytes(bytes, xml) { + var byteFormat = "", show = ""; + + $("Options", xml).each(function getByteFormat(id) { + byteFormat = $(this).attr("byteFormat"); + }); + + switch (byteFormat.toLowerCase()) { + case "pib": + show += round(bytes / Math.pow(1024, 5), 2); + show += " " + genlang(90, true); + break; + case "tib": + show += round(bytes / Math.pow(1024, 4), 2); + show += " " + genlang(86, true); + break; + case "gib": + show += round(bytes / Math.pow(1024, 3), 2); + show += " " + genlang(87, true); + break; + case "mib": + show += round(bytes / Math.pow(1024, 2), 2); + show += " " + genlang(88, true); + break; + case "kib": + show += round(bytes / Math.pow(1024, 1), 2); + show += " " + genlang(89, true); + break; + case "pb": + show += round(bytes / Math.pow(1000, 5), 2); + show += " " + genlang(91, true); + break; + case "tb": + show += round(bytes / Math.pow(1000, 4), 2); + show += " " + genlang(85, true); + break; + case "gb": + show += round(bytes / Math.pow(1000, 3), 2); + show += " " + genlang(41, true); + break; + case "mb": + show += round(bytes / Math.pow(1000, 2), 2); + show += " " + genlang(40, true); + break; + case "kb": + show += round(bytes / Math.pow(1000, 1), 2); + show += " " + genlang(39, true); + break; + case "b": + show += bytes; + show += " " + genlang(96, true); + break; + case "auto_decimal": + if (bytes > Math.pow(1000, 5)) { + show += round(bytes / Math.pow(1000, 5), 2); + show += " " + genlang(91, true); + } + else { + if (bytes > Math.pow(1000, 4)) { + show += round(bytes / Math.pow(1000, 4), 2); + show += " " + genlang(85, true); + } + else { + if (bytes > Math.pow(1000, 3)) { + show += round(bytes / Math.pow(1000, 3), 2); + show += " " + genlang(41, true); + } + else { + if (bytes > Math.pow(1000, 2)) { + show += round(bytes / Math.pow(1000, 2), 2); + show += " " + genlang(40, true); + } + else { + if (bytes > Math.pow(1000, 1)) { + show += round(bytes / Math.pow(1000, 1), 2); + show += " " + genlang(39, true); + } + else { + show += bytes; + show += " " + genlang(96, true); + } + } + } + } + } + break; + default: + if (bytes > Math.pow(1024, 5)) { + show += round(bytes / Math.pow(1024, 5), 2); + show += " " + genlang(90, true); + } + else { + if (bytes > Math.pow(1024, 4)) { + show += round(bytes / Math.pow(1024, 4), 2); + show += " " + genlang(86, true); + } + else { + if (bytes > Math.pow(1024, 3)) { + show += round(bytes / Math.pow(1024, 3), 2); + show += " " + genlang(87, true); + } + else { + if (bytes > Math.pow(1024, 2)) { + show += round(bytes / Math.pow(1024, 2), 2); + show += " " + genlang(88, true); + } + else { + if (bytes > Math.pow(1024, 1)) { + show += round(bytes / Math.pow(1024, 1), 2); + show += " " + genlang(89, true); + } + else { + show += bytes; + show += " " + genlang(96, true); + } + } + } + } + } + } + return show; +} + +/** + * format a celcius temperature to fahrenheit and also append the right suffix + * @param {String} degreeC temperature in celvius + * @param {jQuery} xml phpSysInfo-XML + * @return {String} html string with no breaking spaces and translation statements + */ +function formatTemp(degreeC, xml) { + var tempFormat = "", degree = 0; + + $("Options", xml).each(function getOptions(id) { + tempFormat = $(this).attr("tempFormat").toString().toLowerCase(); + }); + + degree = parseFloat(degreeC); + if (isNaN(degreeC)) { + return "---"; + } + else { + switch (tempFormat) { + case "f": + return round((((9 * degree) / 5) + 32), 1) + " " + genlang(61, true); + case "c": + return round(degree, 1) + " " + genlang(60, true); + case "c-f": + return round(degree, 1) + " " + genlang(60, true) + "
(" + round((((9 * degree) / 5) + 32), 1) + " " + genlang(61, true) + ")"; + case "f-c": + return round((((9 * degree) / 5) + 32), 1) + " " + genlang(61, true) + "
(" + round(degree, 1) + " " + genlang(60, true) + ")"; + } + } +} + +/** + * create a visual HTML bar from a given size, the layout of that bar can be costumized through the bar css-class + * @param {Number} size barclass + * @return {String} HTML string which contains the full layout of the bar + */ +function createBar(size, barclass) { + if (barclass === undefined) { + barclass = "bar"; + } + return "
 
 " + size + "%"; +} + +/** + * (re)fill the vitals block with the values from the given xml + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshVitals(xml) { + var hostname = "", ip = "", kernel = "", distro = "", icon = "", uptime = "", users = 0, loadavg = ""; + var processes = 0, prunning = 0, psleeping = 0, pstopped = 0, pzombie = 0, pwaiting = 0, pother = 0; + var syslang = "", codepage = ""; + var lastboot = 0; + var timestamp = parseInt($("Generation", xml).attr("timestamp"), 10)*1000; //server time + var not_first = false; + if (isNaN(timestamp)) timestamp = Number(new Date()); //client time + + $("Vitals", xml).each(function getVitals(id) { + hostname = $(this).attr("Hostname"); + ip = $(this).attr("IPAddr"); + kernel = $(this).attr("Kernel"); + distro = $(this).attr("Distro"); + icon = $(this).attr("Distroicon"); + uptime = formatUptime(parseInt($(this).attr("Uptime"), 10)); + lastboot = new Date(timestamp - (parseInt($(this).attr("Uptime"), 10)*1000)); + users = parseInt($(this).attr("Users"), 10); + loadavg = $(this).attr("LoadAvg"); + if ($(this).attr("CPULoad") !== undefined) { + loadavg = loadavg + "
" + createBar(parseInt($(this).attr("CPULoad"), 10)); + } + if ($(this).attr("SysLang") !== undefined) { + syslang = $(this).attr("SysLang"); + document.getElementById("s_syslang_tr").style.display=''; + } + + if ($(this).attr("CodePage") !== undefined) { + codepage = $(this).attr("CodePage"); + if ($(this).attr("SysLang") !== undefined) { + document.getElementById("s_codepage_tr1").style.display=''; + } else { + document.getElementById("s_codepage_tr2").style.display=''; + } + } + + //processes + if ($(this).attr("Processes") !== undefined) { + processes = parseInt($(this).attr("Processes"), 10); + if ((($(this).attr("CodePage") !== undefined) && ($(this).attr("SysLang") == undefined)) || + (($(this).attr("CodePage") == undefined) && ($(this).attr("SysLang") !== undefined))) { + document.getElementById("s_processes_tr1").style.display=''; + } else { + document.getElementById("s_processes_tr2").style.display=''; + } + } + if ($(this).attr("ProcessesRunning") !== undefined) { + prunning = parseInt($(this).attr("ProcessesRunning"), 10); + } + if ($(this).attr("ProcessesSleeping") !== undefined) { + psleeping = parseInt($(this).attr("ProcessesSleeping"), 10); + } + if ($(this).attr("ProcessesStopped") !== undefined) { + pstopped = parseInt($(this).attr("ProcessesStopped"), 10); + } + if ($(this).attr("ProcessesZombie") !== undefined) { + pzombie = parseInt($(this).attr("ProcessesZombie"), 10); + } + if ($(this).attr("ProcessesWaiting") !== undefined) { + pwaiting = parseInt($(this).attr("ProcessesWaiting"), 10); + } + if ($(this).attr("ProcessesOther") !== undefined) { + pother = parseInt($(this).attr("ProcessesOther"), 10); + } + + document.title = "System information: " + hostname + " (" + ip + ")"; + $("#s_hostname_title").html(hostname); + $("#s_ip_title").html(ip); + $("#s_hostname").html(hostname); + $("#s_ip").html(ip); + $("#s_kernel").html(kernel); + $("#s_distro").html("Icon " + distro); + $("#s_uptime").html(uptime); + if (typeof(lastboot.toUTCString)==="function") { + $("#s_lastboot").html(lastboot.toUTCString()); //toUTCstring() or toLocaleString() + } else { + //deprecated + $("#s_lastboot").html(lastboot.toGMTString()); //toGMTString() or toLocaleString() + } + $("#s_users").html(users); + $("#s_loadavg").html(loadavg); + $("#s_syslang").html(syslang); + $("#s_codepage_1").html(codepage); + $("#s_codepage_2").html(codepage); + $("#s_processes_1").html(processes); + if (prunning || psleeping || pstopped || pzombie || pwaiting || pother) { + $("#s_processes_1").append(" ("); + var typelist = {running:111,sleeping:112,stopped:113,zombie:114,waiting:115,other:116}; + for (var proc_type in typelist) { + if (eval("p" + proc_type)) { + if (not_first) { + $("#s_processes_1").append(", "); + } + $("#s_processes_1").append(eval("p" + proc_type) + " " + genlang(typelist[proc_type], true)); + not_first = true; + } + } + $("#s_processes_1").append(") "); + } + $("#s_processes_2").html($("#s_processes_1").html()); + }); +} + + +/** + * build the cpu information as table rows + * @param {jQuery} xml phpSysInfo-XML + * @param {Array} tree array that holds the positions for treetable plugin + * @param {Number} rootposition position of the parent element + * @param {Array} collapsed array that holds all collapsed elements hwne opening page + */ +function fillCpu(xml, tree, rootposition, collapsed) { + var cpucount = 0, html = ""; + var showCPUInfoExpanded = ""; + var showCPUListExpanded = ""; + $("Options", xml).each(function getOptions(id) { + showCPUInfoExpanded = $(this).attr("showCPUInfoExpanded"); + showCPUListExpanded = $(this).attr("showCPUListExpanded"); + }); + $("Hardware CPU CpuCore", xml).each(function getCpuCore(cpuCoreId) { + var model = "", speed = 0, bus = 0, cache = 0, bogo = 0, temp = 0, load = 0, speedmax = 0, speedmin = 0, cpucoreposition = 0, virt = ""; + cpucount += 1; + model = $(this).attr("Model"); + speed = parseInt($(this).attr("CpuSpeed"), 10); + speedmax = parseInt($(this).attr("CpuSpeedMax"), 10); + speedmin = parseInt($(this).attr("CpuSpeedMin"), 10); + cache = parseInt($(this).attr("Cache"), 10); + virt = $(this).attr("Virt"); + bus = parseInt($(this).attr("BusSpeed"), 10); + temp = parseInt($(this).attr("Cputemp"), 10); + bogo = parseInt($(this).attr("Bogomips"), 10); + load = parseInt($(this).attr("Load"), 10); + + if (showCPUListExpanded === 'false') { + collapsed.push(rootposition); + } + html += "" + model + "\n"; + cpucoreposition = tree.push(rootposition); + if (showCPUInfoExpanded !== 'true') { + collapsed.push(cpucoreposition); + } + if (!isNaN(speed)) { + html += "" + genlang(13, true) + ":" + formatHertz(speed) + "\n"; + tree.push(cpucoreposition); + } + if (!isNaN(speedmax)) { + html += "" + genlang(100, true) + ":" + formatHertz(speedmax) + "\n"; + tree.push(cpucoreposition); + } + if (!isNaN(speedmin)) { + html += "" + genlang(101, true) + ":" + formatHertz(speedmin) + "\n"; + tree.push(cpucoreposition); + } + if (!isNaN(cache)) { + html += "" + genlang(15, true) + ":" + formatBytes(cache) + "\n"; + tree.push(cpucoreposition); + } + if (virt != undefined) { + html += "" + genlang(94, true) + ":" + virt + "\n"; + tree.push(cpucoreposition); + } + if (!isNaN(bus)) { + html += "" + genlang(14, true) + ":" + formatHertz(bus) + "\n"; + tree.push(cpucoreposition); + } + if (!isNaN(bogo)) { + html += "" + genlang(16, true) + ":" + bogo.toString() + "\n"; + tree.push(cpucoreposition); + } + if (!isNaN(temp)) { + html += "" + genlang(51, true) + ":" + formatTemp(temp, xml) + "\n"; + tree.push(cpucoreposition); + } + if (!isNaN(load)) { + html += "" + genlang(9, true) + ":" + createBar(load) + "\n"; + tree.push(cpucoreposition); + } + }); + if (cpucount === 0) { + html += "" + genlang(42, true) + "\n"; + tree.push(rootposition); + } + return html; +} + +function countCpu(xml) { + var cpucount = 0; + $("Hardware CPU CpuCore", xml).each(function getCpuCore(cpuCoreId) { + cpucount += 1; + }); + return cpucount; +} + +/** + * build rows for a treetable out of the hardwaredevices + * @param {jQuery} xml phpSysInfo-XML + * @param {String} type type of the hardware device + * @param {Array} tree array that holds the positions for treetable plugin + * @param {Number} rootposition position of the parent element + */ +function fillHWDevice(xml, type, tree, rootposition) { + var devicecount = 0, html = ""; + $("Hardware " + type + " Device", xml).each(function getPciDevice(deviceId) { + var name = "", count = 0; + devicecount += 1; + name = $(this).attr("Name"); + count = parseInt($(this).attr("Count"), 10); + if (!isNaN(count) && count > 1) { + name = "(" + count + "x) " + name; + } + html += "" + name + "\n"; + tree.push(rootposition); + }); + if (devicecount === 0) { + html += "" + genlang(42, true) + "\n"; + tree.push(rootposition); + } + return html; +} + +function countHWDevice(xml, type) { + var devicecount = 0; + $("Hardware " + type + " Device", xml).each(function getPciDevice(deviceId) { + devicecount += 1; + }); + return devicecount; +} + +/** + * (re)fill the hardware block with the values from the given xml + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshHardware(xml) { + var html = "", tree = [], closed = [], index = 0, machine = ""; + $("#hardware").empty(); + html += "

" + genlang(10, false) + "

\n"; + html += " \n"; + html += " \n"; + + $("Hardware", xml).each(function getMachine(id) { + machine = $(this).attr("Name"); + }); + if ((machine !== undefined) && (machine != "")) { + html += " \n"; + html += "\n"; + tree.push(tree.push(0)); + } + + if (countCpu(xml)) { + html += " \n"; + html += fillCpu(xml, tree, tree.push(0), closed); + } + + if (countHWDevice(xml, 'PCI')) { + html += " \n"; + index = tree.push(0); + closed.push(index); + html += fillHWDevice(xml, 'PCI', tree, index); + } + + if (countHWDevice(xml, 'IDE')) { + html += " \n"; + index = tree.push(0); + closed.push(index); + html += fillHWDevice(xml, 'IDE', tree, index); + } + + if (countHWDevice(xml, 'SCSI')) { + html += " \n"; + index = tree.push(0); + closed.push(index); + html += fillHWDevice(xml, 'SCSI', tree, index); + } + + if (countHWDevice(xml, 'USB')) { + html += " \n"; + index = tree.push(0); + closed.push(index); + html += fillHWDevice(xml, 'USB', tree, index); + } + + if (countHWDevice(xml, 'TB')) { + html += " \n"; + index = tree.push(0); + closed.push(index); + html += fillHWDevice(xml, 'TB', tree, index); + } + + if (countHWDevice(xml, 'I2C')) { + html += " \n"; + index = tree.push(0); + closed.push(index); + html += fillHWDevice(xml, 'I2C', tree, index); + } + + html += " \n"; + html += "
" + genlang(107, false) + "
" + machine + "
" + genlang(11, false) + "
" + genlang(17, false) + "
" + genlang(18, false) + "
" + genlang(19, false) + "
" + genlang(20, false) + "
" + genlang(117, false) + "
" + genlang(118, false) + "
\n"; + $("#hardware").append(html); + + $("#HardwareTree").jqTreeTable(tree, { + openImg: "./gfx/treeTable/tv-collapsable.gif", + shutImg: "./gfx/treeTable/tv-expandable.gif", + leafImg: "./gfx/treeTable/tv-item.gif", + lastOpenImg: "./gfx/treeTable/tv-collapsable-last.gif", + lastShutImg: "./gfx/treeTable/tv-expandable-last.gif", + lastLeafImg: "./gfx/treeTable/tv-item-last.gif", + vertLineImg: "./gfx/treeTable/vertline.gif", + blankImg: "./gfx/treeTable/blank.gif", + collapse: closed, + column: 0, + striped: true, + highlight: false, + state: false + }); +} + +/** + *(re)fill the network block with the values from the given xml + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshNetwork(xml) { + var tree = [], closed = [], html0= "", html1= "" ,html = "", isinfo = false; + $("#network").empty(); + + html0 += "

" + genlang(21, false) + "

\n"; + + html1 += " \n"; + html1 += " \n"; + html1 += " " + genlang(22, true) + "\n"; + html1 += " " + genlang(23, true) + "\n"; + html1 += " " + genlang(24, true) + "\n"; + html1 += " " + genlang(25, true) + "\n"; + html1 += " \n"; + html1 += " \n"; + + $("Network NetDevice", xml).each(function getDevice(id) { + var name = "", rx = 0, tx = 0, er = 0, dr = 0, info = "", networkindex = 0; + name = $(this).attr("Name"); + rx = parseInt($(this).attr("RxBytes"), 10); + tx = parseInt($(this).attr("TxBytes"), 10); + er = parseInt($(this).attr("Err"), 10); + dr = parseInt($(this).attr("Drops"), 10); + html +="" + name + "" + formatBytes(rx, xml) + "" + formatBytes(tx, xml) + "" + er.toString() + "\/​" + dr.toString() + ""; + + networkindex = tree.push(0); + + info = $(this).attr("Info"); + if ( (info !== undefined) && (info != "") ) { + var i =0, infos = info.replace(/:/g, "​:").split(";"); /* split long addresses */ + isinfo = true; + for(i = 0; i < infos.length; i++){ + html +="" + infos[i] + ""; + tree.push(networkindex); + } + closed.push(networkindex); + } + }); + html += "\n"; + html += "\n"; + if (isinfo) { + html0 += "\n"; + html1 += " \n"; + } else { + html0 += "
\n"; + html1 += " \n"; + } + $("#network").append(html0+html1+html); + + if (isinfo) $("#NetworkTree").jqTreeTable(tree, { + openImg: "./gfx/treeTable/tv-collapsable.gif", + shutImg: "./gfx/treeTable/tv-expandable.gif", + leafImg: "./gfx/treeTable/tv-item.gif", + lastOpenImg: "./gfx/treeTable/tv-collapsable-last.gif", + lastShutImg: "./gfx/treeTable/tv-expandable-last.gif", + lastLeafImg: "./gfx/treeTable/tv-item-last.gif", + vertLineImg: "./gfx/treeTable/vertline.gif", + blankImg: "./gfx/treeTable/blank.gif", + collapse: closed, + column: 0, + striped: true, + highlight: false, + state: false + }); +} + +/** + * (re)fill the memory block with the values from the given xml + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshMemory(xml) { + var html = "", tree = [], closed = []; + + $("#memory").empty(); + html += "

" + genlang(27, false) + "

\n"; + html += "
\n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + html += " \n"; + + $("Memory", xml).each(function getMemory(id) { + var free = 0, total = 0, used = 0, percent = 0, memoryindex = 0; + free = parseInt($(this).attr("Free"), 10); + used = parseInt($(this).attr("Used"), 10); + total = parseInt($(this).attr("Total"), 10); + percent = parseInt($(this).attr("Percent"), 10); + html += ""; + memoryindex = tree.push(0); + + $("Memory Details", xml).each(function getMemorydetails(id) { + var app = 0, appp = 0, buff = 0, buffp = 0, cached = 0, cachedp = 0; + app = parseInt($(this).attr("App"), 10); + appp = parseInt($(this).attr("AppPercent"), 10); + buff = parseInt($(this).attr("Buffers"), 10); + buffp = parseInt($(this).attr("BuffersPercent"), 10); + cached = parseInt($(this).attr("Cached"), 10); + cachedp = parseInt($(this).attr("CachedPercent"), 10); + if (!isNaN(app)) { + html += ""; + tree.push(memoryindex); + } + if (!isNaN(cached)) { + html += ""; + tree.push(memoryindex); + } + if (!isNaN(buff)) { + html += ""; + tree.push(memoryindex); + } + if (!isNaN(app) || !isNaN(buff) || !isNaN(cached)) { + closed.push(memoryindex); + } + }); + }); + $("Memory Swap", xml).each(function getSwap(id) { + var free = 0, total = 0, used = 0, percent = 0, swapindex = 0; + free = parseInt($(this).attr("Free"), 10); + used = parseInt($(this).attr("Used"), 10); + total = parseInt($(this).attr("Total"), 10); + percent = parseInt($(this).attr("Percent"), 10); + html += ""; + swapindex = tree.push(0); + + $("Memory Swap Mount", xml).each(function getDevices(id) { + var free = 0, total = 0, used = 0, percent = 0, mpoint = "", mpid = 0; + closed.push(swapindex); + free = parseInt($(this).attr("Free"), 10); + used = parseInt($(this).attr("Used"), 10); + total = parseInt($(this).attr("Total"), 10); + percent = parseInt($(this).attr("Percent"), 10); + mpid = parseInt($(this).attr("MountPointID"), 10); + mpoint = $(this).attr("MountPoint"); + + if (mpoint === undefined) { + mpoint = mpid; + } + + html += ""; + tree.push(swapindex); + }); + }); + + html += " \n"; + html += "
" + genlang(34, true) + "" + genlang(33, true) + "" + genlang(35, true) + "" + genlang(36, true) + "" + genlang(37, true) + "
" + genlang(28, false) + "" + createBar(percent) + "" + formatBytes(free, xml) + "" + formatBytes(used, xml) + "" + formatBytes(total, xml) + "
" + genlang(64, false) + "" + createBar(appp) + " " + formatBytes(app, xml) + " 
" + genlang(66, false) + "" + createBar(cachedp) + " " + formatBytes(cached, xml) + " 
" + genlang(65, false) + "" + createBar(buffp) + " " + formatBytes(buff, xml) + " 
" + genlang(29, false) + "" + createBar(percent) + "" + formatBytes(free, xml) + "" + formatBytes(used, xml) + "" + formatBytes(total, xml) + "
" + mpoint + "" + createBar(percent) + "" + formatBytes(free, xml) + "" + formatBytes(used, xml) + "" + formatBytes(total, xml) + "
\n"; + $("#memory").append(html); + + $("#MemoryTree").jqTreeTable(tree, { + openImg: "./gfx/treeTable/tv-collapsable.gif", + shutImg: "./gfx/treeTable/tv-expandable.gif", + leafImg: "./gfx/treeTable/tv-item.gif", + lastOpenImg: "./gfx/treeTable/tv-collapsable-last.gif", + lastShutImg: "./gfx/treeTable/tv-expandable-last.gif", + lastLeafImg: "./gfx/treeTable/tv-item-last.gif", + vertLineImg: "./gfx/treeTable/vertline.gif", + blankImg: "./gfx/treeTable/blank.gif", + collapse: closed, + column: 0, + striped: true, + highlight: false, + state: false + }); + +} + +/** + * (re)fill the filesystems block with the values from the given xml

+ * appends the filesystems (each in a row) to the filesystem table in the tbody
before the rows are inserted the entire + * tbody is cleared + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshFilesystems(xml) { + var total_usage = 0, total_used = 0, total_free = 0, total_size = 0, threshold = 0; + + filesystemTable.fnClearTable(); + + $("Options", xml).each(function getThreshold(id) { + threshold = parseInt($(this).attr("threshold"), 10); + }); + + $("FileSystem Mount", xml).each(function getMount(mid) { + var mpoint = "", mpid = 0, type = "", name = "", free = 0, used = 0, size = 0, percent = 0, options = "", inodes = 0, inodes_text = "", options_text = ""; + mpid = parseInt($(this).attr("MountPointID"), 10); + type = $(this).attr("FSType"); + name = $(this).attr("Name"); + free = parseInt($(this).attr("Free"), 10); + used = parseInt($(this).attr("Used"), 10); + size = parseInt($(this).attr("Total"), 10); + percent = parseInt($(this).attr("Percent"), 10); + options = $(this).attr("MountOptions"); + inodes = parseInt($(this).attr("Inodes"), 10); + mpoint = $(this).attr("MountPoint"); + + if (mpoint === undefined) { + mpoint = mpid; + } + if (options !== undefined) { + options_text = "
(" + options + ")"; + } + if (!isNaN(inodes)) { + inodes_text = " (" + inodes.toString() + "%)"; + } + + if (!isNaN(threshold) && (percent >= threshold)) { + filesystemTable.fnAddData(["" + mpoint + "" + mpoint, "" + type + "" + type, "" + name + "" + name + options_text, "" + percent.toString() + "" + createBar(percent, "barwarn") + inodes_text, "" + free.toString() + "" + formatBytes(free, xml), "" + used.toString() + "" + formatBytes(used, xml), "" + size.toString() + "" + formatBytes(size, xml)]); + } else { + filesystemTable.fnAddData(["" + mpoint + "" + mpoint, "" + type + "" + type, "" + name + "" + name + options_text, "" + percent.toString() + "" + createBar(percent) + inodes_text, "" + free.toString() + "" + formatBytes(free, xml), "" + used.toString() + "" + formatBytes(used, xml), "" + size.toString() + "" + formatBytes(size, xml)]); + } + total_used += used; + total_free += free; + total_size += size; + total_usage = round((total_used / total_size) * 100, 2); + }); + + if (!isNaN(threshold) && (total_usage >= threshold)) { + $("#s_fs_total").html(createBar(total_usage, "barwarn")); + } else { + $("#s_fs_total").html(createBar(total_usage)); + } + $("#s_fs_tfree").html(formatBytes(total_free, xml)); + $("#s_fs_tused").html(formatBytes(total_used, xml)); + $("#s_fs_tsize").html(formatBytes(total_size, xml)); +} + +/** + * (re)fill the temperature block with the values from the given xml

+ * build the block content for the temperature block, this includes normal temperature information in the XML + * and also the HDDTemp information, if there are no information the entire table will be removed + * to avoid HTML warnings + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshTemp(xml) { + var values = false; + $("#tempTable tbody").empty(); + $("MBInfo Temperature Item", xml).each(function getTemperatures(id) { + var label = "", value = "", limit = 0, _limit = "", event = ""; + label = $(this).attr("Label"); + value = $(this).attr("Value").replace(/\+/g, ""); + limit = ($(this).attr("Max") !== undefined) ? parseFloat($(this).attr("Max").replace(/\+/g, "")) : 'NaN'; + if (isFinite(limit)) + _limit = formatTemp(limit, xml); + event = $(this).attr("Event"); + if (event !== undefined) + label += " \"!\""; + $("#tempTable tbody").append("" + label + "" + formatTemp(value, xml) + "" + _limit + ""); + values = true; + }); + if (values) { + $("#temp").show(); + } + else { + $("#temp").remove(); + } +} + +/** + * (re)fill the voltage block with the values from the given xml

+ * build the voltage information into a separate block, if there is no voltage information available the + * entire table will be removed to avoid HTML warnings + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshVoltage(xml) { + var values = false; + $("#voltageTable tbody").empty(); + $("MBInfo Voltage Item", xml).each(function getVoltages(id) { + var label = "", value = 0, max = 0, min = 0, _min = "", _max = "", event = ""; + label = $(this).attr("Label"); + value = parseFloat($(this).attr("Value")); + max = parseFloat($(this).attr("Max")); + if (isFinite(max)) + _max = round(max, 2) + " " + genlang(62, true); + min = parseFloat($(this).attr("Min")); + if (isFinite(min)) + _min = round(min, 2) + " " + genlang(62, true); + event = $(this).attr("Event"); + if (event !== undefined) + label += " \"!\""; + $("#voltageTable tbody").append("" + label + "" + round(value, 2) + " " + genlang(62, true) + "" + _min + "" + _max + ""); + values = true; + }); + if (values) { + $("#voltage").show(); + } + else { + $("#voltage").remove(); + } +} + +/** + * (re)fill the fan block with the values from the given xml

+ * build the fan information into a separate block, if there is no fan information available the + * entire table will be removed to avoid HTML warnings + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshFan(xml) { + var values = false; + $("#fanTable tbody").empty(); + $("MBInfo Fans Item", xml).each(function getFans(id) { + var label = "", value = 0, min = 0, _min = "", event = ""; + label = $(this).attr("Label"); + value = parseFloat($(this).attr("Value")); + min = parseFloat($(this).attr("Min")); + if (isFinite(min)) + _min = round(min,0) + " " + genlang(63, true); + event = $(this).attr("Event"); + if (event !== undefined) + label += " \"!\""; + $("#fanTable tbody").append("" + label + "" + round(value,0) + " " + genlang(63, true) + "" + _min + ""); + values = true; + }); + if (values) { + $("#fan").show(); + } + else { + $("#fan").remove(); + } +} + +/** + * (re)fill the power block with the values from the given xml

+ * build the power information into a separate block, if there is no power information available the + * entire table will be removed to avoid HTML warnings + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshPower(xml) { + var values = false; + $("#powerTable tbody").empty(); + $("MBInfo Power Item", xml).each(function getPowers(id) { + var label = "", value = "", limit = 0, _limit = "", event = ""; + label = $(this).attr("Label"); + value = $(this).attr("Value").replace(/\+/g, ""); + limit = ($(this).attr("Max") !== undefined) ? parseFloat($(this).attr("Max").replace(/\+/g, "")) : 'NaN'; + if (isFinite(limit)) + _limit = round(limit, 2) + " " + genlang(103, true); + event = $(this).attr("Event"); + if (event !== undefined) + label += " \"!\""; + $("#powerTable tbody").append("" + label + "" + round(value, 2) + " " + genlang(103, true) + "" + _limit + ""); + values = true; + }); + if (values) { + $("#power").show(); + } + else { + $("#power").remove(); + } +} + +/** + * (re)fill the current block with the values from the given xml

+ * build the current information into a separate block, if there is no current information available the + * entire table will be removed to avoid HTML warnings + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshCurrent(xml) { + var values = false; + $("#currentTable tbody").empty(); + $("MBInfo Current Item", xml).each(function getCurrents(id) { + var label = "", value = "", limit = 0, _limit = "", event = ""; + label = $(this).attr("Label"); + value = $(this).attr("Value").replace(/\+/g, ""); + limit = ($(this).attr("Max") !== undefined) ? parseFloat($(this).attr("Max").replace(/\+/g, "")) : 'NaN'; + if (isFinite(limit)) + _limit = round(limit, 2) + " " + genlang(106, true); + event = $(this).attr("Event"); + if (event !== undefined) + label += " \"!\""; + $("#currentTable tbody").append("" + label + "" + round(value, 2) + " " + genlang(106, true) + "" + _limit + ""); + values = true; + }); + if (values) { + $("#current").show(); + } + else { + $("#current").remove(); + } +} + +/** + * (re)fill the ups block with the values from the given xml

+ * build the ups information into a separate block, if there is no ups information available the + * entire table will be removed to avoid HTML warnings + * @param {jQuery} xml phpSysInfo-XML + */ +function refreshUps(xml) { + var add_apcupsd_cgi_links = ($("[ApcupsdCgiLinks='1']", xml).length > 0); + var html = "", tree = [], closed = [], index = 0, values = false; + html += "

" + genlang(68, false) + "

\n"; + html += " \n"; + html += " \n"; + + $("#ups").empty(); + $("UPSInfo UPS", xml).each(function getUps(id) { + var name = "", model = "", mode = "", start_time = "", upsstatus = "", temperature = "", outages_count = "", last_outage = "", last_outage_finish = "", line_voltage = "", line_frequency = "", load_percent = "", battery_date = "", battery_voltage = "", battery_charge_percent = "", time_left_minutes = ""; + name = $(this).attr("Name"); + model = $(this).attr("Model"); + mode = $(this).attr("Mode"); + start_time = $(this).attr("StartTime"); + upsstatus = $(this).attr("Status"); + + temperature = $(this).attr("Temperature"); + outages_count = $(this).attr("OutagesCount"); + last_outage = $(this).attr("LastOutage"); + last_outage_finish = $(this).attr("LastOutageFinish"); + line_voltage = $(this).attr("LineVoltage"); + line_frequency = $(this).attr("LineFrequency"); + load_percent = parseInt($(this).attr("LoadPercent"), 10); + battery_date = $(this).attr("BatteryDate"); + battery_voltage = $(this).attr("BatteryVoltage"); + battery_charge_percent = parseInt($(this).attr("BatteryChargePercent"), 10); + time_left_minutes = $(this).attr("TimeLeftMinutes"); + + html += "\n"; + index = tree.push(0); + if (model !== undefined) { + html += "\n"; + tree.push(index); + } + if (start_time !== undefined) { + html += "\n"; + tree.push(index); + } + if (upsstatus !== undefined) { + html += "\n"; + tree.push(index); + } + if (temperature !== undefined) { + html += "\n"; + tree.push(index); + } + if (outages_count !== undefined) { + html += "\n"; + tree.push(index); + } + if (last_outage !== undefined) { + html += "\n"; + tree.push(index); + } + if (last_outage_finish !== undefined) { + html += "\n"; + tree.push(index); + } + if (line_voltage !== undefined) { + html += "\n"; + tree.push(index); + } + if (line_frequency !== undefined) { + html += "\n"; + tree.push(index); + } + if (!isNaN(load_percent)) { + html += "\n"; + tree.push(index); + } + if (battery_date !== undefined) { + html += "\n"; + tree.push(index); + } + if (battery_voltage !== undefined) { + html += "\n"; + tree.push(index); + } + if (!isNaN(battery_charge_percent)) { + html += "\n"; + tree.push(index); + } + if (time_left_minutes !== undefined) { + html += "\n"; + tree.push(index); + } + values=true; + }); + html += " \n"; + html += "
" + name + " (" + mode + ")
" + genlang(70, false) + "" + model + "
" + genlang(72, false) + "" + start_time + "
" + genlang(73, false) + "" + upsstatus + "
" + genlang(84, false) + "" + temperature + "
" + genlang(74, false) + "" + outages_count + "
" + genlang(75, false) + "" + last_outage + "
" + genlang(76, false) + "" + last_outage_finish + "
" + genlang(77, false) + "" + line_voltage + " " + genlang(82, true) + "
" + genlang(108, false) + "" + line_frequency + " " + genlang(109, true) + "
" + genlang(78, false) + "" + createBar(load_percent) + "
" + genlang(104, false) + "" + battery_date + "
" + genlang(79, false) + "" + battery_voltage + " " + genlang(82, true) + "
" + genlang(80, false) + "" + createBar(battery_charge_percent) + "
" + genlang(81, false) + "" + time_left_minutes + " " + genlang(83, false) + "
\n"; + if (add_apcupsd_cgi_links){ + html += " (" + genlang(99, false) + ")\n"; + } + + $("#ups").append(html); + + if (values) { + $("#UPSTree").jqTreeTable(tree, { + openImg: "./gfx/treeTable/tv-collapsable.gif", + shutImg: "./gfx/treeTable/tv-expandable.gif", + leafImg: "./gfx/treeTable/tv-item.gif", + lastOpenImg: "./gfx/treeTable/tv-collapsable-last.gif", + lastShutImg: "./gfx/treeTable/tv-expandable-last.gif", + lastLeafImg: "./gfx/treeTable/tv-item-last.gif", + vertLineImg: "./gfx/treeTable/vertline.gif", + blankImg: "./gfx/treeTable/blank.gif", + collapse: closed, + column: 0, + striped: true, + highlight: false, + state: false + }); + $("#ups").show(); + } + else { + $("#ups").remove(); + } +} + +/** + * reload the page, this means all values are refreshed, except the plugins + */ +function reload() { + $.ajax({ + url: 'xml.php', + dataType: 'xml', + error: function error() { + $.jGrowl("Error loading XML document!"); + }, + success: function buildblocks(xml) { + refreshVitals(xml); + refreshNetwork(xml); + refreshHardware(xml); + refreshMemory(xml); + refreshFilesystems(xml); + refreshVoltage(xml); + refreshFan(xml); + refreshTemp(xml); + refreshPower(xml); + refreshCurrent(xml); + refreshUps(xml); + + $('.stripeMe tr:nth-child(even)').addClass('even'); + langcounter = 1; + } + }); +} + +/** + * set a reload timer for the page + * @param {jQuery} xml phpSysInfo-XML + */ +function settimer(xml) { + $("Options", xml).each(function getRefreshTime(id) { + var options, refresh = ""; + options = $("Options", xml).get(id); + refresh = $(this).attr("refresh"); + if (refresh !== '0') { + $.timer(refresh, reload); + } + }); +} + +cookie_language = readCookie("language"); +cookie_template = readCookie("template"); + +if (cookie_template) { + switchStyle(cookie_template); +} + +$(document).ready(function buildpage() { + filesystemtable(); + + $.ajax({ + url: 'xml.php', + dataType: 'xml', + error: function error() { + $.jGrowl("Error loading XML document!", { + sticky: true + }); + }, + success: function buildblocks(xml) { + populateErrors(xml); + + refreshVitals(xml); + refreshHardware(xml); + refreshNetwork(xml); + refreshMemory(xml); + refreshFilesystems(xml); + refreshTemp(xml); + refreshVoltage(xml); + refreshFan(xml); + refreshPower(xml); + refreshCurrent(xml); + refreshUps(xml); + + changeLanguage(); + displayPage(xml); + settimer(xml); + + $('.stripeMe tr:nth-child(even)').addClass('even'); + langcounter = 1; + } + }); + + $("#errors").nyroModal(); + + $("#lang").change(function changeLang() { + var language = "", i = 0; + language = $("#lang").val().toString(); + createCookie('language', language, 365); + cookie_language = readCookie('language'); + changeLanguage(); + for (i = 0; i < plugin_liste.length; i += 1) { + changeLanguage(plugin_liste[i]); + } + return false; + }); + + $("#template").change(function changeTemplate() { + switchStyle($("#template").val().toString()); + return false; + }); +}); + +jQuery.fn.dataTableExt.oSort['span-string-asc'] = function sortStringAsc(a, b) { + var x = "", y = ""; + x = a.substring(a.indexOf(">") + 1, a.indexOf("") + 1, b.indexOf(" y) ? 1 : 0)); +}; + +jQuery.fn.dataTableExt.oSort['span-string-desc'] = function sortStringDesc(a, b) { + var x = "", y = ""; + x = a.substring(a.indexOf(">") + 1, a.indexOf("") + 1, b.indexOf(" y) ? -1 : 0)); +}; + +jQuery.fn.dataTableExt.oSort['span-number-asc'] = function sortNumberAsc(a, b) { + var x = 0, y = 0; + x = parseInt(a.substring(a.indexOf(">") + 1, a.indexOf("") + 1, b.indexOf(" y) ? 1 : 0)); +}; + +jQuery.fn.dataTableExt.oSort['span-number-desc'] = function sortNumberDesc(a, b) { + var x = 0, y = 0; + x = parseInt(a.substring(a.indexOf(">") + 1, a.indexOf("") + 1, b.indexOf(" y) ? -1 : 0)); +}; + +/** + * generate the block element for a specific plugin that is available + * @param {String} plugin name of the plugin + * @param {Number} translationid id of the translated headline in the plugin translation file + * @param {Boolean} reload controls if a reload button should be appended to the headline + * @return {String} HTML string which contains the full layout of the block + */ +function buildBlock(plugin, translationid, reload) { + var block = "", reloadpic = ""; + if (reload) { + reloadpic = "\"reload\" "; + } + block += "
\n"; + block += "

" + reloadpic + genlang(translationid, false, plugin) + "

\n"; + block += "
\n"; + return block; +} + +/** + * translate a plugin and add this plugin to the internal plugin-list, this is only needed once and shouldn't be called more than once + * @param {String} plugin name of the plugin that should be translated + */ +function plugin_translate(plugin) { + plugin_liste.push(plugin); + changeLanguage(plugin); +} + +/** + * generate a formatted datetime string of the current datetime + * @return {String} formatted datetime string + */ +function datetime() { + var date, day = 0, month = 0, year = 0, hour = 0, minute = 0, days = "", months = "", years = "", hours = "", minutes = ""; + date = new Date(); + day = date.getDate(); + month = date.getMonth() + 1; + year = date.getFullYear(); + hour = date.getHours(); + minute = date.getMinutes(); + + // format values smaller that 10 with a leading 0 + days = (day < 10) ? "0" + day.toString() : day.toString(); + months = (month < 10) ? "0" + month.toString() : month.toString(); + years = (year < 1000) ? year.toString() : year.toString(); + minutes = (minute < 10) ? "0" + minute.toString() : minute.toString(); + hours = (hour < 10) ? "0" + hour.toString() : hour.toString(); + + return days + "." + months + "." + years + " - " + hours + ":" + minutes; +} + +/** + * insert dynamically a js script file into the website + * @param {String} name name of the script that should be included + */ +/* +function appendjs(name) { + var scrptE, hdEl; + scrptE = document.createElement("script"); + hdEl = document.getElementsByTagName("head")[0]; + scrptE.setAttribute("src", name); + scrptE.setAttribute("type", "text/javascript"); + hdEl.appendChild(scrptE); +} +*/ +/** + * insert dynamically a css file into the website + * @param {String} name name of the css file that should be included + */ +/* +function appendcss(name) { + var scrptE, hdEl; + scrptE = document.createElement("link"); + hdEl = document.getElementsByTagName("head")[0]; + scrptE.setAttribute("type", "text/css"); + scrptE.setAttribute("rel", "stylesheet"); + scrptE.setAttribute("href", name); + hdEl.appendChild(scrptE); +} +*/ diff --git a/root/opt/phpsysinfo/js/phpSysInfo/phpsysinfo_bootstrap.js b/root/opt/phpsysinfo/js/phpSysInfo/phpsysinfo_bootstrap.js new file mode 100644 index 0000000..cfe8626 --- /dev/null +++ b/root/opt/phpsysinfo/js/phpSysInfo/phpsysinfo_bootstrap.js @@ -0,0 +1,1172 @@ +//var data_dbg; + +function reload(initiate) { + $("#errorbutton").hide(); + $("#errors").empty(); + $.ajax({ + dataType: "json", + url: "xml.php?json", + success: function (data) { +// console.log(data); +// data_dbg = data; + if ((initiate === true) && (data["Options"] !== undefined) && (data["Options"]["@attributes"] !== undefined) + && ((refrtime = data["Options"]["@attributes"]["refresh"]) !== undefined) && (refrtime !== "0")) { + setInterval(reload, refrtime); + } + renderErrors(data); + renderVitals(data); + renderHardware(data); + renderMemory(data); + renderFilesystem(data); + renderNetwork(data); + renderVoltage(data); + renderTemperature(data); + renderFans(data); + renderPower(data); + renderCurrent(data); + renderUPS(data); + if (data['UnusedPlugins'] !== undefined) { + var plugins = items(data["UnusedPlugins"]["Plugin"]); + for (var i = 0; i < plugins.length; i++) { + $.ajax({ + dataType: "json", + url: "xml.php?plugin=" + plugins[i]["@attributes"]["name"]+"&json", + pluginname: plugins[i]["@attributes"]["name"], + success: function (data) { + try { + // dynamic call + window['renderPlugin_' + this.pluginname](data); + } + catch (err) { + } + renderErrors(data); + } + }); + } + } + } + }); +} + +$(document).ready(function () { + $(document).ajaxStart(function () { + $("#loader").show(); + }); + $(document).ajaxStop(function () { + $("#loader").hide(); + }); + + $.getScript( "./js.php?name=bootstrap", function(data, status, jqxhr) { + reload(true); + + $(".navbar-logo").click(function () { + reload(); + }); + }); + +}); + +Array.prototype.push_attrs=function(element) { + for (var i = 0; i < element.length ; i++) { + this.push(element[i]["@attributes"]); + } + return i; +}; + +function items(data) { + if (data !== undefined) { + if ((data.length > 0) && (data[0] !== undefined) && (data[0]["@attributes"] !== undefined)) { + return data; + } else if (data["@attributes"] !== undefined ) { + return [data]; + } else { + return []; + } + } else { + return []; + } +} + +function renderVitals(data) { + var directives = { + Uptime: { + text: function () { + return formatUptime(this["Uptime"]); + } + }, + LastBoot: { + text: function () { + var lastboot; + var timestamp = 0; + if ((data["Generation"] !== undefined) && (data["Generation"]["@attributes"] !== undefined) && (data["Generation"]["@attributes"]["timestamp"] !== undefined) ) { + timestamp = parseInt(data["Generation"]["@attributes"]["timestamp"])*1000; //server time + if (isNaN(timestamp)) timestamp = Number(new Date()); //client time + } else { + timestamp = Number(new Date()); //client time + } + lastboot = new Date(timestamp - (parseInt(this["Uptime"])*1000)); + if (typeof(lastboot.toUTCString) === "function") { + return lastboot.toUTCString(); //toUTCstring() or toLocaleString() + } else { + //deprecated + return lastboot.toGMTString(); //toGMTString() or toLocaleString() + } + } + }, + Distro: { + html: function () { + return '' + " " +this["Distro"]; + } + }, + LoadAvg: { + html: function () { + if (this["CPULoad"] !== undefined) { + return '
'+this["LoadAvg"] + '
' + + '
' + + '
' + round(this["CPULoad"],0) + '%
'; + } else { + return this["LoadAvg"]; + } + } + }, + Processes: { + text: function () { + var processes = "", prunning = 0, psleeping = 0, pstopped = 0, pzombie = 0, pwaiting = 0, pother = 0; + var not_first = false; + processes = parseInt(this["Processes"]); + if (this["ProcessesRunning"] !== undefined) { + prunning = parseInt(this["ProcessesRunning"]); + } + if (this["ProcessesSleeping"] !== undefined) { + psleeping = parseInt(this["ProcessesSleeping"]); + } + if (this["ProcessesStopped"] !== undefined) { + pstopped = parseInt(this["ProcessesStopped"]); + } + if (this["ProcessesZombie"] !== undefined) { + pzombie = parseInt(this["ProcessesZombie"]); + } + if (this["ProcessesWaiting"] !== undefined) { + pwaiting = parseInt(this["ProcessesWaiting"]); + } + if (this["ProcessesOther"] !== undefined) { + pother = parseInt(this["ProcessesOther"]); + } + if (prunning || psleeping || pstopped || pzombie || pwaiting || pother) { + processes += " ("; + for (proc_type in {running:0,sleeping:1,stopped:2,zombie:3,waiting:4,other:5}) { + if (eval("p" + proc_type)) { + if (not_first) { + processes += ", "; + } + processes += eval("p" + proc_type) + String.fromCharCode(160) + proc_type; + not_first = true; + } + } + processes += ")"; + } + return processes; + } + } + }; + + if (data["Vitals"]["@attributes"]["SysLang"] === undefined) { + $("#tr_SysLang").hide(); + } + if (data["Vitals"]["@attributes"]["CodePage"] === undefined) { + $("#tr_CodePage").hide(); + } + if (data["Vitals"]["@attributes"]["Processes"] === undefined) { + $("#tr_Processes").hide(); + } + $('#vitals').render(data["Vitals"]["@attributes"], directives); +} + +function renderHardware(data) { + + var directives = { + Model: { + text: function () { + return this["Model"]; + } + }, + CpuSpeed: { + text: function () { + return formatHertz(this["CpuSpeed"]); + } + }, + CpuSpeedMax: { + text: function () { + return formatHertz(this["CpuSpeedMax"]); + } + }, + CpuSpeedMin: { + text: function () { + return formatHertz(this["CpuSpeedMin"]); + } + }, + Cache: { + text: function () { + return formatBytes(this["Cache"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + BusSpeed: { + text: function () { + return formatHertz(this["BusSpeed"]); + } + }, + Cputemp: { + html: function () { + return formatTemp(this["Cputemp"], data["Options"]["@attributes"]["tempFormat"]); + } + }, + Bogomips: { + text: function () { + return parseInt(this["Bogomips"]); + } + }, + Load: { + html: function () { + return '
' + + '
' + + '
' + round(this["Load"],0) + '%
'; + } + } + }; + + var hw_directives = { + hwName: { + text: function() { + return this["Name"]; + } + }, + hwCount: { + text: function() { + if (this["Count"] == "1") { + return ""; + } + return this["Count"]; + } + } + }; + + var html=""; + + if ((data["Hardware"]["@attributes"] !== undefined) && (data["Hardware"]["@attributes"]["Name"] !== undefined)) { + html+=""; + html+="Machine"; + html+=""; + html+=""; + html+=""; + } + + var paramlist = {CpuSpeed:"CPU Speed",CpuSpeedMax:"CPU Speed Max",CpuSpeedMin:"CPU Speed Min",Cache:"Cache Size",Virt:"Virtualization",BusSpeed:"BUS Speed",Bogomips:"System Bogomips",Cputemp:"Temperature",Load:"Load Averages"}; + try { + var datas = items(data["Hardware"]["CPU"]["CpuCore"]); + for (var i = 0; i < datas.length; i++) { + if (i == 0) { + html+=""; + html+="CPU"; + html+="Number of processors:"; + html+=""; + html+=""; + } + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + for (var proc_param in paramlist) { + if (datas[i]["@attributes"][proc_param] !== undefined) { + html+=""; + html+=""; + html+=""+ paramlist[proc_param]+""; + html+=""; + html+=""; + } + } + + } + } + catch (err) { + $("#hardware-CPU").hide(); + } + + for (hw_type in {PCI:0,IDE:1,SCSI:2,USB:3,TB:4,I2C:5}) { + try { + var datas = items(data["Hardware"][hw_type]["Device"]); + for (var i = 0; i < datas.length; i++) { + if (i == 0) { + html+=""; + html+="" + hw_type + ""; + html+="Number of devices:"; + html+=""; + html+=""; + } + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + } + } + catch (err) { + $("#hardware-"+hw_type).hide(); + } + } + $("#hardware").empty().append(html); + + + if ((data["Hardware"]["@attributes"] !== undefined) && (data["Hardware"]["@attributes"]["Name"] !== undefined)) { + $('#hardware-Machine').render(data["Hardware"]["@attributes"]); + } + + try { + var datas = items(data["Hardware"]["CPU"]["CpuCore"]); + for (var i = 0; i < datas.length; i++) { + $('#hardware-CPU-'+ i).render(datas[i]["@attributes"]); + for (var proc_param in paramlist) { + if (datas[i]["@attributes"][proc_param] !== undefined) { + $('#hardware-CPU-'+ i +'-'+proc_param).render(datas[i]["@attributes"], directives); + } + } + } + if (i > 0) { + $("#hardware-CPU span").html(i); + } + } + catch (err) { + $("#hardware-CPU").hide(); + } + + for (hw_type in {PCI:0,IDE:1,SCSI:2,USB:3,TB:4,I2C:5}) { + try { + var licz = 0; + var datas = items(data["Hardware"][hw_type]["Device"]); + for (var i = 0; i < datas.length; i++) { + $('#hardware-'+hw_type+'-'+ i).render(datas[i]["@attributes"], hw_directives); + if (datas[i]["@attributes"]["Count"] !== undefined) { + licz += parseInt(datas[i]["@attributes"]["Count"]); + } else { + licz++; + } + } + if (i > 0) { + $("#hardware-" + hw_type + " span").html(licz); + } + } + catch (err) { + $("#hardware-"+hw_type).hide(); + } + } + $('#hardware').treegrid({ + initialState: 'collapsed', + expanderExpandedClass: 'normalicon normalicon-down', + expanderCollapsedClass: 'normalicon normalicon-right' + }); + if (data["Options"]["@attributes"]["showCPUListExpanded"] !== "false") { + try { + $('#hardware-CPU').treegrid('expand'); + } + catch (err) { + } + } + if (data["Options"]["@attributes"]["showCPUInfoExpanded"] === "true") { + try { + var datas = items(data["Hardware"]["CPU"]["CpuCore"]); + for (var i = 0; i < datas.length; i++) { + $('#hardware-CPU-'+i).treegrid('expand'); + } + } + catch (err) { + } + } +} + +function renderMemory(data) { + var directives = { + Total: { + text: function () { + return formatBytes(this["@attributes"]["Total"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + Free: { + text: function () { + return formatBytes(this["@attributes"]["Free"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + Used: { + text: function () { + return formatBytes(this["@attributes"]["Used"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + Usage: { + html: function () { + if ((this["Details"] === undefined) || (this["Details"]["@attributes"] === undefined)) { + return '
' + + '
' + + '
' + this["@attributes"]["Percent"] + '%
'; + } + else { + var rest = parseInt(this["@attributes"]["Percent"]); + var html = '
'; + if ((this["Details"]["@attributes"]["AppPercent"] !== undefined) && (this["Details"]["@attributes"]["AppPercent"] > 0)) { + html += '
'; + rest -= parseInt(this["Details"]["@attributes"]["AppPercent"]); + } + if ((this["Details"]["@attributes"]["CachedPercent"] !== undefined) && (this["Details"]["@attributes"]["CachedPercent"] > 0)) { + html += '
'; + rest -= parseInt(this["Details"]["@attributes"]["CachedPercent"]); + } + if ((this["Details"]["@attributes"]["BuffersPercent"] !== undefined) && (this["Details"]["@attributes"]["BuffersPercent"] > 0)) { + html += '
'; + rest -= parseInt(this["Details"]["@attributes"]["BuffersPercent"]); + } + if (rest > 0) { + html += '
'; + } + html += '
'; + html += '
' + 'Total: ' + this["@attributes"]["Percent"] + '% ' + '('; + var not_first = false; + if (this["Details"]["@attributes"]["AppPercent"] !== undefined) { + html += 'Kernel+Apps: '+ this["Details"]["@attributes"]["AppPercent"] + '%'; + not_first = true; + } + if (this["Details"]["@attributes"]["CachedPercent"] !== undefined) { + if (not_first) html += ' - '; + html += 'Cache: ' + this["Details"]["@attributes"]["CachedPercent"] + '%'; + not_first = true; + } + if (this["Details"]["@attributes"]["BuffersPercent"] !== undefined) { + if (not_first) html += ' - '; + html += 'Buffers: ' + this["Details"]["@attributes"]["BuffersPercent"] + '%'; + } + html += ')
'; + return html; + } + } + }, + Type: { + text: function () { + return "Physical Memory"; + } + } + }; + + var directive_swap = { + Total: { + text: function () { + return formatBytes(this["Total"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + Free: { + text: function () { + return formatBytes(this["Free"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + Used: { + text: function () { + return formatBytes(this["Used"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + Usage: { + html: function () { + return '
' + + '
' + + '
' + this["Percent"] + '%
'; + } + }, + Name: { + html: function () { + return this['Name'] + '
' + ((this["MountPoint"] !== undefined) ? this["MountPoint"] : this["MountPointID"]); + } + } + }; + + var data_memory = []; + if (data["Memory"]["Swap"] !== undefined) { + var datas = items(data["Memory"]["Swap"]["Mount"]); + data_memory.push_attrs(datas); + $('#swap-data').render(data_memory, directive_swap); + $('#swap-data').show(); + } else { + $('#swap-data').hide(); + } + $('#memory-data').render(data["Memory"], directives); +} + +function renderFilesystem(data) { + var directives = { + Total: { + text: function () { + return formatBytes(this["Total"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + Free: { + text: function () { + return formatBytes(this["Free"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + Used: { + text: function () { + return formatBytes(this["Used"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + MountPoint: { + text: function () { + return ((this["MountPoint"] !== undefined) ? this["MountPoint"] : this["MountPointID"]); + } + }, + Name: { + html: function () { + return this["Name"] + ((this["MountOptions"] !== undefined) ? '
(' + this["MountOptions"] + ')' : ''); + } + }, + Percent: { + html: function () { + return '
' + '
= parseInt(data["Options"]["@attributes"]["threshold"]))) ? 'progress-bar progress-bar-danger' : 'progress-bar progress-bar-info') + + '" style="width: ' + this["Percent"] + '% ;">
' + + '
' + '
' + this["Percent"] + '% ' + ((this["Inodes"] !== undefined) ? '(' + this["Inodes"] + '%)' : '') + '
'; + } + } + }; + + try { + var fs_data = []; + var datas = items(data["FileSystem"]["Mount"]); + var total = {Total:0,Free:0,Used:0}; + for (var i = 0; i < datas.length; i++) { + fs_data.push(datas[i]["@attributes"]); + total["Total"] += parseInt(datas[i]["@attributes"]["Total"]); + total["Free"] += parseInt(datas[i]["@attributes"]["Free"]); + total["Used"] += parseInt(datas[i]["@attributes"]["Used"]); + total["Percent"] = (total["Total"] !== 0) ? round((total["Used"] / total["Total"]) * 100, 2) : 0; + } + if (i > 0) { + $('#filesystem-data').render(fs_data, directives); + $('#filesystem-foot').render(total, directives); + $('#filesystem_MountPoint').removeClass("sorttable_sorted"); // reset sort order +// sorttable.innerSortFunction.apply(document.getElementById('filesystem_MountPoint'), []); + sorttable.innerSortFunction.apply($('#filesystem_MountPoint')[0], []); + $("#block_filesystem").show(); + } else { + $("#block_filesystem").hide(); + } + } + catch (err) { + $("#block_filesystem").hide(); + } +} + + +function renderNetwork(data) { + var directives = { + RxBytes: { + text: function () { + return formatBytes(this["RxBytes"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + TxBytes: { + text: function () { + return formatBytes(this["TxBytes"], data["Options"]["@attributes"]["byteFormat"]); + } + }, + Drops: { + text: function () { + return this["Err"] + "/" + String.fromCharCode(8203) + this["Drops"]; + } + } + }; + + var html = ""; + + html+=""; + html+=""; + html+="Device"; + html+="Receive"; + html+="Sent"; + html+="Err/" + String.fromCharCode(8203) +"Drop"; + html+=""; + html+=""; + + try { + var network_data = []; + var datas = items(data["Network"]["NetDevice"]); + for (var i = 0; i < datas.length; i++) { + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + + var info = datas[i]["@attributes"]["Info"]; + if ( (info !== undefined) && (info !== "") ) { + var infos = info.replace(/:/g, String.fromCharCode(8203)+":").split(";"); /* split long addresses */ + for (var j = 0; j < infos.length; j++){ + html +="" + infos[j] + ""; + } + } + } + $("#network").empty().append(html); + if (i > 0) { + for (var i = 0; i < datas.length; i++) { + $('#network-' + i).render(datas[i]["@attributes"], directives); + } + $("#block_network").show(); + } else { + $("#block_network").hide(); + } + } + catch (err) { + $("#block_network").hide(); + } + + $('#network').treegrid({ + initialState: 'collapsed', + expanderExpandedClass: 'normalicon normalicon-down', + expanderCollapsedClass: 'normalicon normalicon-right' + }); + +} + +function renderVoltage(data) { + var directives = { + Value: { + text: function () { + return this["Value"] + String.fromCharCode(160) + "V"; + } + }, + Min: { + text: function () { + if (this["Min"] !== undefined) + return this["Min"] + String.fromCharCode(160) + "V"; + } + }, + Max: { + text: function () { + if (this["Max"] !== undefined) + return this["Max"] + String.fromCharCode(160) + "V"; + } + }, + Label: { + text: function () { + if (this["Event"] === undefined) + return this["Label"]; + else + return this["Label"] + " ! "+this["Event"]; + } + } + }; + try { + var voltage_data = []; + var datas = items(data["MBInfo"]["Voltage"]["Item"]); + if (voltage_data.push_attrs(datas) > 0) { + $('#voltage-data').render(voltage_data, directives); + $("#block_voltage").show(); + } else { + $("#block_voltage").hide(); + } + } + catch (err) { + $("#block_voltage").hide(); + } +} + +function renderTemperature(data) { + var directives = { + Value: { + html: function () { + return formatTemp(this["Value"], data["Options"]["@attributes"]["tempFormat"]); + } + }, + Max: { + html: function () { + if (this["Max"] !== undefined) + return formatTemp(this["Max"], data["Options"]["@attributes"]["tempFormat"]); + } + }, + Label: { + text: function () { + if (this["Event"] === undefined) + return this["Label"]; + else + return this["Label"] + " ! "+this["Event"]; + } + } + }; + + try { + var temperature_data = []; + var datas = items(data["MBInfo"]["Temperature"]["Item"]); + if (temperature_data.push_attrs(datas) > 0) { + $('#temperature-data').render(temperature_data, directives); + $("#block_temperature").show(); + } else { + $("#block_temperature").hide(); + } + } + catch (err) { + $("#block_temperature").hide(); + } +} + +function renderFans(data) { + var directives = { + Value: { + text: function () { + return this["Value"] + String.fromCharCode(160) + "RPM"; + } + }, + Min: { + text: function () { + if (this["Min"] !== undefined) + return this["Min"] + String.fromCharCode(160) + "RPM"; + } + }, + Label: { + text: function () { + if (this["Event"] === undefined) + return this["Label"]; + else + return this["Label"] + " ! "+this["Event"]; + } + } + }; + + try { + var fans_data = []; + var datas = items(data["MBInfo"]["Fans"]["Item"]); + if (fans_data.push_attrs(datas) > 0) { + $('#fans-data').render(fans_data, directives); + $("#block_fans").show(); + } else { + $("#block_fans").hide(); + } + } + catch (err) { + $("#block_fans").hide(); + } +} + +function renderPower(data) { + var directives = { + Value: { + text: function () { + return this["Value"] + String.fromCharCode(160) + "W"; + } + }, + Max: { + text: function () { + if (this["Max"] !== undefined) + return this["Max"] + String.fromCharCode(160) + "W"; + } + }, + Label: { + text: function () { + if (this["Event"] === undefined) + return this["Label"]; + else + return this["Label"] + " ! "+this["Event"]; + } + } + }; + + try { + var power_data = []; + var datas = items(data["MBInfo"]["Power"]["Item"]); + if (power_data.push_attrs(datas) > 0) { + $('#power-data').render(power_data, directives); + $("#block_power").show(); + } else { + $("#block_power").hide(); + } + } + catch (err) { + $("#block_power").hide(); + } +} + +function renderCurrent(data) { + var directives = { + Value: { + text: function () { + return this["Value"] + String.fromCharCode(160) + "A"; + } + }, + Max: { + text: function () { + if (this["Max"] !== undefined) + return this["Max"] + String.fromCharCode(160) + "A"; + } + }, + Label: { + text: function () { + if (this["Event"] === undefined) + return this["Label"]; + else + return this["Label"] + " ! "+this["Event"]; + } + } + }; + + try { + var current_data = []; + var datas = items(data["MBInfo"]["Current"]["Item"]); + if (current_data.push_attrs(datas) > 0) { + $('#current-data').render(current_data, directives); + $("#block_current").show(); + } else { + $("#block_current").hide(); + } + } + catch (err) { + $("#block_current").hide(); + } +} + +function renderUPS(data) { + + var directives = { + Name: { + text: function () { + return this["Name"] + ((this["Mode"] !== undefined) ? " (" + this["Mode"] + ")" : ""); + } + }, + LineVoltage: { + text: function () { + return this["LineVoltage"] + String.fromCharCode(160) + "V"; + } + }, + LineFrequency: { + text: function () { + return this["LineFrequency"] + String.fromCharCode(160) + "Hz"; + } + }, + BatteryVoltage: { + text: function () { + return this["BatteryVoltage"] + String.fromCharCode(160) + "V"; + } + }, + TimeLeftMinutes: { + text: function () { + return this["TimeLeftMinutes"] + String.fromCharCode(160) + "minutes"; + } + }, + LoadPercent: { + html: function () { + return '
' + + '
' + + '
' + round(this["LoadPercent"],0) + '%
'; + } + }, + BatteryChargePercent: { + html: function () { + return '
' + + '
' + + '
' + round(this["BatteryChargePercent"],0) + '%
'; + } + } + }; + + if ((data["UPSInfo"] !== undefined) && (items(data["UPSInfo"]["UPS"]).length > 0)) { + var html=""; + var paramlist = {Model:"Model",StartTime:"Started",Status:"Status",Temperature:"Temperature",OutagesCount:"Outages",LastOutage:"Last outage cause",LastOutageFinish:"Last outage timestamp",LineVoltage:"Line voltage",LineFrequency:"Line frequency",LoadPercent:"Load percent",BatteryDate:"Battery date",BatteryVoltage:"Battery voltage",BatteryChargePercent:"Battery charge",TimeLeftMinutes:"Time left on batteries"}; + + try { + var datas = items(data["UPSInfo"]["UPS"]); + for (var i = 0; i < datas.length; i++) { + html+=""; + html+=""; + html+=""; + html+=""; + for (var proc_param in paramlist) { + if (datas[i]["@attributes"][proc_param] !== undefined) { + html+=""; + html+=""+ paramlist[proc_param]+""; + html+=""; + html+=""; + } + } + + } + } + catch (err) { + } + + if ((data["UPSInfo"]["@attributes"] !== undefined) && (data["UPSInfo"]["@attributes"]["ApcupsdCgiLinks"] === "1")) { + html+=""; + html+="(Details)"; + html+=""; + html+=""; + } + + $("#ups").empty().append(html); + + try { + var datas = items(data["UPSInfo"]["UPS"]); + for (var i = 0; i < datas.length; i++) { + $('#ups-'+ i).render(datas[i]["@attributes"], directives); + for (var proc_param in paramlist) { + if (datas[i]["@attributes"][proc_param] !== undefined) { + $('#ups-'+ i +'-'+proc_param).render(datas[i]["@attributes"], directives); + } + } + } + } + catch (err) { + } + + $('#ups').treegrid({ + initialState: 'expanded', + expanderExpandedClass: 'normalicon normalicon-down', + expanderCollapsedClass: 'normalicon normalicon-right' + }); + + $("#block_ups").show(); + } else { + $("#block_ups").hide(); + } +} + +function renderErrors(data) { + try { + var datas = items(data["Errors"]["Error"]); + for (var i = 0; i < datas.length; i++) { + $("#errors").append("
  • "+datas[i]["@attributes"]["Function"]+" - "+datas[i]["@attributes"]["Message"].replace(/\n/g, "
    ")+"

  • "); + } + if (i > 0) { + $("#errorbutton").show(); + } + } + catch (err) { + $("#errorbutton").hide(); + } +} + +/** + * format seconds to a better readable statement with days, hours and minutes + * @param {Number} sec seconds that should be formatted + * @return {String} html string with no breaking spaces and translation statemen +*/ +function formatUptime(sec) { + var txt = "", intMin = 0, intHours = 0, intDays = 0; + intMin = sec / 60; + intHours = intMin / 60; + intDays = Math.floor(intHours / 24); + intHours = Math.floor(intHours - (intDays * 24)); + intMin = Math.floor(intMin - (intDays * 60 * 24) - (intHours * 60)); + if (intDays) { + txt += intDays.toString() + String.fromCharCode(160) + "days" + String.fromCharCode(160); + } + if (intHours) { + txt += intHours.toString() + String.fromCharCode(160) + "hours" + String.fromCharCode(160); + } + return txt + intMin.toString() + String.fromCharCode(160) + "minutes"; +} + +/** + * format a celcius temperature to fahrenheit and also append the right suffix + * @param {String} degreeC temperature in celvius + * @param {jQuery} xml phpSysInfo-XML + * @return {String} html string with no breaking spaces and translation statements + */ +function formatTemp(degreeC, tempFormat) { + var degree = 0; + if (tempFormat === undefined) { + tempFormat = "c"; + } + degree = parseFloat(degreeC); + if (isNaN(degreeC)) { + return "---"; + } + else { + switch (tempFormat.toLowerCase()) { + case "f": + return round((((9 * degree) / 5) + 32), 1) + String.fromCharCode(160) + "F"; + case "c": + return round(degree, 1) + String.fromCharCode(160) + "C"; + case "c-f": + return round(degree, 1) + String.fromCharCode(160) + "C
    (" + round((((9 * degree) / 5) + 32), 1) + String.fromCharCode(160) + "F)"; + case "f-c": + return round((((9 * degree) / 5) + 32), 1) + String.fromCharCode(160) + "F
    (" + round(degree, 1) + String.fromCharCode(160) + "C)"; + } + } +} + +/** + * format a given MHz value to a better readable statement with the right suffix + * @param {Number} mhertz mhertz value that should be formatted + * @return {String} html string with no breaking spaces and translation statements + */ +function formatHertz(mhertz) { + if (mhertz && mhertz < 1000) { + return mhertz.toString() + String.fromCharCode(160) + "MHz"; + } + else { + if (mhertz && mhertz >= 1000) { + return round(mhertz / 1000, 2) + String.fromCharCode(160) + "GHz"; + } + else { + return ""; + } + } +} + +/** + * format the byte values into a user friendly value with the corespondenting unit expression
    support is included + * for binary and decimal output
    user can specify a constant format for all byte outputs or the output is formated + * automatically so that every value can be read in a user friendly way + * @param {Number} bytes value that should be converted in the corespondenting format, which is specified in the phpsysinfo.ini + * @param {jQuery} xml phpSysInfo-XML + * @return {String} string of the converted bytes with the translated unit expression + */ +function formatBytes(bytes, byteFormat) { + var show = ""; + + if (byteFormat === undefined) { + byteFormat = "auto_binary"; + } + + switch (byteFormat.toLowerCase()) { + case "pib": + show += round(bytes / Math.pow(1024, 5), 2); + show += String.fromCharCode(160) + "PiB"; + break; + case "tib": + show += round(bytes / Math.pow(1024, 4), 2); + show += String.fromCharCode(160) + "TiB"; + break; + case "gib": + show += round(bytes / Math.pow(1024, 3), 2); + show += String.fromCharCode(160) + "GiB"; + break; + case "mib": + show += round(bytes / Math.pow(1024, 2), 2); + show += String.fromCharCode(160) + "MiB"; + break; + case "kib": + show += round(bytes / Math.pow(1024, 1), 2); + show += String.fromCharCode(160) + "KiB"; + break; + case "pb": + show += round(bytes / Math.pow(1000, 5), 2); + show += String.fromCharCode(160) + "PB"; + break; + case "tb": + show += round(bytes / Math.pow(1000, 4), 2); + show += String.fromCharCode(160) + "TB"; + break; + case "gb": + show += round(bytes / Math.pow(1000, 3), 2); + show += String.fromCharCode(160) + "GB"; + break; + case "mb": + show += round(bytes / Math.pow(1000, 2), 2); + show += String.fromCharCode(160) + "MB"; + break; + case "kb": + show += round(bytes / Math.pow(1000, 1), 2); + show += String.fromCharCode(160) + "kB"; + break; + case "b": + show += bytes; + show += String.fromCharCode(160) + "B"; + break; + case "auto_decimal": + if (bytes > Math.pow(1000, 5)) { + show += round(bytes / Math.pow(1000, 5), 2); + show += String.fromCharCode(160) + "PB"; + } + else { + if (bytes > Math.pow(1000, 4)) { + show += round(bytes / Math.pow(1000, 4), 2); + show += String.fromCharCode(160) + "TB"; + } + else { + if (bytes > Math.pow(1000, 3)) { + show += round(bytes / Math.pow(1000, 3), 2); + show += String.fromCharCode(160) + "GB"; + } + else { + if (bytes > Math.pow(1000, 2)) { + show += round(bytes / Math.pow(1000, 2), 2); + show += String.fromCharCode(160) + "MB"; + } + else { + if (bytes > Math.pow(1000, 1)) { + show += round(bytes / Math.pow(1000, 1), 2); + show += String.fromCharCode(160) + "kB"; + } + else { + show += bytes; + show += String.fromCharCode(160) + "B"; + } + } + } + } + } + break; + default: + if (bytes > Math.pow(1024, 5)) { + show += round(bytes / Math.pow(1024, 5), 2); + show += String.fromCharCode(160) + "PiB"; + } + else { + if (bytes > Math.pow(1024, 4)) { + show += round(bytes / Math.pow(1024, 4), 2); + show += String.fromCharCode(160) + "TiB"; + } + else { + if (bytes > Math.pow(1024, 3)) { + show += round(bytes / Math.pow(1024, 3), 2); + show += String.fromCharCode(160) + "GiB"; + } + else { + if (bytes > Math.pow(1024, 2)) { + show += round(bytes / Math.pow(1024, 2), 2); + show += String.fromCharCode(160) + "MiB"; + } + else { + if (bytes > Math.pow(1024, 1)) { + show += round(bytes / Math.pow(1024, 1), 2); + show += String.fromCharCode(160) + "KiB"; + } + else { + show += bytes; + show += String.fromCharCode(160) + "B"; + } + } + } + } + } + } + return show; +} + +/** + * round a given value to the specified precision, difference to Math.round() is that there + * will be appended Zeros to the end if the precision is not reached (0.1 gets rounded to 0.100 when precision is set to 3) + * @param {Number} x value to round + * @param {Number} n precision + * @return {String} + */ +function round(x, n) { + var e = 0, k = ""; + if (n < 0 || n > 14) { + return 0; + } + if (n === 0) { + return Math.round(x); + } else { + e = Math.pow(10, n); + k = (Math.round(x * e) / e).toString(); + if (k.indexOf('.') === -1) { + k += '.'; + } + k += e.toString().substring(1); + return k.substring(0, k.indexOf('.') + n + 1); + } +} diff --git a/root/opt/phpsysinfo/js/vendor/README b/root/opt/phpsysinfo/js/vendor/README new file mode 100644 index 0000000..45aea86 --- /dev/null +++ b/root/opt/phpsysinfo/js/vendor/README @@ -0,0 +1,37 @@ +versions, links and simple description of used jquery files +=========================================================== + +bootstrap.min.js +--------- +VERSION : 3.3.5 +URL : http://getbootstrap.com/ +DESC : Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web +USED : used for the entire bootstrap userinterface + +transparency.js +--------- +VERSION : 0.10.0 +URL : http://leonidas.github.io/transparency/ +DESC : Transparency is a minimal template engine for jQuery. It maps JSON objects to DOM elements with zero configuration. Just call .render() +USED : used for the entire bootstrap userinterface + +html5shiv-printshiv.js +--------- +VERSION : 3.7.2 +URL : https://code.google.com/p/html5shiv-printshiv/ +DESC : Enabling HTML5 Shiv Script and Print Support on old IE6-9 Browser Safari 4.x and Firefox 3.x +USED : used for the entire bootstrap userinterface + +console-shim.js +--------- +VERSION : +URL : https://github.com/liamnewmarch/console-shim +DESC : Shim to make browsers store console messages without Dev Tools open (e.g. IE9) +USED : used for the entire bootstrap userinterface + +sorttable.js +--------- +VERSION : 2+2014.12.25.12_fix +URL : http://www.kryogenix.org/code/browser/sorttable/ +DESC : Make all your tables sortable +USED : used for the entire bootstrap userinterface diff --git a/root/opt/phpsysinfo/js/vendor/bootstrap.min.js b/root/opt/phpsysinfo/js/vendor/bootstrap.min.js new file mode 100644 index 0000000..133aeec --- /dev/null +++ b/root/opt/phpsysinfo/js/vendor/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.5",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.5",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/root/opt/phpsysinfo/js/vendor/console-shim.js b/root/opt/phpsysinfo/js/vendor/console-shim.js new file mode 100644 index 0000000..bd3d135 --- /dev/null +++ b/root/opt/phpsysinfo/js/vendor/console-shim.js @@ -0,0 +1,32 @@ +/* https://github.com/liamnewmarch/console-shim 2014 CC-BY @liamnewmarch */ +if (!('console' in window)) { + (function() { + var Console, __console; + Console = function() { + var check, key, log, methods, _i, _len, _ref; + this.__buffer = []; + log = function() { + return this.__buffer.push(arguments); + }; + methods = 'assert count debug dir dirxml error exception info log trace warn'; + _ref = methods.split(' '); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + key = _ref[_i]; + this[key] = log; + } + check = setInterval(function() { + var data, func, _j, _len1, _ref1, _ref2; + if ((((_ref1 = window.console) != null ? _ref1.log : void 0) != null) && !console.__buffer) { + clearInterval(check); + func = Function.prototype.bind ? Function.prototype.bind.call(console.log, console) : console.log; + _ref2 = __console.__buffer; + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + data = _ref2[_j]; + func.apply(console, data); + } + } + }, 1000); + }; + return __console = window.console = new Console(); + })(); +} diff --git a/root/opt/phpsysinfo/js/vendor/html5shiv-printshiv.js b/root/opt/phpsysinfo/js/vendor/html5shiv-printshiv.js new file mode 100644 index 0000000..c2913b5 --- /dev/null +++ b/root/opt/phpsysinfo/js/vendor/html5shiv-printshiv.js @@ -0,0 +1,520 @@ +/** +* @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +;(function(window, document) { +/*jshint evil:true */ + /** version */ + var version = '3.7.2'; + + /** Preset options */ + var options = window.html5 || {}; + + /** Used to skip problem elements */ + var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; + + /** Not all elements can be cloned in IE **/ + var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; + + /** Detect whether the browser supports default html5 styles */ + var supportsHtml5Styles; + + /** Name of the expando, to work with multiple documents or to re-shiv one document */ + var expando = '_html5shiv'; + + /** The id for the the documents expando */ + var expanID = 0; + + /** Cached data for each document */ + var expandoData = {}; + + /** Detect whether the browser supports unknown elements */ + var supportsUnknownElements; + + (function() { + try { + var a = document.createElement('a'); + a.innerHTML = ''; + //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles + supportsHtml5Styles = ('hidden' in a); + + supportsUnknownElements = a.childNodes.length == 1 || (function() { + // assign a false positive if unable to shiv + (document.createElement)('a'); + var frag = document.createDocumentFragment(); + return ( + typeof frag.cloneNode == 'undefined' || + typeof frag.createDocumentFragment == 'undefined' || + typeof frag.createElement == 'undefined' + ); + }()); + } catch(e) { + // assign a false positive if detection fails => unable to shiv + supportsHtml5Styles = true; + supportsUnknownElements = true; + } + + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a style sheet with the given CSS text and adds it to the document. + * @private + * @param {Document} ownerDocument The document. + * @param {String} cssText The CSS text. + * @returns {StyleSheet} The style element. + */ + function addStyleSheet(ownerDocument, cssText) { + var p = ownerDocument.createElement('p'), + parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; + + p.innerHTML = 'x'; + return parent.insertBefore(p.lastChild, parent.firstChild); + } + + /** + * Returns the value of `html5.elements` as an array. + * @private + * @returns {Array} An array of shived element node names. + */ + function getElements() { + var elements = html5.elements; + return typeof elements == 'string' ? elements.split(' ') : elements; + } + + /** + * Extends the built-in list of html5 elements + * @memberOf html5 + * @param {String|Array} newElements whitespace separated list or array of new element names to shiv + * @param {Document} ownerDocument The context document. + */ + function addElements(newElements, ownerDocument) { + var elements = html5.elements; + if(typeof elements != 'string'){ + elements = elements.join(' '); + } + if(typeof newElements != 'string'){ + newElements = newElements.join(' '); + } + html5.elements = elements +' '+ newElements; + shivDocument(ownerDocument); + } + + /** + * Returns the data associated to the given document + * @private + * @param {Document} ownerDocument The document. + * @returns {Object} An object of data. + */ + function getExpandoData(ownerDocument) { + var data = expandoData[ownerDocument[expando]]; + if (!data) { + data = {}; + expanID++; + ownerDocument[expando] = expanID; + expandoData[expanID] = data; + } + return data; + } + + /** + * returns a shived element for the given nodeName and document + * @memberOf html5 + * @param {String} nodeName name of the element + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived element. + */ + function createElement(nodeName, ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createElement(nodeName); + } + if (!data) { + data = getExpandoData(ownerDocument); + } + var node; + + if (data.cache[nodeName]) { + node = data.cache[nodeName].cloneNode(); + } else if (saveClones.test(nodeName)) { + node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); + } else { + node = data.createElem(nodeName); + } + + // Avoid adding some elements to fragments in IE < 9 because + // * Attributes like `name` or `type` cannot be set/changed once an element + // is inserted into a document/fragment + // * Link elements with `src` attributes that are inaccessible, as with + // a 403 response, will cause the tab/window to crash + // * Script elements appended to fragments will execute when their `src` + // or `text` property is set + return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; + } + + /** + * returns a shived DocumentFragment for the given document + * @memberOf html5 + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived DocumentFragment. + */ + function createDocumentFragment(ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createDocumentFragment(); + } + data = data || getExpandoData(ownerDocument); + var clone = data.frag.cloneNode(), + i = 0, + elems = getElements(), + l = elems.length; + for(;i+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'), + replacement = '$1' + shivNamespace + '\\:$2'; + + while (index--) { + pair = parts[index] = parts[index].split('}'); + pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement); + parts[index] = pair.join('}'); + } + return parts.join('{'); + } + + /** + * Removes the given wrappers, leaving the original elements. + * @private + * @params {Array} wrappers An array of printable wrappers. + */ + function removeWrappers(wrappers) { + var index = wrappers.length; + while (index--) { + wrappers[index].removeNode(); + } + } + + /*--------------------------------------------------------------------------*/ + + /** + * Shivs the given document for print. + * @memberOf html5 + * @param {Document} ownerDocument The document to shiv. + * @returns {Document} The shived document. + */ + function shivPrint(ownerDocument) { + var shivedSheet, + wrappers, + data = getExpandoData(ownerDocument), + namespaces = ownerDocument.namespaces, + ownerWindow = ownerDocument.parentWindow; + + if (!supportsShivableSheets || ownerDocument.printShived) { + return ownerDocument; + } + if (typeof namespaces[shivNamespace] == 'undefined') { + namespaces.add(shivNamespace); + } + + function removeSheet() { + clearTimeout(data._removeSheetTimer); + if (shivedSheet) { + shivedSheet.removeNode(true); + } + shivedSheet= null; + } + + ownerWindow.attachEvent('onbeforeprint', function() { + + removeSheet(); + + var imports, + length, + sheet, + collection = ownerDocument.styleSheets, + cssText = [], + index = collection.length, + sheets = Array(index); + + // convert styleSheets collection to an array + while (index--) { + sheets[index] = collection[index]; + } + // concat all style sheet CSS text + while ((sheet = sheets.pop())) { + // IE does not enforce a same origin policy for external style sheets... + // but has trouble with some dynamically created stylesheets + if (!sheet.disabled && reMedia.test(sheet.media)) { + + try { + imports = sheet.imports; + length = imports.length; + } catch(er){ + length = 0; + } + + for (index = 0; index < length; index++) { + sheets.push(imports[index]); + } + + try { + cssText.push(sheet.cssText); + } catch(er){} + } + } + + // wrap all HTML5 elements with printable elements and add the shived style sheet + cssText = shivCssText(cssText.reverse().join('')); + wrappers = addWrappers(ownerDocument); + shivedSheet = addStyleSheet(ownerDocument, cssText); + + }); + + ownerWindow.attachEvent('onafterprint', function() { + // remove wrappers, leaving the original elements, and remove the shived style sheet + removeWrappers(wrappers); + clearTimeout(data._removeSheetTimer); + data._removeSheetTimer = setTimeout(removeSheet, 500); + }); + + ownerDocument.printShived = true; + return ownerDocument; + } + + /*--------------------------------------------------------------------------*/ + + // expose API + html5.type += ' print'; + html5.shivPrint = shivPrint; + + // shiv for print + shivPrint(document); + +}(this, document)); diff --git a/root/opt/phpsysinfo/js/vendor/sorttable.js b/root/opt/phpsysinfo/js/vendor/sorttable.js new file mode 100644 index 0000000..9b242af --- /dev/null +++ b/root/opt/phpsysinfo/js/vendor/sorttable.js @@ -0,0 +1,503 @@ +/* + SortTable + version 2+2014.12.25_fix + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + 25th December 2014 + Fixed behavior of multiple sortable tables in same page. + Redefinition of sortfwdind and sortrevind icons. + Mieczyslaw Nalewaj (namiltd@users.sourceforge.net) + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backwards compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + sortrevind.innerHTML = ' ▲'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind'+$(this).parent().parent().parent()[0].id)); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"+$(this).parent().parent().parent()[0].id; +// sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + sortfwdind.innerHTML = ' ▼'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'+$(this).parent().parent().parent()[0].id); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'+$(this).parent().parent().parent()[0].id); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"+$(this).parent().parent().parent()[0].id; +// sortfwdind.innerHTML = stIsIE ? ' 6;' : ' ▾'; + sortfwdind.innerHTML = ' ▼'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + if (!node) return ""; + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +}; + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backwards compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + if (!node) return ""; + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + + +

    REDIRECTING ...

    +
    +

    Loading redirection target

    +

    In approx. 2 seconds the redirection target page should load.
    + If it doesn't please select the link above.

    +

    Generated by phpSysInfo - 

    +
    + + diff --git a/root/opt/phpsysinfo/templates/html/index_bootstrap.html b/root/opt/phpsysinfo/templates/html/index_bootstrap.html new file mode 100644 index 0000000..caab853 --- /dev/null +++ b/root/opt/phpsysinfo/templates/html/index_bootstrap.html @@ -0,0 +1,375 @@ + + + + + + + + phpSysInfo + + + + + + + + + + + +
    + +
    +
    +
    +
    System Vitals
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Hostname
    Listening IP
    Kernel Version
    Distro Name
    Uptime
    Last boot
    Current Users
    Load Averages
    System Language
    Code Page
    Processes
    +
    +
    +
    + + +
    +
    +
    Hardware Information
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    Memory Usage
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TypeUsageFreeUsedSize
    +
    +
    +
    +
    + +
    + +
    + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + +
    + + + + + + + + + + + + + + + + + + diff --git a/root/opt/phpsysinfo/templates/html/index_dynamic.html b/root/opt/phpsysinfo/templates/html/index_dynamic.html new file mode 100644 index 0000000..b5c7eea --- /dev/null +++ b/root/opt/phpsysinfo/templates/html/index_dynamic.html @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + phpSysInfo <?php echo PSI_VERSION_STRING ?> + + +
    +

    Loading... please wait!

    +
    + +
    +
    + + + + diff --git a/root/opt/phpsysinfo/templates/idash.css b/root/opt/phpsysinfo/templates/idash.css new file mode 100644 index 0000000..ffac6d9 --- /dev/null +++ b/root/opt/phpsysinfo/templates/idash.css @@ -0,0 +1,151 @@ +/* NextGen Remixed by iDash.pl */ +a { + text-decoration: none; + color: #006; +} + +a:hover { + text-decoration: underline; + color: #5A7000; +} + +* { + margin: 0; + padding: 0; +} + +html { + height: 100%; + background: url("idash/bg.png") repeat-x scroll center top #111; +} + +body { + position: relative; + width: 940px; + _width: 945px; /* ie6 */ + min-height: 100%; + overflow: auto; + margin: 0 auto; + padding: 20px 20px 0 20px; + font: 0.75em tahoma, arial, sans-serif; + color: #CCC; +} + +div#container { + margin: -20px -10px 0 -10px; + padding: 95px 0 0 0; +} + +h1 { + position: absolute; + top: 35px; + left: 10px; + margin: 0; + padding: 0px 10px; + font-size: 2em; + font-weight: normal; + color: #FFF; +} + +#select { + position: absolute; + top: 75px; + color: #FFF; + right: 30px; + width: 370px; + text-align: right; +} + +#select select { + width: 100px; +} + +#vitals, #network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups { + float: left; + width: 451px; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; + border: 1px solid #354242; +} + +h2 { + padding: 5px 10px; + font-family: "trebuchet ms"; + font-size: 1.2em; + font-weight: bold; + letter-spacing: 0.0em; + text-transform: uppercase; + color: #FFF; /* #7D9100; */ + background: #354242; +} + +table { + width: 100%; +} + +.plugin { + float: left; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; + border: 1px solid #354242; +} + +.dataTables_wrapper{ + margin: 0 0 0 0 !important; + border: 0px !important; +} + + +th, td, h3 { + padding: 4px 10px 2px 10px; + text-align: left; + vertical-align: top; +} + +h3 { + font-size: 120%; +} + +.even { + background: #333; +} + +#footer { + color: #777777; + clear: both; + margin: 12px; + padding: 13px 25px; + line-height: 18px; + text-align: right; +} + +#memory, #filesystem { + width: 915px; +} + +.bar { + background: #34DA64 url("idash/html.gif"); +} + +.barwarn { + background: #e69575 url("idash/htmlwarn.gif"); +} + +p { + padding: 4px 10px 2px 10px; + line-height: 1.6; + text-align: left; + vertical-align: top; +} + +.right { + text-align: right; + padding-right: 20px; +} + +#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable { + padding: 0px 30px; +} +#lang_047{color:444} diff --git a/root/opt/phpsysinfo/templates/idash/bg.png b/root/opt/phpsysinfo/templates/idash/bg.png new file mode 100644 index 0000000..60b8e4c Binary files /dev/null and b/root/opt/phpsysinfo/templates/idash/bg.png differ diff --git a/root/opt/phpsysinfo/templates/idash/html.gif b/root/opt/phpsysinfo/templates/idash/html.gif new file mode 100644 index 0000000..cc6e205 Binary files /dev/null and b/root/opt/phpsysinfo/templates/idash/html.gif differ diff --git a/root/opt/phpsysinfo/templates/idash/htmlwarn.gif b/root/opt/phpsysinfo/templates/idash/htmlwarn.gif new file mode 100644 index 0000000..7257e8b Binary files /dev/null and b/root/opt/phpsysinfo/templates/idash/htmlwarn.gif differ diff --git a/root/opt/phpsysinfo/templates/jstyle_blue.css b/root/opt/phpsysinfo/templates/jstyle_blue.css new file mode 100644 index 0000000..8e2938b --- /dev/null +++ b/root/opt/phpsysinfo/templates/jstyle_blue.css @@ -0,0 +1,137 @@ +/* + $Id: jstyle_blue.css 518 2011-10-28 08:09:07Z namiltd $ + */ +a { + text-decoration: none; + color: #c03000; +} + +a:hover { + text-decoration: underline; +}* { + margin: 0; + padding: 0; +} + +html { + font-size: 100%; + height: 100%; + background-color: #f3f1e9; + color: #666666; +} + +body { + font-family: Verdana, "Bitstream Vera Sans"; + font-size: .75em; + position: relative; + width: 940px; + _width: 945px; /* ie6 */ + min-height: 100%; + overflow: auto; + margin: 0 auto; + padding: 20px 20px 0 20px; +} + +h1 { + margin: 0 10px; + _margin: 0 15px 0 10px; /* ie6 */ + padding: 10px 10px; + text-align: center; + color: #fff; + font-family: Georgia, serif; + font-weight: normal; + font-size: 150%; + line-height: 1.5em; + color: #326ea1; +} + +#select { + text-align: right; +} + +#select select { + width: 100px; +} + +#vitals, #network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups { + float: left; + width: 451px; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; +} + +h2 { + font-family: Georgia, serif; + font-weight: bold; + font-size: 130%; + padding: 3px 10px; + text-transform: uppercase; + line-height: 1.5em; + color: #326ea1; + border-bottom: 2px solid #326ea1; +} + +table { + width: 100%; +} + +.plugin { + float: left; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; +} + +th, td, h3 { + padding: 4px 10px 2px 10px; + text-align: left; + vertical-align: top; + font-size: 100%; +} + +.even { + background: #EBE8DA; +} + +#footer { + clear: both; + color: #5C5C5C; + margin: 12px; + padding: 13px 25px; + line-height: 18px; + font-size: 80%; + text-align: center; +} + +#memory, #filesystem { + width: 915px; +} + +.bar { + background-color: #326edf; +} + +.barwarn { + background-color: #df326e; +} + +p { + padding: 4px 10px 2px 10px; + line-height: 1.6; + text-align: left; + vertical-align: top; +} + +#filesystemTable thead tr .header { + cursor: pointer; +} + +.right { + text-align: right; + padding-right: 20px; +} + +#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable { + padding: 0px 30px; +} diff --git a/root/opt/phpsysinfo/templates/jstyle_green.css b/root/opt/phpsysinfo/templates/jstyle_green.css new file mode 100644 index 0000000..3594e17 --- /dev/null +++ b/root/opt/phpsysinfo/templates/jstyle_green.css @@ -0,0 +1,142 @@ +/* + $Id: jstyle_green.css 518 2011-10-28 08:09:07Z namiltd $ + */ + +* { + margin:0; + padding:0; +} + +html { + background-color:#f3f1e9; + color:#666; + font-size:100%; + height:100%; +} + +body { + font-family:Verdana, "Bitstream Vera Sans"; + font-size:.75em; + margin:0 auto; + min-height:100%; + overflow:auto; + padding:20px 20px 0; + position:relative; + width:940px; + _width: 945px; /* ie6 */ +} + +h1 { + color:#693; + font-family:Georgia, serif; + font-size:150%; + font-weight:400; + line-height:1.5em; + margin:0 10px; + _margin: 0 15px 0 10px; /* ie6 */ + padding:10px; + text-align:center; +} + +h2 { + border-bottom:2px solid #693; + color:#693; + font-family:Georgia, serif; + font-size:130%; + font-weight:700; + line-height:1.5em; + padding:3px 10px; + text-transform:uppercase; +} + +p { + line-height:1.6; + padding:4px 10px 2px; + text-align:left; + vertical-align:top; +} + +table { + width:100%; +} +.plugin { + float: left; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; +} + +th,td,h3 { + font-size:100%; + padding:4px 10px 2px; + text-align:left; + vertical-align:top; +} + +a { + color:#c03000; + text-decoration:none; +} + +a:hover { + text-decoration:underline; +} + +/****/ + +.bar { + background-color:#C1DC70; +} + +.barwarn { + background-color:#DC8B70; +} + +.even { + background:#EBE8DA; +} + +.right { + padding-right:20px; + text-align:right; +} + +/****/ + +#filesystemTable thead tr .header { + cursor:pointer; +} + +#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable { + padding:0 30px; +} + +#vitals,#network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups { + float:left; + margin:10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding:1px; + width:451px; +} + +#memory,#filesystem { + width:915px; +} + +#select { + text-align:right; +} + +#select select { + width:100px; +} + +#footer { + clear:both; + color:#5C5C5C; + font-size:80%; + line-height:18px; + margin:12px; + padding:13px 25px; + text-align:center; +} diff --git a/root/opt/phpsysinfo/templates/nextgen.css b/root/opt/phpsysinfo/templates/nextgen.css new file mode 100644 index 0000000..80998e4 --- /dev/null +++ b/root/opt/phpsysinfo/templates/nextgen.css @@ -0,0 +1,152 @@ +/* + $Id: nextgen.css 518 2011-10-28 08:09:07Z namiltd $ + */ +a { + text-decoration: none; + color: #00A; +} + +a:hover { + text-decoration: underline; + color: #7D9100; +} + +* { + margin: 0; + padding: 0; +} + +html { + height: 100%; + background: url("nextgen/nextgen_bg.png") repeat-x scroll center top #F3F1E9; +} + +body { + position: relative; + width: 940px; + _width: 945px; /* ie6 */ + min-height: 100%; + overflow: auto; + margin: 0 auto; + padding: 20px 20px 0 20px; + font: 0.75em arial, tahoma, helvetica, sans-serif; + color: #000; +} + +div#container { + margin: -20px -10px 0 -10px; + padding: 116px 0 0 0; +} + +h1 { + position: absolute; + top: 35px; + left: 10px; + margin: 0; + padding: 0px 10px; + font-size: 2em; + font-weight: normal; + color: #fff; +} + +#select { + position: absolute; + top: 75px; + color: #FFF; + right: 30px; + width: 370px; + text-align: right; +} + +#select select { + width: 100px; +} + +#vitals, #network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups { + float: left; + width: 451px; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; + border: 1px solid #354242; +} + +h2 { + padding: 5px 10px; + font-family: "trebuchet ms"; + font-size: 1.2em; + font-weight: bold; + letter-spacing: 0.0em; + text-transform: uppercase; + color: #C9DE55; /* #7D9100; */ + background: #354242; +} + +table { + width: 100%; +} + +.plugin { + float: left; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; + border: 1px solid #354242; +} + +.dataTables_wrapper{ + margin: 0 0 0 0 !important; + border: 0px !important; +} + + +th, td, h3 { + padding: 4px 10px 2px 10px; + text-align: left; + vertical-align: top; +} + +h3 { + font-size: 120%; +} + +.even { + background: #DDD; +} + +#footer { + color: #777777; + clear: both; + margin: 12px; + padding: 13px 25px; + line-height: 18px; + text-align: right; +} + +#memory, #filesystem { + width: 915px; +} + +.bar { + background: #C1DC70 url("../gfx/html.gif"); +} + +.barwarn { + background: #DC8B70 url("../gfx/htmlwarn.gif"); +} + +p { + padding: 4px 10px 2px 10px; + line-height: 1.6; + text-align: left; + vertical-align: top; +} + +.right { + text-align: right; + padding-right: 20px; +} + +#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable { + padding: 0px 30px; +} diff --git a/root/opt/phpsysinfo/templates/nextgen/nextgen_bg.png b/root/opt/phpsysinfo/templates/nextgen/nextgen_bg.png new file mode 100644 index 0000000..d6eb330 Binary files /dev/null and b/root/opt/phpsysinfo/templates/nextgen/nextgen_bg.png differ diff --git a/root/opt/phpsysinfo/templates/phpsysinfo.css b/root/opt/phpsysinfo/templates/phpsysinfo.css new file mode 100644 index 0000000..a4140d1 --- /dev/null +++ b/root/opt/phpsysinfo/templates/phpsysinfo.css @@ -0,0 +1,142 @@ +/* + $Id: phpsysinfo.css 589 2012-07-01 09:58:44Z namiltd $ + */ +a { + text-decoration: none; + color: #c03000; +} + +a:hover { + text-decoration: underline; +}* { + margin: 0; + padding: 0; +} + +html { + height: 100%; + background: url("../gfx/html.gif"); +} + +body { + position: relative; + width: 940px; + _width: 945px; /* ie6 */ + min-height: 100%; + overflow: auto; + margin: 0 auto; + padding: 20px 20px 0 20px; + font: 0.75em arial, tahoma, helvetica, sans-serif; + color: #000; + background: #fff url("../gfx/body.png") repeat-y; + _bac\kground: #fff; /* ie6 only */ +} + +h1 { + margin: 0 10px; + _margin: 0 15px 0 10px; /* ie6 */ + padding: 10px 10px; + border-top: 1px solid #8A6E5A; + border-bottom: 1px solid #8A6E5A; + font-size: 2em; + font-weight: normal; + color: #fff; + background: #8A6E5A; +} + +#select { + text-align: right; + padding: 10px; +} + +#select select { + width: 100px; +} + +#vitals, #network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups { + float: left; + width: 451px; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; + border: 1px solid #5A7E8A; +} + +h2 { + padding: 5px 10px; + font-family: "trebuchet ms"; + font-size: 1.2em; + font-weight: bold; + letter-spacing: 0.0em; + text-transform: uppercase; + color: #fff; + background: #5A7E8A; +} + +table { + width: 100%; +} + +.plugin { + float: left; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; + border: 1px solid #5A7E8A; +} + +.dataTables_wrapper{ + margin: 0 0 0 0 !important; + border: 0px !important; +} + + +th, td, h3 { + padding: 4px 10px 2px 10px; + text-align: left; + vertical-align: top; +} + +h3 { + font-size: 120%; +} + +.even { + background: #d6d6d6; +} + +#footer { + clear: both; + color: #c9c9c9; + margin: 12px; + padding: 13px 25px; + line-height: 18px; +} + +#memory, #filesystem { + width: 915px; +} + +.bar { + background: #C1DC70 url("../gfx/html.gif"); +} + +.barwarn { + background: #DC8B70 url("../gfx/htmlwarn.gif"); +} + +p { + padding: 4px 10px 2px 10px; + line-height: 1.6; + text-align: left; + vertical-align: top; +} + +.right { + text-align: right; + padding-right: 20px; +} + +#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable { + padding: 0px 30px; +} diff --git a/root/opt/phpsysinfo/templates/phpsysinfo_bootstrap.css b/root/opt/phpsysinfo/templates/phpsysinfo_bootstrap.css new file mode 100644 index 0000000..0729a76 --- /dev/null +++ b/root/opt/phpsysinfo/templates/phpsysinfo_bootstrap.css @@ -0,0 +1,84 @@ +body { + font-size: 13px; + padding-top: 80px; +} + +.progress { + margin-bottom: 0; +} + +.table td.rightCell, .table th.rightCell { + text-align: right; +} + +.percent { + text-align: center; +} + +.panel-primary { + border: none; +} + +.navbar { + background-color: #428bca; +} + +.navbar-brand, .navbar-brand:hover { + color: #fff; +} + +.navbar-brand>img { + display: inline; +} + +.treegrid-indent { + width:16px; + height: 16px; + display: inline; + position: relative; +} + +.treegrid-expander { + width:16px; + height: 16px; + display: inline; + position: relative; + cursor: pointer; +} + +.normalicon { + position: relative; + top: 1px; + display: inline-block; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.normalicon-right:before { + content: "\25ba"; +} +.normalicon-down:before { + content: "\25bc"; +} + +table.sortable thead th { + cursor: pointer; + position: relative; + top: 0; + left: 0; +} + +table.sortable thead th:hover { + background: #efefef; +} + +table.borderless td,table.borderless th{ + border: none !important; +} + +.navbar-logo { + cursor: pointer; +} diff --git a/root/opt/phpsysinfo/templates/plugin/jquery.dataTables.css b/root/opt/phpsysinfo/templates/plugin/jquery.dataTables.css new file mode 100644 index 0000000..1b1f16c --- /dev/null +++ b/root/opt/phpsysinfo/templates/plugin/jquery.dataTables.css @@ -0,0 +1,14 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables sorting + */ +.sorting_asc { + background: url('../../gfx/sort_asc.png') no-repeat center right; +} + +.sorting_desc { + background: url('../../gfx/sort_desc.png') no-repeat center right; +} + +.sorting { + background: url('../../gfx/sort_both.png') no-repeat center right; +} \ No newline at end of file diff --git a/root/opt/phpsysinfo/templates/plugin/jquery.jgrowl.css b/root/opt/phpsysinfo/templates/plugin/jquery.jgrowl.css new file mode 100644 index 0000000..082a044 --- /dev/null +++ b/root/opt/phpsysinfo/templates/plugin/jquery.jgrowl.css @@ -0,0 +1,132 @@ + +div.jGrowl { + padding: 10px; + z-index: 9999; + color: #fff; + font-size: 12px; +} + +/** Special IE6 Style Positioning **/ +div.ie6 { + position: absolute; +} + +div.ie6.top-right { + right: auto; + bottom: auto; + left: expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' ); + top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' ); +} + +div.ie6.top-left { + left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' ); + top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' ); +} + +div.ie6.bottom-right { + left: expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' ); + top: expression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' ); +} + +div.ie6.bottom-left { + left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' ); + top: expression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' ); +} + +div.ie6.center { + left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' ); + top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' ); + width: 100%; +} + +/** Normal Style Positions **/ +div.jGrowl { + position: absolute; +} + +body > div.jGrowl { + position: fixed; +} + +div.jGrowl.top-left { + left: 0px; + top: 0px; +} + +div.jGrowl.top-right { + right: 0px; + top: 0px; +} + +div.jGrowl.bottom-left { + left: 0px; + bottom: 0px; +} + +div.jGrowl.bottom-right { + right: 0px; + bottom: 0px; +} + +div.jGrowl.center { + top: 0px; + width: 50%; + left: 25%; +} + +/** Cross Browser Styling **/ +div.center div.jGrowl-notification, div.center div.jGrowl-closer { + margin-left: auto; + margin-right: auto; +} + +div.jGrowl div.jGrowl-notification, div.jGrowl div.jGrowl-closer { + background-color: #000; + opacity: .85; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=85); + zoom: 1; + width: 235px; + padding: 10px; + margin-top: 5px; + margin-bottom: 5px; + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 1em; + text-align: left; + display: none; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.jGrowl div.jGrowl-notification { + min-height: 40px; +} + +div.jGrowl div.jGrowl-notification div.jGrowl-header { + font-weight: bold; + font-size: .85em; +} + +div.jGrowl div.jGrowl-notification div.jGrowl-close { + z-index: 99; + float: right; + font-weight: bold; + font-size: 1em; + cursor: pointer; +} + +div.jGrowl div.jGrowl-closer { + padding-top: 4px; + padding-bottom: 4px; + cursor: pointer; + font-size: .9em; + font-weight: bold; + text-align: center; +} + +/** Hide jGrowl when printing **/ +@media print { + div.jGrowl { + display: none; + } +} \ No newline at end of file diff --git a/root/opt/phpsysinfo/templates/plugin/jquery.treeTable.css b/root/opt/phpsysinfo/templates/plugin/jquery.treeTable.css new file mode 100644 index 0000000..4e6e853 --- /dev/null +++ b/root/opt/phpsysinfo/templates/plugin/jquery.treeTable.css @@ -0,0 +1,37 @@ +/* + Copyright: Paul Hanlon + + Released under the MIT/BSD licence which means you can do anything you want + with it, as long as you keep this copyright notice on the page + */ +.collapsed { + display: none; +} + +.tablemain { + border-collapse: collapse; + padding: 0px; + text-align: left; +} + +.tablemain td { + margin-left: 3px; +} + +.tree td { + padding: 0px 2px 0px 0px; + cursor: pointer; +} + +.adeimg, .ttimage, .parimg, .preimg { + border: none; + margin: 0px; + padding: 0px; + vertical-align: bottom; + width: 16px; + height: 16px; +} + +.adeimg, .parimg { + cursor: pointer; +} diff --git a/root/opt/phpsysinfo/templates/plugin/nyroModal.full.css b/root/opt/phpsysinfo/templates/plugin/nyroModal.full.css new file mode 100644 index 0000000..c747207 --- /dev/null +++ b/root/opt/phpsysinfo/templates/plugin/nyroModal.full.css @@ -0,0 +1,105 @@ +div#nyroModalFull { + font-size: 12px; + color: #777; +} +div#nyroModalFull div#nyroModalLoading { + border: 4px solid #777; + width: 150px; + height: 150px; + text-indent: -9999em; + background: #fff url(../../gfx/ajaxLoader.gif) no-repeat; + background-position: center; +} +div#nyroModalFull div#nyroModalLoading.error { + border: 4px solid #f66; + line-height: 20px; + padding: 20px; + width: 300px; + height: 100px; + text-indent: 0; + background: #fff; +} +div#nyroModalFull div#nyroModalWrapper { + background: #fff; + border: 4px solid #777; +} +div#nyroModalFull div#nyroModalWrapper a#closeBut { + position: absolute; + display: block; + top: -13px; + right: -13px; + width: 12px; + height: 12px; + text-indent: -9999em; + background: url(../../gfx/close.gif) no-repeat; + outline: 0; +} +div#nyroModalFull div#nyroModalWrapper h1#nyroModalTitle { + margin: 0; + padding: 0; + position: absolute; + top: -22px; + left: 5px; + font-size: 12px; + color: #ddd; +} +div#nyroModalFull div#nyroModalWrapper div#nyroModalContent { + overflow: auto; +} +div#nyroModalFull div#nyroModalWrapper div.wrapper div#nyroModalContent { + padding: 5px; +} +div#nyroModalFull div#nyroModalWrapper div.wrapperImg div#nyroModalContent { + position: relative; + overflow: hidden; + text-align: center; +} +div#nyroModalFull div#nyroModalWrapper div.wrapperImg div#nyroModalContent img { + vertical-align: baseline; +} +div#nyroModalFull div#nyroModalWrapper div.wrapperImg div#nyroModalContent div { + position: absolute; + bottom: 0; + left: 0; + background: black; + padding: 10px; + margin: 10px; + border: 1px white dotted; + overflow: hidden; + opacity: 0.2; + filter: alpha(opacity=20); +} +div#nyroModalFull div#nyroModalWrapper div.wrapperImg div#nyroModalContent div:hover { + opacity: 0.5; + filter: alpha(opacity=50); + cursor: help; +} +div#nyroModalFull div#nyroModalWrapper a.nyroModalPrev, div#nyroModalFull div#nyroModalWrapper a.nyroModalNext { + z-index: 105; + outline: none; + position: absolute; + top: 0; + height: 100%; + width: 40%; + cursor: pointer; + text-indent: -9999em; + background: left 20% no-repeat; + background-image: url(data:image/gif;base64,AAAA); /* Trick IE6 */ +} +div#nyroModalFull div#nyroModalWrapper div.wrapperSwf a.nyroModalPrev, div#nyroModalFull div#nyroModalWrapper div.wrapperSwf a.nyroModalNext, div#nyroModalFull div#nyroModalWrapper div.wrapper a.nyroModalPrev, div#nyroModalFull div#nyroModalWrapper div.wrapper a.nyroModalNext { + height: 60%; + width: 20%; +} +div#nyroModalFull div#nyroModalWrapper div#nyroModalContent a.nyroModalPrev { + left: 0; +} +div#nyroModalFull div#nyroModalWrapper div#nyroModalContent a.nyroModalPrev:hover { + background-image: url(../../gfx/prev.png); +} +div#nyroModalFull div#nyroModalWrapper div#nyroModalContent a.nyroModalNext { + right: 0; + background-position: right 20%; +} +div#nyroModalFull div#nyroModalWrapper div#nyroModalContent a.nyroModalNext:hover { + background-image: url(../../gfx/next.png); +} \ No newline at end of file diff --git a/root/opt/phpsysinfo/templates/two.css b/root/opt/phpsysinfo/templates/two.css new file mode 100644 index 0000000..e506be6 --- /dev/null +++ b/root/opt/phpsysinfo/templates/two.css @@ -0,0 +1,123 @@ +/* + $Id: two.css 518 2011-10-28 08:09:07Z namiltd $ + */ +a { + text-decoration: none; + color: #c03000; +} + +a:hover { + text-decoration: underline; +}* { + margin: 0; + padding: 0; +} + +html { + font-size: 100%; + height: 100%; + color: #2B2828; + background: url("two/gradient.png") repeat-x #EEF2FE; +} + +body { + font-family: Verdana, "Bitstream Vera Sans"; + font-size: .75em; + position: relative; + width: 940px; + _width: 945px; /* ie6 */ + min-height: 100%; + overflow: auto; + margin: 0 auto; + padding: 20px 20px 0 20px; +} + +h1 { + margin: 0 10px; + _margin: 0 15px 0 10px; /* ie6 */ + padding: 10px 10px; + text-align: center; + color: #fff; + font-weight: normal; + font-size: 170%; + line-height: 1.5em; +} + +#select { + color: #fff; + text-align: right; + margin-bottom: 45px; +} + +#select select { + width: 100px; +} + +h2 { + font-weight: bold; + font-size: 130%; + line-height: 1.5em; + color: #8B272A; + border-bottom: 2px solid #8B272A; +} + +table { + width: 100%; +} + +.plugin { + float: left; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; +} + +th, td, h3 { + padding: 4px 10px 2px 10px; + text-align: left; + vertical-align: top; + font-size: 100%; +} + +#footer { + clear: both; + color: #5C5C5C; + margin: 12px; + padding: 13px 25px; + line-height: 18px; + font-size: 80%; + text-align: center; +} + +.bar { + background-color: #8B272A; +} + +.barwarn { + background-color: #88278B; +} + +#vitals, #network, #memory, #filesystem, #hardware, #temp, #voltage, #fan, #power, #current, #ups { + float: left; + width: 451px; + margin: 10px 0 0 10px; + _margin: 10px 5px 0 5px; /* ie6 */ + padding: 1px; +} + +#memory, #filesystem { + width: 915px; +} + +#filesystemTable thead tr .header { + cursor: pointer; +} + +.right { + text-align: right; + padding-right: 20px; +} + +#pciTable, #ideTable, #scsiTable, #usbTable, #tbTable, #i2cTable { + padding: 0px 30px; +} diff --git a/root/opt/phpsysinfo/templates/two/gradient.png b/root/opt/phpsysinfo/templates/two/gradient.png new file mode 100644 index 0000000..9a7a470 Binary files /dev/null and b/root/opt/phpsysinfo/templates/two/gradient.png differ diff --git a/root/opt/phpsysinfo/templates/vendor/bootstrap.min.css b/root/opt/phpsysinfo/templates/vendor/bootstrap.min.css new file mode 100644 index 0000000..28f154d --- /dev/null +++ b/root/opt/phpsysinfo/templates/vendor/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:absolute;top:0;right:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/root/opt/phpsysinfo/tools/MakeRelease.sh b/root/opt/phpsysinfo/tools/MakeRelease.sh new file mode 100755 index 0000000..6cbd4af --- /dev/null +++ b/root/opt/phpsysinfo/tools/MakeRelease.sh @@ -0,0 +1,32 @@ +#!/bin/sh -x + +if [ $# -ne 1 ] +then + echo "Usage : ./tools/MakeRelease " + exit +fi + +sed -i "s/PSI_VERSION = '.*'/PSI_VERSION = '$1'/g" includes/class.CommonFunctions.inc.php +ARCHIVE_NAME="phpsysinfo-$1.tar.gz" + +#copy to temp dir +rm -rf /tmp/phpsysinfo +mkdir /tmp/phpsysinfo +cp -R . /tmp/phpsysinfo +cd /tmp/phpsysinfo + +# remove the svn directories +find . -type d -name .svn -exec rm -fr {} \; +#or find . -iname ".svn" -print0 | xargs -0 rm -r + +#remove some dirs +rm -rf tools sample + +#remove phpsysinfo.ini +rm -rf phpsysinfo.ini .cvsignore .project + +#create archive +cd .. +tar -czf $ARCHIVE_NAME phpsysinfo + +md5sum $ARCHIVE_NAME diff --git a/root/opt/phpsysinfo/tools/README b/root/opt/phpsysinfo/tools/README new file mode 100644 index 0000000..71d6c21 --- /dev/null +++ b/root/opt/phpsysinfo/tools/README @@ -0,0 +1,4 @@ +check.sh - Script for checking *.php files and reformat them +MakeRelease.sh - Cleanup the code a bit for a release +phpsysinfo.ini - Configuration file for generating documentation with phpDocumentor +lint.bat - run php lint on every php file to check for syntax (windows util) diff --git a/root/opt/phpsysinfo/tools/aptana/js.xml b/root/opt/phpsysinfo/tools/aptana/js.xml new file mode 100644 index 0000000..ca19006 --- /dev/null +++ b/root/opt/phpsysinfo/tools/aptana/js.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/root/opt/phpsysinfo/tools/aptana/php.xml b/root/opt/phpsysinfo/tools/aptana/php.xml new file mode 100644 index 0000000..15fadc4 --- /dev/null +++ b/root/opt/phpsysinfo/tools/aptana/php.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/root/opt/phpsysinfo/tools/check.sh b/root/opt/phpsysinfo/tools/check.sh new file mode 100755 index 0000000..62d32cb --- /dev/null +++ b/root/opt/phpsysinfo/tools/check.sh @@ -0,0 +1,15 @@ +#!/bin/bash +FILES=`find ../ \( \( -iwholename '*tool*' -o -iwholename '*lang*' \) -prune -o -iname '*.php' \) -a -type f` + +for entry in ${FILES}; do + php -l ${entry} + if [ $? -ne 0 ] + then + exit; + fi +done + +for entry in ${FILES}; do + echo "running phpcs --standard=PEAR on ${entry}" + phpcs --standard=PEAR ${entry} +done diff --git a/root/opt/phpsysinfo/tools/checkdistro.php b/root/opt/phpsysinfo/tools/checkdistro.php new file mode 100644 index 0000000..7bbd033 --- /dev/null +++ b/root/opt/phpsysinfo/tools/checkdistro.php @@ -0,0 +1,208 @@ +"; +echo ""; +echo " "; +echo ""; +if (PHP_OS != 'Linux') { + echo "Test works only on Linux"; + echo ""; + die(); +} + +define('APP_ROOT', dirname(__FILE__).'/..'); +require_once APP_ROOT.'/includes/interface/class.PSI_Interface_OS.inc.php'; +require_once APP_ROOT.'/includes/os/class.OS.inc.php'; +require_once APP_ROOT.'/includes/to/class.System.inc.php'; +require_once APP_ROOT.'/includes/os/class.Linux.inc.php'; +define('PSI_USE_VHOST', false); +define('PSI_DEBUG', false); +define('PSI_LOAD_BAR', false); + +$log_file = ""; +$lsb = true; //enable detection lsb_release -a +$lsbfile = true; //enable detection /etc/lsb-release + +class Error +{ + public static function singleton() + { + } +} + +class Parser +{ + public static function lspci() + { + return array(); + } + public static function df() + { + return array(); + } +} + +class CommonFunctions +{ + private static function _parse_log_file($string) + { + global $log_file; + if (file_exists($log_file)) { + $contents = @file_get_contents($log_file); + if ($contents && preg_match("/^\-\-\-\-\-\-\-\-\-\-".preg_quote($string, '/')."\-\-\-\-\-\-\-\-\-\-\n/m", $contents, $matches, PREG_OFFSET_CAPTURE)) { + $findIndex = $matches[0][1]; + if (preg_match("/\n/m", $contents, $matches, PREG_OFFSET_CAPTURE, $findIndex)) { + $startIndex = $matches[0][1]+1; + if (preg_match("/^\-\-\-\-\-\-\-\-\-\-/m", $contents, $matches, PREG_OFFSET_CAPTURE, $startIndex)) { + $stopIndex = $matches[0][1]; + + return substr($contents, $startIndex, $stopIndex-$startIndex); + } else { + return substr($contents, $startIndex); + } + } + } + } + + return false; + } + + public static function rfts($strFileName, &$strRet, $intLines = 0, $intBytes = 4096, $booErrorRep = true) + { + global $lsb; + global $lsbfile; + if ($lsb || $lsbfile || ($strFileName != "/etc/lsb-release")) { + $strRet=self::_parse_log_file($strFileName); + if ($strRet && ($intLines == 1) && (strpos($strRet, "\n") !== false)) { + $strRet=trim(substr($strRet, 0, strpos($strRet, "\n"))); + } + + return $strRet; + } else { + return false; + } + } + + public static function executeProgram($strProgramname, $strArgs, &$strBuffer, $booErrorRep = true) + { + global $lsb; + $strBuffer = ''; + if ($strProgramname=='lsb_release') { + return $lsb && ($strBuffer = self::_parse_log_file('lsb_release -a')); + } else { + return $strBuffer = self::_parse_log_file($strProgramname); + } + } + + public static function fileexists($strFileName) + { + global $log_file; + global $lsb; + global $lsbfile; + if (file_exists($log_file) + && ($lsb || $lsbfile || ($strFileName != "/etc/lsb-release")) + && ($contents = @file_get_contents($log_file)) + && preg_match("/^\-\-\-\-\-\-\-\-\-\-".preg_quote($strFileName, '/')."\-\-\-\-\-\-\-\-\-\-\n/m", $contents)) { + return true; + } + + return false; + } + + public static function gdc() + { + return array(); + } +} + +$system = new Linux(); +if ($handle = opendir(APP_ROOT.'/sample/distrotest')) { + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + while (false !== ($entry = readdir($handle))) { + if (($entry!=".")&&($entry!="..")) { + if ($shandle = opendir(APP_ROOT."/sample/distrotest/$entry")) { + while (false !== ($sentry = readdir($shandle))) { + if (($sentry!=".")&&($sentry!="..")) { + $log_file=APP_ROOT.'/sample/distrotest/'.$entry.'/'.$sentry; + echo ""; + echo ""; + + $lsb = true; + $lsbfile = true; + $sys=$system->getSys(); + $distro=$sys->getDistribution(); + $icon=$sys->getDistributionIcon(); + if ($icon == '') $icon="unknown.png"; + if ($icon != $entry.'.png') + echo ""; + if ($icon != $entry.'.png') + echo ""; + $sys->setDistribution(""); + $sys->setDistributionIcon(""); + + $lsb = false; + $lsbfile = true; + $sys=$system->getSys(); + $distro=$sys->getDistribution(); + $icon=$sys->getDistributionIcon(); + if ($icon == '') $icon="unknown.png"; + if ($icon != $entry.'.png') + echo ""; + if ($icon != $entry.'.png') + echo ""; + $sys->setDistribution(""); + $sys->setDistributionIcon(""); + + $lsb = false; + $lsbfile = false; + $sys=$system->getSys(); + $distro=$sys->getDistribution(); + $icon=$sys->getDistributionIcon(); + if ($icon == '') $icon="unknown.png"; + if ($icon != $entry.'.png') + echo ""; + if ($icon != $entry.'.png') + echo ""; + $sys->setDistribution(""); + $sys->setDistributionIcon(""); + + echo ""; + } + } + closedir($shandle); + } + } + } + echo "
    Distrotest sampleDistro NameDistro IconDistro Name (no lsb_release)Distro Icon (no lsb_release)Distro Name (no lsb_release and no /etc/lsb-release)Distro Icon (no lsb_release and no /etc/lsb-release)
    ".$entry.'/'.$sentry.""; + else + echo ""; + echo $distro.""; + else + echo ""; + echo ""; + echo $icon.""; + else + echo ""; + echo $distro.""; + else + echo ""; + echo ""; + echo $icon.""; + else + echo ""; + echo $distro.""; + else + echo ""; + echo ""; + echo $icon."
    "; + closedir($handle); +} +echo ""; diff --git a/root/opt/phpsysinfo/tools/distrotest.php b/root/opt/phpsysinfo/tools/distrotest.php new file mode 100644 index 0000000..2b3b891 --- /dev/null +++ b/root/opt/phpsysinfo/tools/distrotest.php @@ -0,0 +1,44 @@ +/dev/null", "r"); +if (is_resource($fp)) { + $contents=""; + $start=true; + while (!feof($fp)) { + $contents=fgets($fp, 4096); + if ($start && (strlen($contents)>0)) { + echo "----------lsb_release -a----------\n"; + $start=false; + } + echo $contents; + } + if ((strlen($contents)>0)&&(substr($contents, -1)!="\n")) { + echo "\n"; + } + pclose($fp); +} + +foreach ($filemaskarray as $filemask) { + foreach (glob($filemask) as $filename) { + echo "----------".$filename."----------\n"; + echo $contents=file_get_contents($filename); + if ((strlen($contents)>0)&&(substr($contents, -1)!="\n")) { + echo "\n"; + } + } +} diff --git a/root/opt/phpsysinfo/tools/lint.bat b/root/opt/phpsysinfo/tools/lint.bat new file mode 100644 index 0000000..b0502ab --- /dev/null +++ b/root/opt/phpsysinfo/tools/lint.bat @@ -0,0 +1,10 @@ +@echo off +echo. +echo Starting SVN Stat + PHP Lint +echo ============================ +svn stat |findstr /I /R "\.php$ \.phtml$" >lint.txt +for /F "tokens=2 delims= " %%i in (lint.txt) do q:\php53\php.exe -l %%i |findstr /I /B /V "No syntax errors" +del lint.txt +echo. +echo ============================ +echo Finished SVN Stat + PHP Lint diff --git a/root/opt/phpsysinfo/xml.php b/root/opt/phpsysinfo/xml.php new file mode 100644 index 0000000..9d8f10b --- /dev/null +++ b/root/opt/phpsysinfo/xml.php @@ -0,0 +1,60 @@ + + * @copyright 2009 phpSysInfo + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @version SVN: $Id: xml.php 614 2012-07-28 09:02:59Z jacky672 $ + * @link http://phpsysinfo.sourceforge.net + */ + + /** + * application root path + * + * @var string + */ +define('APP_ROOT', dirname(__FILE__)); + +/** + * internal xml or external + * external is needed when running in static mode + * + * @var boolean + */ +define('PSI_INTERNAL_XML', true); + +require_once APP_ROOT.'/includes/autoloader.inc.php'; + +// check what xml part should be generated +if (isset($_GET['plugin'])) { + $plugin = basename(htmlspecialchars($_GET['plugin'])); + if ($plugin == "complete") { + $output = new WebpageXML(true, null); + } elseif ($plugin != "") { + $output = new WebpageXML(false, $plugin); + } else { + unset($output); + } +} else { + $output = new WebpageXML(false, null); +} +// if $output is correct generate output in proper type +if (isset($output) && is_object($output)) { + if (isset($_GET['json']) || isset($_GET['jsonp'])) { + if (defined('PSI_JSON_ISSUE') && (PSI_JSON_ISSUE)) { + $json = json_encode(simplexml_load_string(str_replace(">", ">\n", $output->getXMLString()))); // solving json_encode issue + } else { + $json = json_encode(simplexml_load_string($output->getXMLString())); + } + // check for jsonp with callback name restriction + echo isset($_GET['jsonp']) ? (!preg_match('/[^A-Za-z0-9_\?]/', $_GET['callback'])?$_GET['callback']:'') . '('.$json.')' : $json; + } else { + $output->run(); + } +} diff --git a/smeserver-phpsysinfo.spec b/smeserver-phpsysinfo.spec new file mode 100644 index 0000000..0620465 --- /dev/null +++ b/smeserver-phpsysinfo.spec @@ -0,0 +1,148 @@ +# $Id: smeserver-phpsysinfo.spec,v 1.4 2022/08/01 03:32:28 jpp Exp $ +# Authority: darrellmay +# Name: Darrell May + +Summary: phpSysInfo for SME Server +%define name smeserver-phpsysinfo +Name: %{name} +%define version 3.2.3 +%define release 7 +Version: %{version} +Release: %{release}%{?dist} +License: GPL +Group: SME/addon +Source: %{name}-%{version}.tar.xz + +URL: http://phpsysinfo.sourceforge.net +BuildRoot: /var/tmp/%{name}-%{version}-%{release}-buildroot +BuildArchitectures: noarch +Requires: smeserver-release >= 10.0 +Requires: e-smith-apache >= 2.6.0-19 +Requires: hddtemp lm_sensors +BuildRequires: e-smith-devtools +AutoReqProv: no + +%description +%name is an implementation of phpSysInfo on SME Server. +Access with admin login credentials via https://yourdomain/phpsysinfo + +%changelog +* Sat Sep 07 2024 cvs2git.sh aka Brian Read 3.2.3-7.sme +- Roll up patches and move to git repo [SME: 12338] + +* Sat Sep 07 2024 BogusDateBot +- Eliminated rpmbuild "bogus date" warnings due to inconsistent weekday, + by assuming the date is correct and changing the weekday. + +* Sun Jul 31 2022 Jean-Philippe Pialasse 3.2.3-6.sme +- update to httpd 2.4 access syntax [SME: 12057] + removed compatibnility, added Requires e-smith-apache >= 2.6.0-19 + +* Sun Jul 24 2022 Jean-Philippe Pialasse 3.2.3-5.sme +- update to httpd 2.4 access syntax [SME: 12057] + +* Wed Apr 07 2021 Brian Read 3.2.3-4.sme +- Add Update event to createlinks [SME: 11054] + +* Wed Apr 07 2021 BogusDateBot +- Eliminated rpmbuild "bogus date" warnings due to inconsistent weekday, + by assuming the date is correct and changing the weekday. + Thu May 30 2001 --> Thu May 24 2001 or Wed May 30 2001 or Thu May 31 2001 or .... + Wed Sep 22 2015 --> Wed Sep 16 2015 or Tue Sep 22 2015 or Wed Sep 23 2015 or .... + +* Sun Jan 20 2019 Jean-Philipe Pialasse 3.2.3-3.sme +- Add Update event to createlinks process formating [SME: 10329] + +* Tue Sep 22 2015 stephane de Labrusse 3.2.3-1.sme + Wed Sep 22 2015 --> Wed Sep 16 2015 or Tue Sep 22 2015 or Wed Sep 23 2015 or .... +- Upgrade to upstream 3.2.3 +- Require hddtemp lm_sensors + +* Sat Jun 21 2014 stephane de Labrusse 3.1.13-1.sme +- Initial release to sme9 +- upgrade of phpsysinfo to 3.1.13 https://github.com/phpsysinfo/phpsysinfo/releases/tag/v3.1.13 +- added a menu in the administration panel of server-manager + +* Mon Apr 21 2008 Shad L. Lords +- Prep for import into buildsys +- Clean up spec + +* Fri Oct 19 2007 Darrell May +- accounts and configuration db phpsysinfo defaults added +- default access restricted to private (private|public) +- phpsysinfo-2.5.4 +- [2.5.4-0dmay] +* Mon Apr 09 2007 Darrell May +- [2.5.3-1dmay] +* Sun Apr 01 2007 Darrell May +- phpsysinfo-2.5.3 +- [2.5.3-0dmay] +* Tue Jan 02 2007 Darrell May +- phpsysinfo-2.5.2 +- [2.5.2-0] +* Fri Aug 04 2006 Darrell May +- phpsysinfo-2.5.2-rc3 +- [2.5.2-rc3] +* Wed Dec 14 2005 Darrell May +- phpsysinfo-2.5 +- [2.5-0] +* Fri Apr 22 2005 Darrell May +- added support for SME Server 7.x +- [2.3-2] +* Mon Nov 15 2004 Darrell May +- updated to release 2.3 +- renamed smeserver-phpsysinfo +- updated includes/os/class.Linux.inc.php to recognize SME Server +- [2.3-1] +* Sat Jun 29 2002 Darrell May +- updated to release 2.1 +- [2.1-1] +* Sun Mar 10 2002 Darrell May +- updated to release 2.0 +- [2.0-1] +* Sun Mar 10 2002 Darrell May +- changed rights/ownership to tighten security +- [1.9-2] +* Tue Mar 05 2002 Darrell May +- changed %post/postun to graceful +- [1.9-1] +* Mon Jan 21 2002 Darrell May +- updated to version 1.9 +- [1.9-0] +* Wed Oct 31 2001 Darrell May +- updated to version 1.8 +- [1.8-0] +* Sun Sep 23 2001 Darrell May +- name change +* Wed May 30 2001 Darrell May + Thu May 30 2001 --> Thu May 24 2001 or Wed May 30 2001 or Thu May 31 2001 or .... +- 2.1.0-1 +- Original version + +%prep +%setup + +%build +perl createlinks + + +%install +/bin/rm -rf $RPM_BUILD_ROOT +(cd root ; /usr/bin/find . -depth -print | /bin/cpio -dump $RPM_BUILD_ROOT) +/bin/rm -f %{name}-%{version}-filelist +/sbin/e-smith/genfilelist $RPM_BUILD_ROOT > %{name}-%{version}-filelist + +%clean +/bin/rm -rf $RPM_BUILD_ROOT + +%files -f %{name}-%{version}-filelist +%defattr(-,root,root) + +%pre +if [[ -f /opt/phpsysinfo/phpsysinfo.ini ]]; then + /bin/cp /opt/phpsysinfo/phpsysinfo.ini /opt/phpsysinfo/phpsysinfo.ini-$(date +"%H:%M-%b-%d-%Y") +fi +%post +if ! [[ -f /opt/phpsysinfo/phpsysinfo.ini ]]; then + cp /opt/phpsysinfo/phpsysinfo.ini.new /opt/phpsysinfo/phpsysinfo.ini +fi