Fix the terminal to stop glitching out and not displaying unless window is resized.

This commit is contained in:
Dane Everitt 2017-04-14 01:21:38 -04:00
parent 6fb44f7d7b
commit a2b451b990
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
11 changed files with 478 additions and 603 deletions

View File

@ -9,6 +9,7 @@ This project follows [Semantic Versioning](http://semver.org) guidelines.
* `[pre.7]` — Fixes bug with injected JS that was causing `<!DOCTYPE html>` to be ignored in templates. * `[pre.7]` — Fixes bug with injected JS that was causing `<!DOCTYPE html>` to be ignored in templates.
* `[pre.7]` — Fixes exception thrown when trying to delete a node due to a misnamed model. * `[pre.7]` — Fixes exception thrown when trying to delete a node due to a misnamed model.
* `[pre.7]` — Fixes username vanishing on failed login attempts. * `[pre.7]` — Fixes username vanishing on failed login attempts.
* `[pre.7]` — Terminal is now fixed to actually output all lines, rather than leaving one hanging in neverland until the browser is resized.
### Added ### Added
* Login attempts and pasword reset requests are now protected by invisible ReCaptcha. This feature can be disabled with a `.env` variable. * Login attempts and pasword reset requests are now protected by invisible ReCaptcha. This feature can be disabled with a `.env` variable.
@ -24,6 +25,7 @@ This project follows [Semantic Versioning](http://semver.org) guidelines.
* Routes are now handled in the `routes/` folder, and use a significantly cleaner syntax. Controller names and methods have been updated as well to be clearer as well as avoid conflicts with PHP reserved keywords. * Routes are now handled in the `routes/` folder, and use a significantly cleaner syntax. Controller names and methods have been updated as well to be clearer as well as avoid conflicts with PHP reserved keywords.
* API has been completely overhauled to use new permissions system. **Any old API keys will immediately become invalid and fail to operate properly anymore. You will need to generate new keys.** * API has been completely overhauled to use new permissions system. **Any old API keys will immediately become invalid and fail to operate properly anymore. You will need to generate new keys.**
* Cleaned up dynamic database connection setting to use a single function call from the host model. * Cleaned up dynamic database connection setting to use a single function call from the host model.
* `[pre.7]` — Corrected a config option for spigot servers to set a boolean value as boolean, and not as a string.
## v0.6.0-pre.7 (Courageous Carniadactylus) ## v0.6.0-pre.7 (Courageous Carniadactylus)
### Fixed ### Fixed

View File

@ -17,32 +17,22 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE. // SOFTWARE.
var CONSOLE_PUSH_COUNT = Pterodactyl.config.console_count || 10;
var CONSOLE_PUSH_FREQ = Pterodactyl.config.console_freq || 200;
var CONSOLE_OUTPUT_LIMIT = Pterodactyl.config.console_limit || 2000;
var InitialLogSent = false;
var Console = (function () { (function initConsole() {
var CONSOLE_PUSH_COUNT = Pterodactyl.config.console_count; window.TerminalQueue = [];
var CONSOLE_PUSH_FREQ = Pterodactyl.config.console_freq; window.Terminal = $('#terminal').terminal(function (command, term) {
var terminalQueue;
var terminal;
var recievedInitialLog = false;
var cpuChart;
var cpuData;
var memoryChart;
var memoryData;
var timeLabels;
var $terminalNotify;
function initConsole() {
terminalQueue = [];
terminal = $('#terminal').terminal(function (command, term) {
Socket.emit('send command', command); Socket.emit('send command', command);
}, { }, {
greetings: '', greetings: '',
name: Pterodactyl.server.uuid, name: Pterodactyl.server.uuid,
height: 450, height: 450,
exit: false, exit: false,
echoCommand: false,
outputLimit: CONSOLE_OUTPUT_LIMIT,
prompt: Pterodactyl.server.username + ':~$ ', prompt: Pterodactyl.server.username + ':~$ ',
scrollOnEcho: false, scrollOnEcho: false,
scrollBottomOffset: 5, scrollBottomOffset: 5,
@ -51,116 +41,53 @@ var Console = (function () {
} }
}); });
$terminalNotify = $('#terminalNotify'); window.TerminalNotifyElement = $('#terminalNotify');
$terminalNotify.on('click', function () { TerminalNotifyElement.on('click', function () {
terminal.scroll_to_bottom(); Terminal.scroll_to_bottom();
$terminalNotify.addClass('hidden'); TerminalNotifyElement.addClass('hidden');
}) })
terminal.on('scroll', function () { Terminal.on('scroll', function () {
if (terminal.is_bottom()) { if (Terminal.is_bottom()) {
$terminalNotify.addClass('hidden'); TerminalNotifyElement.addClass('hidden');
} }
}) })
// Socket.on('initial status', function (data) {
// Terminal.clear();
// if (data.status === 1 || data.status === 2) {
// Socket.emit('send server log');
// }
// });
})();
(function pushOutputQueue() {
if (TerminalQueue.length > CONSOLE_PUSH_COUNT) {
// console throttled warning show
} }
function initGraphs() { if (TerminalQueue.length > 0) {
var ctc = $('#chart_cpu'); for (var i = 0; i < CONSOLE_PUSH_COUNT && TerminalQueue.length > 0; i++) {
timeLabels = []; Terminal.echo(TerminalQueue[0], { flush: false });
cpuData = []; TerminalQueue.shift();
cpuChart = new Chart(ctc, {
type: 'line',
data: {
labels: timeLabels,
datasets: [
{
label: "Percent Use",
fill: false,
lineTension: 0.03,
backgroundColor: "#3c8dbc",
borderColor: "#3c8dbc",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "#3c8dbc",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "#3c8dbc",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data: cpuData,
spanGaps: false,
}
]
},
options: {
title: {
display: true,
text: 'CPU Usage (as Percent Total)'
},
legend: {
display: false,
},
animation: {
duration: 1,
}
}
});
var ctm = $('#chart_memory');
memoryData = [];
memoryChart = new Chart(ctm, {
type: 'line',
data: {
labels: timeLabels,
datasets: [
{
label: "Memory Use",
fill: false,
lineTension: 0.03,
backgroundColor: "#3c8dbc",
borderColor: "#3c8dbc",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "#3c8dbc",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "#3c8dbc",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data: memoryData,
spanGaps: false,
}
]
},
options: {
title: {
display: true,
text: 'Memory Usage (in Megabytes)'
},
legend: {
display: false,
},
animation: {
duration: 1,
}
}
});
} }
function addSocketListeners() { // Flush after looping through all.
Terminal.flush();
// Show Warning
if (! Terminal.is_bottom()) {
TerminalNotifyElement.removeClass('hidden');
}
}
window.setTimeout(pushOutputQueue, CONSOLE_PUSH_FREQ);
})();
(function setupSocketListeners() {
// Update Listings on Initial Status // Update Listings on Initial Status
Socket.on('initial status', function (data) { Socket.on('initial status', function (data) {
if (! recievedInitialLog) { console.log('initial status 2');
if (! InitialLogSent) {
updateServerPowerControls(data.status); updateServerPowerControls(data.status);
if (data.status === 1 || data.status === 2) { if (data.status === 1 || data.status === 2) {
@ -175,56 +102,18 @@ var Console = (function () {
}); });
Socket.on('server log', function (data) { Socket.on('server log', function (data) {
if (! recievedInitialLog) { if (! InitialLogSent) {
terminal.clear(); Terminal.clear();
terminalQueue.push(data); TerminalQueue.push(data);
recievedInitialLog = true; InitialLogSent = true;
} }
}); });
Socket.on('console', function (data) { Socket.on('console', function (data) {
terminalQueue.push(data.line); TerminalQueue.push(data.line);
}); });
})();
Socket.on('proc', function (proc) {
if (cpuData.length > 10) {
cpuData.shift();
memoryData.shift();
timeLabels.shift();
}
var cpuUse = (Pterodactyl.server.cpu > 0) ? parseFloat(((proc.data.cpu.total / Pterodactyl.server.cpu) * 100).toFixed(3).toString()) : proc.data.cpu.total;
cpuData.push(cpuUse);
memoryData.push(parseInt(proc.data.memory.total / (1024 * 1024)));
var m = new Date();
timeLabels.push($.format.date(new Date(), 'HH:mm:ss'));
cpuChart.update();
memoryChart.update();
});
}
function pushOutputQueue() {
if (terminalQueue.length > CONSOLE_PUSH_COUNT) {
// console throttled warning show
}
if (terminalQueue.length > 0) {
for (var i = 0; i < CONSOLE_PUSH_COUNT && terminalQueue.length > 0; i++) {
terminal.echo(terminalQueue[0], {flush: false});
terminalQueue.shift();
}
terminal.flush()
// Show
if (!terminal.is_bottom()) {
$terminalNotify.removeClass('hidden');
}
}
window.setTimeout(pushOutputQueue, CONSOLE_PUSH_FREQ);
}
function updateServerPowerControls (data) { function updateServerPowerControls (data) {
// Server is On or Starting // Server is On or Starting
@ -245,32 +134,119 @@ var Console = (function () {
} }
} }
return { $(document).ready(function () {
init: function () {
initConsole();
pushOutputQueue();
initGraphs();
addSocketListeners();
$('[data-attr="power"]').click(function (event) { $('[data-attr="power"]').click(function (event) {
if (! $(this).hasClass('disabled')) { if (! $(this).hasClass('disabled')) {
Socket.emit('set status', $(this).data('action')); Socket.emit('set status', $(this).data('action'));
} }
}); });
},
getTerminal: function () { Socket.on('proc', function (proc) {
return terminal if (CPUData.length > 10) {
}, CPUData.shift();
MemoryData.shift();
getTerminalQueue: function () { TimeLabels.shift();
return terminalQueue
},
} }
})(); var cpuUse = (Pterodactyl.server.cpu > 0) ? parseFloat(((proc.data.cpu.total / Pterodactyl.server.cpu) * 100).toFixed(3).toString()) : proc.data.cpu.total;
CPUData.push(cpuUse);
MemoryData.push(parseInt(proc.data.memory.total / (1024 * 1024)));
$(document).ready(function () { TimeLabels.push($.format.date(new Date(), 'HH:mm:ss'));
Console.init();
CPUChart.update();
MemoryChart.update();
});
var ctc = $('#chart_cpu');
var TimeLabels = [];
var CPUData = [];
var CPUChart = new Chart(ctc, {
type: 'line',
data: {
labels: TimeLabels,
datasets: [
{
label: "Percent Use",
fill: false,
lineTension: 0.03,
backgroundColor: "#3c8dbc",
borderColor: "#3c8dbc",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "#3c8dbc",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "#3c8dbc",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data: CPUData,
spanGaps: false,
}
]
},
options: {
title: {
display: true,
text: 'CPU Usage (as Percent Total)'
},
legend: {
display: false,
},
animation: {
duration: 1,
}
}
});
var ctm = $('#chart_memory');
MemoryData = [];
MemoryChart = new Chart(ctm, {
type: 'line',
data: {
labels: TimeLabels,
datasets: [
{
label: "Memory Use",
fill: false,
lineTension: 0.03,
backgroundColor: "#3c8dbc",
borderColor: "#3c8dbc",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "#3c8dbc",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "#3c8dbc",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data: MemoryData,
spanGaps: false,
}
]
},
options: {
title: {
display: true,
text: 'Memory Usage (in Megabytes)'
},
legend: {
display: false,
},
animation: {
duration: 1,
}
}
});
}); });

View File

@ -50,11 +50,13 @@ var Server = (function () {
var notifySocketError = false; var notifySocketError = false;
console.log('Starting connection');
window.Socket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/ws/' + Pterodactyl.server.uuid, { window.Socket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/ws/' + Pterodactyl.server.uuid, {
'query': 'token=' + Pterodactyl.server.daemonSecret, 'query': 'token=' + Pterodactyl.server.daemonSecret,
}); });
Socket.io.on('connect_error', function (err) { Socket.io.on('connect_error', function (err) {
console.log('connect_error');
if(typeof notifySocketError !== 'object') { if(typeof notifySocketError !== 'object') {
notifySocketError = $.notify({ notifySocketError = $.notify({
message: 'There was an error attempting to establish a WebSocket connection to the Daemon. This panel will not work as expected.<br /><br />' + err, message: 'There was an error attempting to establish a WebSocket connection to the Daemon. This panel will not work as expected.<br /><br />' + err,
@ -67,6 +69,7 @@ var Server = (function () {
// Connected to Socket Successfully // Connected to Socket Successfully
Socket.on('connect', function () { Socket.on('connect', function () {
console.log('connect');
if (notifySocketError !== false) { if (notifySocketError !== false) {
notifySocketError.close(); notifySocketError.close();
notifySocketError = false; notifySocketError = false;
@ -74,6 +77,7 @@ var Server = (function () {
}); });
Socket.on('initial status', function (data) { Socket.on('initial status', function (data) {
console.log('initial status');
setStatusIcon(data.status); setStatusIcon(data.status);
}); });

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,121 @@
/* global define, KeyboardEvent, module */
// https://github.com/cvan/keyboardevent-key-polyfill/blob/master/LICENSE.md
(function () {
var keyboardeventKeyPolyfill = {
polyfill: polyfill,
keys: {
3: 'Cancel',
6: 'Help',
8: 'Backspace',
9: 'Tab',
12: 'Clear',
13: 'Enter',
16: 'Shift',
17: 'Control',
18: 'Alt',
19: 'Pause',
20: 'CapsLock',
27: 'Escape',
28: 'Convert',
29: 'NonConvert',
30: 'Accept',
31: 'ModeChange',
32: ' ',
33: 'PageUp',
34: 'PageDown',
35: 'End',
36: 'Home',
37: 'ArrowLeft',
38: 'ArrowUp',
39: 'ArrowRight',
40: 'ArrowDown',
41: 'Select',
42: 'Print',
43: 'Execute',
44: 'PrintScreen',
45: 'Insert',
46: 'Delete',
48: ['0', ')'],
49: ['1', '!'],
50: ['2', '@'],
51: ['3', '#'],
52: ['4', '$'],
53: ['5', '%'],
54: ['6', '^'],
55: ['7', '&'],
56: ['8', '*'],
57: ['9', '('],
91: 'OS',
93: 'ContextMenu',
144: 'NumLock',
145: 'ScrollLock',
181: 'VolumeMute',
182: 'VolumeDown',
183: 'VolumeUp',
186: [';', ':'],
187: ['=', '+'],
188: [',', '<'],
189: ['-', '_'],
190: ['.', '>'],
191: ['/', '?'],
192: ['`', '~'],
219: ['[', '{'],
220: ['\\', '|'],
221: [']', '}'],
222: ["'", '"'],
224: 'Meta',
225: 'AltGraph',
246: 'Attn',
247: 'CrSel',
248: 'ExSel',
249: 'EraseEof',
250: 'Play',
251: 'ZoomOut'
}
};
// Function keys (F1-24).
var i;
for (i = 1; i < 25; i++) {
keyboardeventKeyPolyfill.keys[111 + i] = 'F' + i;
}
// Printable ASCII characters.
var letter = '';
for (i = 65; i < 91; i++) {
letter = String.fromCharCode(i);
keyboardeventKeyPolyfill.keys[i] = [letter.toLowerCase(), letter.toUpperCase()];
}
function polyfill () {
if (!('KeyboardEvent' in window) ||
'key' in KeyboardEvent.prototype) {
return false;
}
// Polyfill `key` on `KeyboardEvent`.
var proto = {
get: function (x) {
var key = keyboardeventKeyPolyfill.keys[this.which || this.keyCode];
if (Array.isArray(key)) {
key = key[+this.shiftKey];
}
return key;
}
};
Object.defineProperty(KeyboardEvent.prototype, 'key', proto);
return proto;
}
if (typeof define === 'function' && define.amd) {
define('keyboardevent-key-polyfill', keyboardeventKeyPolyfill);
} else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
module.exports = keyboardeventKeyPolyfill;
} else if (window) {
window.keyboardeventKeyPolyfill = keyboardeventKeyPolyfill;
}
})();

View File

@ -9,7 +9,7 @@
* *
* This is example of how to create custom formatter for jQuery Terminal * This is example of how to create custom formatter for jQuery Terminal
* *
* Copyright (c) 2014-2016 Jakub Jankiewicz <http://jcubic.pl> * Copyright (c) 2014-2016 Jakub Jankiewicz <http://jcubic.pl/me>
* Released under the MIT license * Released under the MIT license
* *
*/ */
@ -21,10 +21,10 @@
// :: Replace overtyping (from man) formatting with terminal formatting // :: Replace overtyping (from man) formatting with terminal formatting
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
$.terminal.overtyping = function(string) { $.terminal.overtyping = function(string) {
return string.replace(/((?:_\x08.|.\x08_)+)/g, function(full, g) { return string.replace(/((?:_\x08.|.\x08_)+)/g, function(full) {
var striped = full.replace(/_x08|\x08_|_\u0008|\u0008_/g, ''); var striped = full.replace(/_x08|\x08_|_\u0008|\u0008_/g, '');
return '[[u;;]' + striped + ']'; return '[[u;;]' + striped + ']';
}).replace(/((?:.\x08.)+)/g, function(full, g) { }).replace(/((?:.\x08.)+)/g, function(full) {
return '[[b;#fff;]' + full.replace(/(.)(?:\x08|\u0008)\1/g, return '[[b;#fff;]' + full.replace(/(.)(?:\x08|\u0008)\1/g,
function(full, g) { function(full, g) {
return g; return g;
@ -153,17 +153,7 @@
var _8bit_background = false; var _8bit_background = false;
var process_8bit = false; var process_8bit = false;
var palette = $.terminal.ansi_colors.palette; var palette = $.terminal.ansi_colors.palette;
for(var i in controls) { function set_styles(num) {
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) { switch (num) {
case 1: case 1:
styles.push('b'); styles.push('b');
@ -193,7 +183,7 @@
reverse = true; reverse = true;
break; break;
default: default:
if (controls.indexOf('5') == -1) { if (controls.indexOf('5') === -1) {
if (color_list[num]) { if (color_list[num]) {
output_color = color_list[num]; output_color = color_list[num];
} }
@ -203,6 +193,19 @@
} }
} }
} }
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 {
set_styles(num);
}
} }
} }
if (reverse) { if (reverse) {
@ -225,14 +228,14 @@
} }
if (_8bit_color) { if (_8bit_color) {
color = output_color; color = output_color;
} else if (output_color == 'inherit') { } else if (output_color === 'inherit') {
color = output_color; color = output_color;
} else { } else {
color = colors[output_color]; color = colors[output_color];
} }
if (_8bit_background) { if (_8bit_background) {
background = output_background; background = output_background;
} else if (output_background == 'transparent') { } else if (output_background === 'transparent') {
background = output_background; background = output_background;
} else { } else {
background = backgrounds[output_background]; background = backgrounds[output_background];
@ -245,7 +248,7 @@
return group.replace(/m\x1B\[/g, ';'); return group.replace(/m\x1B\[/g, ';');
});*/ });*/
var splitted = input.split(/(\x1B\[[0-9;]*[A-Za-z])/g); var splitted = input.split(/(\x1B\[[0-9;]*[A-Za-z])/g);
if (splitted.length == 1) { if (splitted.length === 1) {
return input; return input;
} }
var output = []; var output = [];
@ -256,7 +259,7 @@
splitted = splitted.slice(3); splitted = splitted.slice(3);
} }
} }
var next, prev_color, prev_background, code, match; var prev_color, prev_background, code, match;
var inside = false; var inside = false;
for (var i = 0; i < splitted.length; ++i) { for (var i = 0; i < splitted.length; ++i) {
match = splitted[i].match(/^\x1B\[([0-9;]*)([A-Za-z])$/); match = splitted[i].match(/^\x1B\[([0-9;]*)([A-Za-z])$/);
@ -285,8 +288,7 @@
prev_background = code[2]; prev_background = code[2];
} }
} }
} else { } else if (+match[1] !== 0) {
if (+match[1] !== 0) {
inside = true; inside = true;
code[1] = code[1] || prev_color; code[1] = code[1] || prev_color;
code[2] = code[2] || prev_background; code[2] = code[2] || prev_background;
@ -299,7 +301,6 @@
prev_background = code[2]; prev_background = code[2];
} }
} }
}
break; break;
} }
} else { } else {

View File

@ -222,6 +222,9 @@
<div class="control-sidebar-bg"></div> <div class="control-sidebar-bg"></div>
</div> </div>
@section('footer-scripts') @section('footer-scripts')
{!! Theme::js('vendor/terminal/keyboard.polyfill.js') !!}
<script>keyboardeventKeyPolyfill.polyfill();</script>
{!! Theme::js('js/laroute.js') !!} {!! Theme::js('js/laroute.js') !!}
{!! Theme::js('vendor/jquery/jquery.min.js') !!} {!! Theme::js('vendor/jquery/jquery.min.js') !!}
{!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!} {!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!}

View File

@ -262,6 +262,9 @@
<div class="control-sidebar-bg"></div> <div class="control-sidebar-bg"></div>
</div> </div>
@section('footer-scripts') @section('footer-scripts')
{!! Theme::js('vendor/terminal/keyboard.polyfill.js') !!}
<script>keyboardeventKeyPolyfill.polyfill();</script>
{!! Theme::js('js/laroute.js') !!} {!! Theme::js('js/laroute.js') !!}
{!! Theme::js('vendor/jquery/jquery.min.js') !!} {!! Theme::js('vendor/jquery/jquery.min.js') !!}
{!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!} {!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!}

View File

@ -83,7 +83,7 @@
@parent @parent
{!! Theme::js('js/frontend/server.socket.js') !!} {!! Theme::js('js/frontend/server.socket.js') !!}
{!! Theme::js('vendor/mousewheel/jquery.mousewheel-min.js') !!} {!! Theme::js('vendor/mousewheel/jquery.mousewheel-min.js') !!}
{!! Theme::js('vendor/terminal/jquery.terminal-0.11.23.min.js') !!} {!! Theme::js('vendor/terminal/jquery.terminal.min.js') !!}
{!! Theme::js('vendor/terminal/unix_formatting.js') !!} {!! Theme::js('vendor/terminal/unix_formatting.js') !!}
{!! Theme::js('js/frontend/console.js') !!} {!! Theme::js('js/frontend/console.js') !!}
{!! Theme::js('vendor/chartjs/chart.min.js') !!} {!! Theme::js('vendor/chartjs/chart.min.js') !!}