Merge branch 'master' into storageareas
commit
87f68e4a5b
|
@ -802,6 +802,24 @@ if(WITH_SYSTEMD)
|
|||
endif(NOT POLKIT_FOUND)
|
||||
endif(WITH_SYSTEMD)
|
||||
|
||||
# Find the path to an arp compatible executable
|
||||
if(ZM_PATH_ARP STREQUAL "")
|
||||
find_program(ARP_EXECUTABLE arp)
|
||||
if(ARP_EXECUTABLE)
|
||||
set(ZM_PATH_ARP "${ARP_EXECUTABLE}")
|
||||
mark_as_advanced(ARP_EXECUTABLE)
|
||||
else(ARP_EXECUTABLE)
|
||||
find_program(ARP_EXECUTABLE ip)
|
||||
if(ARP_EXECUTABLE)
|
||||
set(ZM_PATH_ARP "${ARP_EXECUTABLE} neigh")
|
||||
mark_as_advanced(ARP_EXECUTABLE)
|
||||
endif(ARP_EXECUTABLE)
|
||||
endif(ARP_EXECUTABLE)
|
||||
if(ARP_EXECUTABLE-NOTFOUND)
|
||||
message(WARNING "Unable to find a compatible arp binary. Monitor probe will not function." )
|
||||
endif(ARP_EXECUTABLE-NOTFOUND)
|
||||
endif(ZM_PATH_ARP STREQUAL "")
|
||||
|
||||
# Some variables that zm expects
|
||||
set(ZM_PID "${ZM_RUNDIR}/zm.pid")
|
||||
set(ZM_CONFIG "${ZM_CONFIG_DIR}/zm.conf")
|
||||
|
|
|
@ -13,6 +13,7 @@ Build-Depends: debhelper (>= 9), cmake
|
|||
, libv4l-dev (>= 0.8.3)
|
||||
, libbz2-dev
|
||||
, ffmpeg | libav-tools
|
||||
, net-tools
|
||||
, libnetpbm10-dev
|
||||
, libvlccore-dev, libvlc-dev
|
||||
, libcurl4-gnutls-dev | libcurl4-nss-dev | libcurl4-openssl-dev
|
||||
|
|
|
@ -8,16 +8,6 @@ SET(zmgid_final www)
|
|||
SET(webroot /srv/www/htdocs)
|
||||
SET(zm_webdir ${webroot}/zoneminder)
|
||||
|
||||
# Download jscalendar & move files into position
|
||||
file(DOWNLOAD http://downloads.sourceforge.net/jscalendar/jscalendar-1.0.zip ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar-1.0.zip STATUS download_jsc)
|
||||
if(download_jsc EQUAL 0)
|
||||
message(STATUS "Jscalander successfully downloaded. Installing...")
|
||||
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ERROR_VARIABLE unzip_jsc)
|
||||
message(STATUS "Status of jscalender script was: ${unzip_jsc}")
|
||||
else(download_jsc EQUAL 0)
|
||||
message(STATUS "Unable to download optional jscalander. Skipping...")
|
||||
endif(download_jsc EQUAL 0)
|
||||
|
||||
# Create several empty folders
|
||||
file(MAKE_DIRECTORY sock swap zoneminder zoneminder-upload events images temp)
|
||||
|
||||
|
@ -45,7 +35,3 @@ install(FILES zoneminder.tmpfiles DESTINATION /etc/tmpfiles.d RENAME zoneminder.
|
|||
install(FILES redalert.wav DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/sounds PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
install(FILES zoneminder.service DESTINATION /usr/lib/systemd/system PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
|
||||
|
||||
# Install jscalendar
|
||||
if(unzip_jsc STREQUAL "")
|
||||
install(DIRECTORY jscalendar-1.0/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/tools/jscalendar)
|
||||
endif(unzip_jsc STREQUAL "")
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
unzip -o jscalendar-1.0.zip
|
||||
mkdir -v jscalendar-doc
|
||||
cd jscalendar-1.0
|
||||
mv -v *html *php doc/* README ../jscalendar-doc
|
||||
rmdir -v doc
|
|
@ -16,7 +16,6 @@ Version: 1.27.0
|
|||
Release: 1%{?dist}
|
||||
Summary: A camera monitoring and analysis tool
|
||||
Group: System Environment/Daemons
|
||||
# jscalendar is LGPL (any version): http://www.dynarch.com/projects/calendar/
|
||||
# Mootools is under the MIT license: http://mootools.net/
|
||||
License: GPLv2+ and LGPLv2+ and MIT
|
||||
URL: http://www.zoneminder.com/
|
||||
|
@ -141,7 +140,7 @@ fi
|
|||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc AUTHORS COPYING README.md distros/opensuse/README.OpenSuse distros/opensuse/jscalendar-doc
|
||||
%doc AUTHORS COPYING README.md distros/opensuse/README.OpenSuse
|
||||
%docdir /opt/zoneminder/share/man
|
||||
%config %attr(640,root,%{zmgid_final}) /etc/zm.conf
|
||||
%config(noreplace) %attr(644,root,root) /etc/apache2/conf.d/zoneminder.conf
|
||||
|
|
|
@ -27,18 +27,6 @@ else(ZM_WEB_USER STREQUAL "nginx")
|
|||
configure_file(systemd/zoneminder.tmpfiles.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.tmpfiles @ONLY)
|
||||
endif(ZM_WEB_USER STREQUAL "nginx")
|
||||
|
||||
# Unpack jscalendar & move files into position
|
||||
message(STATUS "Unpacking and Installing jscalendar...")
|
||||
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/misc/jscalendar.sh
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
ERROR_VARIABLE unzip_jsc
|
||||
)
|
||||
if("${unzip_jsc}" STREQUAL "")
|
||||
message(STATUS "jscalendar successfully installed.")
|
||||
else("${unzip_jsc}" STREQUAL "")
|
||||
message(FATAL_ERROR "\nAn error occurred while jscalendar was being processed:\n${unzip_jsc}")
|
||||
endif("${unzip_jsc}" STREQUAL "")
|
||||
|
||||
# Create several empty folders
|
||||
file(MAKE_DIRECTORY sock swap zoneminder zoneminder-upload events images temp)
|
||||
|
||||
|
@ -58,7 +46,6 @@ install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DE
|
|||
|
||||
# Install auxiliary files
|
||||
install(FILES misc/redalert.wav DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/sounds PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
install(DIRECTORY jscalendar-1.0/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/tools/jscalendar)
|
||||
|
||||
# Install zoneminder service files
|
||||
install(FILES zoneminder.logrotate DESTINATION /etc/logrotate.d RENAME zoneminder PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
|
||||
|
|
Binary file not shown.
|
@ -1,7 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
unzip -o misc/jscalendar-1.0.zip
|
||||
mkdir -v jscalendar-doc
|
||||
cd jscalendar-1.0
|
||||
mv -v *html *php doc/* README ../jscalendar-doc
|
||||
rmdir -v doc
|
|
@ -30,7 +30,6 @@ Version: 1.31.44
|
|||
Release: 1%{?dist}
|
||||
Summary: A camera monitoring and analysis tool
|
||||
Group: System Environment/Daemons
|
||||
# jscalendar is LGPL (any version): http://www.dynarch.com/projects/calendar/
|
||||
# Mootools is inder the MIT license: http://mootools.net/
|
||||
# CakePHP is under the MIT license: https://github.com/cakephp/cakephp
|
||||
# Crud is under the MIT license: https://github.com/FriendsOfCake/crud
|
||||
|
@ -53,6 +52,7 @@ BuildRequires: pcre-devel
|
|||
BuildRequires: libjpeg-turbo-devel
|
||||
BuildRequires: findutils
|
||||
BuildRequires: coreutils
|
||||
BuildRequires: net-tools
|
||||
BuildRequires: perl
|
||||
BuildRequires: perl-generators
|
||||
BuildRequires: perl(Archive::Tar)
|
||||
|
@ -252,7 +252,7 @@ EOF
|
|||
|
||||
%files
|
||||
%license COPYING
|
||||
%doc AUTHORS README.md distros/redhat/readme/README.%{readme_suffix} distros/redhat/readme/README.https distros/redhat/jscalendar-doc
|
||||
%doc AUTHORS README.md distros/redhat/readme/README.%{readme_suffix} distros/redhat/readme/README.https
|
||||
|
||||
# We want these two folders to have "normal" read permission
|
||||
# compared to the folder contents
|
||||
|
|
|
@ -11,6 +11,8 @@ Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apa
|
|||
,libavformat-dev (>= 6:10~)
|
||||
,libavutil-dev (>= 6:10~)
|
||||
,libswscale-dev (>= 6:10~)
|
||||
,ffmpeg | libav-tools
|
||||
,net-tools
|
||||
,libbz2-dev
|
||||
,libgcrypt-dev | libgcrypt11-dev
|
||||
,libcurl4-gnutls-dev
|
||||
|
|
|
@ -78,36 +78,42 @@ class AppController extends Controller {
|
|||
if ( $zmOptAuth == '1' ) {
|
||||
require_once "../../../includes/auth.php";
|
||||
|
||||
$this->loadModel('User');
|
||||
global $user;
|
||||
$user = $this->Session->read('user');
|
||||
|
||||
if ( isset($_REQUEST['user']) and isset($_REQUEST['pass']) ) {
|
||||
$user = $this->User->find('first', array ('conditions' => array (
|
||||
'User.Username' => $_REQUEST['user'],
|
||||
'User.Password' => DboSource::expression('PASSWORD(\''.$_REQUEST['pass'].'\')'),
|
||||
)) );
|
||||
if ( ! $user ) {
|
||||
$user = userLogin($_REQUEST['user'],$_REQUEST['pass']);
|
||||
if ( !$user ) {
|
||||
throw new UnauthorizedException(__('User not found'));
|
||||
return;
|
||||
} else {
|
||||
$this->Session->Write( 'user', $user['User'] );
|
||||
$this->Session->Write( 'user.Username', $user['User']['Username'] );
|
||||
$this->Session->Write( 'user.Enabled', $user['User']['Enabled'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset($_REQUEST['auth']) ) {
|
||||
|
||||
$user = getAuthUser($_REQUEST['auth']);
|
||||
if ( ! $user ) {
|
||||
throw new UnauthorizedException(__('User not found'));
|
||||
return;
|
||||
} else {
|
||||
if ( ! $this->Session->Write('user.Username', $user['Username']) )
|
||||
$this->log("Error writing session var user.Username");
|
||||
if ( ! $this->Session->Write('user.Enabled', $user['Enabled']) )
|
||||
$this->log("Error writing session var user.Enabled");
|
||||
}
|
||||
} # end if REQUEST['auth']
|
||||
|
||||
if ( 0 and $user ) {
|
||||
# We have to redo the session variables because cakephp's Session code will overwrite the normal php session
|
||||
# Actually I'm not sure that is true. Getting indeterminate behaviour
|
||||
Logger::Debug("user.Username: " . $this->Session->read('user.Username'));
|
||||
if ( ! $this->Session->Write('user', $user) )
|
||||
$this->log("Error writing session var user");
|
||||
Logger::Debug("user.Username: " . $this->Session->read('user.Username'));
|
||||
if ( ! $this->Session->Write('user.Username', $user['Username']) )
|
||||
$this->log("Error writing session var user.Username");
|
||||
if ( ! $this->Session->Write('password', $user['Password']) )
|
||||
$this->log("Error writing session var user.Username");
|
||||
if ( ! $this->Session->Write('user.Enabled', $user['Enabled']) )
|
||||
$this->log("Error writing session var user.Enabled");
|
||||
if ( ! $this->Session->Write('remoteAddr', $_SERVER['REMOTE_ADDR']) )
|
||||
$this->log("Error writing session var remoteAddr");
|
||||
}
|
||||
|
||||
if ( ! $this->Session->read('user.Username') ) {
|
||||
throw new UnauthorizedException(__('Not Authenticated'));
|
||||
return;
|
||||
|
@ -116,14 +122,12 @@ class AppController extends Controller {
|
|||
return;
|
||||
}
|
||||
|
||||
$options = array ('conditions' => array ('User.Username' => $this->Session->Read('user.Username')));
|
||||
$userMonitors = $this->User->find('first', $options);
|
||||
$this->Session->Write('allowedMonitors',$userMonitors['User']['MonitorIds']);
|
||||
$this->Session->Write('streamPermission',$userMonitors['User']['Stream']);
|
||||
$this->Session->Write('eventPermission',$userMonitors['User']['Events']);
|
||||
$this->Session->Write('controlPermission',$userMonitors['User']['Control']);
|
||||
$this->Session->Write('systemPermission',$userMonitors['User']['System']);
|
||||
$this->Session->Write('monitorPermission',$userMonitors['User']['Monitors']);
|
||||
$this->Session->Write('allowedMonitors',$user['MonitorIds']);
|
||||
$this->Session->Write('streamPermission',$user['Stream']);
|
||||
$this->Session->Write('eventPermission',$user['Events']);
|
||||
$this->Session->Write('controlPermission',$user['Control']);
|
||||
$this->Session->Write('systemPermission',$user['System']);
|
||||
$this->Session->Write('monitorPermission',$user['Monitors']);
|
||||
} else {
|
||||
// if auth is not on, you can do everything
|
||||
//$userMonitors = $this->User->find('first', $options);
|
||||
|
@ -134,8 +138,5 @@ class AppController extends Controller {
|
|||
$this->Session->Write('systemPermission','Edit');
|
||||
$this->Session->Write('monitorPermission','Edit');
|
||||
}
|
||||
|
||||
|
||||
} # end function beforeFilter()
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
App::uses('AppController', 'Controller');
|
||||
|
||||
class HostController extends AppController {
|
||||
|
||||
|
||||
public $components = array('RequestHandler');
|
||||
|
||||
public function daemonCheck($daemon=false, $args=false) {
|
||||
|
@ -30,37 +30,34 @@ class HostController extends AppController {
|
|||
));
|
||||
}
|
||||
|
||||
function getCredentials() {
|
||||
function getCredentials() {
|
||||
// ignore debug warnings from other functions
|
||||
$this->view='Json';
|
||||
$credentials = "";
|
||||
$appendPassword = 0;
|
||||
|
||||
$this->loadModel('Config');
|
||||
$this->view='Json';
|
||||
$credentials = '';
|
||||
$appendPassword = 0;
|
||||
|
||||
$this->loadModel('Config');
|
||||
$isZmAuth = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH')))['Config']['Value'];
|
||||
|
||||
if ($isZmAuth) {
|
||||
$zmAuthRelay = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY')))['Config']['Value'];
|
||||
if ($zmAuthRelay == 'hashed') {
|
||||
$zmAuthHashIps= $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_IPS')))['Config']['Value'];
|
||||
$credentials = 'auth='.generateAuthHash($zmAuthHashIps);
|
||||
}
|
||||
elseif ($zmAuthRelay == 'plain') {
|
||||
// user will need to append the store password here
|
||||
$credentials = "user=".$this->Session->read('user.Username')."&pass=";
|
||||
$appendPassword = 1;
|
||||
}
|
||||
elseif ($zmAuthRelay == 'none') {
|
||||
$credentials = "user=".$this->Session->read('user.Username');
|
||||
}
|
||||
|
||||
if ( $isZmAuth ) {
|
||||
$zmAuthRelay = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY')))['Config']['Value'];
|
||||
if ( $zmAuthRelay == 'hashed' ) {
|
||||
$zmAuthHashIps= $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_IPS')))['Config']['Value'];
|
||||
$credentials = 'auth='.generateAuthHash($zmAuthHashIps);
|
||||
} else if ( $zmAuthRelay == 'plain' ) {
|
||||
// user will need to append the store password here
|
||||
$credentials = 'user='.$this->Session->read('user.Username').'&pass=';
|
||||
$appendPassword = 1;
|
||||
} else if ( $zmAuthRelay == 'none' ) {
|
||||
$credentials = 'user='.$this->Session->read('user.Username');
|
||||
}
|
||||
}
|
||||
$this->set(array(
|
||||
'credentials'=> $credentials,
|
||||
'append_password'=>$appendPassword,
|
||||
'_serialize' => array('credentials', 'append_password')
|
||||
) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If $mid is set, only return disk usage for that monitor
|
||||
// Else, return an array of total disk usage, and per-monitor
|
||||
|
@ -70,7 +67,7 @@ class HostController extends AppController {
|
|||
$this->loadModel('Monitor');
|
||||
|
||||
// If $mid is passed, see if it is valid
|
||||
if ($mid) {
|
||||
if ($mid) {
|
||||
if (!$this->Monitor->exists($mid)) {
|
||||
throw new NotFoundException(__('Invalid monitor'));
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
//
|
||||
|
||||
function userLogin($username, $password='', $passwordHashed=false) {
|
||||
global $user, $cookies;
|
||||
global $user;
|
||||
|
||||
$sql = 'SELECT * FROM Users WHERE Enabled=1';
|
||||
$sql_values = NULL;
|
||||
|
@ -34,7 +34,12 @@ function userLogin($username, $password='', $passwordHashed=false) {
|
|||
$sql .= ' AND Username=?';
|
||||
$sql_values = array($username);
|
||||
}
|
||||
session_start();
|
||||
$close_session = 0;
|
||||
if ( !is_session_started() ) {
|
||||
Logger::Debug("Starting session in userLogin");
|
||||
session_start();
|
||||
$close_session = 1;
|
||||
}
|
||||
$_SESSION['username'] = $username;
|
||||
if ( ZM_AUTH_RELAY == 'plain' ) {
|
||||
// Need to save this in session
|
||||
|
@ -54,7 +59,9 @@ function userLogin($username, $password='', $passwordHashed=false) {
|
|||
$_SESSION['loginFailed'] = true;
|
||||
unset($user);
|
||||
}
|
||||
session_write_close();
|
||||
if ( $close_session )
|
||||
session_write_close();
|
||||
return $user;
|
||||
} # end function userLogin
|
||||
|
||||
function userLogout() {
|
||||
|
@ -121,7 +128,11 @@ function generateAuthHash($useRemoteAddr, $force=false) {
|
|||
#Logger::Debug("Generated using hour:".$local_time[2] . ' mday:' . $local_time[3] . ' month:'.$local_time[4] . ' year: ' . $local_time[5] );
|
||||
$auth = md5($authKey);
|
||||
if ( !$force ) {
|
||||
session_start();
|
||||
$close_session = 0;
|
||||
if ( !is_session_started() ) {
|
||||
session_start();
|
||||
$close_session = 1;
|
||||
}
|
||||
$_SESSION['AuthHash'] = $auth;
|
||||
$_SESSION['AuthHashGeneratedAt'] = $time;
|
||||
session_write_close();
|
||||
|
@ -155,4 +166,17 @@ function canEdit($area, $mid=false) {
|
|||
return ( $user[$area] == 'Edit' && ( !$mid || visibleMonitor($mid) ));
|
||||
}
|
||||
|
||||
function is_session_started() {
|
||||
if ( php_sapi_name() !== 'cli' ) {
|
||||
if ( version_compare(phpversion(), '5.4.0', '>=') ) {
|
||||
return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
|
||||
} else {
|
||||
return session_id() === '' ? FALSE : TRUE;
|
||||
}
|
||||
} else {
|
||||
Warning("php_sapi_name === 'cli'");
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -2064,7 +2064,7 @@ function cache_bust( $file ) {
|
|||
$dirname = preg_replace( '/\//', '_', $parts['dirname'] );
|
||||
$cacheFile = $dirname.'_'.$parts['filename'].'-'.$css.'-'.filemtime($file).'.'.$parts['extension'];
|
||||
if ( file_exists(ZM_DIR_CACHE.'/'.$cacheFile) or symlink(ZM_PATH_WEB.'/'.$file, ZM_DIR_CACHE.'/'.$cacheFile) ) {
|
||||
return '/zm/cache/'.$cacheFile;
|
||||
return 'cache/'.$cacheFile;
|
||||
} else {
|
||||
Warning("Failed linking $file to $cacheFile");
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB |
|
@ -1,11 +0,0 @@
|
|||
var config = {
|
||||
'.chosen-select' : {},
|
||||
'.chosen-select-deselect' : { allow_single_deselect: true },
|
||||
'.chosen-select-no-single' : { disable_search_threshold: 10 },
|
||||
'.chosen-select-no-results': { no_results_text: 'Oops, nothing found!' },
|
||||
'.chosen-select-rtl' : { rtl: true },
|
||||
'.chosen-select-width' : { width: '95%' }
|
||||
}
|
||||
for (var selector in config) {
|
||||
$(selector).chosen(config[selector]);
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
document.observe('dom:loaded', function(evt) {
|
||||
var config = {
|
||||
'.chosen-select' : {},
|
||||
'.chosen-select-deselect' : { allow_single_deselect: true },
|
||||
'.chosen-select-no-single' : { disable_search_threshold: 10 },
|
||||
'.chosen-select-no-results': { no_results_text: 'Oops, nothing found!' },
|
||||
'.chosen-select-rtl' : { rtl: true },
|
||||
'.chosen-select-width' : { width: '95%' }
|
||||
}
|
||||
|
||||
for (var selector in config) {
|
||||
$$(selector).each(function(element) {
|
||||
new Chosen(element, config[selector]);
|
||||
});
|
||||
}
|
||||
});
|
Binary file not shown.
Before Width: | Height: | Size: 4.3 KiB |
|
@ -1,108 +0,0 @@
|
|||
/**
|
||||
* okaidia theme for JavaScript, CSS and HTML
|
||||
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
|
||||
* @author ocodia
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: #f8f8f2;
|
||||
text-shadow: 0 1px rgba(0,0,0,0.3);
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #272822;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.number{
|
||||
color: #ae81ff;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value
|
||||
{
|
||||
color: #e6db74;
|
||||
}
|
||||
|
||||
|
||||
.token.keyword{
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important {
|
||||
color: #fd971f;
|
||||
}
|
||||
|
||||
.token.important {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
/**
|
||||
* Prism: Lightweight, robust, elegant syntax highlighting
|
||||
* MIT license http://www.opensource.org/licenses/mit-license.php/
|
||||
* @author Lea Verou http://lea.verou.me
|
||||
*/(function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var r={};for(var i in e)e.hasOwnProperty(i)&&(r[i]=t.util.clone(e[i]));return r;case"Array":return e.slice()}return e}},languages:{extend:function(e,n){var r=t.util.clone(t.languages[e]);for(var i in n)r[i]=n[i];return r},insertBefore:function(e,n,r,i){i=i||t.languages;var s=i[e],o={};for(var u in s)if(s.hasOwnProperty(u)){if(u==n)for(var a in r)r.hasOwnProperty(a)&&(o[a]=r[a]);o[u]=s[u]}return i[e]=o},DFS:function(e,n){for(var r in e){n.call(e,r,e[r]);t.util.type(e)==="Object"&&t.languages.DFS(e[r],n)}}},highlightAll:function(e,n){var r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');for(var i=0,s;s=r[i++];)t.highlightElement(s,e===!0,n)},highlightElement:function(r,i,s){var o,u,a=r;while(a&&!e.test(a.className))a=a.parentNode;if(a){o=(a.className.match(e)||[,""])[1];u=t.languages[o]}if(!u)return;r.className=r.className.replace(e,"").replace(/\s+/g," ")+" language-"+o;a=r.parentNode;/pre/i.test(a.nodeName)&&(a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+o);var f=r.textContent;if(!f)return;f=f.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ");var l={element:r,language:o,grammar:u,code:f};t.hooks.run("before-highlight",l);if(i&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){l.highlightedCode=n.stringify(JSON.parse(e.data),o);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(l.element);t.hooks.run("after-highlight",l)};c.postMessage(JSON.stringify({language:l.language,code:l.code}))}else{l.highlightedCode=t.highlight(l.code,l.grammar,l.language);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(r);t.hooks.run("after-highlight",l)}},highlight:function(e,r,i){return n.stringify(t.tokenize(e,r),i)},tokenize:function(e,n,r){var i=t.Token,s=[e],o=n.rest;if(o){for(var u in o)n[u]=o[u];delete n.rest}e:for(var u in n){if(!n.hasOwnProperty(u)||!n[u])continue;var a=n[u],f=a.inside,l=!!a.lookbehind,c=0;a=a.pattern||a;for(var h=0;h<s.length;h++){var p=s[h];if(s.length>e.length)break e;if(p instanceof i)continue;a.lastIndex=0;var d=a.exec(p);if(d){l&&(c=d[1].length);var v=d.index-1+c,d=d[0].slice(c),m=d.length,g=v+m,y=p.slice(0,v+1),b=p.slice(g+1),w=[h,1];y&&w.push(y);var E=new i(u,f?t.tokenize(d,f):d);w.push(E);b&&w.push(b);Array.prototype.splice.apply(s,w)}}}return s},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length)return;for(var i=0,s;s=r[i++];)s(n)}}},n=t.Token=function(e,t){this.type=e;this.content=t};n.stringify=function(e,r,i){if(typeof e=="string")return e;if(Object.prototype.toString.call(e)=="[object Array]")return e.map(function(t){return n.stringify(t,r,e)}).join("");var s={type:e.type,content:n.stringify(e.content,r,i),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:i};s.type=="comment"&&(s.attributes.spellcheck="true");t.hooks.run("wrap",s);var o="";for(var u in s.attributes)o+=u+'="'+(s.attributes[u]||"")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'" '+o+">"+s.content+"</"+s.tag+">"};if(!self.document){self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.tokenize(i,t.languages[r])));self.close()},!1);return}var r=document.getElementsByTagName("script");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)}})();;
|
||||
Prism.languages.markup={comment:/<!--[\w\W]*?-->/g,prolog:/<\?.+?\?>/,doctype:/<!DOCTYPE.+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|\w+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/gi};Prism.hooks.add("wrap",function(e){e.type==="entity"&&(e.attributes.title=e.content.replace(/&/,"&"))});;
|
||||
Prism.languages.css={comment:/\/\*[\w\W]*?\*\//g,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*{))/gi,inside:{punctuation:/[;:]/g}},url:/url\((["']?).*?\1\)/gi,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/g,property:/(\b|\B)[\w-]+(?=\s*:)/ig,string:/("|')(\\?.)*?\1/g,important:/\B!important\b/gi,ignore:/&(lt|gt|amp);/gi,punctuation:/[\{\};:]/g};Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{style:{pattern:/(<|<)style[\w\W]*?(>|>)[\w\W]*?(<|<)\/style(>|>)/ig,inside:{tag:{pattern:/(<|<)style[\w\W]*?(>|>)|(<|<)\/style(>|>)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css}}});;
|
||||
Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/ig,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/ig,inside:{punctuation:/\(/}}, number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|(&){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};;
|
||||
Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(var|let|if|else|while|do|for|return|in|instanceof|function|new|with|typeof|try|catch|finally|null|break|continue)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g});Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}});Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(<|<)script[\w\W]*?(>|>)[\w\W]*?(<|<)\/script(>|>)/ig,inside:{tag:{pattern:/(<|<)script[\w\W]*?(>|>)|(<|<)\/script(>|>)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});;
|
|
@ -1,3 +0,0 @@
|
|||
Outdated, source-less minified file. Original may have been lost.
|
||||
|
||||
https://github.com/harvesthq/chosen/issues/3005
|
|
@ -1,219 +0,0 @@
|
|||
/* Reset */
|
||||
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; }
|
||||
|
||||
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
|
||||
|
||||
blockquote, q { quotes: none; }
|
||||
blockquote:before, blockquote:after, q:before, q:after { content: ""; content: none; }
|
||||
ins { background-color: #ff9; color: #000; text-decoration: none; }
|
||||
mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
|
||||
del { text-decoration: line-through; }
|
||||
abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
|
||||
table { border-collapse: collapse; border-spacing: 0; }
|
||||
hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
|
||||
input, select { vertical-align: middle; }
|
||||
|
||||
body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
|
||||
select, input, textarea, button { font:99% sans-serif; }
|
||||
pre, code, kbd, samp { font-family: monospace, sans-serif; }
|
||||
|
||||
|
||||
body { background: #EEE; color: #444; line-height: 1.4em; }
|
||||
|
||||
header h1 { color: black; font-size: 2em; line-height: 1.1em; display: inline-block; height: 27px; margin: 20px 0 25px; }
|
||||
header h1 small { font-size: 0.6em; }
|
||||
|
||||
div#content { background: white; border: 1px solid #ccc; border-width: 0 1px 1px; margin: 0 auto; padding: 40px 50px 40px; width: 738px; }
|
||||
|
||||
footer { color: #999; padding-top: 40px; font-size: 0.8em; text-align: center; }
|
||||
|
||||
body { font-family: sans-serif; font-size: 1em; }
|
||||
|
||||
p { margin: 0 0 .7em; max-width: 700px; }
|
||||
table+p { margin-top: 1em; }
|
||||
|
||||
h2 { border-bottom: 1px solid #ccc; font-size: 1.2em; margin: 3em 0 1em 0; font-weight: bold;}
|
||||
h3 { font-weight: bold; }
|
||||
|
||||
h2.intro { border-bottom: none; font-size: 1em; font-weight: normal; margin-top:0; }
|
||||
|
||||
ul li { list-style: disc; margin-left: 1em; margin-bottom: 1.25em; }
|
||||
ol li { margin-left: 1.25em; }
|
||||
ol ul, ul ul { margin: .25em 0 0; }
|
||||
ol ul li, ul ul li { list-style-type: circle; margin: 0 0 .25em 1em; }
|
||||
|
||||
li > p { margin-top: .25em; }
|
||||
|
||||
div.side-by-side { width: 100%; margin-bottom: 1em; }
|
||||
div.side-by-side > div { float: left; width: 49%; }
|
||||
div.side-by-side > div > em { margin-bottom: 10px; display: block; }
|
||||
|
||||
.faqs em { display: block; }
|
||||
|
||||
.clearfix:after {
|
||||
content: "\0020";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
a { color: #F36C00; outline: none; text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
|
||||
ul.credits li { margin-bottom: .25em; }
|
||||
|
||||
strong { font-weight: bold; }
|
||||
i { font-style: italic; }
|
||||
|
||||
.button {
|
||||
background: #fafafa;
|
||||
background: -webkit-linear-gradient(top, #ffffff, #eeeeee);
|
||||
background: -moz-linear-gradient(top, #ffffff, #eeeeee);
|
||||
background: -o-linear-gradient(top, #ffffff, #eeeeee);
|
||||
background: linear-gradient(to bottom, #ffffff, #eeeeee);
|
||||
border: 1px solid #bbbbbb;
|
||||
border-radius: 4px;
|
||||
box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.2);
|
||||
color: #555555;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-family: "Helvetica Neue", Arial, Verdana, "Nimbus Sans L", sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
height: 31px;
|
||||
line-height: 28px;
|
||||
outline: none;
|
||||
padding: 0 13px;
|
||||
text-shadow: 0 1px 0 white;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.button-blue {
|
||||
background: #1385e5;
|
||||
background: -webkit-linear-gradient(top, #53b2fc, #1385e5);
|
||||
background: -moz-linear-gradient(top, #53b2fc, #1385e5);
|
||||
background: -o-linear-gradient(top, #53b2fc, #1385e5);
|
||||
background: linear-gradient(to bottom, #53b2fc, #1385e5);
|
||||
border-color: #075fa9;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
|
||||
/* Tweak navbar brand link to be super sleek
|
||||
-------------------------------------------------- */
|
||||
.oss-bar {
|
||||
top: 0;
|
||||
right: 20px;
|
||||
position: fixed;
|
||||
z-index: 1030;
|
||||
}
|
||||
.oss-bar ul {
|
||||
float: right;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.oss-bar ul li {
|
||||
list-style: none;
|
||||
float: left;
|
||||
line-height: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.oss-bar ul li a {
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
margin-top: -10px;
|
||||
display: block;
|
||||
height: 58px;
|
||||
background: #F36C00 url(oss-credit.png) no-repeat 20px 22px;
|
||||
padding: 22px 20px 12px 20px;
|
||||
text-indent: 120%; /* stupid padding */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-webkit-transition: all 0.10s ease-in-out;
|
||||
-moz-transition: all 0.10s ease-in-out;
|
||||
transition: all 0.15s ease-in-out;
|
||||
}
|
||||
.oss-bar ul li a:hover {
|
||||
margin-top: 0px;
|
||||
}
|
||||
.oss-bar a.harvest {
|
||||
width: 196px;
|
||||
background-color: #F36C00;
|
||||
background-position: -142px 22px;
|
||||
padding-right: 22px; /* optical illusion */
|
||||
}
|
||||
.oss-bar a.fork {
|
||||
width: 162px;
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
.docs-table th, .docs-table td {
|
||||
border: 1px solid #000;
|
||||
padding: 4px 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.docs-table td:last-child {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.docs-table th {
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#content pre[class*=language-] {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#content pre[class*=language-] code {
|
||||
font-size: 14px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#content code[class*=language-] {
|
||||
font-size: 12px;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
.anchor {
|
||||
color: inherit;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.anchor:hover {
|
||||
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSI3Ij48ZyBmaWxsPSIjNDE0MDQyIj48cGF0aCBkPSJNOS44IDdoLS45bC0uOS0uMWMtLjctLjMtMS40LS43LTEuOC0xLjMtLjItLjEtLjMtLjMtLjMtLjVsLS4zLS40Yy0uMS0uNC0uMi0uOC0uMi0xLjIgMC0uNC4xLS44LjItMS4yaDEuN2MtLjMuNC0uNC44LS40IDEuMiAwIC40LjEuOC4zIDEuMS4xLjIuMi4zLjQuNC4xLjEuMi4yLjQuMy4zLjIuNy4zIDEgLjNoMy40YzEuMiAwIDIuMi0uOSAyLjItMi4xcy0xLTIuMS0yLjItMi4xaC0xLjRjLS4zLS42LS43LTEtMS4yLTEuNGgyLjZjMiAwIDMuNiAxLjYgMy42IDMuNXMtMS42IDMuNS0zLjYgMy41aC0yLjZ6TTguNCAyYy0uMS0uMS0uMi0uMy0uNC0uMy0uMy0uMi0uNy0uMy0xLS4zaC0zLjRjLTEuMiAwLTIuMi45LTIuMiAyLjEgMCAxLjIgMSAyLjEgMi4yIDIuMWgxLjRjLjMuNS43IDEgMS4yIDEuNGgtMi42Yy0yIDAtMy42LTEuNi0zLjYtMy41czEuNi0zLjUgMy42LTMuNWgzLjUwMDAwMDAwMDAwMDAwMDRsLjkuMWMuNy4yIDEuNC43IDEuOCAxLjMuMS4xLjIuMy4zLjUuMS4xLjIuMy4yLjUuMS40LjIuOC4yIDEuMiAwIC40LS4xLjgtLjIgMS4yaC0xLjZjLjMtLjUuNC0uOS40LTEuM3MtLjEtLjgtLjMtMS4xYy0uMS0uMi0uMi0uMy0uNC0uNHoiLz48L2c+PC9zdmc+) 0 50% no-repeat;
|
||||
background-size: 21px 9px;
|
||||
margin-left: -27px;
|
||||
padding-left: 27px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.select,
|
||||
.chosen-select,
|
||||
.chosen-select-no-single,
|
||||
.chosen-select-no-results,
|
||||
.chosen-select-deselect,
|
||||
.chosen-select-rtl,
|
||||
.chosen-select-width {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.jquery-version-refer {
|
||||
margin-top: 40px;
|
||||
font-style: italic;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,306 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Chosen: A jQuery Plugin by Harvest to Tame Unwieldy Select Boxes</title>
|
||||
<link rel="stylesheet" href="docsupport/style.css">
|
||||
<link rel="stylesheet" href="docsupport/prism.css">
|
||||
<link rel="stylesheet" href="chosen.css">
|
||||
<style type="text/css" media="all">
|
||||
/* fix rtl for demo */
|
||||
.chosen-rtl .chosen-drop { left: -9000px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="content">
|
||||
<header>
|
||||
<h1>Chosen <small>(<span id="latest-version">v1.8.2</span>)</small></h1>
|
||||
</header>
|
||||
<p>Chosen has a number of options and attributes that allow you to have full control of your select boxes.</p>
|
||||
|
||||
<h2><a name="options" class="anchor" href="#options">Options</a></h2>
|
||||
<p>The following options are available to pass into Chosen on instantiation.</p>
|
||||
|
||||
<h3>Example:</h3>
|
||||
<pre>
|
||||
<code class="language-javascript">$(".my_select_box").chosen({
|
||||
disable_search_threshold: 10,
|
||||
no_results_text: "Oops, nothing found!",
|
||||
width: "95%"
|
||||
});</code>
|
||||
</pre>
|
||||
|
||||
<table class="docs-table">
|
||||
<tr>
|
||||
<th>Option</th><th>Default</th><th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>allow_single_deselect</td>
|
||||
<td>false</td>
|
||||
<td>When set to <code class="language-javascript">true</code> on a single select, Chosen adds a UI element which selects the first element (if it is blank).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>disable_search</td>
|
||||
<td>false</td>
|
||||
<td>When set to <code class="language-javascript">true</code>, Chosen will not display the search field (single selects only).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>disable_search_threshold</td>
|
||||
<td>0</td>
|
||||
<td>Hide the search input on single selects if there are <i>n</i> or fewer options.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>enable_split_word_search</td>
|
||||
<td>true</td>
|
||||
<td>By default, searching will match on any word within an option tag. Set this option to <code class="language-javascript">false</code> if you want to only match on the entire text of an option tag.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>inherit_select_classes</td>
|
||||
<td>false</td>
|
||||
<td>When set to <code class="language-javascript">true</code>, Chosen will grab any classes on the original select field and add them to Chosen’s container div.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max_selected_options</td>
|
||||
<td>Infinity</td>
|
||||
<td>Limits how many options the user can select. When the limit is reached, the <code class="language-javascript">chosen:maxselected</code> event is triggered.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>no_results_text</td>
|
||||
<td>"No results match"</td>
|
||||
<td>The text to be displayed when no matching results are found. The current search is shown at the end of the text (<i>e.g.</i>,
|
||||
No results match "Bad Search").</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>placeholder_text_multiple</td>
|
||||
<td>"Select Some Options"</td>
|
||||
<td>The text to be displayed as a placeholder when no options are selected for a multiple select.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>placeholder_text_single</td>
|
||||
<td>"Select an Option"</td>
|
||||
<td>The text to be displayed as a placeholder when no options are selected for a single select.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>search_contains</td>
|
||||
<td>false</td>
|
||||
<td>By default, Chosen’s search matches starting at the beginning of a word. Setting this option to <code class="language-javascript">true</code> allows matches starting from anywhere within a word. This is especially useful for options that include a lot of special characters or phrases in ()s and []s.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>single_backstroke_delete</td>
|
||||
<td>true</td>
|
||||
<td>By default, pressing delete/backspace on multiple selects will remove a selected choice. When <code class="language-javascript">false</code>, pressing delete/backspace will highlight the last choice, and a second press deselects it.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>width</td>
|
||||
<td>Original select width.</td>
|
||||
<td>The width of the Chosen select box. By default, Chosen attempts to match the width of the select box you are replacing. If your select is hidden when Chosen is instantiated, you must specify a width or the select will show up with a width of 0.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>display_disabled_options</td>
|
||||
<td>true</td>
|
||||
<td>By default, Chosen includes disabled options in search results with a special styling. Setting this option to false will hide disabled results and exclude them from searches.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>display_selected_options</td>
|
||||
<td>true</td>
|
||||
<td>
|
||||
<p>By default, Chosen includes selected options in search results with a special styling. Setting this option to false will hide selected results and exclude them from searches.</p>
|
||||
<p><strong>Note:</strong> this is for multiple selects only. In single selects, the selected result will always be displayed.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>include_group_label_in_selected</td>
|
||||
<td>false</td>
|
||||
<td>
|
||||
<p>By default, Chosen only shows the text of a selected option. Setting this option to <code class="language-javascript">true</code> will show the text and group (if any) of the selected option.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max_shown_results</td>
|
||||
<td>Infinity</td>
|
||||
<td>
|
||||
<p>Only show the first (n) matching options in the results. This can be used to increase performance for selects with very many options.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>case_sensitive_search</td>
|
||||
<td>false</td>
|
||||
<td>
|
||||
<p>By default Chosen's search is case-insensitive. Setting this option to <code class="language-javascript">true</code> makes the search case-sensitive.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>hide_results_on_select</td>
|
||||
<td>true</td>
|
||||
<td>
|
||||
<p>By default Chosen's results are hidden after a option is selected. Setting this option to <code class="language-javascript">false</code> will keep the results open after selection. This only applies to multiple selects.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>rtl</td>
|
||||
<td>false</td>
|
||||
<td>
|
||||
<p>Chosen supports right-to-left text in select boxes. Set this option to <code class="language-javascript">true</code> to support right-to-left text options.</p>
|
||||
<p><strong>Note:</strong> <a href="#classes">the <code class="language-javascript">chosen-rtl</code> class</a> on the select has precedence over this option. However, the classname approach is deprecated and will be removed in future versions of Chosen.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="attributes" class="anchor" href="#attributes">Attributes</a></h2>
|
||||
<p>Certain attributes placed on the select tag or its options can be used to configure Chosen.</p>
|
||||
|
||||
<h3>Example:</h3>
|
||||
|
||||
<pre>
|
||||
<code class="language-markup"><select class="my_select_box" data-placeholder="Select Your Options">
|
||||
<option value="1">Option 1</option>
|
||||
<option value="2" selected>Option 2</option>
|
||||
<option value="3" disabled>Option 3</option>
|
||||
</select></code>
|
||||
</pre>
|
||||
|
||||
<table class="docs-table">
|
||||
<tr>
|
||||
<th>Attribute</th><th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data-placeholder</td>
|
||||
<td>
|
||||
<p>The text to be displayed as a placeholder when no options are selected for a select. Defaults to "Select an Option" for single selects or "Select Some Options" for multiple selects.</p>
|
||||
<p><strong>Note:</strong>This attribute overrides anything set in the <code class="language-javascript">placeholder_text_multiple</code> or <code class="language-javascript">placeholder_text_single</code> options.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>multiple</td>
|
||||
<td>The attribute <code class="language-html">multiple</code> on your select box dictates whether Chosen will render a multiple or single select.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>selected, disabled</td>
|
||||
<td>Chosen automatically highlights selected options and disables disabled options.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="classes" class="anchor" href="#classes">Classes</a></h2>
|
||||
<p>Classes placed on the select tag can be used to configure Chosen.</p>
|
||||
|
||||
<h3>Example:</h3>
|
||||
|
||||
<pre>
|
||||
<code class="language-markup"><select class="my_select_box chosen-rtl">
|
||||
<option value="1">Option 1</option>
|
||||
<option value="2">Option 2</option>
|
||||
<option value="3">Option 3</option>
|
||||
</select></code>
|
||||
</pre>
|
||||
|
||||
<table class="docs-table">
|
||||
<tr>
|
||||
<th>Classname</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>chosen-rtl</td>
|
||||
<td>
|
||||
<p>Chosen supports right-to-left text in select boxes. Add the class <code class="language-html">chosen-rtl</code> to your select tag to support right-to-left text options.</p>
|
||||
<p><strong>Note:</strong> The <code class="language-html">chosen-rtl</code> class will pass through to the Chosen select even when the <code class="language-javascript">inherit_select_classes</code> option is set to <code class="language-javascript">false</code>.</p>
|
||||
<p><strong>Note:</strong> This is deprecated in favor of using the <code class="language-javascript">rtl: true</code> option (see the <a href="#options">Options section</a>).</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="triggered-events" class="anchor" href="#triggered-events">Triggered Events</a></h2>
|
||||
<p>Chosen triggers a number of standard and custom events on the original select field.</p>
|
||||
|
||||
<h3>Example:</h3>
|
||||
|
||||
<pre>
|
||||
<code class="language-javascript">$('.my_select_box').on('change', function(evt, params) {
|
||||
do_something(evt, params);
|
||||
});</code>
|
||||
</pre>
|
||||
|
||||
<table class="docs-table">
|
||||
<tr>
|
||||
<th>Event</th><th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>change</td>
|
||||
<td>
|
||||
<p>Chosen triggers the standard DOM event whenever a selection is made (it also sends a <code class="language-javascript">selected</code> or <code class="language-javascript">deselected</code> parameter that tells you which option was changed).</p>
|
||||
<p><strong>Note:</strong> The selected and deselected parameters are not available for Prototype.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>chosen:ready</td>
|
||||
<td>Triggered after Chosen has been fully instantiated.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>chosen:maxselected</td>
|
||||
<td>Triggered if <code class="language-javascript">max_selected_options</code> is set and that total is broken.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>chosen:showing_dropdown</td>
|
||||
<td>Triggered when Chosen’s dropdown is opened.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>chosen:hiding_dropdown</td>
|
||||
<td>Triggered when Chosen’s dropdown is closed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>chosen:no_results</td>
|
||||
<td>Triggered when a search returns no matching results.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> all custom Chosen events (those that begin with <code class="language-javascript">chosen:</code>) also include the <code class="language-javascript">chosen</code> object as a parameter.
|
||||
</p>
|
||||
|
||||
<h2><a name="triggerable-events" class="anchor" href="#triggerable-events">Triggerable Events</a></h2>
|
||||
<p>You can trigger several events on the original select field to invoke a behavior in Chosen.</p>
|
||||
|
||||
<h3>Example:</h3>
|
||||
|
||||
<pre>
|
||||
<code class="language-javascript">// tell Chosen that a select has changed
|
||||
$('.my_select_box').trigger('chosen:updated');</code>
|
||||
</pre>
|
||||
|
||||
<table class="docs-table">
|
||||
<tr>
|
||||
<th>Event</th><th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>chosen:updated</td>
|
||||
<td>This event should be triggered whenever Chosen’s underlying select element changes (such as a change in selected options).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>chosen:activate</td>
|
||||
<td>This is the equivalant of focusing a standard HTML select field. When activated, Chosen will capure keypress events as if you had clicked the field directly.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>chosen:open</td>
|
||||
<td>This event activates Chosen and also displays the search results.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>chosen:close</td>
|
||||
<td>This event deactivates Chosen and hides the search results.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<footer>
|
||||
© 2011–2016 <a href="http://www.getharvest.com/">Harvest</a>. Chosen is licensed under the <a href="https://github.com/harvesthq/chosen/blob/master/LICENSE.md">MIT license</a>.
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="oss-bar">
|
||||
<ul>
|
||||
<li><a class="fork" href="https://github.com/harvesthq/chosen">Fork on Github</a></li>
|
||||
<li><a class="harvest" href="http://www.getharvest.com/">Built by Harvest</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<script src="docsupport/prism.js" type="text/javascript" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -18,7 +18,7 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'Stream' ) ) {
|
||||
if ( !canView('Stream') ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
@ -77,14 +77,17 @@ xhtmlHeaders(__FILE__, translate('CycleWatch'));
|
|||
<?php } ?>
|
||||
</div>
|
||||
<div class="controlHeader">
|
||||
<?php echo $filterbar ?>
|
||||
<form method="get">
|
||||
<input type="hidden" name="view" value="cycle"/>
|
||||
<?php echo $filterbar ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="imageFeed">
|
||||
<?php
|
||||
if ( $monitor ) {
|
||||
echo getStreamHTML($monitor, array('scale'=>$scale, 'mode'=>$mode));
|
||||
echo getStreamHTML($monitor, array('scale'=>$scale, 'mode'=>$mode, 'width'=>'100%'));
|
||||
} else {
|
||||
echo "There are no monitors to view.";
|
||||
}
|
||||
|
|
|
@ -23,10 +23,10 @@ if ( !canEdit('Monitors') ) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Probe Local Cameras
|
||||
// Probe Local Cameras
|
||||
function probeV4L() {
|
||||
|
||||
$cameras = array();
|
||||
$cameras = array();
|
||||
|
||||
$command = getZmuCommand(' --query --device');
|
||||
if ( !empty($_REQUEST['device']) )
|
||||
|
@ -35,81 +35,82 @@ function probeV4L() {
|
|||
$result = exec(escapeshellcmd($command), $output, $status);
|
||||
if ( $status ) {
|
||||
Error("Unable to probe local cameras, status is '$status'");
|
||||
return $cameras;
|
||||
}
|
||||
return $cameras;
|
||||
}
|
||||
|
||||
$monitors = array();
|
||||
foreach ( dbFetchAll("SELECT Id, Name, Device,Channel FROM Monitors WHERE Type = 'Local' ORDER BY Device, Channel" ) as $monitor )
|
||||
$monitors[$monitor['Device'].':'.$monitor['Channel']] = $monitor;
|
||||
$monitors = array();
|
||||
foreach ( dbFetchAll("SELECT Id, Name, Device,Channel FROM Monitors WHERE Type = 'Local' ORDER BY Device, Channel" ) as $monitor )
|
||||
$monitors[$monitor['Device'].':'.$monitor['Channel']] = $monitor;
|
||||
|
||||
$devices = array();
|
||||
$preferredStandards = array('PAL', 'NTSC');
|
||||
$preferredFormats = array('BGR3', 'RGB3', 'YUYV', 'UYVY', 'JPEG', 'MJPG', '422P', 'YU12', 'GREY');
|
||||
foreach ( $output as $line ) {
|
||||
if ( !preg_match('/^d:([^|]+).*S:([^|]*).*F:([^|]+).*I:(\d+)\|(.+)$/', $line, $deviceMatches) )
|
||||
Fatal("Can't parse command output '$line'");
|
||||
$standards = explode('/',$deviceMatches[2]);
|
||||
$preferredStandard = false;
|
||||
foreach ( $preferredStandards as $standard ) {
|
||||
if ( in_array( $standard, $standards ) ) {
|
||||
$preferredStandard = $standard;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$formats = explode('/',$deviceMatches[3]);
|
||||
$preferredFormat = false;
|
||||
foreach ( $preferredFormats as $format ) {
|
||||
if ( in_array($format, $formats) ) {
|
||||
$preferredFormat = $format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$device = array(
|
||||
'device' => $deviceMatches[1],
|
||||
'standards' => $standard,
|
||||
'preferredStandard' => $preferredStandard,
|
||||
'formats' => $formats,
|
||||
'preferredFormat' => $preferredFormat,
|
||||
);
|
||||
$inputs = array();
|
||||
for ( $i = 0; $i < $deviceMatches[4]; $i++ ) {
|
||||
if ( !preg_match('/i'.$i.':([^|]+)\|i'.$i.'T:([^|]+)\|/', $deviceMatches[5], $inputMatches) )
|
||||
Fatal("Can't parse input '".$deviceMatches[5]."'");
|
||||
if ( $inputMatches[2] == 'Camera' ) {
|
||||
$input = array(
|
||||
'index' => $i,
|
||||
'id' => $deviceMatches[1].':'.$i,
|
||||
'name' => $inputMatches[1],
|
||||
'free' => empty($monitors[$deviceMatches[1].':'.$i]),
|
||||
);
|
||||
$inputMonitor = array(
|
||||
'Type' => 'Local',
|
||||
'Device' => $deviceMatches[1],
|
||||
'Channel' => $i,
|
||||
'Colours' => 3,
|
||||
'Format' => $preferredStandard,
|
||||
'Palette' => $preferredFormat,
|
||||
);
|
||||
if ( $preferredStandard == 'NTSC' ) {
|
||||
$inputMonitor['Width'] = 320;
|
||||
$inputMonitor['Height'] = 240;
|
||||
} else {
|
||||
$inputMonitor['Width'] = 384;
|
||||
$inputMonitor['Height'] = 288;
|
||||
}
|
||||
if ( $preferredFormat == 'GREY' ) {
|
||||
$inputMonitor['Colours'] = 1;
|
||||
$inputMonitor['SignalCheckColour'] = '#000023';
|
||||
}
|
||||
$inputDesc = base64_encode(serialize($inputMonitor));
|
||||
$inputString = $deviceMatches[1].', chan '.$i.($input['free']?(' - '.translate('Available')):(' ('.$monitors[$input['id']]['Name'].')'));
|
||||
$inputs[] = $input;
|
||||
$cameras[$inputDesc] = $inputString;
|
||||
}
|
||||
}
|
||||
$device['inputs'] = $inputs;
|
||||
$devices[] = $device;
|
||||
} # end foreach output line
|
||||
$devices = array();
|
||||
$preferredStandards = array('PAL', 'NTSC');
|
||||
$preferredFormats = array('BGR3', 'RGB3', 'YUYV', 'UYVY', 'JPEG', 'MJPG', '422P', 'YU12', 'GREY');
|
||||
foreach ( $output as $line ) {
|
||||
if ( !preg_match('/^d:([^|]+).*S:([^|]*).*F:([^|]+).*I:(\d+)\|(.+)$/', $line, $deviceMatches) )
|
||||
Fatal("Can't parse command output '$line'");
|
||||
$standards = explode('/',$deviceMatches[2]);
|
||||
$preferredStandard = false;
|
||||
foreach ( $preferredStandards as $standard ) {
|
||||
if ( in_array( $standard, $standards ) ) {
|
||||
$preferredStandard = $standard;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$formats = explode('/',$deviceMatches[3]);
|
||||
$preferredFormat = false;
|
||||
foreach ( $preferredFormats as $format ) {
|
||||
if ( in_array($format, $formats) ) {
|
||||
$preferredFormat = $format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$device = array(
|
||||
'device' => $deviceMatches[1],
|
||||
'standards' => $standard,
|
||||
'preferredStandard' => $preferredStandard,
|
||||
'formats' => $formats,
|
||||
'preferredFormat' => $preferredFormat,
|
||||
);
|
||||
$inputs = array();
|
||||
for ( $i = 0; $i < $deviceMatches[4]; $i++ ) {
|
||||
if ( !preg_match('/i'.$i.':([^|]+)\|i'.$i.'T:([^|]+)\|/', $deviceMatches[5], $inputMatches) )
|
||||
Fatal("Can't parse input '".$deviceMatches[5]."'");
|
||||
if ( $inputMatches[2] == 'Camera' ) {
|
||||
$input = array(
|
||||
'index' => $i,
|
||||
'id' => $deviceMatches[1].':'.$i,
|
||||
'name' => $inputMatches[1],
|
||||
'free' => empty($monitors[$deviceMatches[1].':'.$i]),
|
||||
);
|
||||
$inputMonitor = array(
|
||||
'Type' => 'Local',
|
||||
'Device' => $deviceMatches[1],
|
||||
'Channel' => $i,
|
||||
'Colours' => 3,
|
||||
'Format' => $preferredStandard,
|
||||
'Palette' => $preferredFormat,
|
||||
);
|
||||
if ( $preferredStandard == 'NTSC' ) {
|
||||
$inputMonitor['Width'] = 320;
|
||||
$inputMonitor['Height'] = 240;
|
||||
} else {
|
||||
$inputMonitor['Width'] = 384;
|
||||
$inputMonitor['Height'] = 288;
|
||||
}
|
||||
if ( $preferredFormat == 'GREY' ) {
|
||||
$inputMonitor['Colours'] = 1;
|
||||
$inputMonitor['SignalCheckColour'] = '#000023';
|
||||
}
|
||||
$inputDesc = base64_encode(serialize($inputMonitor));
|
||||
$inputString = $deviceMatches[1].', chan '.$i.($input['free']?(' - '.translate('Available')):(' ('.$monitors[$input['id']]['Name'].')'));
|
||||
$inputs[] = $input;
|
||||
$cameras[$inputDesc] = $inputString;
|
||||
}
|
||||
}
|
||||
$device['inputs'] = $inputs;
|
||||
$devices[] = $device;
|
||||
} # end foreach output line
|
||||
return $cameras;
|
||||
} # end function probeV4L
|
||||
|
||||
// Probe Network Cameras
|
||||
|
@ -235,98 +236,77 @@ function probeWansview($ip) {
|
|||
'Path' => 'videostream.cgi',
|
||||
'Width' => 640,
|
||||
'Height' => 480,
|
||||
'Palette' => 3
|
||||
'Palette' => 3
|
||||
),
|
||||
);
|
||||
return $camera;
|
||||
}
|
||||
|
||||
function probeNetwork() {
|
||||
// Calling arp without the full path was reported to fail on some systems
|
||||
// Use the builtin unix command "type" to tell us where the command is
|
||||
$arp_command = '';
|
||||
$result = explode(' ', ZM_PATH_ARP);
|
||||
if ( !is_executable($result[0]) ) {
|
||||
if ( ZM_PATH_ARP ) {
|
||||
Warning("User assigned ARP tool not found. Verify ZM_PATH_ARP points to a valid arp tool and is executable by the web user account.");
|
||||
}
|
||||
$result = exec('type -p arp', $output, $status);
|
||||
if ( $status ) {
|
||||
Warning("Unable to determine path for arp command, type -p arp returned '$status' output is: " . implode("\n", $output));
|
||||
unset($output);
|
||||
$result = exec('which arp', $output, $status);
|
||||
if ( $status ) {
|
||||
Warning("Unable to determine path for arp command, which arp returned '$status'");
|
||||
if ( file_exists('/usr/sbin/arp') ) {
|
||||
$arp_command = '/usr/sbin/arp -a';
|
||||
}
|
||||
} else {
|
||||
$arp_command = $output[0].' -a';
|
||||
}
|
||||
} else {
|
||||
$arp_command = $output[0].' -a';
|
||||
}
|
||||
} else {
|
||||
$arp_command = ZM_PATH_ARP;
|
||||
}
|
||||
// Now that we know where arp is, call it using the full path
|
||||
unset($output);
|
||||
$result = exec(escapeshellcmd($arp_command), $output, $status);
|
||||
if ( $status ) {
|
||||
Error("Unable to probe network cameras, status is '$status'");
|
||||
return;
|
||||
}
|
||||
$cameras = array();
|
||||
$arp_command = ZM_PATH_ARP;
|
||||
$result = explode(' ', $arp_command);
|
||||
if ( !is_executable($result[0]) ) {
|
||||
Error("ARP compatible binary not found or not executable by the web user account. Verify ZM_PATH_ARP points to a valid arp tool.");
|
||||
return;
|
||||
}
|
||||
|
||||
$monitors = array();
|
||||
foreach ( dbFetchAll("SELECT Id, Name, Host FROM Monitors WHERE Type = 'Remote' ORDER BY Host") as $monitor ) {
|
||||
if ( preg_match('/^(.+)@(.+)$/', $monitor['Host'], $matches) ) {
|
||||
//echo "1: ".$matches[2]." = ".gethostbyname($matches[2])."<br/>";
|
||||
$monitors[gethostbyname($matches[2])] = $monitor;
|
||||
} else {
|
||||
//echo "2: ".$monitor['Host']." = ".gethostbyname($monitor['Host'])."<br/>";
|
||||
$monitors[gethostbyname($monitor['Host'])] = $monitor;
|
||||
}
|
||||
}
|
||||
$result = exec(escapeshellcmd($arp_command), $output, $status);
|
||||
if ( $status ) {
|
||||
Error("Unable to probe network cameras, status is '$status'");
|
||||
return;
|
||||
}
|
||||
|
||||
$macBases = array(
|
||||
'00:40:8c' => array('type'=>'Axis', 'probeFunc'=>'probeAxis'),
|
||||
'00:80:f0' => array('type'=>'Panasonic','probeFunc'=>'probePana'),
|
||||
'00:0f:7c' => array('type'=>'ACTi','probeFunc'=>'probeACTi'),
|
||||
'00:02:d1' => array('type'=>'Vivotek','probeFunc'=>'probeVivotek'),
|
||||
'7c:dd:90' => array('type'=>'Wansview','probeFunc'=>'probeWansview'),
|
||||
'78:a5:dd' => array('type'=>'Wansview','probeFunc'=>'probeWansview')
|
||||
);
|
||||
$monitors = array();
|
||||
foreach ( dbFetchAll("SELECT Id, Name, Host FROM Monitors WHERE Type = 'Remote' ORDER BY Host") as $monitor ) {
|
||||
if ( preg_match('/^(.+)@(.+)$/', $monitor['Host'], $matches) ) {
|
||||
//echo "1: ".$matches[2]." = ".gethostbyname($matches[2])."<br/>";
|
||||
$monitors[gethostbyname($matches[2])] = $monitor;
|
||||
} else {
|
||||
//echo "2: ".$monitor['Host']." = ".gethostbyname($monitor['Host'])."<br/>";
|
||||
$monitors[gethostbyname($monitor['Host'])] = $monitor;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $output as $line ) {
|
||||
if ( !preg_match('/(\d+\.\d+\.\d+\.\d+).*(([0-9a-f]{2}:){5})/', $line, $matches) )
|
||||
continue;
|
||||
$ip = $matches[1];
|
||||
$host = $ip;
|
||||
$mac = $matches[2];
|
||||
//echo "I:$ip, H:$host, M:$mac<br/>";
|
||||
$macRoot = substr($mac,0,8);
|
||||
if ( isset($macBases[$macRoot]) ) {
|
||||
$macBase = $macBases[$macRoot];
|
||||
$camera = call_user_func($macBase['probeFunc'], $ip);
|
||||
$sourceDesc = htmlspecialchars(serialize($camera['monitor']));
|
||||
$sourceString = $camera['model'].' @ '.$host;
|
||||
if ( isset($monitors[$ip]) ) {
|
||||
$monitor = $monitors[$ip];
|
||||
$sourceString .= ' ('.$monitor['Name'].')';
|
||||
} else {
|
||||
$sourceString .= ' - '.translate('Available');
|
||||
}
|
||||
$cameras[$sourceDesc] = $sourceString;
|
||||
}
|
||||
} # end foreach output line
|
||||
return $cameras;
|
||||
$macBases = array(
|
||||
'00:40:8c' => array('type'=>'Axis', 'probeFunc'=>'probeAxis'),
|
||||
'00:80:f0' => array('type'=>'Panasonic','probeFunc'=>'probePana'),
|
||||
'00:0f:7c' => array('type'=>'ACTi','probeFunc'=>'probeACTi'),
|
||||
'00:02:d1' => array('type'=>'Vivotek','probeFunc'=>'probeVivotek'),
|
||||
'7c:dd:90' => array('type'=>'Wansview','probeFunc'=>'probeWansview'),
|
||||
'78:a5:dd' => array('type'=>'Wansview','probeFunc'=>'probeWansview')
|
||||
);
|
||||
|
||||
foreach ( $output as $line ) {
|
||||
if ( !preg_match('/(\d+\.\d+\.\d+\.\d+).*(([0-9a-f]{2}:){5})/', $line, $matches) )
|
||||
continue;
|
||||
$ip = $matches[1];
|
||||
$host = $ip;
|
||||
$mac = $matches[2];
|
||||
//echo "I:$ip, H:$host, M:$mac<br/>";
|
||||
$macRoot = substr($mac,0,8);
|
||||
if ( isset($macBases[$macRoot]) ) {
|
||||
$macBase = $macBases[$macRoot];
|
||||
$camera = call_user_func($macBase['probeFunc'], $ip);
|
||||
$sourceDesc = htmlspecialchars(serialize($camera['monitor']));
|
||||
$sourceString = $camera['model'].' @ '.$host;
|
||||
if ( isset($monitors[$ip]) ) {
|
||||
$monitor = $monitors[$ip];
|
||||
$sourceString .= ' ('.$monitor['Name'].')';
|
||||
} else {
|
||||
$sourceString .= ' - '.translate('Available');
|
||||
}
|
||||
$cameras[$sourceDesc] = $sourceString;
|
||||
}
|
||||
} # end foreach output line
|
||||
return $cameras;
|
||||
} # end function probeNetwork()
|
||||
|
||||
$cameras = array();
|
||||
$cameras[0] = translate('ChooseDetectedCamera');
|
||||
|
||||
if ( ZM_HAS_V4L2 )
|
||||
$cameras += probeV4L();
|
||||
$cameras += probeV4L();
|
||||
$cameras += probeNetwork();
|
||||
|
||||
if ( count($cameras) <= 1 )
|
||||
|
@ -350,12 +330,12 @@ xhtmlHeaders(__FILE__, translate('MonitorProbe') );
|
|||
</p>
|
||||
<p>
|
||||
<label for="probe"><?php echo translate('DetectedCameras') ?></label>
|
||||
<?php echo buildSelect('probe', $cameras, 'configureButtons(this)'); ?>
|
||||
<?php echo buildSelect('probe', $cameras, 'configureButtons(this)'); ?>
|
||||
</p>
|
||||
<div id="contentButtons">
|
||||
<button type="button" name="saveBtn" value="Save" onclick="submitCamera(this);" disabled="disabled">
|
||||
<?php echo translate('Save') ?></button>
|
||||
<button type="button" onclick="closeWindow();"><?php echo translate('Cancel') ?></button>
|
||||
<button type="button" name="saveBtn" value="Save" onclick="submitCamera(this);" disabled="disabled">
|
||||
<?php echo translate('Save') ?></button>
|
||||
<button type="button" onclick="closeWindow();"><?php echo translate('Cancel') ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue