2017-10-14 04:55:42 +00:00
< ? php
2018-07-31 21:37:52 +00:00
require_once 'config.php' ;
require_once RASPI_CONFIG . '/raspap.php' ;
2020-02-14 01:29:58 +00:00
if ( RASPI_MONITOR_ENABLED ) {
2020-02-15 17:57:46 +00:00
die ();
2020-02-14 01:29:58 +00:00
};
2018-07-31 21:37:52 +00:00
session_start ();
header ( 'X-Frame-Options: SAMEORIGIN' );
header ( " Content-Security-Policy: default-src 'none'; frame-src 'self'; connect-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' " );
require_once 'authenticate.php' ;
2017-10-14 04:55:42 +00:00
// Web Console v0.9.7 (2016-11-05)
//
// Author: Nickolay Kovalev (http://nickola.ru)
// GitHub: https://github.com/nickola/web-console
// URL: http://web-console.org
// Disable login (don't ask for credentials, be careful)
// Example: $NO_LOGIN = true;
$NO_LOGIN = true ;
// Single-user credentials
// Example: $USER = 'user'; $PASSWORD = 'password';
$USER = '' ;
$PASSWORD = '' ;
// Multi-user credentials
// Example: $ACCOUNTS = array('user1' => 'password1', 'user2' => 'password2');
$ACCOUNTS = array ();
// Password hash algorithm (password must be hashed)
// Example: $PASSWORD_HASH_ALGORITHM = 'md5';
// $PASSWORD_HASH_ALGORITHM = 'sha256';
$PASSWORD_HASH_ALGORITHM = '' ;
// Home directory (multi-user mode supported)
// Example: $HOME_DIRECTORY = '/tmp';
// $HOME_DIRECTORY = array('user1' => '/home/user1', 'user2' => '/home/user2');
$HOME_DIRECTORY = '' ;
// Code below is automatically generated from different components
// For more information see: https://github.com/nickola/web-console
//
// Used components:
// - jQuery JavaScript Library: https://github.com/jquery/jquery
// - jQuery Terminal Emulator: https://github.com/jcubic/jquery.terminal
// - jQuery Mouse Wheel Plugin: https://github.com/brandonaaron/jquery-mousewheel
// - PHP JSON-RPC 2.0 Server/Client Implementation: https://github.com/sergeyfast/eazy-jsonrpc
// - Normalize.css: https://github.com/necolas/normalize.css
?>
< ? php
/**
* JSON RPC Server for Eaze
*
* Reads $_GET [ 'rawRequest' ] or php :// input for Request Data
2020-02-15 17:57:46 +00:00
*
2017-10-14 04:55:42 +00:00
* @ link http :// www . jsonrpc . org / specification
* @ link http :// dojotoolkit . org / reference - guide / 1.8 / dojox / rpc / smd . html
* @ package Eaze
* @ subpackage Model
* @ author Sergeyfast
*/
2020-02-15 17:57:46 +00:00
class BaseJsonRpcServer
{
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
const ParseError = - 32700 ,
InvalidRequest = - 32600 ,
MethodNotFound = - 32601 ,
InvalidParams = - 32602 ,
InternalError = - 32603 ;
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Exposed Instances
*
* @ var object [] namespace => method
*/
protected $instances = array ();
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Decoded Json Request
*
* @ var object | array
*/
protected $request ;
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Array of Received Calls
*
* @ var array
*/
protected $calls = array ();
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Array of Responses for Calls
*
* @ var array
*/
protected $response = array ();
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Has Calls Flag ( not notifications )
*
* @ var bool
*/
protected $hasCalls = false ;
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Is Batch Call in using
*
* @ var bool
*/
private $isBatchCall = false ;
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Hidden Methods
*
* @ var array
*/
protected $hiddenMethods = array (
'execute' , '__construct' , 'registerinstance'
);
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Content Type
*
* @ var string
*/
public $ContentType = 'application/json' ;
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Allow Cross - Domain Requests
*
* @ var bool
*/
public $IsXDR = true ;
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Max Batch Calls
*
* @ var int
*/
public $MaxBatchCalls = 10 ;
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Error Messages
*
* @ var array
*/
protected $errorMessages = array (
self :: ParseError => 'Parse error' ,
self :: InvalidRequest => 'Invalid Request' ,
self :: MethodNotFound => 'Method not found' ,
self :: InvalidParams => 'Invalid params' ,
self :: InternalError => 'Internal error' ,
);
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Cached Reflection Methods
*
* @ var ReflectionMethod []
*/
private $reflectionMethods = array ();
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Validate Request
*
* @ return int error
*/
private function getRequest ()
{
$error = null ;
do {
if ( array_key_exists ( 'REQUEST_METHOD' , $_SERVER ) && $_SERVER [ 'REQUEST_METHOD' ] != 'POST' ) {
$error = self :: InvalidRequest ;
break ;
};
$request = ! empty ( $_GET [ 'rawRequest' ]) ? $_GET [ 'rawRequest' ] : file_get_contents ( 'php://input' );
$this -> request = json_decode ( $request , false );
if ( $this -> request === null ) {
$error = self :: ParseError ;
break ;
}
if ( $this -> request === array () ) {
$error = self :: InvalidRequest ;
break ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
// check for batch call
if ( is_array ( $this -> request ) ) {
if ( count ( $this -> request ) > $this -> MaxBatchCalls ) {
2017-10-14 04:55:42 +00:00
$error = self :: InvalidRequest ;
break ;
}
2020-02-15 17:57:46 +00:00
$this -> calls = $this -> request ;
$this -> isBatchCall = true ;
} else {
$this -> calls [] = $this -> request ;
}
} while ( false );
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
return $error ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Get Error Response
*
* @ param int $code
* @ param mixed $id
* @ param null $data
* @ return array
*/
private function getError ( $code , $id = null , $data = null )
{
return array (
'jsonrpc' => '2.0' ,
'id' => $id ,
'error' => array (
'code' => $code ,
'message' => isset ( $this -> errorMessages [ $code ]) ? $this -> errorMessages [ $code ] : $this -> errorMessages [ self :: InternalError ],
'data' => $data ,
),
);
}
/**
* Check for jsonrpc version and correct method
*
* @ param object $call
* @ return array | null
*/
private function validateCall ( $call )
{
$result = null ;
$error = null ;
$data = null ;
$id = is_object ( $call ) && property_exists ( $call , 'id' ) ? $call -> id : null ;
do {
if ( ! is_object ( $call ) ) {
$error = self :: InvalidRequest ;
break ;
}
// hack for inputEx smd tester
if ( property_exists ( $call , 'version' ) ) {
if ( $call -> version == 'json-rpc-2.0' ) {
$call -> jsonrpc = '2.0' ;
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
if ( ! property_exists ( $call , 'jsonrpc' ) || $call -> jsonrpc != '2.0' ) {
$error = self :: InvalidRequest ;
break ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
$fullMethod = property_exists ( $call , 'method' ) ? $call -> method : '' ;
$methodInfo = explode ( '.' , $fullMethod , 2 );
$namespace = array_key_exists ( 1 , $methodInfo ) ? $methodInfo [ 0 ] : '' ;
$method = $namespace ? $methodInfo [ 1 ] : $fullMethod ;
if ( ! $method || ! array_key_exists ( $namespace , $this -> instances ) || ! method_exists ( $this -> instances [ $namespace ], $method ) || in_array ( strtolower ( $method ), $this -> hiddenMethods ) ) {
$error = self :: MethodNotFound ;
break ;
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
if ( ! array_key_exists ( $fullMethod , $this -> reflectionMethods ) ) {
$this -> reflectionMethods [ $fullMethod ] = new ReflectionMethod ( $this -> instances [ $namespace ], $method );
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* @ var $params array
*/
$params = property_exists ( $call , 'params' ) ? $call -> params : null ;
$paramsType = gettype ( $params );
if ( $params !== null && $paramsType != 'array' && $paramsType != 'object' ) {
$error = self :: InvalidParams ;
break ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
// check parameters
switch ( $paramsType ) {
case 'array' :
$totalRequired = 0 ;
// doesn't hold required, null, required sequence of params
foreach ( $this -> reflectionMethods [ $fullMethod ] -> getParameters () as $param ) {
if ( ! $param -> isDefaultValueAvailable () ) {
$totalRequired ++ ;
2017-10-14 04:55:42 +00:00
}
}
2020-02-15 17:57:46 +00:00
if ( count ( $params ) < $totalRequired ) {
$error = self :: InvalidParams ;
$data = sprintf ( 'Check numbers of required params (got %d, expected %d)' , count ( $params ), $totalRequired );
}
break ;
case 'object' :
foreach ( $this -> reflectionMethods [ $fullMethod ] -> getParameters () as $param ) {
if ( ! $param -> isDefaultValueAvailable () && ! array_key_exists ( $param -> getName (), $params ) ) {
$error = self :: InvalidParams ;
$data = $param -> getName () . ' not found' ;
break 3 ;
}
}
break ;
case 'NULL' :
if ( $this -> reflectionMethods [ $fullMethod ] -> getNumberOfRequiredParameters () > 0 ) {
$error = self :: InvalidParams ;
$data = 'Empty required params' ;
break 2 ;
}
break ;
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
} while ( false );
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
if ( $error ) {
$result = array ( $error , $id , $data );
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
return $result ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Process Call
*
* @ param $call
* @ return array | null
*/
private function processCall ( $call )
{
$id = property_exists ( $call , 'id' ) ? $call -> id : null ;
$params = property_exists ( $call , 'params' ) ? $call -> params : array ();
$result = null ;
$namespace = substr ( $call -> method , 0 , strpos ( $call -> method , '.' ));
try {
// set named parameters
if ( is_object ( $params ) ) {
$newParams = array ();
foreach ( $this -> reflectionMethods [ $call -> method ] -> getParameters () as $param ) {
$paramName = $param -> getName ();
$defaultValue = $param -> isDefaultValueAvailable () ? $param -> getDefaultValue () : null ;
$newParams [] = property_exists ( $params , $paramName ) ? $params -> $paramName : $defaultValue ;
}
$params = $newParams ;
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
// invoke
$result = $this -> reflectionMethods [ $call -> method ] -> invokeArgs ( $this -> instances [ $namespace ], $params );
} catch ( Exception $e ) {
return $this -> getError ( $e -> getCode (), $id , $e -> getMessage ());
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
if ( ! $id && $id !== 0 ) {
return null ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
return array (
'jsonrpc' => '2.0' ,
'result' => $result ,
'id' => $id ,
);
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Create new Instance
*
* @ param object $instance
*/
public function __construct ( $instance = null )
{
if ( get_parent_class ( $this ) ) {
$this -> RegisterInstance ( $this , '' );
} else if ( $instance ) {
$this -> RegisterInstance ( $instance , '' );
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Register Instance
*
* @ param object $instance
* @ param string $namespace default is empty string
* @ return $this
*/
public function RegisterInstance ( $instance , $namespace = '' )
{
$this -> instances [ $namespace ] = $instance ;
$this -> instances [ $namespace ] -> errorMessages = $this -> errorMessages ;
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
return $this ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Handle Requests
*/
public function Execute ()
{
do {
// check for SMD Discovery request
if ( array_key_exists ( 'smd' , $_GET ) ) {
$this -> response [] = $this -> getServiceMap ();
$this -> hasCalls = true ;
break ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
$error = $this -> getRequest ();
if ( $error ) {
$this -> response [] = $this -> getError ( $error );
$this -> hasCalls = true ;
break ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
foreach ( $this -> calls as $call ) {
$error = $this -> validateCall ( $call );
if ( $error ) {
$this -> response [] = $this -> getError ( $error [ 0 ], $error [ 1 ], $error [ 2 ]);
$this -> hasCalls = true ;
} else {
$result = $this -> processCall ( $call );
if ( $result ) {
$this -> response [] = $result ;
$this -> hasCalls = true ;
2017-10-14 04:55:42 +00:00
}
}
2020-02-15 17:57:46 +00:00
}
} while ( false );
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
// flush response
if ( $this -> hasCalls ) {
if ( ! $this -> isBatchCall ) {
$this -> response = reset ( $this -> response );
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
if ( ! headers_sent () ) {
// Set Content Type
if ( $this -> ContentType ) {
header ( 'Content-Type: ' . $this -> ContentType );
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
// Allow Cross Domain Requests
if ( $this -> IsXDR ) {
header ( 'Access-Control-Allow-Origin: *' );
header ( 'Access-Control-Allow-Headers: x-requested-with, content-type' );
}
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
echo json_encode ( $this -> response );
$this -> resetVars ();
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
}
/**
* Get Doc Comment
*
* @ param $comment
* @ return string | null
*/
private function getDocDescription ( $comment )
{
$result = null ;
if ( preg_match ( '/\*\s+([^@]*)\s+/s' , $comment , $matches ) ) {
$result = str_replace ( '*' , " \n " , trim ( trim ( $matches [ 1 ], '*' )));
}
return $result ;
}
/**
* Get Service Map
* Maybe not so good realization of auto - discover via doc blocks
*
* @ return array
*/
private function getServiceMap ()
{
$result = array (
'transport' => 'POST' ,
'envelope' => 'JSON-RPC-2.0' ,
'SMDVersion' => '2.0' ,
'contentType' => 'application/json' ,
'target' => ! empty ( $_SERVER [ 'REQUEST_URI' ]) ? substr ( $_SERVER [ 'REQUEST_URI' ], 0 , strpos ( $_SERVER [ 'REQUEST_URI' ], '?' )) : '' ,
'services' => array (),
'description' => '' ,
);
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
foreach ( $this -> instances as $namespace => $instance ) {
$rc = new ReflectionClass ( $instance );
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
// Get Class Description
if ( $rcDocComment = $this -> getDocDescription ( $rc -> getDocComment ()) ) {
$result [ 'description' ] .= $rcDocComment . PHP_EOL ;
}
foreach ( $rc -> getMethods () as $method ) {
/**
* @ var ReflectionMethod $method
*/
if ( ! $method -> isPublic () || in_array ( strtolower ( $method -> getName ()), $this -> hiddenMethods ) ) {
continue ;
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
$methodName = ( $namespace ? $namespace . '.' : '' ) . $method -> getName ();
$docComment = $method -> getDocComment ();
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
$result [ 'services' ][ $methodName ] = array ( 'parameters' => array () );
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
// set description
if ( $rmDocComment = $this -> getDocDescription ( $docComment ) ) {
$result [ 'services' ][ $methodName ][ 'description' ] = $rmDocComment ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
// @param\s+([^\s]*)\s+([^\s]*)\s*([^\s\*]*)
$parsedParams = array ();
if ( preg_match_all ( '/@param\s+([^\s]*)\s+([^\s]*)\s*([^\n\*]*)/' , $docComment , $matches ) ) {
foreach ( $matches [ 2 ] as $number => $name ) {
$type = $matches [ 1 ][ $number ];
$desc = $matches [ 3 ][ $number ];
$name = trim ( $name , '$' );
$param = array ( 'type' => $type , 'description' => $desc );
$parsedParams [ $name ] = array_filter ( $param );
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
};
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
// process params
foreach ( $method -> getParameters () as $parameter ) {
$name = $parameter -> getName ();
$param = array ( 'name' => $name , 'optional' => $parameter -> isDefaultValueAvailable () );
if ( array_key_exists ( $name , $parsedParams ) ) {
$param += $parsedParams [ $name ];
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
if ( $param [ 'optional' ] ) {
$param [ 'default' ] = $parameter -> getDefaultValue ();
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
$result [ 'services' ][ $methodName ][ 'parameters' ][] = $param ;
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
// set return type
if ( preg_match ( '/@return\s+([^\s]+)\s*([^\n\*]+)/' , $docComment , $matches ) ) {
$returns = array ( 'type' => $matches [ 1 ], 'description' => trim ( $matches [ 2 ]) );
$result [ 'services' ][ $methodName ][ 'returns' ] = array_filter ( $returns );
}
}
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
return $result ;
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
/**
* Reset Local Class Vars after Execute
*/
private function resetVars ()
{
$this -> response = $this -> calls = array ();
$this -> hasCalls = $this -> isBatchCall = false ;
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
}
2017-10-14 04:55:42 +00:00
?>
< ? php
// Initializing
2020-02-15 17:57:46 +00:00
if ( ! isset ( $NO_LOGIN )) { $NO_LOGIN = false ;
}
if ( ! isset ( $ACCOUNTS )) { $ACCOUNTS = array ();
}
if ( isset ( $USER ) && isset ( $PASSWORD ) && $USER && $PASSWORD ) { $ACCOUNTS [ $USER ] = $PASSWORD ;
}
if ( ! isset ( $PASSWORD_HASH_ALGORITHM )) { $PASSWORD_HASH_ALGORITHM = '' ;
}
if ( ! isset ( $HOME_DIRECTORY )) { $HOME_DIRECTORY = '' ;
}
2017-10-14 04:55:42 +00:00
$IS_CONFIGURED = ( $NO_LOGIN || count ( $ACCOUNTS ) >= 1 ) ? true : false ;
// Utilities
2020-02-15 17:57:46 +00:00
function is_empty_string ( $string )
{
2017-10-14 04:55:42 +00:00
return strlen ( $string ) <= 0 ;
}
2020-02-15 17:57:46 +00:00
function is_equal_strings ( $string1 , $string2 )
{
2017-10-14 04:55:42 +00:00
return strcmp ( $string1 , $string2 ) == 0 ;
}
2020-02-15 17:57:46 +00:00
function get_hash ( $algorithm , $string )
{
2017-10-14 04:55:42 +00:00
return hash ( $algorithm , trim (( string ) $string ));
}
// Command execution
2020-02-15 17:57:46 +00:00
function execute_command ( $command )
{
2017-10-14 04:55:42 +00:00
$descriptors = array (
0 => array ( 'pipe' , 'r' ), // STDIN
1 => array ( 'pipe' , 'w' ), // STDOUT
2 => array ( 'pipe' , 'w' ) // STDERR
);
$process = proc_open ( $command . ' 2>&1' , $descriptors , $pipes );
2020-02-15 17:57:46 +00:00
if ( ! is_resource ( $process )) { die ( " Can't execute command. " );
}
2017-10-14 04:55:42 +00:00
// Nothing to push to STDIN
fclose ( $pipes [ 0 ]);
$output = stream_get_contents ( $pipes [ 1 ]);
fclose ( $pipes [ 1 ]);
$error = stream_get_contents ( $pipes [ 2 ]);
fclose ( $pipes [ 2 ]);
// All pipes must be closed before "proc_close"
$code = proc_close ( $process );
return $output ;
}
// Command parsing
2020-02-15 17:57:46 +00:00
function parse_command ( $command )
{
2017-10-14 04:55:42 +00:00
$value = ltrim (( string ) $command );
if ( ! is_empty_string ( $value )) {
$values = explode ( ' ' , $value );
$values_total = count ( $values );
if ( $values_total > 1 ) {
$value = $values [ $values_total - 1 ];
for ( $index = $values_total - 2 ; $index >= 0 ; $index -- ) {
$value_item = $values [ $index ];
2020-02-15 17:57:46 +00:00
if ( substr ( $value_item , - 1 ) == '\\' ) { $value = $value_item . ' ' . $value ;
} else { break ;
}
2017-10-14 04:55:42 +00:00
}
}
}
return $value ;
}
// RPC Server
2020-02-15 17:57:46 +00:00
class WebConsoleRPCServer extends BaseJsonRpcServer
{
2017-10-14 04:55:42 +00:00
protected $home_directory = '' ;
2020-02-15 17:57:46 +00:00
private function error ( $message )
{
2017-10-14 04:55:42 +00:00
throw new Exception ( $message );
}
// Authentication
2020-02-15 17:57:46 +00:00
private function authenticate_user ( $user , $password )
{
2017-10-14 04:55:42 +00:00
$user = trim (( string ) $user );
$password = trim (( string ) $password );
if ( $user && $password ) {
global $ACCOUNTS , $PASSWORD_HASH_ALGORITHM ;
if ( isset ( $ACCOUNTS [ $user ]) && ! is_empty_string ( $ACCOUNTS [ $user ])) {
2020-02-15 17:57:46 +00:00
if ( $PASSWORD_HASH_ALGORITHM ) { $password = get_hash ( $PASSWORD_HASH_ALGORITHM , $password );
}
2017-10-14 04:55:42 +00:00
2020-02-15 17:57:46 +00:00
if ( is_equal_strings ( $password , $ACCOUNTS [ $user ])) {
2017-10-14 04:55:42 +00:00
return $user . ':' . get_hash ( 'sha256' , $password );
2020-02-15 17:57:46 +00:00
}
2017-10-14 04:55:42 +00:00
}
}
throw new Exception ( " Incorrect user or password " );
}
2020-02-15 17:57:46 +00:00
private function authenticate_token ( $token )
{
2017-10-14 04:55:42 +00:00
global $NO_LOGIN ;
2020-02-15 17:57:46 +00:00
if ( $NO_LOGIN ) { return true ;
}
2017-10-14 04:55:42 +00:00
$token = trim (( string ) $token );
$token_parts = explode ( ':' , $token , 2 );
if ( count ( $token_parts ) == 2 ) {
$user = trim (( string ) $token_parts [ 0 ]);
$password_hash = trim (( string ) $token_parts [ 1 ]);
if ( $user && $password_hash ) {
global $ACCOUNTS ;
if ( isset ( $ACCOUNTS [ $user ]) && ! is_empty_string ( $ACCOUNTS [ $user ])) {
$real_password_hash = get_hash ( 'sha256' , $ACCOUNTS [ $user ]);
2020-02-15 17:57:46 +00:00
if ( is_equal_strings ( $password_hash , $real_password_hash )) { return $user ;
}
2017-10-14 04:55:42 +00:00
}
}
}
throw new Exception ( " Incorrect user or password " );
}
2020-02-15 17:57:46 +00:00
private function get_home_directory ( $user )
{
2017-10-14 04:55:42 +00:00
global $HOME_DIRECTORY ;
if ( is_string ( $HOME_DIRECTORY )) {
2020-02-15 17:57:46 +00:00
if ( ! is_empty_string ( $HOME_DIRECTORY )) { return $HOME_DIRECTORY ;
}
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
else if ( is_string ( $user ) && ! is_empty_string ( $user ) && isset ( $HOME_DIRECTORY [ $user ]) && ! is_empty_string ( $HOME_DIRECTORY [ $user ])) {
2017-10-14 04:55:42 +00:00
return $HOME_DIRECTORY [ $user ];
2020-02-15 17:57:46 +00:00
}
2017-10-14 04:55:42 +00:00
return getcwd ();
}
// Environment
2020-02-15 17:57:46 +00:00
private function get_environment ()
{
2017-10-14 04:55:42 +00:00
$hostname = function_exists ( 'gethostname' ) ? gethostname () : null ;
return array ( 'path' => getcwd (), 'hostname' => $hostname );
}
2020-02-15 17:57:46 +00:00
private function set_environment ( $environment )
{
2017-10-14 04:55:42 +00:00
$environment = ! empty ( $environment ) ? ( array ) $environment : array ();
$path = ( isset ( $environment [ 'path' ]) && ! is_empty_string ( $environment [ 'path' ])) ? $environment [ 'path' ] : $this -> home_directory ;
if ( ! is_empty_string ( $path )) {
if ( is_dir ( $path )) {
2020-02-15 17:57:46 +00:00
if ( !@ chdir ( $path )) { return array ( 'output' => " Unable to change directory to current working directory, updating current directory " ,
2017-10-14 04:55:42 +00:00
'environment' => $this -> get_environment ());
2020-02-15 17:57:46 +00:00
}
2017-10-14 04:55:42 +00:00
}
2020-02-15 17:57:46 +00:00
else { return array ( 'output' => " Current working directory not found, updating current directory " ,
2017-10-14 04:55:42 +00:00
'environment' => $this -> get_environment ());
2020-02-15 17:57:46 +00:00
}
2017-10-14 04:55:42 +00:00
}
}
// Initialization
2020-02-15 17:57:46 +00:00
private function initialize ( $token , $environment )
{
2017-10-14 04:55:42 +00:00
$user = $this -> authenticate_token ( $token );
$this -> home_directory = $this -> get_home_directory ( $user );
$result = $this -> set_environment ( $environment );
2020-02-15 17:57:46 +00:00
if ( $result ) { return $result ;
}
2017-10-14 04:55:42 +00:00
}
// Methods
2020-02-15 17:57:46 +00:00
public function login ( $user , $password )
{
2017-10-14 04:55:42 +00:00
$result = array ( 'token' => $this -> authenticate_user ( $user , $password ),
'environment' => $this -> get_environment ());
$home_directory = $this -> get_home_directory ( $user );
if ( ! is_empty_string ( $home_directory )) {
2020-02-15 17:57:46 +00:00
if ( is_dir ( $home_directory )) { $result [ 'environment' ][ 'path' ] = $home_directory ;
} else { $result [ 'output' ] = " Home directory not found: " . $home_directory ;
}
2017-10-14 04:55:42 +00:00
}
return $result ;
}
2020-02-15 17:57:46 +00:00
public function cd ( $token , $environment , $path )
{
2017-10-14 04:55:42 +00:00
$result = $this -> initialize ( $token , $environment );
2020-02-15 17:57:46 +00:00
if ( $result ) { return $result ;
}
2017-10-14 04:55:42 +00:00
$path = trim (( string ) $path );
2020-02-15 17:57:46 +00:00
if ( is_empty_string ( $path )) { $path = $this -> home_directory ;
}
2017-10-14 04:55:42 +00:00
if ( ! is_empty_string ( $path )) {
if ( is_dir ( $path )) {
2020-02-15 17:57:46 +00:00
if ( !@ chdir ( $path )) { return array ( 'output' => " cd: " . $path . " : Unable to change directory " );
}
}
else { return array ( 'output' => " cd: " . $path . " : No such directory " );
2017-10-14 04:55:42 +00:00
}
}
return array ( 'environment' => $this -> get_environment ());
}
2020-02-15 17:57:46 +00:00
public function completion ( $token , $environment , $pattern , $command )
{
2017-10-14 04:55:42 +00:00
$result = $this -> initialize ( $token , $environment );
2020-02-15 17:57:46 +00:00
if ( $result ) { return $result ;
}
2017-10-14 04:55:42 +00:00
$scan_path = '' ;
$completion_prefix = '' ;
$completion = array ();
if ( ! empty ( $pattern )) {
if ( ! is_dir ( $pattern )) {
$pattern = dirname ( $pattern );
2020-02-15 17:57:46 +00:00
if ( $pattern == '.' ) { $pattern = '' ;
}
2017-10-14 04:55:42 +00:00
}
if ( ! empty ( $pattern )) {
if ( is_dir ( $pattern )) {
$scan_path = $completion_prefix = $pattern ;
2020-02-15 17:57:46 +00:00
if ( substr ( $completion_prefix , - 1 ) != '/' ) { $completion_prefix .= '/' ;
}
2017-10-14 04:55:42 +00:00
}
}
2020-02-15 17:57:46 +00:00
else { $scan_path = getcwd ();
}
}
else { $scan_path = getcwd ();
2017-10-14 04:55:42 +00:00
}
if ( ! empty ( $scan_path )) {
// Loading directory listing
$completion = array_values ( array_diff ( scandir ( $scan_path ), array ( '..' , '.' )));
natsort ( $completion );
// Prefix
if ( ! empty ( $completion_prefix ) && ! empty ( $completion )) {
2020-02-15 17:57:46 +00:00
foreach ( $completion as & $value ) { $value = $completion_prefix . $value ;
}
2017-10-14 04:55:42 +00:00
}
// Pattern
if ( ! empty ( $pattern ) && ! empty ( $completion )) {
// For PHP version that does not support anonymous functions (available since PHP 5.3.0)
2020-02-15 17:57:46 +00:00
function filter_pattern ( $value )
{
2017-10-14 04:55:42 +00:00
global $pattern ;
return ! strncmp ( $pattern , $value , strlen ( $pattern ));
}
$completion = array_values ( array_filter ( $completion , 'filter_pattern' ));
}
}
return array ( 'completion' => $completion );
}
2020-02-15 17:57:46 +00:00
public function run ( $token , $environment , $command )
{
2017-10-14 04:55:42 +00:00
$result = $this -> initialize ( $token , $environment );
2020-02-15 17:57:46 +00:00
if ( $result ) { return $result ;
}
2017-10-14 04:55:42 +00:00
$output = ( $command && ! is_empty_string ( $command )) ? execute_command ( $command ) : '' ;
2020-02-15 17:57:46 +00:00
if ( $output && substr ( $output , - 1 ) == " \n " ) { $output = substr ( $output , 0 , - 1 );
}
2017-10-14 04:55:42 +00:00
return array ( 'output' => $output );
}
}
// Processing request
if ( array_key_exists ( 'REQUEST_METHOD' , $_SERVER ) && $_SERVER [ 'REQUEST_METHOD' ] == 'POST' ) {
$rpc_server = new WebConsoleRPCServer ();
$rpc_server -> Execute ();
}
else if ( ! $IS_CONFIGURED ) {
2020-02-15 17:57:46 +00:00
?>
2017-10-14 04:55:42 +00:00
<! DOCTYPE html >
< html >
< head >
< meta charset = " utf-8 " />
< meta http - equiv = " X-UA-Compatible " content = " IE=edge " />
< title > Web Console </ title >
< meta name = " viewport " content = " width=device-width, initial-scale=1 " />
< meta name = " description " content = " Web Console (http://www.web-console.org) " />
< meta name = " author " content = " Nickolay Kovalev (http://resume.nickola.ru) " />
< meta name = " robots " content = " none " />
< style type = " text/css " > html { font - family : sans - serif ; line - height : 1.15 ; - ms - text - size - adjust : 100 % ; - webkit - text - size - adjust : 100 % } body { margin : 0 } article , aside , footer , header , nav , section { display : block } h1 { font - size : 2 em ; margin :. 67 em 0 } figcaption , figure , main { display : block } figure { margin : 1 em 40 px } hr { box - sizing : content - box ; height : 0 ; overflow : visible } pre { font - family : monospace , monospace ; font - size : 1 em } a { background - color : transparent ; - webkit - text - decoration - skip : objects } a : active , a : hover { outline - width : 0 } abbr [ title ]{ border - bottom : 0 ; text - decoration : underline ; text - decoration : underline dotted } b , strong { font - weight : bolder } code , kbd , samp { font - family : monospace , monospace ; font - size : 1 em } dfn { font - style : italic } mark { background - color : #ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}[hidden],template{display:none}.cmd .format,.cmd .prompt,.cmd .prompt div,.terminal .terminal-output .format,.terminal .terminal-output div div{display:inline-block}.cmd,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6,.terminal pre{margin:0}.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6{line-height:1.2em}.cmd .clipboard{position:absolute;left:-16px;top:0;width:10px;height:16px;background:0 0;border:0;color:transparent;outline:0;padding:0;resize:none;z-index:0;overflow:hidden}.terminal .error{color:red}.terminal{padding:10px;position:relative;overflow:auto}.cmd{padding:0;height:1.3em;position:relative}.cmd .cursor.blink,.cmd .inverted,.terminal .inverted{background-color:#aaa;color:#000}.cmd .cursor.blink{-webkit-animation:terminal-blink 1s infinite steps(1,start);-moz-animation:terminal-blink 1s infinite steps(1,start);-ms-animation:terminal-blink 1s infinite steps(1,start);animation:terminal-blink 1s infinite steps(1,start)}@-webkit-keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@-ms-keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@-moz-keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}.cmd .prompt,.terminal .terminal-output div div{display:block;line-height:14px;height:auto}.cmd .prompt{float:left}.cmd,.terminal{background-color:#000}.terminal-output>div{min-height:14px}.terminal-output>div>div *{word-wrap:break-word}.terminal .terminal-output div span{display:inline-block}.cmd span{float:left}.cmd div,.cmd span,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h
</ head >
< body >
< div class = " configure " >
< p > Web Console must be configured before use :</ p >
< ul >
< li > Open Web Console PHP file in your favorite text editor .</ li >
< li > At the beginning of the file enter your < span class = " variable " > $USER </ span > and < span class = " variable " > $PASSWORD </ span > credentials , edit any other settings that you like ( see description in the comments ) .</ li >
< li > Upload changed file to the web server and open it in the browser .</ li >
</ ul >
< p > For more information visit Web Console website : < a href = " http://web-console.org " > http :// web - console . org </ a ></ p >
</ div >
</ body >
</ html >
2020-02-15 17:57:46 +00:00
< ? php
2017-10-14 04:55:42 +00:00
}
else { ?>
<! DOCTYPE html >
< html class = " no-js " >
< head >
< meta charset = " utf-8 " />
< meta http - equiv = " X-UA-Compatible " content = " IE=edge " />
< title > Web Console </ title >
< meta name = " viewport " content = " width=device-width, initial-scale=1 " />
< meta name = " description " content = " Web Console (http://www.web-console.org) " />
< meta name = " author " content = " Nickolay Kovalev (http://resume.nickola.ru) " />
< meta name = " robots " content = " none " />
< style type = " text/css " > html { font - family : sans - serif ; line - height : 1.15 ; - ms - text - size - adjust : 100 % ; - webkit - text - size - adjust : 100 % } body { margin : 0 } article , aside , footer , header , nav , section { display : block } h1 { font - size : 2 em ; margin :. 67 em 0 } figcaption , figure , main { display : block } figure { margin : 1 em 40 px } hr { box - sizing : content - box ; height : 0 ; overflow : visible } pre { font - family : monospace , monospace ; font - size : 1 em } a { background - color : transparent ; - webkit - text - decoration - skip : objects } a : active , a : hover { outline - width : 0 } abbr [ title ]{ border - bottom : 0 ; text - decoration : underline ; text - decoration : underline dotted } b , strong { font - weight : bolder } code , kbd , samp { font - family : monospace , monospace ; font - size : 1 em } dfn { font - style : italic } mark { background - color : #ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}[hidden],template{display:none}.cmd .format,.cmd .prompt,.cmd .prompt div,.terminal .terminal-output .format,.terminal .terminal-output div div{display:inline-block}.cmd,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6,.terminal pre{margin:0}.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6{line-height:1.2em}.cmd .clipboard{position:absolute;left:-16px;top:0;width:10px;height:16px;background:0 0;border:0;color:transparent;outline:0;padding:0;resize:none;z-index:0;overflow:hidden}.terminal .error{color:red}.terminal{padding:10px;position:relative;overflow:auto}.cmd{padding:0;height:1.3em;position:relative}.cmd .cursor.blink,.cmd .inverted,.terminal .inverted{background-color:#aaa;color:#000}.cmd .cursor.blink{-webkit-animation:terminal-blink 1s infinite steps(1,start);-moz-animation:terminal-blink 1s infinite steps(1,start);-ms-animation:terminal-blink 1s infinite steps(1,start);animation:terminal-blink 1s infinite steps(1,start)}@-webkit-keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@-ms-keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@-moz-keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}.cmd .prompt,.terminal .terminal-output div div{display:block;line-height:14px;height:auto}.cmd .prompt{float:left}.cmd,.terminal{background-color:#000}.terminal-output>div{min-height:14px}.terminal-output>div>div *{word-wrap:break-word}.terminal .terminal-output div span{display:inline-block}.cmd span{float:left}.cmd div,.cmd span,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h
< script type = " text/javascript " >! function ( a , b ){ function c ( a ){ return K . isWindow ( a ) ? a : 9 === a . nodeType ? a . defaultView || a . parentWindow :! 1 } function d ( a ){ if ( ! tb [ a ]){ var b = H . body , c = K ( " < " + a + " > " ) . appendTo ( b ), d = c . css ( " display " ); c . remove (),( " none " === d || " " === d ) && ( pb || ( pb = H . createElement ( " iframe " ), pb . frameBorder = pb . width = pb . height = 0 ), b . appendChild ( pb ), qb && pb . createElement || ( qb = ( pb . contentWindow || pb . contentDocument ) . document , qb . write (( " CSS1Compat " === H . compatMode ? " <!doctype html> " : " " ) + " <html><body> " ), qb . close ()), c = qb . createElement ( a ), qb . body . appendChild ( c ), d = K . css ( c , " display " ), b . removeChild ( pb )), tb [ a ] = d } return tb [ a ]} function e ( a , b ){ var c = {}; return K . each ( wb . concat . apply ([], wb . slice ( 0 , b )), function (){ c [ this ] = a }), c } function f (){ sb = b } function g (){ return setTimeout ( f , 0 ), sb = K . now ()} function h (){ try { return new a . ActiveXObject ( " Microsoft.XMLHTTP " )} catch ( b ){}} function i (){ try { return new a . XMLHttpRequest } catch ( b ){}} function j ( a , c ){ a . dataFilter && ( c = a . dataFilter ( c , a . dataType )); var d , e , f , g , h , i , j , k , l = a . dataTypes , m = {}, n = l . length , o = l [ 0 ]; for ( d = 1 ; n > d ; d ++ ){ if ( 1 === d ) for ( e in a . converters ) " string " == typeof e && ( m [ e . toLowerCase ()] = a . converters [ e ]); if ( g = o , o = l [ d ], " * " === o ) o = g ; else if ( " * " !== g && g !== o ){ if ( h = g + " " + o , i = m [ h ] || m [ " * " + o ], ! i ){ k = b ; for ( j in m ) if ( f = j . split ( " " ),( f [ 0 ] === g || " * " === f [ 0 ]) && ( k = m [ f [ 1 ] + " " + o ])){ j = m [ j ], j ===! 0 ? i = k : k ===! 0 && ( i = j ); break }} ! i &&! k && K . error ( " No conversion from " + h . replace ( " " , " to " )), i !==! 0 && ( c = i ? i ( c ) : k ( j ( c )))}} return c } function k ( a , c , d ){ var e , f , g , h , i = a . contents , j = a . dataTypes , k = a . responseFields ; for ( f in k ) f in d && ( c [ k [ f ]] = d [ f ]); for (; " * " === j [ 0 ];) j . shift (), e === b && ( e = a . mimeType || c . getResponseHeader ( " content-type " )); if ( e ) for ( f in i ) if ( i [ f ] && i [ f ] . test ( e )){ j . unshift ( f ); break } if ( j [ 0 ] in d ) g = j [ 0 ]; else { for ( f in d ){ if ( ! j [ 0 ] || a . converters [ f + " " + j [ 0 ]]){ g = f ; break } h || ( h = f )} g = g || h } return g ? ( g !== j [ 0 ] && j . unshift ( g ), d [ g ]) : void 0 } function l ( a , b , c , d ){ if ( K . isArray ( b )) K . each ( b , function ( b , e ){ c || Ta . test ( a ) ? d ( a , e ) : l ( a + " [ " + ( " object " == typeof e || K . isArray ( e ) ? b : " " ) + " ] " , e , c , d )}); else if ( c || null == b || " object " != typeof b ) d ( a , b ); else for ( var e in b ) l ( a + " [ " + e + " ] " , b [ e ], c , d )} function m ( a , c ){ var d , e , f = K . ajaxSettings . flatOptions || {}; for ( d in c ) c [ d ] !== b && (( f [ d ] ? a : e || ( e = {}))[ d ] = c [ d ]); e && K . extend ( ! 0 , a , e )} function n ( a , c , d , e , f , g ){ f = f || c . dataTypes [ 0 ], g = g || {}, g [ f ] =! 0 ; for ( var h , i = a [ f ], j = 0 , k = i ? i . length : 0 , l = a === gb ; k > j && ( l ||! h ); j ++ ) h = i [ j ]( c , d , e ), " string " == typeof h && ( ! l || g [ h ] ? h = b : ( c . dataTypes . unshift ( h ), h = n ( a , c , d , e , h , g ))); return ( l ||! h ) &&! g [ " * " ] && ( h = n ( a , c , d , e , " * " , g )), h } function o ( a ){ return function ( b , c ){ if ( " string " != typeof b && ( c = b , b = " * " ), K . isFunction ( c )) for ( var d , e , f , g = b . toLowerCase () . split ( cb ), h = 0 , i = g . length ; i > h ; h ++ ) d = g [ h ], f =/^ \ +/. test ( d ), f && ( d = d . substr ( 1 ) || " * " ), e = a [ d ] = a [ d ] || [], e [ f ? " unshift " : " push " ]( c )}} function p ( a , b , c ){ var d = " width " === b ? a . offsetWidth : a . offsetHeight , e = " width " === b ? Oa : Pa , f = 0 , g = e . length ; if ( d > 0 ){ if ( " border " !== c ) for (; g > f ; f ++ ) c || ( d -= parseFloat ( K . css ( a , " padding " + e [ f ])) || 0 ), " margin " === c ? d += parseFloat ( K . css ( a , c + e [ f ])) || 0 : d -= parseFloat ( K . css ( a , " border " + e [ f ] + " Width " )) || 0 ; return d + " px " } if ( d = Ea ( a , b , b ),( 0 > d || null == d ) && ( d = a . style [ b ] || 0 ), d = parseFloat ( d ) || 0 , c ) for (; g > f ; f ++ ) d += parseFloat ( K . css ( a , " padding " + e [ f ])) || 0 , " padding " !== c && ( d += parseFloat ( K . css ( a , " border " + e [ f ] + " Width " )) || 0 ), " margin " === c && ( d += parseFloat ( K . css ( a , c + e [ f ])) || 0 ); return d + " px " } function q ( a , b ){ b . src ? K . ajax ({ url : b . src , async :! 1 , dataType : " script " }) : K . globalEval (( b . text || b . textContent || b . innerHTML || " " ) . replace ( Ba , " /* $ 0*/ " )), b . parentNode && b . parentNode . removeChild ( b )} function r ( a ){ var b = H . createElement ( " div " ); return Da . appendChild ( b ), b . innerHTML = a . outerHTML , b . firstChild } function s ( a ){ var b = ( a . nodeName || " " ) . toLowerCase (); " input " === b ? t ( a ) : " script " !== b && " undefined " != typeof a . getElementsByTagName && K . grep ( a . getElementsByTagName ( " input " ), t )} function t ( a ){( " checkbox " === a . type || " radio " === a . type ) && ( a . defaultChecked = a . checked )} function u ( a ){ return " undefined " != typeof a . getElementsByTagName ? a . getElementsByTagName ( " * " ) : " undefined " != typeof a . querySelectorAll ? a . querySelectorAll ( " * " ) : []} function v ( a , b ){ var c ; 1 === b . nodeType && ( b . clearAttributes && b . clearAttributes (), b . mergeAttributes && b . mergeAttributes ( a ), c = b . nodeName . toLowerCase (), " object " === c ? b
}, ha = function ( a ){ return K . event . special . hover ? a : a . replace ( aa , " mouseenter $ 1 mouseleave $ 1 " )}; K . event = { add : function ( a , c , d , e , f ){ var g , h , i , j , k , l , m , n , o , p , q ; if ( 3 !== a . nodeType && 8 !== a . nodeType && c && d && ( g = K . _data ( a ))){ for ( d . handler && ( o = d , d = o . handler ), d . guid || ( d . guid = K . guid ++ ), i = g . events , i || ( g . events = i = {}), h = g . handle , h || ( g . handle = h = function ( a ){ return " undefined " == typeof K || a && K . event . triggered === a . type ? b : K . event . dispatch . apply ( h . elem , arguments )}, h . elem = a ), c = K . trim ( ha ( c )) . split ( " " ), j = 0 ; j < c . length ; j ++ ) k = _ . exec ( c [ j ]) || [], l = k [ 1 ], m = ( k [ 2 ] || " " ) . split ( " . " ) . sort (), q = K . event . special [ l ] || {}, l = ( f ? q . delegateType : q . bindType ) || l , q = K . event . special [ l ] || {}, n = K . extend ({ type : l , origType : k [ 1 ], data : e , handler : d , guid : d . guid , selector : f , quick : fa ( f ), namespace : m . join ( " . " )}, o ), p = i [ l ], p || ( p = i [ l ] = [], p . delegateCount = 0 , q . setup && q . setup . call ( a , e , m , h ) !==! 1 || ( a . addEventListener ? a . addEventListener ( l , h , ! 1 ) : a . attachEvent && a . attachEvent ( " on " + l , h ))), q . add && ( q . add . call ( a , n ), n . handler . guid || ( n . handler . guid = d . guid )), f ? p . splice ( p . delegateCount ++ , 0 , n ) : p . push ( n ), K . event . global [ l ] =! 0 ; a = null }}, global : {}, remove : function ( a , b , c , d , e ){ var f , g , h , i , j , k , l , m , n , o , p , q , r = K . hasData ( a ) && K . _data ( a ); if ( r && ( m = r . events )){ for ( b = K . trim ( ha ( b || " " )) . split ( " " ), f = 0 ; f < b . length ; f ++ ) if ( g = _ . exec ( b [ f ]) || [], h = i = g [ 1 ], j = g [ 2 ], h ){ for ( n = K . event . special [ h ] || {}, h = ( d ? n . delegateType : n . bindType ) || h , p = m [ h ] || [], k = p . length , j = j ? new RegExp ( " (^| \\ .) " + j . split ( " . " ) . sort () . join ( " \\ .(?:.* \\ .)? " ) + " ( \\ .| $ ) " ) : null , l = 0 ; l < p . length ; l ++ ) q = p [ l ],( e || i === q . origType ) && ( ! c || c . guid === q . guid ) && ( ! j || j . test ( q . namespace )) && ( ! d || d === q . selector || " ** " === d && q . selector ) && ( p . splice ( l -- , 1 ), q . selector && p . delegateCount -- , n . remove && n . remove . call ( a , q )); 0 === p . length && k !== p . length && (( ! n . teardown || n . teardown . call ( a , j ) ===! 1 ) && K . removeEvent ( a , h , r . handle ), delete m [ h ])} else for ( h in m ) K . event . remove ( a , h + b [ f ], c , d , ! 0 ); K . isEmptyObject ( m ) && ( o = r . handle , o && ( o . elem = null ), K . removeData ( a ,[ " events " , " handle " ], ! 0 ))}}, customEvent : { getData :! 0 , setData :! 0 , changeData :! 0 }, trigger : function ( c , d , e , f ){ if ( ! e || 3 !== e . nodeType && 8 !== e . nodeType ){ var g , h , i , j , k , l , m , n , o , p , q = c . type || c , r = []; if ( da . test ( q + K . event . triggered )) return ; if ( q . indexOf ( " ! " ) >= 0 && ( q = q . slice ( 0 , - 1 ), h =! 0 ), q . indexOf ( " . " ) >= 0 && ( r = q . split ( " . " ), q = r . shift (), r . sort ()),( ! e || K . event . customEvent [ q ]) &&! K . event . global [ q ]) return ; if ( c = " object " == typeof c ? c [ K . expando ] ? c : new K . Event ( q , c ) : new K . Event ( q ), c . type = q , c . isTrigger =! 0 , c . exclusive = h , c . namespace = r . join ( " . " ), c . namespace_re = c . namespace ? new RegExp ( " (^| \\ .) " + r . join ( " \\ .(?:.* \\ .)? " ) + " ( \\ .| $ ) " ) : null , l = q . indexOf ( " : " ) < 0 ? " on " + q : " " , ! e ){ g = K . cache ; for ( i in g ) g [ i ] . events && g [ i ] . events [ q ] && K . event . trigger ( c , d , g [ i ] . handle . elem , ! 0 ); return } if ( c . result = b , c . target || ( c . target = e ), d = null != d ? K . makeArray ( d ) : [], d . unshift ( c ), m = K . event . special [ q ] || {}, m . trigger && m . trigger . apply ( e , d ) ===! 1 ) return ; if ( o = [[ e , m . bindType || q ]], ! f &&! m . noBubble &&! K . isWindow ( e )){ for ( p = m . delegateType || q , j = da . test ( p + q ) ? e : e . parentNode , k = null ; j ; j = j . parentNode ) o . push ([ j , p ]), k = j ; k && k === e . ownerDocument && o . push ([ k . defaultView || k . parentWindow || a , p ])} for ( i = 0 ; i < o . length &&! c . isPropagationStopped (); i ++ ) j = o [ i ][ 0 ], c . type = o [ i ][ 1 ], n = ( K . _data ( j , " events " ) || {})[ c . type ] && K . _data ( j , " handle " ), n && n . apply ( j , d ), n = l && j [ l ], n && K . acceptData ( j ) && n . apply ( j , d ) ===! 1 && c . preventDefault (); return c . type = q , ! f &&! c . isDefaultPrevented () && ( ! m . _default || m . _default . apply ( e . ownerDocument , d ) ===! 1 ) && ( " click " !== q ||! K . nodeName ( e , " a " )) && K . acceptData ( e ) && l && e [ q ] && ( " focus " !== q && " blur " !== q || 0 !== c . target . offsetWidth ) &&! K . isWindow ( e ) && ( k = e [ l ], k && ( e [ l ] = null ), K . event . triggered = q , e [ q ](), K . event . triggered = b , k && ( e [ l ] = k )), c . result }}, dispatch : function ( c ){ c = K . event . fix ( c || a . event ); var d , e , f , g , h , i , j , k , l , m , n = ( K . _data ( this , " events " ) || {})[ c . type ] || [], o = n . delegateCount , p = [] . slice . call ( arguments , 0 ), q =! c . exclusive &&! c . namespace , r = []; if ( p [ 0 ] = c , c . delegateTarget = this , o &&! c . target . disabled && ( ! c . button || " click " !== c . type )) for ( g = K ( this ), g . context = this . ownerDocument || this , f = c . target ; f != this ; f = f . parentNode || this ){ for ( i = {}, k = [], g [ 0 ] = f , d = 0 ; o > d ; d ++ ) l = n [ d ], m = l . selector , i [ m ] === b && ( i [ m ] = l . quick ? ga ( f , l . quick ) : g . is ( m )), i [ m ] && k . push ( l ); k . length && r . push ({ elem : f , matches : k })} for ( n . length > o && r . push
if ( this [ 0 ] && this [ 0 ] . parentNode ) return this . domManip ( arguments , ! 1 , function ( a ){ this . parentNode . insertBefore ( a , this )}); if ( arguments . length ){ var a = K . clean ( arguments ); return a . push . apply ( a , this . toArray ()), this . pushStack ( a , " before " , arguments )}}, after : function (){ if ( this [ 0 ] && this [ 0 ] . parentNode ) return this . domManip ( arguments , ! 1 , function ( a ){ this . parentNode . insertBefore ( a , this . nextSibling )}); if ( arguments . length ){ var a = this . pushStack ( this , " after " , arguments ); return a . push . apply ( a , K . clean ( arguments )), a }}, remove : function ( a , b ){ for ( var c , d = 0 ; null != ( c = this [ d ]); d ++ )( ! a || K . filter ( a ,[ c ]) . length ) && ( ! b && 1 === c . nodeType && ( K . cleanData ( c . getElementsByTagName ( " * " )), K . cleanData ([ c ])), c . parentNode && c . parentNode . removeChild ( c )); return this }, empty : function (){ for ( var a , b = 0 ; null != ( a = this [ b ]); b ++ ) for ( 1 === a . nodeType && K . cleanData ( a . getElementsByTagName ( " * " )); a . firstChild ;) a . removeChild ( a . firstChild ); return this }, clone : function ( a , b ){ return a = null == a ? ! 1 : a , b = null == b ? a : b , this . map ( function (){ return K . clone ( this , a , b )})}, html : function ( a ){ if ( a === b ) return this [ 0 ] && 1 === this [ 0 ] . nodeType ? this [ 0 ] . innerHTML . replace ( qa , " " ) : null ; if ( " string " != typeof a || wa . test ( a ) ||! K . support . leadingWhitespace && ra . test ( a ) || Ca [( ta . exec ( a ) || [ " " , " " ])[ 1 ] . toLowerCase ()]) K . isFunction ( a ) ? this . each ( function ( b ){ var c = K ( this ); c . html ( a . call ( this , b , c . html ()))}) : this . empty () . append ( a ); else { a = a . replace ( sa , " < $ 1></ $ 2> " ); try { for ( var c = 0 , d = this . length ; d > c ; c ++ ) 1 === this [ c ] . nodeType && ( K . cleanData ( this [ c ] . getElementsByTagName ( " * " )), this [ c ] . innerHTML = a )} catch ( e ){ this . empty () . append ( a )}} return this }, replaceWith : function ( a ){ return this [ 0 ] && this [ 0 ] . parentNode ? K . isFunction ( a ) ? this . each ( function ( b ){ var c = K ( this ), d = c . html (); c . replaceWith ( a . call ( this , b , d ))}) : ( " string " != typeof a && ( a = K ( a ) . detach ()), this . each ( function (){ var b = this . nextSibling , c = this . parentNode ; K ( this ) . remove (), b ? K ( b ) . before ( a ) : K ( c ) . append ( a )})) : this . length ? this . pushStack ( K ( K . isFunction ( a ) ? a () : a ), " replaceWith " , a ) : this }, detach : function ( a ){ return this . remove ( a , ! 0 )}, domManip : function ( a , c , d ){ var e , f , g , h , i = a [ 0 ], j = []; if ( ! K . support . checkClone && 3 === arguments . length && " string " == typeof i && za . test ( i )) return this . each ( function (){ K ( this ) . domManip ( a , c , d , ! 0 )}); if ( K . isFunction ( i )) return this . each ( function ( e ){ var f = K ( this ); a [ 0 ] = i . call ( this , e , c ? f . html () : b ), f . domManip ( a , c , d )}); if ( this [ 0 ]){ if ( h = i && i . parentNode , e = K . support . parentNode && h && 11 === h . nodeType && h . childNodes . length === this . length ? { fragment : h } : K . buildFragment ( a , this , j ), g = e . fragment , f = 1 === g . childNodes . length ? g = g . firstChild : g . firstChild , f ){ c = c && K . nodeName ( f , " tr " ); for ( var k = 0 , l = this . length , m = l - 1 ; l > k ; k ++ ) d . call ( c ? x ( this [ k ], f ) : this [ k ], e . cacheable || l > 1 && m > k ? K . clone ( g , ! 0 , ! 0 ) : g )} j . length && K . each ( j , q )} return this }}), K . buildFragment = function ( a , b , c ){ var d , e , f , g , h = a [ 0 ]; return b && b [ 0 ] && ( g = b [ 0 ] . ownerDocument || b [ 0 ]), g . createDocumentFragment || ( g = H ), 1 === a . length && " string " == typeof h && h . length < 512 && g === H && " < " === h . charAt ( 0 ) &&! xa . test ( h ) && ( K . support . checkClone ||! za . test ( h )) && ( K . support . html5Clone ||! ya . test ( h )) && ( e =! 0 , f = K . fragments [ h ], f && 1 !== f && ( d = f )), d || ( d = g . createDocumentFragment (), K . clean ( a , g , d , c )), e && ( K . fragments [ h ] = f ? d : 1 ),{ fragment : d , cacheable : e }}, K . fragments = {}, K . each ({ appendTo : " append " , prependTo : " prepend " , insertBefore : " before " , insertAfter : " after " , replaceAll : " replaceWith " }, function ( a , b ){ K . fn [ a ] = function ( c ){ var d = [], e = K ( c ), f = 1 === this . length && this [ 0 ] . parentNode ; if ( f && 11 === f . nodeType && 1 === f . childNodes . length && 1 === e . length ) return e [ b ]( this [ 0 ]), this ; for ( var g = 0 , h = e . length ; h > g ; g ++ ){ var i = ( g > 0 ? this . clone ( ! 0 ) : this ) . get (); K ( e [ g ])[ b ]( i ), d = d . concat ( i )} return this . pushStack ( d , a , e . selector )}}), K . extend ({ clone : function ( a , b , c ){ var d , e , f , g = K . support . html5Clone ||! ya . test ( " < " + a . nodeName ) ? a . cloneNode ( ! 0 ) : r ( a ); if ( ! ( K . support . noCloneEvent && K . support . noCloneChecked || 1 !== a . nodeType && 11 !== a . nodeType || K . isXMLDoc ( a ))) for ( v ( a , g ), d = u ( a ), e = u ( g ), f = 0 ; d [ f ]; ++ f ) e [ f ] && v ( d [ f ], e [ f ]); if ( b && ( w ( a , g ), c )) for ( d = u ( a ), e = u ( g ), f = 0 ; d [ f ]; ++ f ) w ( d [ f ], e [ f ]); return d = e = null , g }, clean : function ( a , b , c , d ){ var e ; b = b || H , " undefined " == typeof b . createElement && ( b = b . ownerDocument || b [ 0 ] && b [ 0 ] . ownerDocument || H ); for ( var f , g , h = [], i = 0 ; null != ( g = a [ i ]); i ++ ) if ( " number " ==
2020-02-15 17:57:46 +00:00
f . push ( h [ 1 ])} c [ 2 ] = f } else e |= 2 ; if ( 3 === e ) throw " [sprintf] mixing positional and named placeholders is not (yet) supported " ; d . push ( c )} b = b . substring ( c [ 0 ] . length )} return d }; var e = function ( a , b , c ){ return c = b . slice ( 0 ), c . splice ( 0 , 0 , a ), d . apply ( null , c )}; a . sprintf = d , a . vsprintf = e }( " undefined " != typeof global ? global : window ), function ( a , b ){ " use strict " ; function c ( a , b ){ var c ; if ( " string " == typeof a && " string " == typeof b ) return localStorage [ a ] = b , ! 0 ; if ( " object " == typeof a && " undefined " == typeof b ){ for ( c in a ) a . hasOwnProperty ( c ) && ( localStorage [ c ] = a [ c ]); return ! 0 } return ! 1 } function d ( a , b ){ var c , d , e ; if ( c = new Date , c . setTime ( c . getTime () + 31536e6 ), d = " ; expires= " + c . toGMTString (), " string " == typeof a && " string " == typeof b ) return document . cookie = a + " = " + b + d + " ; path=/ " , ! 0 ; if ( " object " == typeof a && " undefined " == typeof b ){ for ( e in a ) a . hasOwnProperty ( e ) && ( document . cookie = e + " = " + a [ e ] + d + " ; path=/ " ); return ! 0 } return ! 1 } function e ( a ){ return localStorage [ a ]} function f ( a ){ var b , c , d , e ; for ( b = a + " = " , c = document . cookie . split ( " ; " ), d = 0 ; d < c . length ; d ++ ){ for ( e = c [ d ]; " " === e . charAt ( 0 );) e = e . substring ( 1 , e . length ); if ( 0 === e . indexOf ( b )) return e . substring ( b . length , e . length )} return null } function g ( a ){ return delete localStorage [ a ]} function h ( a ){ return d ( a , " " , - 1 )} function i ( a , b ){ var c = [], d = a . length ; if ( b > d ) return [ a ]; if ( 0 > b ) throw new Error ( " str_parts: length can't be negative " ); for ( var e = 0 ; d > e ; e += b ) c . push ( a . substring ( e , e + b )); return c } function j ( b ){ var c = b ? [ b ] : [], d = 0 ; a . extend ( this ,{ get : function (){ return c }, rotate : function (){ return c . filter ( Boolean ) . length ? 1 === c . length ? c [ 0 ] : ( d === c . length - 1 ? d = 0 :++ d , c [ d ] ? c [ d ] : this . rotate ()) : void 0 }, length : function (){ return c . length }, remove : function ( a ){ delete c [ a ]}, set : function ( a ){ for ( var b = c . length ; b -- ;) if ( c [ b ] === a ) return void ( d = b ); this . append ( a )}, front : function (){ if ( c . length ){ for ( var a = d , b =! 1 ; ! c [ a ];) if ( a ++ , a > c . length ){ if ( b ) break ; a = 0 , b =! 0 } return c [ a ]}}, append : function ( a ){ c . push ( a )}})} function k ( b ){ var c = b instanceof Array ? b : b ? [ b ] : []; a . extend ( this ,{ data : function (){ return c }, map : function ( b ){ return a . map ( c , b )}, size : function (){ return c . length }, pop : function (){ if ( 0 === c . length ) return null ; var a = c [ c . length - 1 ]; return c = c . slice ( 0 , c . length - 1 ), a }, push : function ( a ){ return c = c . concat ([ a ]), a }, top : function (){ return c . length > 0 ? c [ c . length - 1 ] : null }, clone : function (){ return new k ( c . slice ( 0 ))}})} function l ( b , c ){ var d =! 0 , e = " " ; " string " == typeof b && " " !== b && ( e = b + " _ " ), e += " commands " ; var f = a . Storage . get ( e ); f = f ? a . parseJSON ( f ) : []; var g = f . length - 1 ; a . extend ( this ,{ append : function ( b ){ d && f [ f . length - 1 ] !== b && ( f . push ( b ), c && f . length > c && ( f = f . slice ( - c )), g = f . length - 1 , a . Storage . set ( e , a . json_stringify ( f )))}, data : function (){ return f }, reset : function (){ g = f . length - 1 }, last : function (){ return f [ f . length - 1 ]}, end : function (){ return g === f . length - 1 }, position : function (){ return g }, current : function (){ return f [ g ]}, next : function (){ return g < f . length - 1 &&++ g , - 1 !== g ? f [ g ] : void 0 }, previous : function (){ var a = g ; return g > 0 &&-- g , - 1 !== a ? f [ g ] : void 0 }, clear : function (){ f = [], this . purge ()}, enabled : function (){ return d }, enable : function (){ d =! 0 }, purge : function (){ a . Storage . remove ( e )}, disable : function (){ d =! 1 }})} function m ( b ){ return a ( " <div> " + a . terminal . strip ( b ) + " </div> " ) . text () . length } function n ( b , c ){ var d = c ( b ); if ( d . length ){ var e = d . shift (), f = new RegExp ( " ^ " + a . terminal . escape_regex ( e )), g = b . replace ( f , " " ) . trim (); return { command : b , name : e , args : d , rest : g }} return { command : b , name : " " , args : [], rest : " " }} function o (){ var b = a ( '<div class="terminal temp"><div class="cmd"><span class="cursor"> </span></div></div>' ) . appendTo ( " body " ), c = b . find ( " span " ), d = { width : c . width (), height : c . outerHeight ()}; return b . remove (), d } function p ( b ){ var c = a ( '<div class="terminal wrap"><span class="cursor"> </span></div>' ) . appendTo ( " body " ) . css ( " padding " , 0 ), d = c . find ( " span " ), e = d [ 0 ] . getBoundingClientRect () . width , f = Math . floor ( b . width () / e ); if ( c . remove (), s ( b )){ var g = 20 , h = b . innerWidth () - b . width (); f -= Math . ceil (( g - h / 2 ) / ( e - 1 ))} return f } function q ( a ){ return Math . floor ( a . height () / o () . height )} function r (){ if ( window . getSelection || document . getSelection ){ var a = ( window . getSelection || document . getSelection )(); return a . text ? a . text : a . toString ()} return document . selection ? document
var g = b . token (); g ? d ( a . name ,[ g ] . concat ( a . args )) : b . error ( " [AUTH] " + ya . noTokenError )} else d ( a . name , a . args )}}} function j ( c , d , f , g ){ return function ( h , i ){ if ( " " !== h ){ var k ; try { k = e ( h )} catch ( l ){ return void ha . error ( l . toString ())} var m = c [ k . name ], n = a . type ( m ); if ( " function " === n ){ if ( ! d || m . length === k . args . length ) return m . apply ( ha , k . args ); ha . error ( " [Arity] " + sprintf ( ya . wrongArity , k . name , m . length , k . args . length ))} else if ( " object " === n || " string " === n ){ var o = []; " object " === n && ( o = Object . keys ( m ), m = j ( m , d , f )), i . push ( m ,{ prompt : k . name + " > " , name : k . name , completion : " object " === n ? o : b })} else a . isFunction ( g ) ? g ( h , ha ) : a . isFunction ( xa . onCommandNotFound ) ? xa . onCommandNotFound ( h , ha ) : i . error ( sprintf ( ya . commandNotFound , k . name ))}}} function l ( b , c , d ){ ha . resume (), a . isFunction ( xa . onAjaxError ) ? xa . onAjaxError . call ( ha , b , c , d ) : " abort " !== c && ha . error ( " [AJAX] " + c + " - " + ya . serverResponse + " : \n " + a . terminal . escape_brackets ( b . responseText ))} function m ( b , c , d ){ a . jrpc ( b , " system.describe " ,[], function ( e ){ if ( e . procs ){ var g = {}; a . each ( e . procs , function ( d , e ){ g [ e . name ] = function (){ var d = c && " help " != e . name , g = Array . prototype . slice . call ( arguments ), i = g . length + ( d ? 1 : 0 ); if ( xa . checkArity && e . params && e . params . length !== i ) ha . error ( " [Arity] " + sprintf ( ya . wrongArity , e . name , e . params . length , i )); else { if ( ha . pause (), d ){ var j = ha . token ( ! 0 ); j ? g = [ j ] . concat ( g ) : ha . error ( " [AUTH] " + ya . noTokenError )} a . jrpc ( b , e . name , g , function ( b ){ b . error ? h ( b . error ) : a . isFunction ( xa . processRPCResponse ) ? xa . processRPCResponse . call ( ha , b . result , ha ) : f ( b . result ), ha . resume ()}, l )}}}), g . help = g . help || function ( b ){ if ( " undefined " == typeof b ) ha . echo ( " Available commands: " + e . procs . map ( function ( a ){ return a . name }) . join ( " , " ) + " , help " ); else { var c =! 1 ; if ( a . each ( e . procs , function ( a , d ){ if ( d . name == b ){ c =! 0 ; var e = " " ; return e += " [[bu;#fff;] " + d . name + " ] " , d . params && ( e += " " + d . params . join ( " " )), d . help && ( e += " \n " + d . help ), ha . echo ( e ), ! 1 }}), ! c ) if ( " help " == b ) ha . echo ( " [[bu;#fff;]help] [method] \n display help for the method or list of methods if not specified " ); else { var d = " Method ` " + b . toString () + " ' not found " ; ha . error ( d )}}}, d ( g )} else d ( null )}, function (){ d ( null )})} function o ( b , c , d ){ d = d || a . noop ; var e , f , g = a . type ( b ), h = {}, k = 0 ; if ( " array " === g ) e = {}, function l ( b , d ){ if ( b . length ){ var g = b [ 0 ], h = b . slice ( 1 ), j = a . type ( g ); " string " === j ? ( k ++ , ha . pause (), xa . ignoreSystemDescribe ? ( 1 === k ? f = i ( g , c ) : ha . error ( ya . oneRPCWithIgnore ), l ( h , d )) : m ( g , c , function ( b ){ b && a . extend ( e , b ), ha . resume (), l ( h , d )})) : " function " === j ? ( f ? ha . error ( ya . oneInterpreterFunction ) : f = g , l ( h , d )) : " object " === j && ( a . extend ( e , g ), l ( h , d ))} else d ()}( b , function (){ d ({ interpreter : j ( e , ! 1 , c , f ), completion : Object . keys ( e )})}); else if ( " string " === g ) xa . ignoreSystemDescribe ? ( e = { interpreter : i ( b , c )}, a . isArray ( xa . completion ) && ( e . completion = xa . completion ), d ( e )) : ( ha . pause (), m ( b , c , function ( a ){ a ? ( h . interpreter = j ( a , ! 1 , c ), h . completion = Object . keys ( a )) : h . interpreter = i ( b , c ), d ( h ), ha . resume ()})); else if ( " object " === g ) d ({ interpreter : j ( b , xa . checkArity ), completion : Object . keys ( b )}); else { if ( " undefined " === g ) b = a . noop ; else if ( " function " !== g ) throw g + " is invalid interpreter value " ; d ({ interpreter : b , completion : xa . completion })}} function t ( b , c ){ var d = " boolean " === a . type ( c ) ? " login " : c ; return function ( c , e , f , g ){ ha . pause (), a . jrpc ( b , d ,[ c , e ], function ( a ){ f ( ! a . error && a . result ? a . result : null ), ha . resume ()}, l )}} function v ( a ){ return " string " == typeof a ? a : " string " == typeof a . fileName ? a . fileName + " : " + a . message : a . message } function w ( b , c ){ a . isFunction ( xa . exceptionHandler ) ? xa . exceptionHandler . call ( ha , b ) : ha . exception ( b , c )} function x (){ var a ; a = ia . prop ? ia . prop ( " scrollHeight " ) : ia . attr ( " scrollHeight " ), ia . scrollTop ( a )} function y ( b , c ){ try { if ( a . isFunction ( c )) c ( function (){}); else if ( " string " != typeof c ){ var d = b + " must be string or function " ; throw d }} catch ( e ){ return w ( e , b . toUpperCase ()), ! 1 } return ! 0 } function z ( b , c ){ xa . convertLinks && ( b = b . replace ( K , " [[!;;] $ 1] " ) . replace ( J , " [[!;;] $ 1] " )); var d , e , f = a . terminal . defaults . formatters ; if ( ! c . raw ){ for ( d = 0 ; d < f . length ; ++ d ) try { if ( " function " == typeof f [ d ]){ var g = f [ d ]( b ); " string " == typeof g && ( b = g )}} catch ( h ){ alert ( " formatting error at formatters[ " + d + " ] \n " + ( h . stack ? h . stack : h ))} b = a . terminal . encode ( b )} if ( da . push ( ea ), ! c . raw && ( b . l
2017-10-14 04:55:42 +00:00
</ head >
< body ></ body >
</ html >
< ? php } ?>