Add a better console page
This commit is contained in:
parent
120a6a5f6e
commit
a787e99f88
9 changed files with 1246 additions and 86 deletions
|
@ -12,7 +12,8 @@ Requires `Daemon@0.2.0`
|
|||
* Adds support for suspending servers
|
||||
* Adds support for viewing SFTP password within the panel ([#74](https://github.com/Pterodactyl/Panel/issues/74), thanks [@ET-Bent](https://github.com/ET-Bent))
|
||||
* Improved API with support for server suspension and build modification.
|
||||
* Improved service managment and setup on first install.
|
||||
* Improved service management and setup on first install.
|
||||
* New terminal that supports ANSI color codes as well as cleaner output. You can also simply type `start` or `boot` to start your server rather than having to use the start button.
|
||||
|
||||
### Bug Fixes
|
||||
* Fixes password auto-generation on 'Manage Server' page. ([#67](https://github.com/Pterodactyl/Panel/issues/67), thanks [@ET-Bent](https://github.com/ET-Bent))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Pterodactyl is the free game server management panel designed by users, for users. Featuring support for Vanilla Minecraft, Spigot, Source Dedicated Servers, BungeeCord, and many more. Pterodactyl is built on the `Laravel PHP Framework (v5.2)`.
|
||||
|
||||
## Support & Documentation
|
||||
Support for using Pterodactyl can be found on our [community forums](https://community.pterodactyl.io) or on our [Discord chat](https://discord.gg/0gYt8oU8QOkDhKLS).
|
||||
Support for using Pterodactyl can be found on our [wiki](https://github.com/Pterodactyl/Panel/wiki) or on our [Discord chat](https://discord.gg/0gYt8oU8QOkDhKLS).
|
||||
|
||||
## License
|
||||
```
|
||||
|
@ -46,6 +46,8 @@ FuelUX - [license](https://github.com/ExactTarget/fuelux/blob/master/LICENSE) -
|
|||
|
||||
jQuery - [license](https://github.com/jquery/jquery/blob/master/LICENSE.txt) - [homepage](http://jquery.com)
|
||||
|
||||
jQuery Terminal - [license](https://github.com/jcubic/jquery.terminal/blob/master/LICENSE) - [homepage](http://terminal.jcubic.pl)
|
||||
|
||||
MetricsGraphics.js - [license](https://github.com/mozilla/metrics-graphics/blob/master/LICENSE) - [homepage](http://metricsgraphicsjs.org/)
|
||||
|
||||
Socket.io - [license](https://github.com/socketio/socket.io/blob/master/LICENSE) - [homepage](http://socket.io)
|
||||
|
|
253
public/css/jquery.terminal.css
Executable file
253
public/css/jquery.terminal.css
Executable file
|
@ -0,0 +1,253 @@
|
|||
/*!
|
||||
* __ _____ ________ __
|
||||
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
|
||||
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
|
||||
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
|
||||
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
|
||||
* \/ /____/ version 0.11.6
|
||||
* http://terminal.jcubic.pl
|
||||
*
|
||||
* This file is part of jQuery Terminal.
|
||||
*
|
||||
* Copyright (c) 2011-2016 Jakub Jankiewicz <http://jcubic.pl>
|
||||
* Released under the MIT license
|
||||
*
|
||||
* Date: Thu, 15 Sep 2016 20:19:20 +0000
|
||||
*/
|
||||
.terminal .terminal-output .format, .cmd .format,
|
||||
.cmd .prompt, .cmd .prompt div, .terminal .terminal-output div div{
|
||||
display: inline-block;
|
||||
}
|
||||
.terminal h1, .terminal h2, .terminal h3, .terminal h4, .terminal h5, .terminal h6, .terminal pre, .cmd {
|
||||
margin: 0;
|
||||
}
|
||||
.terminal h1, .terminal h2, .terminal h3, .terminal h4, .terminal h5, .terminal h6 {
|
||||
line-height: 1.2em;
|
||||
}
|
||||
/*
|
||||
.cmd .mask {
|
||||
width: 10px;
|
||||
height: 11px;
|
||||
background: black;
|
||||
z-index: 100;
|
||||
}
|
||||
*/
|
||||
.cmd .clipboard {
|
||||
position: absolute;
|
||||
left: -16px;
|
||||
top: 0;
|
||||
width: 10px;
|
||||
height: 16px;
|
||||
/* this seems to work after all on Android */
|
||||
/*left: -99999px;
|
||||
clip: rect(1px,1px,1px,1px);
|
||||
/* on desktop textarea appear when paste */
|
||||
/*
|
||||
opacity: 0.01;
|
||||
filter: alpha(opacity = 0.01);
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.01);
|
||||
*/
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: transparent;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
resize: none;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.terminal .error {
|
||||
color: #f00;
|
||||
}
|
||||
.terminal {
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
/*overflow: hidden;*/
|
||||
overflow: auto;
|
||||
}
|
||||
.cmd {
|
||||
padding: 0;
|
||||
height: 1.3em;
|
||||
position: relative;
|
||||
/*margin-top: 3px; */
|
||||
}
|
||||
.terminal .inverted, .cmd .inverted, .cmd .cursor.blink {
|
||||
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; /* not #aaa because it's seems there is Google Chrome bug */
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.terminal .terminal-output div div, .cmd .prompt {
|
||||
display: block;
|
||||
line-height: 14px;
|
||||
height: auto;
|
||||
}
|
||||
.cmd .prompt {
|
||||
float: left;
|
||||
}
|
||||
.terminal, .cmd {
|
||||
font-family: monospace;
|
||||
/*font-family: FreeMono, monospace; this don't work on Android */
|
||||
color: #aaa;
|
||||
background-color: #000;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
}
|
||||
.terminal-output > div {
|
||||
/*padding-top: 3px;*/
|
||||
min-height: 14px;
|
||||
}
|
||||
.terminal-output > div > div * {
|
||||
word-wrap: break-word; /* when echo html */
|
||||
}
|
||||
.terminal .terminal-output div span {
|
||||
display: inline-block;
|
||||
}
|
||||
.cmd span {
|
||||
float: left;
|
||||
/*display: inline-block; */
|
||||
}
|
||||
/* fix double style of selecting text in terminal */
|
||||
.terminal-output span, .terminal-output a, .cmd div, .cmd span, .terminal td,
|
||||
.terminal pre, .terminal h1, .terminal h2, .terminal h3, .terminal h4,
|
||||
.terminal h5, .terminal h6 {
|
||||
-webkit-touch-callout: initial;
|
||||
-webkit-user-select: initial;
|
||||
-khtml-user-select: initial;
|
||||
-moz-user-select: initial;
|
||||
-ms-user-select: initial;
|
||||
user-select: initial;
|
||||
}
|
||||
.terminal, .terminal-output, .terminal-output div {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
/* firefox hack */
|
||||
@-moz-document url-prefix() {
|
||||
.terminal, .terminal-output, .terminal-output div {
|
||||
-webkit-touch-callout: initial;
|
||||
-webkit-user-select: initial;
|
||||
-khtml-user-select: initial;
|
||||
-moz-user-select: initial;
|
||||
-ms-user-select: initial;
|
||||
user-select: initial;
|
||||
}
|
||||
}
|
||||
.terminal table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.terminal td {
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
.terminal h1::-moz-selection,
|
||||
.terminal h2::-moz-selection,
|
||||
.terminal h3::-moz-selection,
|
||||
.terminal h4::-moz-selection,
|
||||
.terminal h5::-moz-selection,
|
||||
.terminal h6::-moz-selection,
|
||||
.terminal pre::-moz-selection,
|
||||
.terminal td::-moz-selection,
|
||||
.terminal .terminal-output div div::-moz-selection,
|
||||
.terminal .terminal-output div span::-moz-selection,
|
||||
.terminal .terminal-output div div a::-moz-selection,
|
||||
.cmd div::-moz-selection,
|
||||
.cmd > span::-moz-selection,
|
||||
.cmd .prompt span::-moz-selection {
|
||||
background-color: #aaa;
|
||||
color: #000;
|
||||
}
|
||||
/* this don't work in Chrome
|
||||
.terminal tr td::-moz-selection {
|
||||
border-color: #000;
|
||||
}
|
||||
.terminal tr td::selection {
|
||||
border-color: #000;
|
||||
}
|
||||
*/
|
||||
.terminal h1::selection,
|
||||
.terminal h2::selection,
|
||||
.terminal h3::selection,
|
||||
.terminal h4::selection,
|
||||
.terminal h5::selection,
|
||||
.terminal h6::selection,
|
||||
.terminal pre::selection,
|
||||
.terminal td::selection,
|
||||
.terminal .terminal-output div div::selection,
|
||||
.terminal .terminal-output div div a::selection,
|
||||
.terminal .terminal-output div span::selection,
|
||||
.cmd div::selection,
|
||||
.cmd > span::selection,
|
||||
.cmd .prompt span::selection {
|
||||
background-color: #aaa;
|
||||
color: #000;
|
||||
}
|
||||
.terminal .terminal-output div.error, .terminal .terminal-output div.error div {
|
||||
color: red;
|
||||
}
|
||||
.tilda {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 1100;
|
||||
}
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
.terminal a {
|
||||
color: #0F60FF;
|
||||
}
|
||||
.terminal a:hover {
|
||||
color: red;
|
||||
}
|
2
public/js/jquery.mousewheel-min.js
vendored
Executable file
2
public/js/jquery.mousewheel-min.js
vendored
Executable file
|
@ -0,0 +1,2 @@
|
|||
(function(c){function g(a){var b=a||window.event,i=[].slice.call(arguments,1),e=0,h=0,f=0;a=c.event.fix(b);a.type="mousewheel";if(b.wheelDelta)e=b.wheelDelta/120;if(b.detail)e=-b.detail/3;f=e;if(b.axis!==undefined&&b.axis===b.HORIZONTAL_AXIS){f=0;h=-1*e}if(b.wheelDeltaY!==undefined)f=b.wheelDeltaY/120;if(b.wheelDeltaX!==undefined)h=-1*b.wheelDeltaX/120;i.unshift(a,e,h,f);return(c.event.dispatch||c.event.handle).apply(this,i)}var d=["DOMMouseScroll","mousewheel"];if(c.event.fixHooks)for(var j=d.length;j;)c.event.fixHooks[d[--j]]=
|
||||
c.event.mouseHooks;c.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=d.length;a;)this.addEventListener(d[--a],g,false);else this.onmousewheel=g},teardown:function(){if(this.removeEventListener)for(var a=d.length;a;)this.removeEventListener(d[--a],g,false);else this.onmousewheel=null}};c.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
|
37
public/js/jquery.terminal-0.11.6.min.js
vendored
Executable file
37
public/js/jquery.terminal-0.11.6.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
317
public/js/unix_formatting.js
Executable file
317
public/js/unix_formatting.js
Executable file
|
@ -0,0 +1,317 @@
|
|||
/**@license
|
||||
* __ _____ ________ __
|
||||
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
|
||||
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
|
||||
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
|
||||
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
|
||||
* \/ /____/
|
||||
* http://terminal.jcubic.pl
|
||||
*
|
||||
* This is example of how to create custom formatter for jQuery Terminal
|
||||
*
|
||||
* Copyright (c) 2014-2016 Jakub Jankiewicz <http://jcubic.pl>
|
||||
* Released under the MIT license
|
||||
*
|
||||
*/
|
||||
(function($) {
|
||||
if (!$.terminal) {
|
||||
throw new Error('$.terminal is not defined');
|
||||
}
|
||||
// ---------------------------------------------------------------------
|
||||
// :: Replace overtyping (from man) formatting with terminal formatting
|
||||
// ---------------------------------------------------------------------
|
||||
$.terminal.overtyping = function(string) {
|
||||
return string.replace(/((?:_\x08.|.\x08_)+)/g, function(full, g) {
|
||||
var striped = full.replace(/_x08|\x08_|_\u0008|\u0008_/g, '');
|
||||
return '[[u;;]' + striped + ']';
|
||||
}).replace(/((?:.\x08.)+)/g, function(full, g) {
|
||||
return '[[b;#fff;]' + full.replace(/(.)(?:\x08|\u0008)\1/g,
|
||||
function(full, g) {
|
||||
return g;
|
||||
}) + ']';
|
||||
});
|
||||
};
|
||||
// ---------------------------------------------------------------------
|
||||
// :: Html colors taken from ANSI formatting in Linux Terminal
|
||||
// ---------------------------------------------------------------------
|
||||
$.terminal.ansi_colors = {
|
||||
normal: {
|
||||
black: '#000',
|
||||
red: '#A00',
|
||||
green: '#008400',
|
||||
yellow: '#A50',
|
||||
blue: '#00A',
|
||||
magenta: '#A0A',
|
||||
cyan: '#0AA',
|
||||
white: '#AAA'
|
||||
},
|
||||
faited: {
|
||||
black: '#000',
|
||||
red: '#640000',
|
||||
green: '#006100',
|
||||
yellow: '#737300',
|
||||
blue: '#000087',
|
||||
magenta: '#650065',
|
||||
cyan: '#008787',
|
||||
white: '#818181'
|
||||
},
|
||||
bold: {
|
||||
black: '#000',
|
||||
red: '#F55',
|
||||
green: '#44D544',
|
||||
yellow: '#FF5',
|
||||
blue: '#55F',
|
||||
magenta: '#F5F',
|
||||
cyan: '#5FF',
|
||||
white: '#FFF'
|
||||
},
|
||||
// XTerm 8-bit pallete
|
||||
palette: [
|
||||
'#000000', '#AA0000', '#00AA00', '#AA5500', '#0000AA', '#AA00AA',
|
||||
'#00AAAA', '#AAAAAA', '#555555', '#FF5555', '#55FF55', '#FFFF55',
|
||||
'#5555FF', '#FF55FF', '#55FFFF', '#FFFFFF', '#000000', '#00005F',
|
||||
'#000087', '#0000AF', '#0000D7', '#0000FF', '#005F00', '#005F5F',
|
||||
'#005F87', '#005FAF', '#005FD7', '#005FFF', '#008700', '#00875F',
|
||||
'#008787', '#0087AF', '#0087D7', '#0087FF', '#00AF00', '#00AF5F',
|
||||
'#00AF87', '#00AFAF', '#00AFD7', '#00AFFF', '#00D700', '#00D75F',
|
||||
'#00D787', '#00D7AF', '#00D7D7', '#00D7FF', '#00FF00', '#00FF5F',
|
||||
'#00FF87', '#00FFAF', '#00FFD7', '#00FFFF', '#5F0000', '#5F005F',
|
||||
'#5F0087', '#5F00AF', '#5F00D7', '#5F00FF', '#5F5F00', '#5F5F5F',
|
||||
'#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF', '#5F8700', '#5F875F',
|
||||
'#5F8787', '#5F87AF', '#5F87D7', '#5F87FF', '#5FAF00', '#5FAF5F',
|
||||
'#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF', '#5FD700', '#5FD75F',
|
||||
'#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF', '#5FFF00', '#5FFF5F',
|
||||
'#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF', '#870000', '#87005F',
|
||||
'#870087', '#8700AF', '#8700D7', '#8700FF', '#875F00', '#875F5F',
|
||||
'#875F87', '#875FAF', '#875FD7', '#875FFF', '#878700', '#87875F',
|
||||
'#878787', '#8787AF', '#8787D7', '#8787FF', '#87AF00', '#87AF5F',
|
||||
'#87AF87', '#87AFAF', '#87AFD7', '#87AFFF', '#87D700', '#87D75F',
|
||||
'#87D787', '#87D7AF', '#87D7D7', '#87D7FF', '#87FF00', '#87FF5F',
|
||||
'#87FF87', '#87FFAF', '#87FFD7', '#87FFFF', '#AF0000', '#AF005F',
|
||||
'#AF0087', '#AF00AF', '#AF00D7', '#AF00FF', '#AF5F00', '#AF5F5F',
|
||||
'#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF', '#AF8700', '#AF875F',
|
||||
'#AF8787', '#AF87AF', '#AF87D7', '#AF87FF', '#AFAF00', '#AFAF5F',
|
||||
'#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF', '#AFD700', '#AFD75F',
|
||||
'#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF', '#AFFF00', '#AFFF5F',
|
||||
'#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF', '#D70000', '#D7005F',
|
||||
'#D70087', '#D700AF', '#D700D7', '#D700FF', '#D75F00', '#D75F5F',
|
||||
'#D75F87', '#D75FAF', '#D75FD7', '#D75FFF', '#D78700', '#D7875F',
|
||||
'#D78787', '#D787AF', '#D787D7', '#D787FF', '#D7AF00', '#D7AF5F',
|
||||
'#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF', '#D7D700', '#D7D75F',
|
||||
'#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF', '#D7FF00', '#D7FF5F',
|
||||
'#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF', '#FF0000', '#FF005F',
|
||||
'#FF0087', '#FF00AF', '#FF00D7', '#FF00FF', '#FF5F00', '#FF5F5F',
|
||||
'#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF', '#FF8700', '#FF875F',
|
||||
'#FF8787', '#FF87AF', '#FF87D7', '#FF87FF', '#FFAF00', '#FFAF5F',
|
||||
'#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF', '#FFD700', '#FFD75F',
|
||||
'#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF', '#FFFF00', '#FFFF5F',
|
||||
'#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF', '#080808', '#121212',
|
||||
'#1C1C1C', '#262626', '#303030', '#3A3A3A', '#444444', '#4E4E4E',
|
||||
'#585858', '#626262', '#6C6C6C', '#767676', '#808080', '#8A8A8A',
|
||||
'#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', '#BCBCBC', '#C6C6C6',
|
||||
'#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
|
||||
]
|
||||
};
|
||||
// ---------------------------------------------------------------------
|
||||
// :: Replace ANSI formatting with terminal formatting
|
||||
// ---------------------------------------------------------------------
|
||||
$.terminal.from_ansi = (function() {
|
||||
var color_list = {
|
||||
30: 'black',
|
||||
31: 'red',
|
||||
32: 'green',
|
||||
33: 'yellow',
|
||||
34: 'blue',
|
||||
35: 'magenta',
|
||||
36: 'cyan',
|
||||
37: 'white',
|
||||
|
||||
39: 'inherit' // default color
|
||||
};
|
||||
var background_list = {
|
||||
40: 'black',
|
||||
41: 'red',
|
||||
42: 'green',
|
||||
43: 'yellow',
|
||||
44: 'blue',
|
||||
45: 'magenta',
|
||||
46: 'cyan',
|
||||
47: 'white',
|
||||
|
||||
49: 'transparent' // default background
|
||||
};
|
||||
function format_ansi(code) {
|
||||
var controls = code.split(';');
|
||||
var num;
|
||||
var faited = false;
|
||||
var reverse = false;
|
||||
var bold = false;
|
||||
var styles = [];
|
||||
var output_color = '';
|
||||
var output_background = '';
|
||||
var _8bit_color = false;
|
||||
var _8bit_background = false;
|
||||
var process_8bit = false;
|
||||
var palette = $.terminal.ansi_colors.palette;
|
||||
for(var i in controls) {
|
||||
if (controls.hasOwnProperty(i)) {
|
||||
num = parseInt(controls[i], 10);
|
||||
if (process_8bit && (_8bit_background || _8bit_color)) {
|
||||
if (_8bit_color && palette[num]) {
|
||||
output_color = palette[num];
|
||||
}
|
||||
if (_8bit_background && palette[num]) {
|
||||
output_background = palette[num];
|
||||
}
|
||||
} else {
|
||||
switch(num) {
|
||||
case 1:
|
||||
styles.push('b');
|
||||
bold = true;
|
||||
faited = false;
|
||||
break;
|
||||
case 4:
|
||||
styles.push('u');
|
||||
break;
|
||||
case 3:
|
||||
styles.push('i');
|
||||
break;
|
||||
case 5:
|
||||
process_8bit = true;
|
||||
break;
|
||||
case 38:
|
||||
_8bit_color = true;
|
||||
break;
|
||||
case 48:
|
||||
_8bit_background = true;
|
||||
break;
|
||||
case 2:
|
||||
faited = true;
|
||||
bold = false;
|
||||
break;
|
||||
case 7:
|
||||
reverse = true;
|
||||
break;
|
||||
default:
|
||||
if (controls.indexOf('5') == -1) {
|
||||
if (color_list[num]) {
|
||||
output_color = color_list[num];
|
||||
}
|
||||
if (background_list[num]) {
|
||||
output_background = background_list[num];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reverse) {
|
||||
if (output_color || output_background) {
|
||||
var tmp = output_background;
|
||||
output_background = output_color;
|
||||
output_color = tmp;
|
||||
} else {
|
||||
output_color = 'black';
|
||||
output_background = 'white';
|
||||
}
|
||||
}
|
||||
var colors, color, background, backgrounds;
|
||||
if (bold) {
|
||||
colors = backgrounds = $.terminal.ansi_colors.bold;
|
||||
} else if (faited) {
|
||||
colors = backgrounds = $.terminal.ansi_colors.faited;
|
||||
} else {
|
||||
colors = backgrounds = $.terminal.ansi_colors.normal;
|
||||
}
|
||||
if (_8bit_color) {
|
||||
color = output_color;
|
||||
} else if (output_color == 'inherit') {
|
||||
color = output_color;
|
||||
} else {
|
||||
color = colors[output_color];
|
||||
}
|
||||
if (_8bit_background) {
|
||||
background = output_background;
|
||||
} else if (output_background == 'transparent') {
|
||||
background = output_background;
|
||||
} else {
|
||||
background = backgrounds[output_background];
|
||||
}
|
||||
return [styles.join(''), color, background];
|
||||
}
|
||||
return function(input) {
|
||||
//merge multiple codes
|
||||
/*input = input.replace(/((?:\x1B\[[0-9;]*[A-Za-z])*)/g, function(group) {
|
||||
return group.replace(/m\x1B\[/g, ';');
|
||||
});*/
|
||||
var splitted = input.split(/(\x1B\[[0-9;]*[A-Za-z])/g);
|
||||
if (splitted.length == 1) {
|
||||
return input;
|
||||
}
|
||||
var output = [];
|
||||
//skip closing at the begining
|
||||
if (splitted.length > 3) {
|
||||
var str = splitted.slice(0,3).join('');
|
||||
if (str.match(/^\[0*m$/)) {
|
||||
splitted = splitted.slice(3);
|
||||
}
|
||||
}
|
||||
var next, prev_color, prev_background, code, match;
|
||||
var inside = false;
|
||||
for (var i=0; i<splitted.length; ++i) {
|
||||
match = splitted[i].match(/^\x1B\[([0-9;]*)([A-Za-z])$/);
|
||||
if (match) {
|
||||
switch (match[2]) {
|
||||
case 'm':
|
||||
if (+match[1] !== 0) {
|
||||
code = format_ansi(match[1]);
|
||||
}
|
||||
if (inside) {
|
||||
output.push(']');
|
||||
if (+match[1] === 0) {
|
||||
//just closing
|
||||
inside = false;
|
||||
prev_color = prev_background = '';
|
||||
} else {
|
||||
// someone forget to close - move to next
|
||||
code[1] = code[1] || prev_color;
|
||||
code[2] = code[2] || prev_background;
|
||||
output.push('[[' + code.join(';') + ']');
|
||||
// store colors to next use
|
||||
if (code[1]) {
|
||||
prev_color = code[1];
|
||||
}
|
||||
if (code[2]) {
|
||||
prev_background = code[2];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (+match[1] !== 0) {
|
||||
inside = true;
|
||||
code[1] = code[1] || prev_color;
|
||||
code[2] = code[2] || prev_background;
|
||||
output.push('[[' + code.join(';') + ']');
|
||||
// store colors to next use
|
||||
if (code[1]) {
|
||||
prev_color = code[1];
|
||||
}
|
||||
if (code[2]) {
|
||||
prev_background = code[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
output.push(splitted[i]);
|
||||
}
|
||||
}
|
||||
if (inside) {
|
||||
output.push(']');
|
||||
}
|
||||
return output.join(''); //.replace(/\[\[[^\]]+\]\]/g, '');
|
||||
};
|
||||
})();
|
||||
$.terminal.defaults.formatters.push($.terminal.overtyping);
|
||||
$.terminal.defaults.formatters.push($.terminal.from_ansi);
|
||||
})(jQuery);
|
252
public/themes/default/css/jquery.terminal.css
Normal file
252
public/themes/default/css/jquery.terminal.css
Normal file
|
@ -0,0 +1,252 @@
|
|||
/*!
|
||||
* __ _____ ________ __
|
||||
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
|
||||
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
|
||||
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
|
||||
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
|
||||
* \/ /____/ version 0.11.6
|
||||
* http://terminal.jcubic.pl
|
||||
*
|
||||
* This file is part of jQuery Terminal.
|
||||
*
|
||||
* Copyright (c) 2011-2016 Jakub Jankiewicz <http://jcubic.pl>
|
||||
* Released under the MIT license
|
||||
*
|
||||
* Date: Thu, 15 Sep 2016 20:19:20 +0000
|
||||
*/
|
||||
.terminal .terminal-output .format, .cmd .format,
|
||||
.cmd .prompt, .cmd .prompt div, .terminal .terminal-output div div{
|
||||
display: inline-block;
|
||||
}
|
||||
.terminal h1, .terminal h2, .terminal h3, .terminal h4, .terminal h5, .terminal h6, .terminal pre, .cmd {
|
||||
margin: 0;
|
||||
}
|
||||
.terminal h1, .terminal h2, .terminal h3, .terminal h4, .terminal h5, .terminal h6 {
|
||||
line-height: 1.2em;
|
||||
}
|
||||
/*
|
||||
.cmd .mask {
|
||||
width: 10px;
|
||||
height: 11px;
|
||||
background: black;
|
||||
z-index: 100;
|
||||
}
|
||||
*/
|
||||
.cmd .clipboard {
|
||||
position: absolute;
|
||||
left: -16px;
|
||||
top: 0;
|
||||
width: 10px;
|
||||
height: 16px;
|
||||
/* this seems to work after all on Android */
|
||||
/*left: -99999px;
|
||||
clip: rect(1px,1px,1px,1px);
|
||||
/* on desktop textarea appear when paste */
|
||||
/*
|
||||
opacity: 0.01;
|
||||
filter: alpha(opacity = 0.01);
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.01);
|
||||
*/
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: transparent;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
resize: none;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.terminal .error {
|
||||
color: #f00;
|
||||
}
|
||||
.terminal {
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
/*overflow: hidden;*/
|
||||
overflow: auto;
|
||||
}
|
||||
.cmd {
|
||||
padding: 0;
|
||||
height: 1.3em;
|
||||
position: relative;
|
||||
/*margin-top: 3px; */
|
||||
}
|
||||
|
||||
.terminal .inverted, .cmd .inverted, .cmd .cursor.blink {
|
||||
background-color: #f0f0f0;
|
||||
color: #e8e8e6;
|
||||
}
|
||||
.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: #f0f0f0;
|
||||
color: #e8e8e6;
|
||||
}
|
||||
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: #f0f0f0;
|
||||
color: #e8e8e6;
|
||||
}
|
||||
50% {
|
||||
background-color: #bbb; /* not #aaa because it's seems there is Google Chrome bug */
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.terminal .terminal-output div div, .cmd .prompt {
|
||||
display: block;
|
||||
line-height: 14px;
|
||||
height: auto;
|
||||
}
|
||||
.cmd .prompt {
|
||||
float: left;
|
||||
}
|
||||
.terminal, .cmd {
|
||||
font-family: monospace;
|
||||
/*font-family: FreeMono, monospace; this don't work on Android */
|
||||
border-radius: 4px;
|
||||
color: #f0f0f0 !important;
|
||||
background-color: #2e2e2d !important;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
}
|
||||
.terminal-output > div {
|
||||
/*padding-top: 3px;*/
|
||||
min-height: 14px;
|
||||
}
|
||||
.terminal-output > div > div * {
|
||||
word-wrap: break-word; /* when echo html */
|
||||
}
|
||||
.terminal .terminal-output div span {
|
||||
display: inline-block;
|
||||
}
|
||||
.cmd span {
|
||||
float: left;
|
||||
/*display: inline-block; */
|
||||
}
|
||||
/* fix double style of selecting text in terminal */
|
||||
.terminal-output span, .terminal-output a, .cmd div, .cmd span, .terminal td,
|
||||
.terminal pre, .terminal h1, .terminal h2, .terminal h3, .terminal h4,
|
||||
.terminal h5, .terminal h6 {
|
||||
-webkit-touch-callout: initial;
|
||||
-webkit-user-select: initial;
|
||||
-khtml-user-select: initial;
|
||||
-moz-user-select: initial;
|
||||
-ms-user-select: initial;
|
||||
user-select: initial;
|
||||
}
|
||||
.terminal, .terminal-output, .terminal-output div {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
/* firefox hack */
|
||||
@-moz-document url-prefix() {
|
||||
.terminal, .terminal-output, .terminal-output div {
|
||||
-webkit-touch-callout: initial;
|
||||
-webkit-user-select: initial;
|
||||
-khtml-user-select: initial;
|
||||
-moz-user-select: initial;
|
||||
-ms-user-select: initial;
|
||||
user-select: initial;
|
||||
}
|
||||
}
|
||||
.terminal table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.terminal td {
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
.terminal h1::-moz-selection,
|
||||
.terminal h2::-moz-selection,
|
||||
.terminal h3::-moz-selection,
|
||||
.terminal h4::-moz-selection,
|
||||
.terminal h5::-moz-selection,
|
||||
.terminal h6::-moz-selection,
|
||||
.terminal pre::-moz-selection,
|
||||
.terminal td::-moz-selection,
|
||||
.terminal .terminal-output div div::-moz-selection,
|
||||
.terminal .terminal-output div span::-moz-selection,
|
||||
.terminal .terminal-output div div a::-moz-selection,
|
||||
.cmd div::-moz-selection,
|
||||
.cmd > span::-moz-selection,
|
||||
.cmd .prompt span::-moz-selection {
|
||||
background-color: #f0f0f0;
|
||||
color: #2e2e2d;
|
||||
}
|
||||
|
||||
.terminal h1::selection,
|
||||
.terminal h2::selection,
|
||||
.terminal h3::selection,
|
||||
.terminal h4::selection,
|
||||
.terminal h5::selection,
|
||||
.terminal h6::selection,
|
||||
.terminal pre::selection,
|
||||
.terminal td::selection,
|
||||
.terminal .terminal-output div div::selection,
|
||||
.terminal .terminal-output div div a::selection,
|
||||
.terminal .terminal-output div span::selection,
|
||||
.cmd div::selection,
|
||||
.cmd > span::selection,
|
||||
.cmd .prompt span::selection {
|
||||
background-color: #f0f0f0;
|
||||
color: #2e2e2d;
|
||||
}
|
||||
|
||||
.terminal .terminal-output div.error, .terminal .terminal-output div.error div {
|
||||
color: rgb(227, 50, 0);
|
||||
}
|
||||
|
||||
.tilda {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 1100;
|
||||
}
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.terminal a {
|
||||
color: #6cb2cc;
|
||||
}
|
||||
|
||||
.terminal a:hover {
|
||||
color: #39bfb4;
|
||||
}
|
317
public/themes/default/js/unix_formatting.js
Normal file
317
public/themes/default/js/unix_formatting.js
Normal file
|
@ -0,0 +1,317 @@
|
|||
/**@license
|
||||
* __ _____ ________ __
|
||||
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
|
||||
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
|
||||
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
|
||||
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
|
||||
* \/ /____/
|
||||
* http://terminal.jcubic.pl
|
||||
*
|
||||
* This is example of how to create custom formatter for jQuery Terminal
|
||||
*
|
||||
* Copyright (c) 2014-2016 Jakub Jankiewicz <http://jcubic.pl>
|
||||
* Released under the MIT license
|
||||
*
|
||||
*/
|
||||
(function($) {
|
||||
if (!$.terminal) {
|
||||
throw new Error('$.terminal is not defined');
|
||||
}
|
||||
// ---------------------------------------------------------------------
|
||||
// :: Replace overtyping (from man) formatting with terminal formatting
|
||||
// ---------------------------------------------------------------------
|
||||
$.terminal.overtyping = function(string) {
|
||||
return string.replace(/((?:_\x08.|.\x08_)+)/g, function(full, g) {
|
||||
var striped = full.replace(/_x08|\x08_|_\u0008|\u0008_/g, '');
|
||||
return '[[u;;]' + striped + ']';
|
||||
}).replace(/((?:.\x08.)+)/g, function(full, g) {
|
||||
return '[[b;#fff;]' + full.replace(/(.)(?:\x08|\u0008)\1/g,
|
||||
function(full, g) {
|
||||
return g;
|
||||
}) + ']';
|
||||
});
|
||||
};
|
||||
// ---------------------------------------------------------------------
|
||||
// :: Html colors taken from ANSI formatting in Linux Terminal
|
||||
// ---------------------------------------------------------------------
|
||||
$.terminal.ansi_colors = {
|
||||
normal: {
|
||||
black: '#2b2b2b',
|
||||
red: '#c2292b',
|
||||
green: '#568a34',
|
||||
yellow: '#f5a536',
|
||||
blue: '#2469bd',
|
||||
magenta: '#692496',
|
||||
cyan: '#18838c',
|
||||
white: '#f0f0f0'
|
||||
},
|
||||
faited: {
|
||||
black: '#2b2b2b',
|
||||
red: '#c2292b',
|
||||
green: '#568a34',
|
||||
yellow: '#f5a536',
|
||||
blue: '#2469bd',
|
||||
magenta: '#692496',
|
||||
cyan: '#18838c',
|
||||
white: '#f0f0f0'
|
||||
},
|
||||
bold: {
|
||||
black: '#2b2b2b',
|
||||
red: '#c2292b',
|
||||
green: '#568a34',
|
||||
yellow: '#f5a536',
|
||||
blue: '#2469bd',
|
||||
magenta: '#692496',
|
||||
cyan: '#18838c',
|
||||
white: '#f0f0f0'
|
||||
},
|
||||
// XTerm 8-bit pallete
|
||||
palette: [
|
||||
'#000000', '#AA0000', '#00AA00', '#AA5500', '#0000AA', '#AA00AA',
|
||||
'#00AAAA', '#AAAAAA', '#555555', '#FF5555', '#55FF55', '#FFFF55',
|
||||
'#5555FF', '#FF55FF', '#55FFFF', '#FFFFFF', '#000000', '#00005F',
|
||||
'#000087', '#0000AF', '#0000D7', '#0000FF', '#005F00', '#005F5F',
|
||||
'#005F87', '#005FAF', '#005FD7', '#005FFF', '#008700', '#00875F',
|
||||
'#008787', '#0087AF', '#0087D7', '#0087FF', '#00AF00', '#00AF5F',
|
||||
'#00AF87', '#00AFAF', '#00AFD7', '#00AFFF', '#00D700', '#00D75F',
|
||||
'#00D787', '#00D7AF', '#00D7D7', '#00D7FF', '#00FF00', '#00FF5F',
|
||||
'#00FF87', '#00FFAF', '#00FFD7', '#00FFFF', '#5F0000', '#5F005F',
|
||||
'#5F0087', '#5F00AF', '#5F00D7', '#5F00FF', '#5F5F00', '#5F5F5F',
|
||||
'#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF', '#5F8700', '#5F875F',
|
||||
'#5F8787', '#5F87AF', '#5F87D7', '#5F87FF', '#5FAF00', '#5FAF5F',
|
||||
'#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF', '#5FD700', '#5FD75F',
|
||||
'#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF', '#5FFF00', '#5FFF5F',
|
||||
'#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF', '#870000', '#87005F',
|
||||
'#870087', '#8700AF', '#8700D7', '#8700FF', '#875F00', '#875F5F',
|
||||
'#875F87', '#875FAF', '#875FD7', '#875FFF', '#878700', '#87875F',
|
||||
'#878787', '#8787AF', '#8787D7', '#8787FF', '#87AF00', '#87AF5F',
|
||||
'#87AF87', '#87AFAF', '#87AFD7', '#87AFFF', '#87D700', '#87D75F',
|
||||
'#87D787', '#87D7AF', '#87D7D7', '#87D7FF', '#87FF00', '#87FF5F',
|
||||
'#87FF87', '#87FFAF', '#87FFD7', '#87FFFF', '#AF0000', '#AF005F',
|
||||
'#AF0087', '#AF00AF', '#AF00D7', '#AF00FF', '#AF5F00', '#AF5F5F',
|
||||
'#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF', '#AF8700', '#AF875F',
|
||||
'#AF8787', '#AF87AF', '#AF87D7', '#AF87FF', '#AFAF00', '#AFAF5F',
|
||||
'#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF', '#AFD700', '#AFD75F',
|
||||
'#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF', '#AFFF00', '#AFFF5F',
|
||||
'#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF', '#D70000', '#D7005F',
|
||||
'#D70087', '#D700AF', '#D700D7', '#D700FF', '#D75F00', '#D75F5F',
|
||||
'#D75F87', '#D75FAF', '#D75FD7', '#D75FFF', '#D78700', '#D7875F',
|
||||
'#D78787', '#D787AF', '#D787D7', '#D787FF', '#D7AF00', '#D7AF5F',
|
||||
'#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF', '#D7D700', '#D7D75F',
|
||||
'#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF', '#D7FF00', '#D7FF5F',
|
||||
'#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF', '#FF0000', '#FF005F',
|
||||
'#FF0087', '#FF00AF', '#FF00D7', '#FF00FF', '#FF5F00', '#FF5F5F',
|
||||
'#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF', '#FF8700', '#FF875F',
|
||||
'#FF8787', '#FF87AF', '#FF87D7', '#FF87FF', '#FFAF00', '#FFAF5F',
|
||||
'#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF', '#FFD700', '#FFD75F',
|
||||
'#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF', '#FFFF00', '#FFFF5F',
|
||||
'#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF', '#080808', '#121212',
|
||||
'#1C1C1C', '#262626', '#303030', '#3A3A3A', '#444444', '#4E4E4E',
|
||||
'#585858', '#626262', '#6C6C6C', '#767676', '#808080', '#8A8A8A',
|
||||
'#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', '#BCBCBC', '#C6C6C6',
|
||||
'#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
|
||||
]
|
||||
};
|
||||
// ---------------------------------------------------------------------
|
||||
// :: Replace ANSI formatting with terminal formatting
|
||||
// ---------------------------------------------------------------------
|
||||
$.terminal.from_ansi = (function() {
|
||||
var color_list = {
|
||||
30: 'black',
|
||||
31: 'red',
|
||||
32: 'green',
|
||||
33: 'yellow',
|
||||
34: 'blue',
|
||||
35: 'magenta',
|
||||
36: 'cyan',
|
||||
37: 'white',
|
||||
|
||||
39: 'inherit' // default color
|
||||
};
|
||||
var background_list = {
|
||||
40: 'black',
|
||||
41: 'red',
|
||||
42: 'green',
|
||||
43: 'yellow',
|
||||
44: 'blue',
|
||||
45: 'magenta',
|
||||
46: 'cyan',
|
||||
47: 'white',
|
||||
|
||||
49: 'transparent' // default background
|
||||
};
|
||||
function format_ansi(code) {
|
||||
var controls = code.split(';');
|
||||
var num;
|
||||
var faited = false;
|
||||
var reverse = false;
|
||||
var bold = false;
|
||||
var styles = [];
|
||||
var output_color = '';
|
||||
var output_background = '';
|
||||
var _8bit_color = false;
|
||||
var _8bit_background = false;
|
||||
var process_8bit = false;
|
||||
var palette = $.terminal.ansi_colors.palette;
|
||||
for(var i in controls) {
|
||||
if (controls.hasOwnProperty(i)) {
|
||||
num = parseInt(controls[i], 10);
|
||||
if (process_8bit && (_8bit_background || _8bit_color)) {
|
||||
if (_8bit_color && palette[num]) {
|
||||
output_color = palette[num];
|
||||
}
|
||||
if (_8bit_background && palette[num]) {
|
||||
output_background = palette[num];
|
||||
}
|
||||
} else {
|
||||
switch(num) {
|
||||
case 1:
|
||||
styles.push('b');
|
||||
bold = true;
|
||||
faited = false;
|
||||
break;
|
||||
case 4:
|
||||
styles.push('u');
|
||||
break;
|
||||
case 3:
|
||||
styles.push('i');
|
||||
break;
|
||||
case 5:
|
||||
process_8bit = true;
|
||||
break;
|
||||
case 38:
|
||||
_8bit_color = true;
|
||||
break;
|
||||
case 48:
|
||||
_8bit_background = true;
|
||||
break;
|
||||
case 2:
|
||||
faited = true;
|
||||
bold = false;
|
||||
break;
|
||||
case 7:
|
||||
reverse = true;
|
||||
break;
|
||||
default:
|
||||
if (controls.indexOf('5') == -1) {
|
||||
if (color_list[num]) {
|
||||
output_color = color_list[num];
|
||||
}
|
||||
if (background_list[num]) {
|
||||
output_background = background_list[num];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reverse) {
|
||||
if (output_color || output_background) {
|
||||
var tmp = output_background;
|
||||
output_background = output_color;
|
||||
output_color = tmp;
|
||||
} else {
|
||||
output_color = 'black';
|
||||
output_background = 'white';
|
||||
}
|
||||
}
|
||||
var colors, color, background, backgrounds;
|
||||
if (bold) {
|
||||
colors = backgrounds = $.terminal.ansi_colors.bold;
|
||||
} else if (faited) {
|
||||
colors = backgrounds = $.terminal.ansi_colors.faited;
|
||||
} else {
|
||||
colors = backgrounds = $.terminal.ansi_colors.normal;
|
||||
}
|
||||
if (_8bit_color) {
|
||||
color = output_color;
|
||||
} else if (output_color == 'inherit') {
|
||||
color = output_color;
|
||||
} else {
|
||||
color = colors[output_color];
|
||||
}
|
||||
if (_8bit_background) {
|
||||
background = output_background;
|
||||
} else if (output_background == 'transparent') {
|
||||
background = output_background;
|
||||
} else {
|
||||
background = backgrounds[output_background];
|
||||
}
|
||||
return [styles.join(''), color, background];
|
||||
}
|
||||
return function(input) {
|
||||
//merge multiple codes
|
||||
/*input = input.replace(/((?:\x1B\[[0-9;]*[A-Za-z])*)/g, function(group) {
|
||||
return group.replace(/m\x1B\[/g, ';');
|
||||
});*/
|
||||
var splitted = input.split(/(\x1B\[[0-9;]*[A-Za-z])/g);
|
||||
if (splitted.length == 1) {
|
||||
return input;
|
||||
}
|
||||
var output = [];
|
||||
//skip closing at the begining
|
||||
if (splitted.length > 3) {
|
||||
var str = splitted.slice(0,3).join('');
|
||||
if (str.match(/^\[0*m$/)) {
|
||||
splitted = splitted.slice(3);
|
||||
}
|
||||
}
|
||||
var next, prev_color, prev_background, code, match;
|
||||
var inside = false;
|
||||
for (var i=0; i<splitted.length; ++i) {
|
||||
match = splitted[i].match(/^\x1B\[([0-9;]*)([A-Za-z])$/);
|
||||
if (match) {
|
||||
switch (match[2]) {
|
||||
case 'm':
|
||||
if (+match[1] !== 0) {
|
||||
code = format_ansi(match[1]);
|
||||
}
|
||||
if (inside) {
|
||||
output.push(']');
|
||||
if (+match[1] === 0) {
|
||||
//just closing
|
||||
inside = false;
|
||||
prev_color = prev_background = '';
|
||||
} else {
|
||||
// someone forget to close - move to next
|
||||
code[1] = code[1] || prev_color;
|
||||
code[2] = code[2] || prev_background;
|
||||
output.push('[[' + code.join(';') + ']');
|
||||
// store colors to next use
|
||||
if (code[1]) {
|
||||
prev_color = code[1];
|
||||
}
|
||||
if (code[2]) {
|
||||
prev_background = code[2];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (+match[1] !== 0) {
|
||||
inside = true;
|
||||
code[1] = code[1] || prev_color;
|
||||
code[2] = code[2] || prev_background;
|
||||
output.push('[[' + code.join(';') + ']');
|
||||
// store colors to next use
|
||||
if (code[1]) {
|
||||
prev_color = code[1];
|
||||
}
|
||||
if (code[2]) {
|
||||
prev_background = code[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
output.push(splitted[i]);
|
||||
}
|
||||
}
|
||||
if (inside) {
|
||||
output.push(']');
|
||||
}
|
||||
return output.join(''); //.replace(/\[\[[^\]]+\]\]/g, '');
|
||||
};
|
||||
})();
|
||||
$.terminal.defaults.formatters.push($.terminal.overtyping);
|
||||
$.terminal.defaults.formatters.push($.terminal.from_ansi);
|
||||
})(jQuery);
|
|
@ -26,15 +26,19 @@
|
|||
@section('scripts')
|
||||
@parent
|
||||
{!! Theme::css('css/metricsgraphics.css') !!}
|
||||
{!! Theme::css('css/jquery.terminal.css') !!}
|
||||
{!! Theme::js('js/d3.min.js') !!}
|
||||
{!! Theme::js('js/metricsgraphics.min.js') !!}
|
||||
{!! Theme::js('js/async.min.js') !!}
|
||||
{!! Theme::js('js/jquery.mousewheel-min.js') !!}
|
||||
{!! Theme::js('js/jquery.terminal-0.11.6.min.js') !!}
|
||||
{!! Theme::js('js/unix_formatting.js') !!}
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="col-md-12">
|
||||
<ul class="nav nav-tabs tabs_with_panel" id="config_tabs">
|
||||
<li id="triggerConsoleView" class="active"><a href="#console" data-toggle="tab">{{ trans('server.index.control') }}</a></li>
|
||||
<li class="active"><a href="#console" data-toggle="tab">{{ trans('server.index.control') }}</a></li>
|
||||
@can('view-allocation', $server)<li><a href="#allocation" data-toggle="tab">{{ trans('server.index.allocation') }}</a></li>@endcan
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
|
@ -44,25 +48,9 @@
|
|||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<textarea id="live_console" class="form-control console" readonly="readonly">Loading Previous Content...</textarea>
|
||||
<div id="terminal"></div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<hr />
|
||||
@can('send-command', $server)
|
||||
<form action="#" method="post" id="console_command" style="display:none;">
|
||||
<fieldset>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="command" id="ccmd" placeholder="{{ trans('server.index.command') }}" />
|
||||
<span class="input-group-btn">
|
||||
<button id="sending_command" class="btn btn-primary btn-sm">→</button>
|
||||
</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<div class="alert alert-danger" id="sc_resp" style="display:none;margin-top: 15px;"></div>
|
||||
@endcan
|
||||
</div>
|
||||
<div class="col-md-6" style="text-align:center;">
|
||||
<div class="col-md-12" style="text-align:center;">
|
||||
<hr />
|
||||
@can('power-start', $server)<button class="btn btn-success btn-sm disabled" data-attr="power" data-action="start">Start</button>@endcan
|
||||
@can('power-restart', $server)<button class="btn btn-primary btn-sm disabled" data-attr="power" data-action="restart">Restart</button>@endcan
|
||||
|
@ -130,12 +118,12 @@
|
|||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title" id="PauseConsole">{{ trans('server.index.scrollstop') }}</h4>
|
||||
<h4 class="modal-title" id="PauseConsole">ScrollStop™</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<textarea id="paused_console" class="form-control console" readonly="readonly"></textarea>
|
||||
<div id="paused_console" style="height: 300px; overflow-x: scroll;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -151,6 +139,51 @@
|
|||
<script>
|
||||
$(window).load(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
var initialStatusSent = false;
|
||||
var currentStatus = 0;
|
||||
|
||||
var terminal = $('#terminal').terminal(function (command, term) {
|
||||
@can('power-start', $server)
|
||||
if (currentStatus === 0 && (command === 'start' || command === 'boot')) {
|
||||
powerToggleServer('start');
|
||||
}
|
||||
@endcan
|
||||
@can('send-command', $server)
|
||||
if (currentStatus === 0 && !(command === 'start' || command === 'boot')) {
|
||||
term.error('Server is currently off, type `start` or `boot` to start server.');
|
||||
}
|
||||
if (currentStatus !== 0 && command !== '') {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'X-Access-Token': '{{ $server->daemonSecret }}',
|
||||
'X-Access-Server': '{{ $server->uuid }}'
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
url: '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/server/command',
|
||||
timeout: 10000,
|
||||
data: JSON.stringify({ command: command })
|
||||
}).fail(function (jqXHR) {
|
||||
console.error(jqXHR);
|
||||
var error = 'An error occured while trying to process this request.';
|
||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
||||
error = jqXHR.responseJSON.error;
|
||||
}
|
||||
term.error(error);
|
||||
});
|
||||
}
|
||||
@else
|
||||
term.error('You do not have permission to send commands to this server.');
|
||||
@endcan
|
||||
}, {
|
||||
greetings: '',
|
||||
name: '{{ $server->uuid }}',
|
||||
height: 400,
|
||||
prompt: '{{$server->name}}@{{ $server->uuidShort }}:~$ ',
|
||||
onBlur: function (terminal) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
var showOnlyTotal = true;
|
||||
$('[data-action="show-all-cores"]').click(function (event) {
|
||||
|
@ -311,12 +344,13 @@ $(window).load(function () {
|
|||
|
||||
// New Console Data Recieved
|
||||
socket.on('console', function (data) {
|
||||
$('#live_console').val($('#live_console').val() + data.line);
|
||||
$('#live_console').scrollTop($('#live_console')[0].scrollHeight);
|
||||
terminal.echo(data.line);
|
||||
});
|
||||
|
||||
// Update Listings on Initial Status
|
||||
socket.on('initial_status', function (data) {
|
||||
currentStatus = data.status;
|
||||
console.log(data.status);
|
||||
if (data.status !== 0) {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
|
@ -327,13 +361,10 @@ $(window).load(function () {
|
|||
url: '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/server/log',
|
||||
timeout: 10000
|
||||
}).done(function(data) {
|
||||
$('#live_console').val(data);
|
||||
$('#live_console').scrollTop($('#live_console')[0].scrollHeight);
|
||||
}).fail(function(jqXHR, textStatus, errorThrown) {
|
||||
alert('Unable to load initial server log, try reloading the page.');
|
||||
terminal.echo(data);
|
||||
}).fail(function() {
|
||||
terminal.error('Unable to load initial server log, try reloading the page.');
|
||||
});
|
||||
} else {
|
||||
$('#live_console').val('Server is currently off.');
|
||||
}
|
||||
updateServerPowerControls(data.status);
|
||||
updatePlayerListVisibility(data.status);
|
||||
|
@ -341,24 +372,14 @@ $(window).load(function () {
|
|||
|
||||
// Update Listings on Status
|
||||
socket.on('status', function (data) {
|
||||
currentStatus = data.status;
|
||||
updateServerPowerControls(data.status);
|
||||
updatePlayerListVisibility(data.status);
|
||||
});
|
||||
|
||||
// Scroll to the top of the Console when switching to that tab.
|
||||
$('#triggerConsoleView').click(function () {
|
||||
$('#live_console').scrollTop($('#live_console')[0].scrollHeight);
|
||||
});
|
||||
if($('triggerConsoleView').is(':visible')) {
|
||||
$('#live_console').scrollTop($('#live_console')[0].scrollHeight);
|
||||
}
|
||||
$('a[data-toggle=\'tab\']').on('shown.bs.tab', function (e) {
|
||||
$('#live_console').scrollTop($('#live_console')[0].scrollHeight);
|
||||
});
|
||||
|
||||
// Load Paused Console with Live Console Data
|
||||
$('#pause_console').click(function(){
|
||||
$('#paused_console').val($('#live_console').val());
|
||||
$('#paused_console').html($('#terminal').html());
|
||||
});
|
||||
|
||||
function updatePlayerListVisibility(data) {
|
||||
|
@ -413,61 +434,19 @@ $(window).load(function () {
|
|||
});
|
||||
@endcan
|
||||
|
||||
@can('send-command', $server)
|
||||
// Send Command to Server
|
||||
$('#console_command').submit(function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
var ccmd = $('#ccmd').val();
|
||||
if (ccmd == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$('#sending_command').html('<i class=\'fa fa-refresh fa-spin\'></i>').addClass('disabled');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'X-Access-Token': '{{ $server->daemonSecret }}',
|
||||
'X-Access-Server': '{{ $server->uuid }}'
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
url: '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/server/command',
|
||||
timeout: 10000,
|
||||
data: JSON.stringify({ command: ccmd })
|
||||
}).fail(function (jqXHR) {
|
||||
console.error(jqXHR);
|
||||
var error = 'An error occured while trying to process this request.';
|
||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
||||
error = jqXHR.responseJSON.error;
|
||||
}
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
text: error
|
||||
});
|
||||
}).done(function () {
|
||||
$('#ccmd').val('');
|
||||
}).always(function () {
|
||||
$('#sending_command').html('→').removeClass('disabled');
|
||||
});
|
||||
});
|
||||
@endcan
|
||||
var can_run = true;
|
||||
function updateServerPowerControls (data) {
|
||||
|
||||
// Reset Console Data
|
||||
if (data === 2) {
|
||||
$('#live_console').val($('#live_console').val() + '\n --+ Server Detected as Booting + --\n');
|
||||
$('#live_console').scrollTop($('#live_console')[0].scrollHeight);
|
||||
terminal.echo('\n[Daemon] -- + Server Detected as Booting + --\n');
|
||||
}
|
||||
|
||||
// Server is On or Starting
|
||||
if(data == 1 || data == 2) {
|
||||
$("#console_command").slideDown();
|
||||
$('[data-attr="power"][data-action="start"]').addClass('disabled');
|
||||
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').removeClass('disabled');
|
||||
} else {
|
||||
$("#console_command").slideUp();
|
||||
$('[data-attr="power"][data-action="start"]').removeClass('disabled');
|
||||
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').addClass('disabled');
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue