diff --git a/config/application.yaml b/config/application.yaml index dffd7be..c95c319 100644 --- a/config/application.yaml +++ b/config/application.yaml @@ -3,7 +3,11 @@ server: address: localhost spring: mvc: - locale: en # as of v0.12 supported locales are: en, ru + locale: en # as of v0.12 supported locales are: en, ru +# Uncomment following 3 lines if the above locale is set to 'ru' +# resources: +# static-locations: +# - 'classpath:/static/ru' nodes: this: diff --git a/src/main/resources/static/download/download.component.js b/src/main/resources/static/download/download.component.js index 899be17..7049dd2 100644 --- a/src/main/resources/static/download/download.component.js +++ b/src/main/resources/static/download/download.component.js @@ -119,12 +119,12 @@ function DownloadController($scope, $element, $attrs, $log, $http) { app.filter('sizeFormatter', function() { return function(bytes) { if (!bytes) - return '[н/д]'; + return '[n/a]'; if (bytes === 0) - return '0 Байт'; + return '0 Bytes'; let k = 1024, dm = /*decimals ||*/ 2, - sizes = ['Байт', 'КБ', 'МБ', 'ГБ', 'ТБ', 'ПБ', 'ЭБ', 'ЗБ', 'YB'], + sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; }; @@ -133,9 +133,9 @@ app.filter('sizeFormatter', function() { app.filter('dateFormatter', function () { return function (utcDateString) { if (!utcDateString) - return '[н/д]'; + return '[n/a]'; let parsedDate = new Date(Date.parse(utcDateString)); - return parsedDate.toLocaleString("ru-RU"); + return parsedDate.toLocaleString("en-US"); } }); @@ -146,16 +146,16 @@ app.filter('errorFormatter', function () { let text; switch (error.status) { case 404: - text = 'не найден'; + text = 'not found'; break; case 403: - text = 'запрещён для загрузки'; + text = 'access denied'; break; case 503: - text = 'временно не доступен'; + text = 'temporarily unavailable'; break; default: - text = 'не может быть получен'; + text = 'can not be downloaded'; } text += (' ' + '(HTTP ' + error.status); if (error.message) diff --git a/src/main/resources/static/download/download.template.html b/src/main/resources/static/download/download.template.html index cefb3d7..5fef9ad 100644 --- a/src/main/resources/static/download/download.template.html +++ b/src/main/resources/static/download/download.template.html @@ -1,5 +1,5 @@
- @@ -7,7 +7,7 @@
-

Контрольная сводка

+

Download Summary

@@ -30,15 +30,15 @@

Контрольная сводка

- Узел{{$ctrl.file2Download.node || 'текущий'}} + Node{{$ctrl.file2Download.node || 'current'}} - Путь{{$ctrl.file2Download.path}} + Path{{$ctrl.file2Download.path}} - Изменен{{$ctrl.lastModified | dateFormatter}} + Changed{{$ctrl.lastModified | dateFormatter}} - Размер{{$ctrl.currentSize | sizeFormatter}} + Size{{$ctrl.currentSize | sizeFormatter}} - Статус{{$ctrl.lastError | errorFormatter}} + Status{{$ctrl.lastError | errorFormatter}} @@ -47,25 +47,25 @@

Контрольная сводка

Скачать целиком + class="btn btn-primary" download>Download Fully
- Отмена + Cancel
diff --git a/src/main/resources/static/general/js/choice-service.js b/src/main/resources/static/general/js/choice-service.js index ec03154..6b90cfb 100644 --- a/src/main/resources/static/general/js/choice-service.js +++ b/src/main/resources/static/general/js/choice-service.js @@ -26,7 +26,7 @@ function ChoicesService($http, $location, $log, $rootScope) { $log.log("Proposed log is unknown among server choices and hence will be added as separate group."); let logType = detectLogType(proposedLogId); selectedChoice = { - group: "Указан через URL", + group: "Specified via URL", title: extractFileName(proposedLogId), type: logType, id: proposedLogId diff --git a/src/main/resources/static/general/js/config.js b/src/main/resources/static/general/js/config.js index 36a76af..8692ce6 100644 --- a/src/main/resources/static/general/js/config.js +++ b/src/main/resources/static/general/js/config.js @@ -4,7 +4,7 @@ */ app.constant('config', { general: { - appTitle: 'АнаЛóг' + appTitle: 'AnaLóg' }, rendering: { diff --git a/src/main/resources/static/general/js/main-controller.js b/src/main/resources/static/general/js/main-controller.js index d5f6f60..6e00054 100644 --- a/src/main/resources/static/general/js/main-controller.js +++ b/src/main/resources/static/general/js/main-controller.js @@ -1,7 +1,7 @@ app = angular.module("AnaLog", ['ngSanitize', 'ngAnimate', 'ui.select']); app.run(function ($rootScope, watchingService) { - $rootScope.watchingLog = "АнаЛóг v0.11 (загрузка...)"; + $rootScope.watchingLog = "AnaLóg v0.12 (loading...)"; watchingService.connect(); }); @@ -102,19 +102,19 @@ app.filter('logTypeDetector', function () { return function (logChoice) { switch (logChoice.type) { case 'LOCAL_FILE': - return 'локальный файл'; + return 'local file'; case 'NODE': - return 'удалённый файл на узле {node}'.format(logChoice); + return 'remote file on {node} node'.format(logChoice); case 'COMPOSITE': - return 'композит из {size} {logs}'.format({size: logChoice.includes.length, + return 'composite of {size} {logs}'.format({size: logChoice.includes.length, logs: quantify(logChoice.includes.length)}); case 'DOCKER': - return 'контейнер в Docker'; + return 'Docker container'; case 'KUBERNETES': case 'K8S': - return 'ресурс в Kubernetes'; + return 'Kubernetes resource'; default: - return '[неизвестный тип лога]'; + return '[unknown log type]'; } } }); diff --git a/src/main/resources/static/general/js/util.js b/src/main/resources/static/general/js/util.js index 75887c1..373c61d 100644 --- a/src/main/resources/static/general/js/util.js +++ b/src/main/resources/static/general/js/util.js @@ -36,9 +36,9 @@ function arePathsEqual(path1, path2) { function quantify(count) { if (count > 1) { - return 'логов'; + return 'logs'; } else { - return 'лога'; + return 'log'; } } diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 61adc27..b5d1f7f 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -5,7 +5,7 @@ - АнаЛóг v0.11 + AnaLóg v0.12 @@ -47,17 +47,17 @@
@@ -104,7 +104,7 @@ diff --git a/src/main/resources/static/notification/notification.constant.js b/src/main/resources/static/notification/notification.constant.js index 6de36d3..0dc6534 100644 --- a/src/main/resources/static/notification/notification.constant.js +++ b/src/main/resources/static/notification/notification.constant.js @@ -6,48 +6,49 @@ app.constant('notifications', { // serverConnected: { level: 'success', - title: 'Сервер снова доступен', - text: 'Связь восстановлена, можно работать.' + title: 'Server Is Available', + text: 'Connection restored, we can go on working.' }, serverDisconnected: { level: 'warning', - title: 'Нет связи с сервером', - text: 'При необходимости слежение продолжится автоматически после восстановления связи.' + title: 'No Connection With Server', + text: 'Log tracking will continue (if necessary) after connection restore.' }, // // logNotFound: { level: 'info', - title: 'Лог не найден', - text: "Лог {logPath} не найден. Ожидаю его появления..." + title: 'Log Not Found', + text: "Log {logPath} not found. Waiting for it to appear..." }, logAppeared: { level: 'success', - title: 'Лог обнаружен', - text: "Лог {logPath} появился. Отслеживаю его изменения." + title: 'Log Detected', + text: "Log {logPath} has appeared. Following it..." }, logRotated: { level: 'info', - title: 'Ротация лога', - text: "Лог {logPath} начал писаться с начала. " + - "Предыдущие записи, вероятно, перенесены в другой лог." + title: 'Log Rotation', + text: "Log {logPath} started to write from scratch. " + + "Perhaps previous records have been moved to another file." }, logDisappeared: { level: 'info', - title: 'Лог потерян', - text: "Лог {logPath} пропал. Продолжу отслеживание, когда появится." + title: 'Log Lost', + text: "Log {logPath} has disappeared. The tracking will continue" + + " automatically when the log is back." }, logTruncated: { level: 'danger', - title: 'Лог сократился', - text: "Лог {logPath} сократился в размере.
" + - "Дальнейшее отслеживание может быть ошибочным.
В этом случае лучше начать его заново." + title: 'Log Reduced', + text: "Log {logPath} has become shorter.
" + + "Current tracking can become incorrect. Restart it if necessary." }, unrecognized: { level: 'warning', - title: 'Сообщение о слежении', - text: "При слежении за логом {logPath} получено сообщение:
" + + title: 'Tracking Notification', + text: "Log {logPath} produced a message:
" + "{message}" }, //
@@ -55,13 +56,13 @@ app.constant('notifications', { // serverFailure: { level: 'danger', - title: 'Сообщение от сервера', - text: "Отслеживание прекращено из-за ошибки:
{message}" + title: 'Server Message', + text: "Tracking has been stopped because of error:
{message}" }, choicesNotFound: { level: 'danger', - title: 'Сбой на сервере', - text: "Не удалось получить варианты логов из-за ошибки:
" + + title: 'Server Failure', + text: "Couldn't fetch log choices because of error:
" + "{message}" } //
diff --git a/src/main/resources/static/ru/download/download.component.js b/src/main/resources/static/ru/download/download.component.js new file mode 100644 index 0000000..899be17 --- /dev/null +++ b/src/main/resources/static/ru/download/download.component.js @@ -0,0 +1,174 @@ +function DownloadController($scope, $element, $attrs, $log, $http) { + let ctrl = this; + + // behavioral (non-visual) state of controller + ctrl.isShowingDialog = false; + ctrl.isShowingButton = false; + ctrl.lastError = undefined; + ctrl.isLoading = false; + ctrl.file2Download = undefined; + + // visual state of controller + ctrl.currentSize = undefined; + ctrl.lastModified = undefined; + ctrl.node = undefined; + ctrl.downloadLink = undefined; + ctrl.allMembers = []; + + ctrl.toggleDialog = function () { + ctrl.isShowingDialog = !ctrl.isShowingDialog; + if (!ctrl.isShowingDialog) + return; + // $log.log("Going to request data for: %o", ctrl.selectedLog); + ctrl.initDialogData(); + }; + + ctrl.initDialogData = function() { + if (!ctrl.selectedLog) { + return []; + } + let path = extractPath(ctrl.selectedLog.id); + let firstMember = { + node: ctrl.selectedLog.node, + path: path, + file: extractFileName(path) + }; + // NOTE: The following assignment will trigger fetchDataFromServer() via corresponding $watch! + ctrl.file2Download = firstMember; + ctrl.allMembers = new Array(firstMember); +/* TODO fix inclusion choice for composite logs + if (ctrl.selectedLog.includes) { + var otherMembers = ctrl.selectedLog.includes.map(function (member) { + return { + node: member.node, + path: member.path, + file: extractFileName(member.path) + } + }); + ctrl.allMembers = ctrl.allMembers.concat(otherMembers); + } +*/ + }; + + ctrl.fetchDataFromServer = function () { + let uriPath = '/download?path=' + ctrl.file2Download.path; + // it doesn't matter whether specified node is remote or local; server will handle it itself + if (angular.isDefined(ctrl.file2Download.node)) { + uriPath += ("&node=" + ctrl.file2Download.node); + } + ctrl.isLoading = true; + $http.head(uriPath) + .then( + // if OK + function (response) { + ctrl.currentSize = response.headers('Content-Length'); + ctrl.lastModified = response.headers('Last-Modified'); + ctrl.lastError = undefined; + ctrl.downloadLink = uriPath; + ctrl.isLoading = false; + }, + // if FAIL + function (response) { + // $log.log("Failed to request data from server: %o", response); + ctrl.lastError = { + status: response.status, + message: response.statusText + }; + ctrl.currentSize = undefined; + ctrl.lastModified = undefined; + ctrl.downloadLink = undefined; + ctrl.isLoading = false; + }) + }; + + ctrl.onDownloadClick = function () { + if (ctrl.lastError || ctrl.isLoading) { + return false; // to prevent any actions of the link in case of error or in-progress loading + + } else { + ctrl.closeDialog(); + } + // don't return anything in order to let the caller proceed normally + }; + + ctrl.closeDialog = function () { + ctrl.isShowingDialog = false; + }; + + // the following watch allows to react instantly on selected log changes when download dialog is open + $scope.$watch(function () { + return ctrl.selectedLog; + }, function () { + if (ctrl.isShowingDialog) { + ctrl.initDialogData(); + } + if (ctrl.selectedLog) { + ctrl.isShowingButton = (ctrl.selectedLog.type === "LOCAL_FILE") || (ctrl.selectedLog.type === "NODE"); + } + }); + + // the following watch allows to react instantly on changes of selected file among composite log's file list + $scope.$watch(function () { + return ctrl.file2Download; + }, function () { + if (ctrl.isShowingDialog) + ctrl.fetchDataFromServer(); + }); +} + +app.filter('sizeFormatter', function() { + return function(bytes) { + if (!bytes) + return '[н/д]'; + if (bytes === 0) + return '0 Байт'; + let k = 1024, + dm = /*decimals ||*/ 2, + sizes = ['Байт', 'КБ', 'МБ', 'ГБ', 'ТБ', 'ПБ', 'ЭБ', 'ЗБ', 'YB'], + i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; + }; +}); + +app.filter('dateFormatter', function () { + return function (utcDateString) { + if (!utcDateString) + return '[н/д]'; + let parsedDate = new Date(Date.parse(utcDateString)); + return parsedDate.toLocaleString("ru-RU"); + } +}); + +app.filter('errorFormatter', function () { + return function (error) { + if (!error) + return 'OK'; + let text; + switch (error.status) { + case 404: + text = 'не найден'; + break; + case 403: + text = 'запрещён для загрузки'; + break; + case 503: + text = 'временно не доступен'; + break; + default: + text = 'не может быть получен'; + } + text += (' ' + '(HTTP ' + error.status); + if (error.message) + text += (' ' + error.message); + text += ')'; + return text; + } +}); + +app.component('downloadDialog', { + templateUrl: 'download/download.template.html', + controller: DownloadController, + bindings: { + selectedLog: '<' + } +}); \ No newline at end of file diff --git a/src/main/resources/static/ru/download/download.style.css b/src/main/resources/static/ru/download/download.style.css new file mode 100644 index 0000000..b29f0ee --- /dev/null +++ b/src/main/resources/static/ru/download/download.style.css @@ -0,0 +1,59 @@ +.loader { + border: 3px solid #de891b; + border-top: 3px solid #ffffff; + border-radius: 80%; + width: 15px; + height: 15px; + animation: spin 1000ms linear infinite; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.dialog-header { + display: flex; + align-items: center; +} + +.dialog-header h4 { + margin-right: 5px; +} + +.panel { + position: fixed; + margin-top: 5px; +} + +.panel table { + margin-bottom: 10px; +} + +.panel table tr { + line-height: 0.8; +} + +.panel .cancel { + margin-left: 15px; +} + +.node-list { + display: block; + /* width: 100%; */ + /* height: 38px; */ + padding: 1px 5px; + font-size: 14px; + line-height: 1.428571; + color: #272b30; + background: #ffffff none; + border: 1px solid #000000; + /*border-radius: 4px;*/ + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + -webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; +} + + diff --git a/src/main/resources/static/ru/download/download.template.html b/src/main/resources/static/ru/download/download.template.html new file mode 100644 index 0000000..cefb3d7 --- /dev/null +++ b/src/main/resources/static/ru/download/download.template.html @@ -0,0 +1,71 @@ +
+ + +
+
+
+

Контрольная сводка

+
+
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + +
Файл + +
Узел{{$ctrl.file2Download.node || 'текущий'}}
Путь{{$ctrl.file2Download.path}}
Изменен{{$ctrl.lastModified | dateFormatter}}
Размер{{$ctrl.currentSize | sizeFormatter}}
Статус{{$ctrl.lastError | errorFormatter}}
+ + + Отмена +
+
+
diff --git a/src/main/resources/static/ru/favicon.ico b/src/main/resources/static/ru/favicon.ico new file mode 100644 index 0000000..2979a08 Binary files /dev/null and b/src/main/resources/static/ru/favicon.ico differ diff --git a/src/main/resources/static/ru/general/css/bootstrap-with-slate-theme.min.css b/src/main/resources/static/ru/general/css/bootstrap-with-slate-theme.min.css new file mode 100644 index 0000000..c7ce011 --- /dev/null +++ b/src/main/resources/static/ru/general/css/bootstrap-with-slate-theme.min.css @@ -0,0 +1,11 @@ +/*! + * bootswatch v3.3.7 + * Homepage: http://bootswatch.com + * Copyright 2012-2017 Thomas Park + * Licensed under MIT + * Based on Bootstrap +*//*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('../general/fonts/glyphicons-halflings-regular.eot');src:url('../general/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'),url('../general/fonts/glyphicons-halflings-regular.woff') format('woff'),url('../general/fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../general/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')} .glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale} .glyphicon-asterisk:before{content:"\002a"} .glyphicon-plus:before{content:"\002b"} .glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"} .glyphicon-minus:before{content:"\2212"} .glyphicon-cloud:before{content:"\2601"} .glyphicon-envelope:before{content:"\2709"} .glyphicon-pencil:before{content:"\270f"} .glyphicon-glass:before{content:"\e001"} .glyphicon-music:before{content:"\e002"} .glyphicon-search:before{content:"\e003"} .glyphicon-heart:before{content:"\e005"} .glyphicon-star:before{content:"\e006"} .glyphicon-star-empty:before{content:"\e007"} .glyphicon-user:before{content:"\e008"} .glyphicon-film:before{content:"\e009"} .glyphicon-th-large:before{content:"\e010"} .glyphicon-th:before{content:"\e011"} .glyphicon-th-list:before{content:"\e012"} .glyphicon-ok:before{content:"\e013"} .glyphicon-remove:before{content:"\e014"} .glyphicon-zoom-in:before{content:"\e015"} .glyphicon-zoom-out:before{content:"\e016"} .glyphicon-off:before{content:"\e017"} .glyphicon-signal:before{content:"\e018"} .glyphicon-cog:before{content:"\e019"} .glyphicon-trash:before{content:"\e020"} .glyphicon-home:before{content:"\e021"} .glyphicon-file:before{content:"\e022"} .glyphicon-time:before{content:"\e023"} .glyphicon-road:before{content:"\e024"} .glyphicon-download-alt:before{content:"\e025"} .glyphicon-download:before{content:"\e026"} .glyphicon-upload:before{content:"\e027"} .glyphicon-inbox:before{content:"\e028"} .glyphicon-play-circle:before{content:"\e029"} .glyphicon-repeat:before{content:"\e030"} .glyphicon-refresh:before{content:"\e031"} .glyphicon-list-alt:before{content:"\e032"} .glyphicon-lock:before{content:"\e033"} .glyphicon-flag:before{content:"\e034"} .glyphicon-headphones:before{content:"\e035"} .glyphicon-volume-off:before{content:"\e036"} .glyphicon-volume-down:before{content:"\e037"} .glyphicon-volume-up:before{content:"\e038"} .glyphicon-qrcode:before{content:"\e039"} .glyphicon-barcode:before{content:"\e040"} .glyphicon-tag:before{content:"\e041"} .glyphicon-tags:before{content:"\e042"} .glyphicon-book:before{content:"\e043"} .glyphicon-bookmark:before{content:"\e044"} .glyphicon-print:before{content:"\e045"} .glyphicon-camera:before{content:"\e046"} .glyphicon-font:before{content:"\e047"} .glyphicon-bold:before{content:"\e048"} .glyphicon-italic:before{content:"\e049"} .glyphicon-text-height:before{content:"\e050"} .glyphicon-text-width:before{content:"\e051"} .glyphicon-align-left:before{content:"\e052"} .glyphicon-align-center:before{content:"\e053"} .glyphicon-align-right:before{content:"\e054"} .glyphicon-align-justify:before{content:"\e055"} .glyphicon-list:before{content:"\e056"} .glyphicon-indent-left:before{content:"\e057"} .glyphicon-indent-right:before{content:"\e058"} .glyphicon-facetime-video:before{content:"\e059"} .glyphicon-picture:before{content:"\e060"} .glyphicon-map-marker:before{content:"\e062"} .glyphicon-adjust:before{content:"\e063"} .glyphicon-tint:before{content:"\e064"} .glyphicon-edit:before{content:"\e065"} .glyphicon-share:before{content:"\e066"} .glyphicon-check:before{content:"\e067"} .glyphicon-move:before{content:"\e068"} .glyphicon-step-backward:before{content:"\e069"} .glyphicon-fast-backward:before{content:"\e070"} .glyphicon-backward:before{content:"\e071"} .glyphicon-play:before{content:"\e072"} .glyphicon-pause:before{content:"\e073"} .glyphicon-stop:before{content:"\e074"} .glyphicon-forward:before{content:"\e075"} .glyphicon-fast-forward:before{content:"\e076"} .glyphicon-step-forward:before{content:"\e077"} .glyphicon-eject:before{content:"\e078"} .glyphicon-chevron-left:before{content:"\e079"} .glyphicon-chevron-right:before{content:"\e080"} .glyphicon-plus-sign:before{content:"\e081"} .glyphicon-minus-sign:before{content:"\e082"} .glyphicon-remove-sign:before{content:"\e083"} .glyphicon-ok-sign:before{content:"\e084"} .glyphicon-question-sign:before{content:"\e085"} .glyphicon-info-sign:before{content:"\e086"} .glyphicon-screenshot:before{content:"\e087"} .glyphicon-remove-circle:before{content:"\e088"} .glyphicon-ok-circle:before{content:"\e089"} .glyphicon-ban-circle:before{content:"\e090"} .glyphicon-arrow-left:before{content:"\e091"} .glyphicon-arrow-right:before{content:"\e092"} .glyphicon-arrow-up:before{content:"\e093"} .glyphicon-arrow-down:before{content:"\e094"} .glyphicon-share-alt:before{content:"\e095"} .glyphicon-resize-full:before{content:"\e096"} .glyphicon-resize-small:before{content:"\e097"} .glyphicon-exclamation-sign:before{content:"\e101"} .glyphicon-gift:before{content:"\e102"} .glyphicon-leaf:before{content:"\e103"} .glyphicon-fire:before{content:"\e104"} .glyphicon-eye-open:before{content:"\e105"} .glyphicon-eye-close:before{content:"\e106"} .glyphicon-warning-sign:before{content:"\e107"} .glyphicon-plane:before{content:"\e108"} .glyphicon-calendar:before{content:"\e109"} .glyphicon-random:before{content:"\e110"} .glyphicon-comment:before{content:"\e111"} .glyphicon-magnet:before{content:"\e112"} .glyphicon-chevron-up:before{content:"\e113"} .glyphicon-chevron-down:before{content:"\e114"} .glyphicon-retweet:before{content:"\e115"} .glyphicon-shopping-cart:before{content:"\e116"} .glyphicon-folder-close:before{content:"\e117"} .glyphicon-folder-open:before{content:"\e118"} .glyphicon-resize-vertical:before{content:"\e119"} .glyphicon-resize-horizontal:before{content:"\e120"} .glyphicon-hdd:before{content:"\e121"} .glyphicon-bullhorn:before{content:"\e122"} .glyphicon-bell:before{content:"\e123"} .glyphicon-certificate:before{content:"\e124"} .glyphicon-thumbs-up:before{content:"\e125"} .glyphicon-thumbs-down:before{content:"\e126"} .glyphicon-hand-right:before{content:"\e127"} .glyphicon-hand-left:before{content:"\e128"} .glyphicon-hand-up:before{content:"\e129"} .glyphicon-hand-down:before{content:"\e130"} .glyphicon-circle-arrow-right:before{content:"\e131"} .glyphicon-circle-arrow-left:before{content:"\e132"} .glyphicon-circle-arrow-up:before{content:"\e133"} .glyphicon-circle-arrow-down:before{content:"\e134"} .glyphicon-globe:before{content:"\e135"} .glyphicon-wrench:before{content:"\e136"} .glyphicon-tasks:before{content:"\e137"} .glyphicon-filter:before{content:"\e138"} .glyphicon-briefcase:before{content:"\e139"} .glyphicon-fullscreen:before{content:"\e140"} .glyphicon-dashboard:before{content:"\e141"} .glyphicon-paperclip:before{content:"\e142"} .glyphicon-heart-empty:before{content:"\e143"} .glyphicon-link:before{content:"\e144"} .glyphicon-phone:before{content:"\e145"} .glyphicon-pushpin:before{content:"\e146"} .glyphicon-usd:before{content:"\e148"} .glyphicon-gbp:before{content:"\e149"} .glyphicon-sort:before{content:"\e150"} .glyphicon-sort-by-alphabet:before{content:"\e151"} .glyphicon-sort-by-alphabet-alt:before{content:"\e152"} .glyphicon-sort-by-order:before{content:"\e153"} .glyphicon-sort-by-order-alt:before{content:"\e154"} .glyphicon-sort-by-attributes:before{content:"\e155"} .glyphicon-sort-by-attributes-alt:before{content:"\e156"} .glyphicon-unchecked:before{content:"\e157"} .glyphicon-expand:before{content:"\e158"} .glyphicon-collapse-down:before{content:"\e159"} .glyphicon-collapse-up:before{content:"\e160"} .glyphicon-log-in:before{content:"\e161"} .glyphicon-flash:before{content:"\e162"} .glyphicon-log-out:before{content:"\e163"} .glyphicon-new-window:before{content:"\e164"} .glyphicon-record:before{content:"\e165"} .glyphicon-save:before{content:"\e166"} .glyphicon-open:before{content:"\e167"} .glyphicon-saved:before{content:"\e168"} .glyphicon-import:before{content:"\e169"} .glyphicon-export:before{content:"\e170"} .glyphicon-send:before{content:"\e171"} .glyphicon-floppy-disk:before{content:"\e172"} .glyphicon-floppy-saved:before{content:"\e173"} .glyphicon-floppy-remove:before{content:"\e174"} .glyphicon-floppy-save:before{content:"\e175"} .glyphicon-floppy-open:before{content:"\e176"} .glyphicon-credit-card:before{content:"\e177"} .glyphicon-transfer:before{content:"\e178"} .glyphicon-cutlery:before{content:"\e179"} .glyphicon-header:before{content:"\e180"} .glyphicon-compressed:before{content:"\e181"} .glyphicon-earphone:before{content:"\e182"} .glyphicon-phone-alt:before{content:"\e183"} .glyphicon-tower:before{content:"\e184"} .glyphicon-stats:before{content:"\e185"} .glyphicon-sd-video:before{content:"\e186"} .glyphicon-hd-video:before{content:"\e187"} .glyphicon-subtitles:before{content:"\e188"} .glyphicon-sound-stereo:before{content:"\e189"} .glyphicon-sound-dolby:before{content:"\e190"} .glyphicon-sound-5-1:before{content:"\e191"} .glyphicon-sound-6-1:before{content:"\e192"} .glyphicon-sound-7-1:before{content:"\e193"} .glyphicon-copyright-mark:before{content:"\e194"} .glyphicon-registration-mark:before{content:"\e195"} .glyphicon-cloud-download:before{content:"\e197"} .glyphicon-cloud-upload:before{content:"\e198"} .glyphicon-tree-conifer:before{content:"\e199"} .glyphicon-tree-deciduous:before{content:"\e200"} .glyphicon-cd:before{content:"\e201"} .glyphicon-save-file:before{content:"\e202"} .glyphicon-open-file:before{content:"\e203"} .glyphicon-level-up:before{content:"\e204"} .glyphicon-copy:before{content:"\e205"} .glyphicon-paste:before{content:"\e206"} .glyphicon-alert:before{content:"\e209"} .glyphicon-equalizer:before{content:"\e210"} .glyphicon-king:before{content:"\e211"} .glyphicon-queen:before{content:"\e212"} .glyphicon-pawn:before{content:"\e213"} .glyphicon-bishop:before{content:"\e214"} .glyphicon-knight:before{content:"\e215"} .glyphicon-baby-formula:before{content:"\e216"} .glyphicon-tent:before{content:"\26fa"} .glyphicon-blackboard:before{content:"\e218"} .glyphicon-bed:before{content:"\e219"} .glyphicon-apple:before{content:"\f8ff"} .glyphicon-erase:before{content:"\e221"} .glyphicon-hourglass:before{content:"\231b"} .glyphicon-lamp:before{content:"\e223"} .glyphicon-duplicate:before{content:"\e224"} .glyphicon-piggy-bank:before{content:"\e225"} .glyphicon-scissors:before{content:"\e226"} .glyphicon-bitcoin:before{content:"\e227"} .glyphicon-btc:before{content:"\e227"} .glyphicon-xbt:before{content:"\e227"} .glyphicon-yen:before{content:"\00a5"} .glyphicon-jpy:before{content:"\00a5"} .glyphicon-ruble:before{content:"\20bd"} .glyphicon-rub:before{content:"\20bd"} .glyphicon-scale:before{content:"\e230"} .glyphicon-ice-lolly:before{content:"\e231"} .glyphicon-ice-lolly-tasted:before{content:"\e232"} .glyphicon-education:before{content:"\e233"} .glyphicon-option-horizontal:before{content:"\e234"} .glyphicon-option-vertical:before{content:"\e235"} .glyphicon-menu-hamburger:before{content:"\e236"} .glyphicon-modal-window:before{content:"\e237"} .glyphicon-oil:before{content:"\e238"} .glyphicon-grain:before{content:"\e239"} .glyphicon-sunglasses:before{content:"\e240"} .glyphicon-text-size:before{content:"\e241"} .glyphicon-text-color:before{content:"\e242"} .glyphicon-text-background:before{content:"\e243"} .glyphicon-object-align-top:before{content:"\e244"} .glyphicon-object-align-bottom:before{content:"\e245"} .glyphicon-object-align-horizontal:before{content:"\e246"} .glyphicon-object-align-left:before{content:"\e247"} .glyphicon-object-align-vertical:before{content:"\e248"} .glyphicon-object-align-right:before{content:"\e249"} .glyphicon-triangle-right:before{content:"\e250"} .glyphicon-triangle-left:before{content:"\e251"} .glyphicon-triangle-bottom:before{content:"\e252"} .glyphicon-triangle-top:before{content:"\e253"} .glyphicon-console:before{content:"\e254"} .glyphicon-superscript:before{content:"\e255"} .glyphicon-subscript:before{content:"\e256"} .glyphicon-menu-left:before{content:"\e257"} .glyphicon-menu-right:before{content:"\e258"} .glyphicon-menu-down:before{content:"\e259"} .glyphicon-menu-up:before{content:"\e260"} *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} *:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)} body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#c8c8c8;background-color:#272b30} input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit} a{color:#ffffff;text-decoration:none} a:hover,a:focus{color:#ffffff;text-decoration:underline} a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px} figure{margin:0} img{vertical-align:middle} .img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto} .img-rounded{border-radius:6px} .img-thumbnail{padding:4px;line-height:1.42857143;background-color:#1c1e22;border:1px solid #0c0d0e;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto} .img-circle{border-radius:50%} hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #1c1e22} .sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0} .sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} [role="button"]{cursor:pointer} h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1;color:inherit} h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#7a8288} h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px} h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%} h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px} h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%} h1,.h1{font-size:36px} h2,.h2{font-size:30px} h3,.h3{font-size:24px} h4,.h4{font-size:18px} h5,.h5{font-size:14px} h6,.h6{font-size:12px} p{margin:0 0 10px} .lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}} small,.small{font-size:85%} mark,.mark{background-color:#f89406;padding:.2em} .text-left{text-align:left} .text-right{text-align:right} .text-center{text-align:center} .text-justify{text-align:justify} .text-nowrap{white-space:nowrap} .text-lowercase{text-transform:lowercase} .text-uppercase{text-transform:uppercase} .text-capitalize{text-transform:capitalize} .text-muted{color:#7a8288} .text-primary{color:#7a8288} a.text-primary:hover,a.text-primary:focus{color:#62686d} .text-success{color:#ffffff} a.text-success:hover,a.text-success:focus{color:#e6e6e6} .text-info{color:#ffffff} a.text-info:hover,a.text-info:focus{color:#e6e6e6} .text-warning{color:#ffffff} a.text-warning:hover,a.text-warning:focus{color:#e6e6e6} .text-danger{color:#ffffff} a.text-danger:hover,a.text-danger:focus{color:#e6e6e6} .bg-primary{color:#fff;background-color:#7a8288} a.bg-primary:hover,a.bg-primary:focus{background-color:#62686d} .bg-success{background-color:#62c462} a.bg-success:hover,a.bg-success:focus{background-color:#42b142} .bg-info{background-color:#5bc0de} a.bg-info:hover,a.bg-info:focus{background-color:#31b0d5} .bg-warning{background-color:#f89406} a.bg-warning:hover,a.bg-warning:focus{background-color:#c67605} .bg-danger{background-color:#ee5f5b} a.bg-danger:hover,a.bg-danger:focus{background-color:#e9322d} .page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #1c1e22} ul,ol{margin-top:0;margin-bottom:10px} ul ul,ol ul,ul ol,ol ol{margin-bottom:0} .list-unstyled{padding-left:0;list-style:none} .list-inline{padding-left:0;list-style:none;margin-left:-5px} .list-inline>li{display:inline-block;padding-left:5px;padding-right:5px} dl{margin-top:0;margin-bottom:20px} dt,dd{line-height:1.42857143} dt{font-weight:bold} dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}} abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #7a8288} .initialism{font-size:90%;text-transform:uppercase} blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #7a8288} blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0} blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#7a8288} blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'} .blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #7a8288;border-left:0;text-align:right} .blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''} .blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'} address{margin-bottom:20px;font-style:normal;line-height:1.42857143} code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace} code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px} kbd{padding:2px 4px;font-size:90%;color:#ffffff;background-color:#333333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)} kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none} pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#3a3f44;background-color:#f5f5f5;border:1px solid #cccccc;border-radius:4px} pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0} .pre-scrollable{max-height:340px;overflow-y:scroll} .container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}} .container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px} .row{margin-left:-15px;margin-right:-15px} .col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px} .col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left} .col-xs-12{width:100%} .col-xs-11{width:91.66666667%} .col-xs-10{width:83.33333333%} .col-xs-9{width:75%} .col-xs-8{width:66.66666667%} .col-xs-7{width:58.33333333%} .col-xs-6{width:50%} .col-xs-5{width:41.66666667%} .col-xs-4{width:33.33333333%} .col-xs-3{width:25%} .col-xs-2{width:16.66666667%} .col-xs-1{width:8.33333333%} .col-xs-pull-12{right:100%} .col-xs-pull-11{right:91.66666667%} .col-xs-pull-10{right:83.33333333%} .col-xs-pull-9{right:75%} .col-xs-pull-8{right:66.66666667%} .col-xs-pull-7{right:58.33333333%} .col-xs-pull-6{right:50%} .col-xs-pull-5{right:41.66666667%} .col-xs-pull-4{right:33.33333333%} .col-xs-pull-3{right:25%} .col-xs-pull-2{right:16.66666667%} .col-xs-pull-1{right:8.33333333%} .col-xs-pull-0{right:auto} .col-xs-push-12{left:100%} .col-xs-push-11{left:91.66666667%} .col-xs-push-10{left:83.33333333%} .col-xs-push-9{left:75%} .col-xs-push-8{left:66.66666667%} .col-xs-push-7{left:58.33333333%} .col-xs-push-6{left:50%} .col-xs-push-5{left:41.66666667%} .col-xs-push-4{left:33.33333333%} .col-xs-push-3{left:25%} .col-xs-push-2{left:16.66666667%} .col-xs-push-1{left:8.33333333%} .col-xs-push-0{left:auto} .col-xs-offset-12{margin-left:100%} .col-xs-offset-11{margin-left:91.66666667%} .col-xs-offset-10{margin-left:83.33333333%} .col-xs-offset-9{margin-left:75%} .col-xs-offset-8{margin-left:66.66666667%} .col-xs-offset-7{margin-left:58.33333333%} .col-xs-offset-6{margin-left:50%} .col-xs-offset-5{margin-left:41.66666667%} .col-xs-offset-4{margin-left:33.33333333%} .col-xs-offset-3{margin-left:25%} .col-xs-offset-2{margin-left:16.66666667%} .col-xs-offset-1{margin-left:8.33333333%} .col-xs-offset-0{margin-left:0%}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}} table{background-color:#2e3338} caption{padding-top:8px;padding-bottom:8px;color:#7a8288;text-align:left} th{text-align:left} .table{width:100%;max-width:100%;margin-bottom:20px} .table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #1c1e22} .table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #1c1e22} .table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0} .table>tbody+tbody{border-top:2px solid #1c1e22} .table .table{background-color:#272b30} .table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px} .table-bordered{border:1px solid #1c1e22} .table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #1c1e22} .table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px} .table-striped>tbody>tr:nth-of-type(odd){background-color:#353a41} .table-hover>tbody>tr:hover{background-color:#49515a} table col[class*="col-"]{position:static;float:none;display:table-column} table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell} .table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#49515a} .table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#3e444c} .table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#62c462} .table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#4fbd4f} .table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#5bc0de} .table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#46b8da} .table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#f89406} .table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#df8505} .table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#ee5f5b} .table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ec4844} .table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #1c1e22}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}} fieldset{padding:0;margin:0;border:0;min-width:0} legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#c8c8c8;border:0;border-bottom:1px solid #1c1e22} label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold} input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal} input[type="file"]{display:block} input[type="range"]{display:block;width:100%} select[multiple],select[size]{height:auto} input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px} output{display:block;padding-top:9px;font-size:14px;line-height:1.42857143;color:#272b30} .form-control{display:block;width:100%;height:38px;padding:8px 12px;font-size:14px;line-height:1.42857143;color:#272b30;background-color:#ffffff;background-image:none;border:1px solid #000000;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s} .form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)} .form-control::-moz-placeholder{color:#7a8288;opacity:1} .form-control:-ms-input-placeholder{color:#7a8288} .form-control::-webkit-input-placeholder{color:#7a8288} .form-control::-ms-expand{border:0;background-color:transparent} .form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#999999;opacity:1} .form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed} textarea.form-control{height:auto} input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:38px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:54px}} .form-group{margin-bottom:15px} .radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px} .radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer} .radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9} .radio+.radio,.checkbox+.checkbox{margin-top:-5px} .radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer} .radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px} input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed} .radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed} .radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed} .form-control-static{padding-top:9px;padding-bottom:9px;margin-bottom:0;min-height:34px} .form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0} .input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px} select.input-sm{height:30px;line-height:30px} textarea.input-sm,select[multiple].input-sm{height:auto} .form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px} .form-group-sm select.form-control{height:30px;line-height:30px} .form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto} .form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5} .input-lg{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px} select.input-lg{height:54px;line-height:54px} textarea.input-lg,select[multiple].input-lg{height:auto} .form-group-lg .form-control{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px} .form-group-lg select.form-control{height:54px;line-height:54px} .form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto} .form-group-lg .form-control-static{height:54px;min-height:38px;padding:15px 16px;font-size:18px;line-height:1.3333333} .has-feedback{position:relative} .has-feedback .form-control{padding-right:47.5px} .form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:38px;height:38px;line-height:38px;text-align:center;pointer-events:none} .input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:54px;height:54px;line-height:54px} .input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px} .has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#ffffff} .has-success .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)} .has-success .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff} .has-success .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#62c462} .has-success .form-control-feedback{color:#ffffff} .has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#ffffff} .has-warning .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)} .has-warning .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff} .has-warning .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#f89406} .has-warning .form-control-feedback{color:#ffffff} .has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#ffffff} .has-error .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)} .has-error .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff} .has-error .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#ee5f5b} .has-error .form-control-feedback{color:#ffffff} .has-feedback label~.form-control-feedback{top:25px} .has-feedback label.sr-only~.form-control-feedback{top:0} .help-block{display:block;margin-top:5px;margin-bottom:10px;color:#ffffff}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}} .form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:9px} .form-horizontal .radio,.form-horizontal .checkbox{min-height:29px} .form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:9px}} .form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:15px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}} .btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:8px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} .btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px} .btn:hover,.btn:focus,.btn.focus{color:#ffffff;text-decoration:none} .btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)} .btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none} a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none} .btn-default{color:#ffffff;background-color:#3a3f44;border-color:#3a3f44} .btn-default:focus,.btn-default.focus{color:#ffffff;background-color:#232628;border-color:#000000} .btn-default:hover{color:#ffffff;background-color:#232628;border-color:#1e2023} .btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#ffffff;background-color:#232628;border-color:#1e2023} .btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#ffffff;background-color:#121415;border-color:#000000} .btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none} .btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#3a3f44;border-color:#3a3f44} .btn-default .badge{color:#3a3f44;background-color:#ffffff} .btn-primary{color:#ffffff;background-color:#7a8288;border-color:#7a8288} .btn-primary:focus,.btn-primary.focus{color:#ffffff;background-color:#62686d;border-color:#3e4245} .btn-primary:hover{color:#ffffff;background-color:#62686d;border-color:#5d6368} .btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#62686d;border-color:#5d6368} .btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#ffffff;background-color:#51565a;border-color:#3e4245} .btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none} .btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#7a8288;border-color:#7a8288} .btn-primary .badge{color:#7a8288;background-color:#ffffff} .btn-success{color:#ffffff;background-color:#62c462;border-color:#62c462} .btn-success:focus,.btn-success.focus{color:#ffffff;background-color:#42b142;border-color:#2d792d} .btn-success:hover{color:#ffffff;background-color:#42b142;border-color:#40a940} .btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#42b142;border-color:#40a940} .btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#ffffff;background-color:#399739;border-color:#2d792d} .btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none} .btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#62c462;border-color:#62c462} .btn-success .badge{color:#62c462;background-color:#ffffff} .btn-info{color:#ffffff;background-color:#5bc0de;border-color:#5bc0de} .btn-info:focus,.btn-info.focus{color:#ffffff;background-color:#31b0d5;border-color:#1f7e9a} .btn-info:hover{color:#ffffff;background-color:#31b0d5;border-color:#2aabd2} .btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#31b0d5;border-color:#2aabd2} .btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#ffffff;background-color:#269abc;border-color:#1f7e9a} .btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none} .btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#5bc0de} .btn-info .badge{color:#5bc0de;background-color:#ffffff} .btn-warning{color:#ffffff;background-color:#f89406;border-color:#f89406} .btn-warning:focus,.btn-warning.focus{color:#ffffff;background-color:#c67605;border-color:#7c4a03} .btn-warning:hover{color:#ffffff;background-color:#c67605;border-color:#bc7005} .btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#c67605;border-color:#bc7005} .btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#ffffff;background-color:#a36104;border-color:#7c4a03} .btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none} .btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f89406;border-color:#f89406} .btn-warning .badge{color:#f89406;background-color:#ffffff} .btn-danger{color:#ffffff;background-color:#ee5f5b;border-color:#ee5f5b} .btn-danger:focus,.btn-danger.focus{color:#ffffff;background-color:#e9322d;border-color:#b71713} .btn-danger:hover{color:#ffffff;background-color:#e9322d;border-color:#e82924} .btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#e9322d;border-color:#e82924} .btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#ffffff;background-color:#dc1c17;border-color:#b71713} .btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none} .btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#ee5f5b;border-color:#ee5f5b} .btn-danger .badge{color:#ee5f5b;background-color:#ffffff} .btn-link{color:#ffffff;font-weight:normal;border-radius:0} .btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none} .btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent} .btn-link:hover,.btn-link:focus{color:#ffffff;text-decoration:underline;background-color:transparent} .btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#7a8288;text-decoration:none} .btn-lg,.btn-group-lg>.btn{padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px} .btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px} .btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px} .btn-block{display:block;width:100%} .btn-block+.btn-block{margin-top:5px} input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%} .fade{opacity:0;-webkit-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear} .fade.in{opacity:1} .collapse{display:none} .collapse.in{display:block} tr.collapse.in{display:table-row} tbody.collapse.in{display:table-row-group} .collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease} .caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent} .dropup,.dropdown{position:relative} .dropdown-toggle:focus{outline:0} .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;text-align:left;background-color:#3a3f44;border:1px solid #272b30;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box} .dropdown-menu.pull-right{right:0;left:auto} .dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#272b30} .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#c8c8c8;white-space:nowrap} .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#ffffff;background-color:#272b30} .dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#272b30} .dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#7a8288} .dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed} .open>.dropdown-menu{display:block} .open>a{outline:0} .dropdown-menu-right{left:auto;right:0} .dropdown-menu-left{left:0;right:auto} .dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#7a8288;white-space:nowrap} .dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990} .pull-right>.dropdown-menu{right:0;left:auto} .dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""} .dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}} .btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle} .btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left} .btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2} .btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px} .btn-toolbar{margin-left:-5px} .btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left} .btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px} .btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0} .btn-group>.btn:first-child{margin-left:0} .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0} .btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0} .btn-group>.btn-group{float:left} .btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0} .btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0} .btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0} .btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0} .btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px} .btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px} .btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)} .btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none} .btn .caret{margin-left:0} .btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0} .dropup .btn-lg .caret{border-width:0 5px 5px} .btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%} .btn-group-vertical>.btn-group>.btn{float:none} .btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0} .btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0} .btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0} .btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px} .btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0} .btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0} .btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0} .btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate} .btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%} .btn-group-justified>.btn-group .btn{width:100%} .btn-group-justified>.btn-group .dropdown-menu{left:auto} [data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none} .input-group{position:relative;display:table;border-collapse:separate} .input-group[class*="col-"]{float:none;padding-left:0;padding-right:0} .input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0} .input-group .form-control:focus{z-index:3} .input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px} select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:54px;line-height:54px} textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto} .input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px} select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px} textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto} .input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell} .input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0} .input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle} .input-group-addon{padding:8px 12px;font-size:14px;font-weight:normal;line-height:1;color:#272b30;text-align:center;background-color:#3a3f44;border:1px solid rgba(0,0,0,0.6);border-radius:4px} .input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px} .input-group-addon.input-lg{padding:14px 16px;font-size:18px;border-radius:6px} .input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0} .input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0} .input-group-addon:first-child{border-right:0} .input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0} .input-group-addon:last-child{border-left:0} .input-group-btn{position:relative;font-size:0;white-space:nowrap} .input-group-btn>.btn{position:relative} .input-group-btn>.btn+.btn{margin-left:-1px} .input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2} .input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px} .input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px} .nav{margin-bottom:0;padding-left:0;list-style:none} .nav>li{position:relative;display:block} .nav>li>a{position:relative;display:block;padding:10px 15px} .nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#3e444c} .nav>li.disabled>a{color:#7a8288} .nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#7a8288;text-decoration:none;background-color:transparent;cursor:not-allowed} .nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#3e444c;border-color:#ffffff} .nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5} .nav>li>a>img{max-width:none} .nav-tabs{border-bottom:1px solid #1c1e22} .nav-tabs>li{float:left;margin-bottom:-1px} .nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0} .nav-tabs>li>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22} .nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#ffffff;background-color:#3e444c;border:1px solid #1c1e22;border-bottom-color:transparent;cursor:default} .nav-tabs.nav-justified{width:100%;border-bottom:0} .nav-tabs.nav-justified>li{float:none} .nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px} .nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}} .nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px} .nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #1c1e22}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #1c1e22;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#272b30}} .nav-pills>li{float:left} .nav-pills>li>a{border-radius:4px} .nav-pills>li+li{margin-left:2px} .nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#ffffff;background-color:transparent} .nav-stacked>li{float:none} .nav-stacked>li+li{margin-top:2px;margin-left:0} .nav-justified{width:100%} .nav-justified>li{float:none} .nav-justified>li>a{text-align:center;margin-bottom:5px} .nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}} .nav-tabs-justified{border-bottom:0} .nav-tabs-justified>li>a{margin-right:0;border-radius:4px} .nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #1c1e22}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #1c1e22;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#272b30}} .tab-content>.tab-pane{display:none} .tab-content>.active{display:block} .nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0} .navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}} .navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch} .navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}} .navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}} .container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}} .navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}} .navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}} .navbar-fixed-top{top:0;border-width:0 0 1px} .navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0} .navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px;height:50px} .navbar-brand:hover,.navbar-brand:focus{text-decoration:none} .navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}} .navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px} .navbar-toggle:focus{outline:0} .navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px} .navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}} .navbar-nav{margin:7.5px -15px} .navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}} .navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:6px;margin-bottom:6px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}} .navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0} .navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0} .navbar-btn{margin-top:6px;margin-bottom:6px} .navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px} .navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px} .navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}} .navbar-default{background-color:#3a3f44;border-color:#2b2e32} .navbar-default .navbar-brand{color:#c8c8c8} .navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#ffffff;background-color:none} .navbar-default .navbar-text{color:#c8c8c8} .navbar-default .navbar-nav>li>a{color:#c8c8c8} .navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#ffffff;background-color:#272b2e} .navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#ffffff;background-color:#272b2e} .navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent} .navbar-default .navbar-toggle{border-color:#272b2e} .navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#272b2e} .navbar-default .navbar-toggle .icon-bar{background-color:#c8c8c8} .navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#2b2e32} .navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#272b2e;color:#ffffff}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#c8c8c8}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:#272b2e}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#272b2e}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#cccccc;background-color:transparent}} .navbar-default .navbar-link{color:#c8c8c8} .navbar-default .navbar-link:hover{color:#ffffff} .navbar-default .btn-link{color:#c8c8c8} .navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#ffffff} .navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#cccccc} .navbar-inverse{background-color:#7a8288;border-color:#62686d} .navbar-inverse .navbar-brand{color:#cccccc} .navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:none} .navbar-inverse .navbar-text{color:#cccccc} .navbar-inverse .navbar-nav>li>a{color:#cccccc} .navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:#5d6368} .navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:#5d6368} .navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent} .navbar-inverse .navbar-toggle{border-color:#5d6368} .navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#5d6368} .navbar-inverse .navbar-toggle .icon-bar{background-color:#ffffff} .navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#697075} .navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#5d6368;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#62686d}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#62686d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#cccccc}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:#5d6368}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#5d6368}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#cccccc;background-color:transparent}} .navbar-inverse .navbar-link{color:#cccccc} .navbar-inverse .navbar-link:hover{color:#ffffff} .navbar-inverse .btn-link{color:#cccccc} .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff} .navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#cccccc} .breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:transparent;border-radius:4px} .breadcrumb>li{display:inline-block} .breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#cccccc} .breadcrumb>.active{color:#7a8288} .pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px} .pagination>li{display:inline} .pagination>li>a,.pagination>li>span{position:relative;float:left;padding:8px 12px;line-height:1.42857143;text-decoration:none;color:#ffffff;background-color:#3a3f44;border:1px solid rgba(0,0,0,0.6);margin-left:-1px} .pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px} .pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px} .pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#ffffff;background-color:transparent;border-color:rgba(0,0,0,0.6)} .pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#ffffff;background-color:#232628;border-color:rgba(0,0,0,0.6);cursor:default} .pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#7a8288;background-color:#ffffff;border-color:rgba(0,0,0,0.6);cursor:not-allowed} .pagination-lg>li>a,.pagination-lg>li>span{padding:14px 16px;font-size:18px;line-height:1.3333333} .pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px} .pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px} .pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5} .pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px} .pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px} .pager{padding-left:0;margin:20px 0;list-style:none;text-align:center} .pager li{display:inline} .pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#3a3f44;border:1px solid rgba(0,0,0,0.6);border-radius:15px} .pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:transparent} .pager .next>a,.pager .next>span{float:right} .pager .previous>a,.pager .previous>span{float:left} .pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#7a8288;background-color:#3a3f44;cursor:not-allowed} .label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em} a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer} .label:empty{display:none} .btn .label{position:relative;top:-1px} .label-default{background-color:#3a3f44} .label-default[href]:hover,.label-default[href]:focus{background-color:#232628} .label-primary{background-color:#7a8288} .label-primary[href]:hover,.label-primary[href]:focus{background-color:#62686d} .label-success{background-color:#62c462} .label-success[href]:hover,.label-success[href]:focus{background-color:#42b142} .label-info{background-color:#5bc0de} .label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5} .label-warning{background-color:#f89406} .label-warning[href]:hover,.label-warning[href]:focus{background-color:#c67605} .label-danger{background-color:#ee5f5b} .label-danger[href]:hover,.label-danger[href]:focus{background-color:#e9322d} .badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#ffffff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#7a8288;border-radius:10px} .badge:empty{display:none} .btn .badge{position:relative;top:-1px} .btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px} a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer} .list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#ffffff;background-color:#7a8288} .list-group-item>.badge{float:right} .list-group-item>.badge+.badge{margin-right:5px} .nav-pills>li>a>.badge{margin-left:3px} .jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#1c1e22} .jumbotron h1,.jumbotron .h1{color:inherit} .jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200} .jumbotron>hr{border-top-color:#050506} .container .jumbotron,.container-fluid .jumbotron{border-radius:6px;padding-left:15px;padding-right:15px} .jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}} .thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#1c1e22;border:1px solid #0c0d0e;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out} .thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto} a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#ffffff} .thumbnail .caption{padding:9px;color:#c8c8c8} .alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px} .alert h4{margin-top:0;color:inherit} .alert .alert-link{font-weight:bold} .alert>p,.alert>ul{margin-bottom:0} .alert>p+p{margin-top:5px} .alert-dismissable,.alert-dismissible{padding-right:35px} .alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit} .alert-success{background-color:#62c462;border-color:#62bd4f;color:#ffffff} .alert-success hr{border-top-color:#55b142} .alert-success .alert-link{color:#e6e6e6} .alert-info{background-color:#5bc0de;border-color:#3dced8;color:#ffffff} .alert-info hr{border-top-color:#2ac7d2} .alert-info .alert-link{color:#e6e6e6} .alert-warning{background-color:#f89406;border-color:#e96506;color:#ffffff} .alert-warning hr{border-top-color:#d05a05} .alert-warning .alert-link{color:#e6e6e6} .alert-danger{background-color:#ee5f5b;border-color:#ed4d63;color:#ffffff} .alert-danger hr{border-top-color:#ea364f} .alert-danger .alert-link{color:#e6e6e6} @-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}} @-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}} @keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}} .progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#1c1e22;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)} .progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#ffffff;text-align:center;background-color:#7a8288;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease} .progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;background-size:40px 40px} .progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite} .progress-bar-success{background-color:#62c462} .progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)} .progress-bar-info{background-color:#5bc0de} .progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)} .progress-bar-warning{background-color:#f89406} .progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)} .progress-bar-danger{background-color:#ee5f5b} .progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)} .media{margin-top:15px} .media:first-child{margin-top:0} .media,.media-body{zoom:1;overflow:hidden} .media-body{width:10000px} .media-object{display:block} .media-object.img-thumbnail{max-width:none} .media-right,.media>.pull-right{padding-left:10px} .media-left,.media>.pull-left{padding-right:10px} .media-left,.media-right,.media-body{display:table-cell;vertical-align:top} .media-middle{vertical-align:middle} .media-bottom{vertical-align:bottom} .media-heading{margin-top:0;margin-bottom:5px} .media-list{padding-left:0;list-style:none} .list-group{margin-bottom:20px;padding-left:0} .list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#32383e;border:1px solid rgba(0,0,0,0.6)} .list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px} .list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px} a.list-group-item,button.list-group-item{color:#c8c8c8} a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#ffffff} a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#c8c8c8;background-color:#3e444c} button.list-group-item{width:100%;text-align:left} .list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#999999;color:#7a8288;cursor:not-allowed} .list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit} .list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#7a8288} .list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#3e444c;border-color:rgba(0,0,0,0.6)} .list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit} .list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#a2aab4} .list-group-item-success{color:#ffffff;background-color:#62c462} a.list-group-item-success,button.list-group-item-success{color:#ffffff} a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit} a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#ffffff;background-color:#4fbd4f} a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff} .list-group-item-info{color:#ffffff;background-color:#5bc0de} a.list-group-item-info,button.list-group-item-info{color:#ffffff} a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit} a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#ffffff;background-color:#46b8da} a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff} .list-group-item-warning{color:#ffffff;background-color:#f89406} a.list-group-item-warning,button.list-group-item-warning{color:#ffffff} a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit} a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#ffffff;background-color:#df8505} a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff} .list-group-item-danger{color:#ffffff;background-color:#ee5f5b} a.list-group-item-danger,button.list-group-item-danger{color:#ffffff} a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit} a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#ffffff;background-color:#ec4844} a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff} .list-group-item-heading{margin-top:0;margin-bottom:5px} .list-group-item-text{margin-bottom:0;line-height:1.3} .panel{margin-bottom:20px;background-color:#2e3338;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)} .panel-body{padding:15px} .panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px} .panel-heading>.dropdown .dropdown-toggle{color:inherit} .panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit} .panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit} .panel-footer{padding:10px 15px;background-color:#3e444c;border-top:1px solid rgba(0,0,0,0.6);border-bottom-right-radius:3px;border-bottom-left-radius:3px} .panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0} .panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0} .panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px} .panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px} .panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0} .panel-heading+.list-group .list-group-item:first-child{border-top-width:0} .list-group+.panel-footer{border-top-width:0} .panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0} .panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-left:15px;padding-right:15px} .panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px} .panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px} .panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px} .panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px} .panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px} .panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:3px;border-bottom-right-radius:3px} .panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px} .panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px} .panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #1c1e22} .panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0} .panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0} .panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0} .panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0} .panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0} .panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0} .panel>.table-responsive{border:0;margin-bottom:0} .panel-group{margin-bottom:20px} .panel-group .panel{margin-bottom:0;border-radius:4px} .panel-group .panel+.panel{margin-top:5px} .panel-group .panel-heading{border-bottom:0} .panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid rgba(0,0,0,0.6)} .panel-group .panel-footer{border-top:0} .panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid rgba(0,0,0,0.6)} .panel-default{border-color:rgba(0,0,0,0.6)} .panel-default>.panel-heading{color:#c8c8c8;background-color:#3e444c;border-color:rgba(0,0,0,0.6)} .panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)} .panel-default>.panel-heading .badge{color:#3e444c;background-color:#c8c8c8} .panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)} .panel-primary{border-color:rgba(0,0,0,0.6)} .panel-primary>.panel-heading{color:#ffffff;background-color:#7a8288;border-color:rgba(0,0,0,0.6)} .panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)} .panel-primary>.panel-heading .badge{color:#7a8288;background-color:#ffffff} .panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)} .panel-success{border-color:rgba(0,0,0,0.6)} .panel-success>.panel-heading{color:#ffffff;background-color:#62c462;border-color:rgba(0,0,0,0.6)} .panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)} .panel-success>.panel-heading .badge{color:#62c462;background-color:#ffffff} .panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)} .panel-info{border-color:rgba(0,0,0,0.6)} .panel-info>.panel-heading{color:#ffffff;background-color:#5bc0de;border-color:rgba(0,0,0,0.6)} .panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)} .panel-info>.panel-heading .badge{color:#5bc0de;background-color:#ffffff} .panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)} .panel-warning{border-color:rgba(0,0,0,0.6)} .panel-warning>.panel-heading{color:#ffffff;background-color:#f89406;border-color:rgba(0,0,0,0.6)} .panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)} .panel-warning>.panel-heading .badge{color:#f89406;background-color:#ffffff} .panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)} .panel-danger{border-color:rgba(0,0,0,0.6)} .panel-danger>.panel-heading{color:#ffffff;background-color:#ee5f5b;border-color:rgba(0,0,0,0.6)} .panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)} .panel-danger>.panel-heading .badge{color:#ee5f5b;background-color:#ffffff} .panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)} .embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden} .embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;bottom:0;height:100%;width:100%;border:0} .embed-responsive-16by9{padding-bottom:56.25%} .embed-responsive-4by3{padding-bottom:75%} .well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#1c1e22;border:1px solid #0c0d0e;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)} .well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)} .well-lg{padding:24px;border-radius:6px} .well-sm{padding:9px;border-radius:3px} .close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20)} .close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)} button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none} .modal-open{overflow:hidden} .modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0} .modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out} .modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)} .modal-open .modal{overflow-x:hidden;overflow-y:auto} .modal-dialog{position:relative;width:auto;margin:10px} .modal-content{position:relative;background-color:#2e3338;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0} .modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000} .modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)} .modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)} .modal-header{padding:15px;border-bottom:1px solid #1c1e22} .modal-header .close{margin-top:-2px} .modal-title{margin:0;line-height:1.42857143} .modal-body{position:relative;padding:20px} .modal-footer{padding:20px;text-align:right;border-top:1px solid #1c1e22} .modal-footer .btn+.btn{margin-left:5px;margin-bottom:0} .modal-footer .btn-group .btn+.btn{margin-left:-1px} .modal-footer .btn-block+.btn-block{margin-left:0} .modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}} .tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)} .tooltip.in{opacity:0.9;filter:alpha(opacity=90)} .tooltip.top{margin-top:-3px;padding:5px 0} .tooltip.right{margin-left:3px;padding:0 5px} .tooltip.bottom{margin-top:3px;padding:5px 0} .tooltip.left{margin-left:-3px;padding:0 5px} .tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;background-color:#000000;border-radius:4px} .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid} .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000} .tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000000} .tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000000} .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000} .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000} .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000} .tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000000} .tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000000} .popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:14px;background-color:#2e3338;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)} .popover.top{margin-top:-10px} .popover.right{margin-left:10px} .popover.bottom{margin-top:10px} .popover.left{margin-left:-10px} .popover-title{margin:0;padding:8px 14px;font-size:14px;background-color:#2e3338;border-bottom:1px solid #22262a;border-radius:5px 5px 0 0} .popover-content{padding:9px 14px} .popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid} .popover>.arrow{border-width:11px} .popover>.arrow:after{border-width:10px;content:""} .popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#666666;border-top-color:rgba(0,0,0,0.25);bottom:-11px} .popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#2e3338} .popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#666666;border-right-color:rgba(0,0,0,0.25)} .popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#2e3338} .popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#666666;border-bottom-color:rgba(0,0,0,0.25);top:-11px} .popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#2e3338} .popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#666666;border-left-color:rgba(0,0,0,0.25)} .popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#2e3338;bottom:-10px} .carousel{position:relative} .carousel-inner{position:relative;overflow:hidden;width:100%} .carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left} .carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left:0}} .carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block} .carousel-inner>.active{left:0} .carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%} .carousel-inner>.next{left:100%} .carousel-inner>.prev{left:-100%} .carousel-inner>.next.left,.carousel-inner>.prev.right{left:0} .carousel-inner>.active.left{left:-100%} .carousel-inner>.active.right{left:100%} .carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)} .carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)} .carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)} .carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)} .carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;z-index:5;display:inline-block} .carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px} .carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px} .carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;line-height:1;font-family:serif} .carousel-control .icon-prev:before{content:'\2039'} .carousel-control .icon-next:before{content:'\203a'} .carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center} .carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)} .carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff} .carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)} .carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}} .clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table} .clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both} .center-block{display:block;margin-left:auto;margin-right:auto} .pull-right{float:right !important} .pull-left{float:left !important} .hide{display:none !important} .show{display:block !important} .invisible{visibility:hidden} .text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0} .hidden{display:none !important} .affix{position:fixed}@-ms-viewport{width:device-width} .visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important} .visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}} .visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}} .visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}} .visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}} .visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}} .navbar-default,.navbar-inverse{border:1px solid rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3)}@media (min-width:768px){.navbar-default .navbar-nav>li>a,.navbar-inverse .navbar-nav>li>a{border-right:1px solid rgba(0,0,0,0.2);border-left:1px solid rgba(255,255,255,0.1)}.navbar-default .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:hover{border-left-color:transparent}.navbar-default .nav .open>a,.navbar-inverse .nav .open>a{border-color:transparent}.navbar-default .navbar-nav>li.active>a,.navbar-inverse .navbar-nav>li.active>a{border-left-color:transparent}.navbar-default .navbar-form,.navbar-inverse .navbar-form{margin-left:5px;margin-right:5px}} .navbar-default{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none} .navbar-default .navbar-nav>li>a:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #141618);background-image:-o-linear-gradient(#020202, #101112 40%, #141618);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#141618));background-image:linear-gradient(#020202, #101112 40%, #141618);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff141618', GradientType=0);-webkit-filter:none;filter:none} .navbar-inverse{background-image:-webkit-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-o-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-webkit-gradient(linear, left top, left bottom, from(#8a9196), color-stop(60%, #7a8288), to(#70787d));background-image:linear-gradient(#8a9196, #7a8288 60%, #70787d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8a9196', endColorstr='#ff70787d', GradientType=0);-webkit-filter:none;filter:none} .navbar-inverse .badge{background-color:#5d6368} .navbar-inverse .navbar-nav>li>a:hover{background-image:-webkit-linear-gradient(#404448, #4e5458 40%, #53595d);background-image:-o-linear-gradient(#404448, #4e5458 40%, #53595d);background-image:-webkit-gradient(linear, left top, left bottom, from(#404448), color-stop(40%, #4e5458), to(#53595d));background-image:linear-gradient(#404448, #4e5458 40%, #53595d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff404448', endColorstr='#ff53595d', GradientType=0);-webkit-filter:none;filter:none} .btn,.btn:hover{border-color:rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3)} .btn-default{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none} .btn-default:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #141618);background-image:-o-linear-gradient(#020202, #101112 40%, #141618);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#141618));background-image:linear-gradient(#020202, #101112 40%, #141618);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff141618', GradientType=0);-webkit-filter:none;filter:none} .btn-primary{background-image:-webkit-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-o-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-webkit-gradient(linear, left top, left bottom, from(#8a9196), color-stop(60%, #7a8288), to(#70787d));background-image:linear-gradient(#8a9196, #7a8288 60%, #70787d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8a9196', endColorstr='#ff70787d', GradientType=0);-webkit-filter:none;filter:none} .btn-primary:hover{background-image:-webkit-linear-gradient(#404448, #4e5458 40%, #53595d);background-image:-o-linear-gradient(#404448, #4e5458 40%, #53595d);background-image:-webkit-gradient(linear, left top, left bottom, from(#404448), color-stop(40%, #4e5458), to(#53595d));background-image:linear-gradient(#404448, #4e5458 40%, #53595d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff404448', endColorstr='#ff53595d', GradientType=0);-webkit-filter:none;filter:none} .btn-success{background-image:-webkit-linear-gradient(#78cc78, #62c462 60%, #53be53);background-image:-o-linear-gradient(#78cc78, #62c462 60%, #53be53);background-image:-webkit-gradient(linear, left top, left bottom, from(#78cc78), color-stop(60%, #62c462), to(#53be53));background-image:linear-gradient(#78cc78, #62c462 60%, #53be53);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff78cc78', endColorstr='#ff53be53', GradientType=0);-webkit-filter:none;filter:none} .btn-success:hover{background-image:-webkit-linear-gradient(#2f7d2f, #379337 40%, #3a9a3a);background-image:-o-linear-gradient(#2f7d2f, #379337 40%, #3a9a3a);background-image:-webkit-gradient(linear, left top, left bottom, from(#2f7d2f), color-stop(40%, #379337), to(#3a9a3a));background-image:linear-gradient(#2f7d2f, #379337 40%, #3a9a3a);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f7d2f', endColorstr='#ff3a9a3a', GradientType=0);-webkit-filter:none;filter:none} .btn-info{background-image:-webkit-linear-gradient(#74cae3, #5bc0de 60%, #4ab9db);background-image:-o-linear-gradient(#74cae3, #5bc0de 60%, #4ab9db);background-image:-webkit-gradient(linear, left top, left bottom, from(#74cae3), color-stop(60%, #5bc0de), to(#4ab9db));background-image:linear-gradient(#74cae3, #5bc0de 60%, #4ab9db);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff74cae3', endColorstr='#ff4ab9db', GradientType=0);-webkit-filter:none;filter:none} .btn-info:hover{background-image:-webkit-linear-gradient(#20829f, #2596b8 40%, #279dc1);background-image:-o-linear-gradient(#20829f, #2596b8 40%, #279dc1);background-image:-webkit-gradient(linear, left top, left bottom, from(#20829f), color-stop(40%, #2596b8), to(#279dc1));background-image:linear-gradient(#20829f, #2596b8 40%, #279dc1);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff20829f', endColorstr='#ff279dc1', GradientType=0);-webkit-filter:none;filter:none} .btn-warning{background-image:-webkit-linear-gradient(#faa123, #f89406 60%, #e48806);background-image:-o-linear-gradient(#faa123, #f89406 60%, #e48806);background-image:-webkit-gradient(linear, left top, left bottom, from(#faa123), color-stop(60%, #f89406), to(#e48806));background-image:linear-gradient(#faa123, #f89406 60%, #e48806);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffaa123', endColorstr='#ffe48806', GradientType=0);-webkit-filter:none;filter:none} .btn-warning:hover{background-image:-webkit-linear-gradient(#804d03, #9e5f04 40%, #a86404);background-image:-o-linear-gradient(#804d03, #9e5f04 40%, #a86404);background-image:-webkit-gradient(linear, left top, left bottom, from(#804d03), color-stop(40%, #9e5f04), to(#a86404));background-image:linear-gradient(#804d03, #9e5f04 40%, #a86404);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff804d03', endColorstr='#ffa86404', GradientType=0);-webkit-filter:none;filter:none} .btn-danger{background-image:-webkit-linear-gradient(#f17a77, #ee5f5b 60%, #ec4d49);background-image:-o-linear-gradient(#f17a77, #ee5f5b 60%, #ec4d49);background-image:-webkit-gradient(linear, left top, left bottom, from(#f17a77), color-stop(60%, #ee5f5b), to(#ec4d49));background-image:linear-gradient(#f17a77, #ee5f5b 60%, #ec4d49);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff17a77', endColorstr='#ffec4d49', GradientType=0);-webkit-filter:none;filter:none} .btn-danger:hover{background-image:-webkit-linear-gradient(#bb1813, #d71c16 40%, #e01d17);background-image:-o-linear-gradient(#bb1813, #d71c16 40%, #e01d17);background-image:-webkit-gradient(linear, left top, left bottom, from(#bb1813), color-stop(40%, #d71c16), to(#e01d17));background-image:linear-gradient(#bb1813, #d71c16 40%, #e01d17);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffbb1813', endColorstr='#ffe01d17', GradientType=0);-webkit-filter:none;filter:none} .btn-link,.btn-link:hover{border-color:transparent} h1,h2,h3,h4,h5,h6{text-shadow:-1px -1px 0 rgba(0,0,0,0.3)} .text-primary,.text-primary:hover{color:#7a8288} .text-success,.text-success:hover{color:#62c462} .text-danger,.text-danger:hover{color:#ee5f5b} .text-warning,.text-warning:hover{color:#f89406} .text-info,.text-info:hover{color:#5bc0de} .table .success,.table .warning,.table .danger,.table .info{color:#fff} .table-bordered tbody tr.success td,.table-bordered tbody tr.warning td,.table-bordered tbody tr.danger td,.table-bordered tbody tr.success:hover td,.table-bordered tbody tr.warning:hover td,.table-bordered tbody tr.danger:hover td{border-color:#1c1e22} .table-responsive>.table{background-color:#2e3338} input,textarea{color:#272b30} .has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label,.has-warning .form-control-feedback{color:#f89406} .has-warning .form-control,.has-warning .form-control:focus{border-color:#f89406} .has-warning .input-group-addon{border-color:rgba(0,0,0,0.6)} .has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label,.has-error .form-control-feedback{color:#ee5f5b} .has-error .form-control,.has-error .form-control:focus{border-color:#ee5f5b} .has-error .input-group-addon{border-color:rgba(0,0,0,0.6)} .has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label,.has-success .form-control-feedback{color:#62c462} .has-success .form-control,.has-success .form-control:focus{border-color:#62c462} .has-success .input-group-addon{border-color:rgba(0,0,0,0.6)} legend{color:#fff} .input-group-addon{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;text-shadow:1px 1px 1px rgba(0,0,0,0.3);color:#ffffff} .nav .open>a,.nav .open>a:hover,.nav .open>a:focus{border-color:rgba(0,0,0,0.6)} .nav-pills>li>a{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3)} .nav-pills>li>a:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #141618);background-image:-o-linear-gradient(#020202, #101112 40%, #141618);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#141618));background-image:linear-gradient(#020202, #101112 40%, #141618);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff141618', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6)} .nav-pills>li.active>a,.nav-pills>li.active>a:hover{background-color:none;background-image:-webkit-linear-gradient(#020202, #101112 40%, #141618);background-image:-o-linear-gradient(#020202, #101112 40%, #141618);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#141618));background-image:linear-gradient(#020202, #101112 40%, #141618);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff141618', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6)} .nav-pills>li.disabled>a,.nav-pills>li.disabled>a:hover{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none} .pagination>li>a,.pagination>li>span{text-shadow:1px 1px 1px rgba(0,0,0,0.3);background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none} .pagination>li>a:hover,.pagination>li>span:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #141618);background-image:-o-linear-gradient(#020202, #101112 40%, #141618);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#141618));background-image:linear-gradient(#020202, #101112 40%, #141618);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff141618', GradientType=0);-webkit-filter:none;filter:none} .pagination>li.active>a,.pagination>li.active>span{background-image:-webkit-linear-gradient(#020202, #101112 40%, #141618);background-image:-o-linear-gradient(#020202, #101112 40%, #141618);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#141618));background-image:linear-gradient(#020202, #101112 40%, #141618);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff141618', GradientType=0);-webkit-filter:none;filter:none} .pagination>li.disabled>a,.pagination>li.disabled>a:hover,.pagination>li.disabled>span,.pagination>li.disabled>span:hover{background-color:transparent;background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none} .pager>li>a{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;text-shadow:1px 1px 1px rgba(0,0,0,0.3)} .pager>li>a:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #141618);background-image:-o-linear-gradient(#020202, #101112 40%, #141618);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#141618));background-image:linear-gradient(#020202, #101112 40%, #141618);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff141618', GradientType=0);-webkit-filter:none;filter:none} .pager>li.disabled>a,.pager>li.disabled>a:hover{background-color:transparent;background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none} .breadcrumb{border:1px solid rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3);background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none} .alert .alert-link,.alert a{color:#fff;text-decoration:underline} .alert .close{color:#000000;text-decoration:none} a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#0c0d0e} a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{border-color:rgba(0,0,0,0.6)} a.list-group-item-success.active{background-color:#62c462} a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{background-color:#4fbd4f} a.list-group-item-warning.active{background-color:#f89406} a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{background-color:#df8505} a.list-group-item-danger.active{background-color:#ee5f5b} a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{background-color:#ec4844} .jumbotron{border:1px solid rgba(0,0,0,0.6)} .panel-primary .panel-heading,.panel-success .panel-heading,.panel-danger .panel-heading,.panel-warning .panel-heading,.panel-info .panel-heading{border-color:#000} \ No newline at end of file diff --git a/src/main/resources/static/ru/general/css/lib-tuning.css b/src/main/resources/static/ru/general/css/lib-tuning.css new file mode 100644 index 0000000..a9752de --- /dev/null +++ b/src/main/resources/static/ru/general/css/lib-tuning.css @@ -0,0 +1,52 @@ +/** + * 3rd party libraries tuning styles + */ + + +/********* HLJS *************/ +.hljs { /* Prevents highlighted code sections from overlapping the substrate */ + background: none; + border: none; +} + +/********* Bootstrap *************/ +.navbar-form.navbar-left.form-group { + width: 590px; + margin-right: 20px; +} +.navbar-form .form-control { + width: 560px; +} +.navbar-brand { + cursor: help; +} +.dropdown-header { + font-weight: bold; + color: #de891b; +} + +/********* Angular UI Select *************/ +.ui-select-bootstrap > .ui-select-choices ,.ui-select-bootstrap > .ui-select-no-choice { + max-height: 50vh; +} +.ui-select-bootstrap .ui-select-choices-row>span { + color: #f3f3f3; +} +.ui-select-bootstrap .ui-select-choices-row>span:hover, +.ui-select-bootstrap .ui-select-choices-row>span:focus { + text-decoration: none; + color: #262626; + background-color: #f5f5f5; +} +.ui-select-bootstrap .ui-select-choices-row .log-choice-detail { + color: #a0a0a0; + text-shadow: none; +} +.ui-select-bootstrap .ui-select-choices-row.active .log-choice-detail { + color: #dcdcdc; +} +.ui-select-bootstrap .ui-select-choices-row>span:hover .log-choice-detail, +.ui-select-bootstrap .ui-select-choices-row>span:focus .log-choice-detail { + text-decoration: none; + color: #848484; +} \ No newline at end of file diff --git a/src/main/resources/static/ru/general/css/main.css b/src/main/resources/static/ru/general/css/main.css new file mode 100644 index 0000000..b7e1b46 --- /dev/null +++ b/src/main/resources/static/ru/general/css/main.css @@ -0,0 +1,97 @@ +/**/ +html { + overflow: -moz-scrollbars-vertical; + overflow-y: scroll; +} /* in order to avoid page re-layout on scroll bar appearance */ +body { + background-color: #282727; + padding-top: 70px; /* an offset for navbar */ +} +.navbar-last-item { + margin-right: 10px; +} +#substrate { + bottom: 0; + max-height: 35%; + opacity: 0.25; + position: fixed; + right: 0; + z-index: -10; +} +/**/ + +#consolePanel { + font-family: Courier New, monospace; + font-size: 13px; +} +.text-nowrap { + white-space: pre; +} +.text-wrap { + white-space: pre-wrap; +} + +/**/ +.TRACE { + color: #848484; + /*color: #bcbbba;*/ +} +.DEBUG { + color: #bcbbba; +} +.INFO { + color: #3a9546; +} +.WARN { + color: #de891b; +} +.ERROR { + color: #de0000; +} +.FATAL { + color: rgb(255, 7, 0); + font-weight: bold; +} +.PLAIN { + color: #808080; + font-style: italic; +} +/**/ + +/**/ +.scroll-down-btn { + position: fixed; + right: 25px; + bottom: 43%; + height: 15%; + opacity: 0.3; + z-index: 2; +} +.scroll-down-btn:hover { + opacity: 1; +} +/**/ + +/**/ +.invisible-cursor { + visibility: hidden; +} +.on-air-cursor { + color: #3a9546; + font-weight: bolder; + font-family: fantasy, monospace; + font-size: large; +} +.blinking-cursor { + animation: 1s blink step-end infinite; +} +@keyframes blink { + from, to { + color: transparent; + } + 50% { + color: #3a9546; + } +} +/**/ + diff --git a/src/main/resources/static/ru/general/fonts/glyphicons-halflings-regular.woff2 b/src/main/resources/static/ru/general/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000..64539b5 Binary files /dev/null and b/src/main/resources/static/ru/general/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/src/main/resources/static/ru/general/img/favicon.png b/src/main/resources/static/ru/general/img/favicon.png new file mode 100644 index 0000000..764044c Binary files /dev/null and b/src/main/resources/static/ru/general/img/favicon.png differ diff --git a/src/main/resources/static/ru/general/img/logo-20-20.png b/src/main/resources/static/ru/general/img/logo-20-20.png new file mode 100644 index 0000000..9f67b15 Binary files /dev/null and b/src/main/resources/static/ru/general/img/logo-20-20.png differ diff --git a/src/main/resources/static/ru/general/img/magnifier.png b/src/main/resources/static/ru/general/img/magnifier.png new file mode 100644 index 0000000..66f3aa4 Binary files /dev/null and b/src/main/resources/static/ru/general/img/magnifier.png differ diff --git a/src/main/resources/static/ru/general/img/preloader.gif b/src/main/resources/static/ru/general/img/preloader.gif new file mode 100644 index 0000000..a6c24c1 Binary files /dev/null and b/src/main/resources/static/ru/general/img/preloader.gif differ diff --git a/src/main/resources/static/ru/general/js/bootstrap3-dropdown.js b/src/main/resources/static/ru/general/js/bootstrap3-dropdown.js new file mode 100644 index 0000000..f11f36e --- /dev/null +++ b/src/main/resources/static/ru/general/js/bootstrap3-dropdown.js @@ -0,0 +1,186 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/*! + * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=3356eb28a4f746ca1528) + * Config saved to config.json and https://gist.github.com/3356eb28a4f746ca1528 + */ +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} ++function ($) { + 'use strict'; + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3') + } +}(jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.3.6 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.3.6' + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector && $(selector) + + return $parent && $parent.length ? $parent : $this.parent() + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) + }) + } + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger($.Event('shown.bs.dropdown', relatedTarget)) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if (!isActive && e.which != 27 || isActive && e.which == 27) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.disabled):visible a' + var $items = $parent.find('.dropdown-menu' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) + +}(jQuery); diff --git a/src/main/resources/static/ru/general/js/choice-service.js b/src/main/resources/static/ru/general/js/choice-service.js new file mode 100644 index 0000000..ec03154 --- /dev/null +++ b/src/main/resources/static/ru/general/js/choice-service.js @@ -0,0 +1,83 @@ +/** + * A service responsible for providing the application with log choice options (aka choices). + */ +function ChoicesService($http, $location, $log, $rootScope) { + return function () { + + let onSuccess = function success(response) { + let choices = response.data; + let selectedChoice = null; + + // сначала проверим, был ли указан путь к логу в URL + if ($location.path()) { + let proposedLogId = removeSlashIfNeeded($location.path()); + $log.log("Proposed log ID found in URL: " + proposedLogId); + // теперь попытаемся выяснить, есть ли указанный лог среди известных на сервере + for (let i in choices) { + let knownChoice = choices[i]; + if (arePathsEqual(knownChoice.id, proposedLogId)) { + $log.log("Proposed log is known within group: " + knownChoice.group); + selectedChoice = knownChoice; // такой лог известен; просто выбираем его + break; + } + } + // если указанный лог неизвестен, создадим для него отдельный вариант выбора и добавим его в список + if (!selectedChoice) { + $log.log("Proposed log is unknown among server choices and hence will be added as separate group."); + let logType = detectLogType(proposedLogId); + selectedChoice = { + group: "Указан через URL", + title: extractFileName(proposedLogId), + type: logType, + id: proposedLogId + }; + if (logType === "NODE") { + selectedChoice.node = extractNode(proposedLogId); + } + choices.push(selectedChoice); + } + + } else { // никакого лога в URL указано не было; полагаемся только на варианты от сервера + $log.log("No proposed log path was given in URL; basing on choices from server only."); + for (let j in choices) { + let choice = choices[j]; + if (choice.selected) { + selectedChoice = choice; + $location.path(addSlashIfNeeded(choice.id)); + break; + } + } + } + + // сохраняем все результаты предшествующих выборов в модели + $rootScope.$broadcast('choicesReady', {choices: choices, selectedChoice: selectedChoice}); + }; + + let onFail = function fail(response) { + let message = ''; + if (response.status) { + message += ('HTTP ' + response.status); + } + if (response.statusText) { + message += (' (' + response.statusText + ')'); + } + if (response.data) { + if (response.data.error) { + if (message) message += ': '; + message += (response.data.error); + } + if (response.data.message) { + if (message) message += ' - '; + message += (response.data.message); + } + } + $log.log("Failed to fetch choices from server. Broadcasting failure message: '" + message + "'"); + $rootScope.$broadcast('choicesNotFound', {message: message}); + }; + + $http.get("/choices") + .then(onSuccess, onFail); + }; +} + +app.service('choicesService', ['$http', '$location', '$log', '$rootScope', ChoicesService]); \ No newline at end of file diff --git a/src/main/resources/static/ru/general/js/config.js b/src/main/resources/static/ru/general/js/config.js new file mode 100644 index 0000000..36a76af --- /dev/null +++ b/src/main/resources/static/ru/general/js/config.js @@ -0,0 +1,41 @@ +/** + * Frontend configuration properties. + * TODO retrieve them from the server with the help of template engine like Thymeleaf + */ +app.constant('config', { + general: { + appTitle: 'АнаЛóг' + }, + + rendering: { + /** Period between successive renderings of records accumulated in the queue */ + periodMs: 1000, + eviction: { + composite: { + threshold: 2200, + depth: 200 + }, + plain: { + threshold: 1000, + depth: 100 + } + } + }, + + websocket: { + topicPrefix: "/topic/", + watchEndpoint: '/watch-endpoint', + reconnectDelayMs: 5000 + }, + + mappings: { + type2class: new Map([ + ['LOCAL_FILE', 'primary'], + ['NODE', 'info'], + ['DOCKER', 'success'], + ['KUBERNETES', 'danger'], + ['K8S', 'danger'], + ['COMPOSITE', 'warning'] + ]) + } +}); \ No newline at end of file diff --git a/src/main/resources/static/ru/general/js/directives.js b/src/main/resources/static/ru/general/js/directives.js new file mode 100644 index 0000000..b7d5b45 --- /dev/null +++ b/src/main/resources/static/ru/general/js/directives.js @@ -0,0 +1,26 @@ +app.directive('hideUponAutoScroll', function ($window, $rootScope, $log) { + let previousScrollTop = 0; // needed to distinguish user scroll (up only) from programmatic scroll (anywhere) + let isAutoScroll = true; + + function link(scope, element) { + angular.element($window).bind("scroll", function () { + const currentScrollTop = $(window).scrollTop(); + if (!isAutoScroll && (currentScrollTop === ($(document).height() - $(window).height()))) { + isAutoScroll = true; + element.addClass('ng-hide'); + $log.log('autoScroll switched to true'); + } else if (isAutoScroll && (currentScrollTop < previousScrollTop) && (currentScrollTop > 0)) { + // supposing that only user might scroll the view up + isAutoScroll = false; + element.removeClass('ng-hide'); + $log.log('autoScroll switched to false'); + } + previousScrollTop = currentScrollTop; // to compare at the next invocation + }); + } + + return { + restrict: 'A', + link: link + }; +}); \ No newline at end of file diff --git a/src/main/resources/static/ru/general/js/main-controller.js b/src/main/resources/static/ru/general/js/main-controller.js new file mode 100644 index 0000000..2d44abd --- /dev/null +++ b/src/main/resources/static/ru/general/js/main-controller.js @@ -0,0 +1,126 @@ +app = angular.module("AnaLog", ['ngSanitize', 'ngAnimate', 'ui.select']); + +app.run(function ($rootScope, watchingService) { + $rootScope.watchingLog = "АнаЛóг v0.12 (загрузка...)"; + watchingService.connect(); +}); + +app.controller('mainController', function ($scope, $rootScope, $window, + choicesService, renderingService, watchingService, config, + $location, $log) { + var vm = this; + vm.selectedLog = undefined; + vm.onAir = false; + vm.textWrap = true; + vm.launching = true; // one-time trigger to automate the very first activating of log watching + + $scope.choices = []; + + vm.onLogChange = function() { + let locationPath = removeSlashIfNeeded($location.path()); + if (arePathsEqual(locationPath, vm.selectedLog.id)) { + $log.log("onLogChange handling has been bypassed as no actual change happened (%s)", vm.selectedLog.id); + return; + } + $log.log("New choice: " + vm.selectedLog.id); + $rootScope.watchingLog = vm.selectedLog.title + " - " + config.general.appTitle; + $location.path(addSlashIfNeeded(vm.selectedLog.id)); + vm.clear(); + if (vm.onAir) { + watchingService.stopWatching(); + watchingService.startWatching(vm.selectedLog, true) + } + }; + // a couple of bindings between this controller's functions and injected services + vm.clear = renderingService.clearConsole; + vm.scrollDown = renderingService.scrollDown; + + // the following watch allows us to react to URL path change instantly (without opening a new browser tab) + $scope.$watch(function () { + return $location.path(); + }, function (value) { + // $log.log("$location.path() raw value: " + value); // helpful for troubleshooting paths starting with 'C:\' + let newId = removeSlashIfNeeded(value); + if (vm.selectedLog && !arePathsEqual(vm.selectedLog.id, newId)) { + $log.log("Log ID change detected from: '" + vm.selectedLog.id + "' to: '" + newId +"'."); + vm.clear(); + choicesService(); + // then the watching will be reactivated (if needed) during the handling of choicesReady event + } + }); + // the following watch allows us to react to any change of onAir mode flag (both from UI and internally) + $scope.$watch(function () { + return vm.onAir; + }, function () { + let needTail = renderingService.isConsoleEmpty(); + $log.log("Turning onAir to: %s", vm.onAir); + if (vm.onAir) { + watchingService.startWatching(vm.selectedLog, needTail) + } else { + watchingService.stopWatching(); + } + }); + // the following subscription allows AnaLog client app to retrieve the freshest log choices on server (re)starts + $scope.$on('serverConnected', function () { + choicesService(); // triggers 'choicesReady' event; it will also update the choices after server restart + }); + // the following subscription is responsible for proper control of watching mode - it must be reactivated on changes + $scope.$on('choicesReady', function (event, result) { + $log.log("ChoicesReady event has been received: %o", result); + $scope.choices = result.choices; + vm.selectedLog = result.selectedChoice; + $rootScope.watchingLog = result.selectedChoice.title + " - " + config.general.appTitle; + + if (!vm.onAir) { + if (vm.launching) { // if AnaLog's page is just loading let's start watching automatically + vm.onAir = true; + vm.launching = false; + } // nothing should be done in this case as it is user's decision not to watch any log + + } else { // i.e. watching has been acting for some time before server get connected (again) + watchingService.stopWatching(); + watchingService.startWatching(vm.selectedLog, renderingService.isConsoleEmpty()); + // it is assumed that selectedLog always equals to previous one so that there is no need to clear console + } + + }); + // to stop watching in case of server failure + $scope.$on('serverFailure', function () { + vm.onAir = false; + // vm.launching = true; // this may allow to reactivate watching even after server failure + }); + // to explicitly stop watching and close server connection upon termination + $scope.$on('$destroy', function() { + vm.onAir = false; + renderingService.stopTimer(); + watchingService.disconnect(); + }); + +}); + +app.filter('logTypeDetector', function () { + return function (logChoice) { + switch (logChoice.type) { + case 'LOCAL_FILE': + return 'локальный файл'; + case 'NODE': + return 'удалённый файл на узле {node}'.format(logChoice); + case 'COMPOSITE': + return 'композит из {size} {logs}'.format({size: logChoice.includes.length, + logs: quantify(logChoice.includes.length)}); + case 'DOCKER': + return 'контейнер в Docker'; + case 'KUBERNETES': + case 'K8S': + return 'ресурс в Kubernetes'; + default: + return '[неизвестный тип лога]'; + } + } +}); + +app.filter('labelClassPicker', ['config', function (config) { + return function (logChoice) { + return "label-" + (config.mappings.type2class.get(logChoice.type) || "default"); + } +}]); diff --git a/src/main/resources/static/ru/general/js/util.js b/src/main/resources/static/ru/general/js/util.js new file mode 100644 index 0000000..75887c1 --- /dev/null +++ b/src/main/resources/static/ru/general/js/util.js @@ -0,0 +1,83 @@ +/** + * @param path - any log path (including custom, e.g. k8s://deploy/some-pod} + * @returns {string} the part of the path after last forward or backward slash; in case of custom path it will not + * be the file name but the target resource name (e.g. container for Docker or pod for Kubernetes) + */ +function extractFileName(path) { + let lastSlashPosition = Math.max( + path.lastIndexOf('/'), + path.lastIndexOf('\\')); + return path.substring(lastSlashPosition + 1); +} + +function removeSlashIfNeeded(logId) { + const leadingSlashRegExp = /^\//; + if (logId.includes(":")) { // it means any kind of path expect pure Unix path like '/home/user/path' + logId = logId.replace(leadingSlashRegExp, ""); + // console.log('Removed leading slash: %s', logId); + } + return logId; +} + +function addSlashIfNeeded(logId) { + if (logId.includes(":") && logId.indexOf('/') !== 0) { + logId = '/' + logId; + // console.log('Added leading slash: %s', logId); + } + return logId; +} + +function arePathsEqual(path1, path2) { + // the following replacements allow us to correctly compare paths from different OS'es + let normalizedPath1 = path1.toLowerCase().replace(new RegExp("\\\\", 'g'), "/"); + let normalizedPath2 = path2.toLowerCase().replace(new RegExp("\\\\", 'g'), "/"); + return (normalizedPath1 === normalizedPath2); +} + +function quantify(count) { + if (count > 1) { + return 'логов'; + } else { + return 'лога'; + } +} + +function detectLogType(logId) { + let tokens = logId.split("://"); + if (tokens.length > 1) { + return tokens[0].toUpperCase(); + } else { + return "LOCAL_FILE"; + } +} + +function extractNode(logId) { + let matchResult = logId.match(/^node:\/\/(\w+).*/i); + if (matchResult) { + return matchResult[1]; + } else { + return "(n/a)"; + } +} + +function extractPath(logId) { + let matchResult = logId.match(/^node:\/\/\w+(.*)/i); + if (!matchResult) { + return logId; + } else { + return removeSlashIfNeeded(matchResult[1]); + } +} + +// TODO move to Angular app initialization +// First, checks if it isn't implemented yet. +if (!String.prototype.format) { + String.prototype.format = function() { + let args = arguments; + return this.replace(/{(\w+)}/g, function(match, varName) { + return (typeof args[0][varName] !== 'undefined') + ? args[0][varName] + : match; + }); + }; +} diff --git a/src/main/resources/static/ru/general/js/watching-service.js b/src/main/resources/static/ru/general/js/watching-service.js new file mode 100644 index 0000000..fdb8f61 --- /dev/null +++ b/src/main/resources/static/ru/general/js/watching-service.js @@ -0,0 +1,79 @@ +app.factory('watchingService', ['$log', '$rootScope', 'renderingService', 'config', + function ($log, $rootScope, renderingService, config) { + let stompClient = undefined; + let subscription = undefined; + + function connect() { + if (angular.isDefined(stompClient)) { + return; // to prevent double connection + } + stompClient = Stomp.over(function () { + return new SockJS(config.websocket.watchEndpoint); + }); + stompClient.reconnect_delay = config.websocket.reconnectDelayMs; // to repeat failed connection attempts + stompClient.connect({}, + function () { + $log.log('Watching service has connected to the server.'); + $rootScope.$broadcast('serverConnected'); + $rootScope.$apply(); // since we're not in "Angular realm", we need to trigger it manually + }, + function () { + // $log.log('Watching service failed to connect to the server.'); // to avoid flooding the console + $rootScope.$broadcast('serverDisconnected'); + $rootScope.$apply(); // since we're not in "Angular realm", we need to trigger it manually + }); + } + + function startWatching(selectedLog, isTailNeeded) { + let headers = { + isTailNeeded: isTailNeeded + }; + let destination = config.websocket.topicPrefix + selectedLog.id; + subscription = stompClient.subscribe(destination, onServerMessage, headers); + $log.log("New subscription to destination '%s' has been created with headers %o", destination, headers) + } + + function onServerMessage(message) { + let payload = JSON.parse(message.body); + let messageType = message.headers['type']; + + switch (messageType) { + case 'RECORD': + renderingService.render(payload); + break; + case 'METADATA': + $rootScope.$broadcast(payload.eventType, payload); + $rootScope.$apply(); // since we're not in "Angular realm", we need to trigger it manually + break; + case 'FAILURE': + $rootScope.$broadcast('serverFailure', payload); + $rootScope.$apply(); // since we're not in "Angular realm", we need to trigger it manually + break; + default: + $log.log("ERROR: received a message of unknown type: " + payload); + } + } + + function stopWatching() { + if (angular.isDefined(subscription)) { + subscription.unsubscribe(); // this causes an exception in case of triggering during server disconnection + subscription = undefined; + $log.log("Subscription has been removed.") + } + } + + function disconnect() { + stopWatching(); + stompClient.disconnect(function () { + $log.log("Watching service has disconnected from peer."); + }); + stompClient = undefined; + } + + return { + connect: connect, + startWatching: startWatching, + stopWatching: stopWatching, + disconnect: disconnect + } +}]); \ No newline at end of file diff --git a/src/main/resources/static/ru/index.html b/src/main/resources/static/ru/index.html new file mode 100644 index 0000000..d67529f --- /dev/null +++ b/src/main/resources/static/ru/index.html @@ -0,0 +1,124 @@ + + + + + + + + АнаЛóг v0.12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + +
+ +

{{notifier.message.title}}

+

+
+ + +substrate logo + + \ No newline at end of file diff --git a/src/main/resources/static/ru/notification/notification.constant.js b/src/main/resources/static/ru/notification/notification.constant.js new file mode 100644 index 0000000..6de36d3 --- /dev/null +++ b/src/main/resources/static/ru/notification/notification.constant.js @@ -0,0 +1,69 @@ +/** + * All the popup notifications that AnaLog is able to show. + * Subject to localize. + */ +app.constant('notifications', { + // + serverConnected: { + level: 'success', + title: 'Сервер снова доступен', + text: 'Связь восстановлена, можно работать.' + }, + serverDisconnected: { + level: 'warning', + title: 'Нет связи с сервером', + text: 'При необходимости слежение продолжится автоматически после восстановления связи.' + }, + // + + // + logNotFound: { + level: 'info', + title: 'Лог не найден', + text: "Лог {logPath} не найден. Ожидаю его появления..." + }, + logAppeared: { + level: 'success', + title: 'Лог обнаружен', + text: "Лог {logPath} появился. Отслеживаю его изменения." + }, + logRotated: { + level: 'info', + title: 'Ротация лога', + text: "Лог {logPath} начал писаться с начала. " + + "Предыдущие записи, вероятно, перенесены в другой лог." + }, + logDisappeared: { + level: 'info', + title: 'Лог потерян', + text: "Лог {logPath} пропал. Продолжу отслеживание, когда появится." + }, + logTruncated: { + level: 'danger', + title: 'Лог сократился', + text: "Лог {logPath} сократился в размере.
" + + "Дальнейшее отслеживание может быть ошибочным.
В этом случае лучше начать его заново." + }, + unrecognized: { + level: 'warning', + title: 'Сообщение о слежении', + text: "При слежении за логом {logPath} получено сообщение:
" + + "{message}" + }, + //
+ + // + serverFailure: { + level: 'danger', + title: 'Сообщение от сервера', + text: "Отслеживание прекращено из-за ошибки:
{message}" + }, + choicesNotFound: { + level: 'danger', + title: 'Сбой на сервере', + text: "Не удалось получить варианты логов из-за ошибки:
" + + "{message}" + } + //
+ +}); \ No newline at end of file diff --git a/src/main/resources/static/ru/notification/notification.controller.js b/src/main/resources/static/ru/notification/notification.controller.js new file mode 100644 index 0000000..f5fe852 --- /dev/null +++ b/src/main/resources/static/ru/notification/notification.controller.js @@ -0,0 +1,104 @@ +/** + * Controller responsible for showing notification balloon messages with information about various asynchronous events. + */ +app.controller('notificationController', ['$scope', '$log', '$interval', 'notifications', + function ($scope, $log, $interval, notifications) { + let vm = this; + const SHOW_DELAY = 10000; // it's better to set it higher than websocket.reconnectDelayMs config value + vm.message = undefined; + vm.showing = false; + vm.onceDisconnected = false; + vm.intervalPromise = undefined; + + // + $scope.$on('serverDisconnected', function () { + vm.message = angular.copy(notifications['serverDisconnected']); + vm.onceDisconnected = true; + vm.startAutoHideTimer(); + vm.showing = true; + }); + $scope.$on('serverConnected', function () { + if (!vm.onceDisconnected) + return; + vm.message = angular.copy(notifications['serverConnected']); + vm.startAutoHideTimer(); + vm.showing = true; + }); + // + + // + $scope.$on('logNotFound', function (event, details) { + vm.message = angular.copy(notifications['logNotFound']); + vm.message.text = vm.message.text.format(details); + vm.startAutoHideTimer(); + vm.showing = true; + }); + $scope.$on('logAppeared', function (event, details) { + vm.message = angular.copy(notifications['logAppeared']); + vm.message.text = vm.message.text.format(details); + vm.startAutoHideTimer(); + vm.showing = true; + }); + $scope.$on('logRotated', function (event, details) { + vm.message = angular.copy(notifications['logRotated']); + vm.message.text = vm.message.text.format(details); + vm.startAutoHideTimer(); + vm.showing = true; + }); + $scope.$on('logDisappeared', function (event, details) { + vm.message = angular.copy(notifications['logDisappeared']); + vm.message.text = vm.message.text.format(details); + vm.startAutoHideTimer(); + vm.showing = true; + }); + $scope.$on('logTruncated', function (event, details) { + vm.message = angular.copy(notifications['logTruncated']); + vm.message.text = vm.message.text.format(details); + vm.startAutoHideTimer(); + vm.showing = true; + }); + $scope.$on('unrecognized', function (event, details) { + vm.message = angular.copy(notifications['unrecognized']); + vm.message.text = vm.message.text.format(details); + vm.startAutoHideTimer(); + vm.showing = true; + }); + // + + // + $scope.$on('serverFailure', function (event, details) { + vm.message = angular.copy(notifications['serverFailure']); + vm.message.text = vm.message.text.format(details); + vm.startAutoHideTimer(); + vm.showing = true; + }); + $scope.$on('choicesNotFound', function (event, details) { + vm.message = angular.copy(notifications['choicesNotFound']); + vm.message.text = vm.message.text.format(details); + vm.startAutoHideTimer(); + vm.showing = true; + }); + // + + vm.close = function () { + vm.stopAutoHideTimer(); + vm.showing = false; + }; + + // + vm.startAutoHideTimer = function () { + vm.stopAutoHideTimer(); // to prevent double starting of timer + vm.intervalPromise = $interval(vm.close, SHOW_DELAY, 1); + }; + + vm.stopAutoHideTimer = function () { + if (angular.isDefined(vm.intervalPromise)) { + $interval.cancel(vm.intervalPromise); + vm.intervalPromise = undefined; + } + }; + + $scope.$on('$destroy', vm.stopAutoHideTimer); + // + + }]); \ No newline at end of file diff --git a/src/main/resources/static/ru/notification/notification.css b/src/main/resources/static/ru/notification/notification.css new file mode 100644 index 0000000..c102d11 --- /dev/null +++ b/src/main/resources/static/ru/notification/notification.css @@ -0,0 +1,54 @@ +.alert { + position: fixed; + z-index: 100; + right: 25px; + top: 65px; + max-width: 450px; +} +.alert p { + font-size: 13px; +} +.alert.ng-hide { + opacity: 0; +} +.alert.ng-hide-add, +.alert.ng-hide-remove { + transition: all linear 0.5s; +} +.alert-info .highlight { + font-weight: bold; + color: lightgoldenrodyellow; +} + +.alert-success .highlight { + font-weight: bold; + color: palegoldenrod; +} + +.alert-warning .highlight { + font-weight: bold; + color: white; +} + +.alert-danger .highlight { + font-weight: bold; + color: cornsilk; +} + +.alert-danger .failure-message { + font-weight: bold; + color: limegreen; + font-family: monospace; + background-color: black; + padding: 3px 3px 3px 3px; + display: inline-block; +} + +.alert-warning .tracking-message { + font-weight: bold; + color: limegreen; + font-family: monospace; + background-color: black; + padding: 3px 3px 3px 3px; + display: inline-block; +} \ No newline at end of file diff --git a/src/main/resources/static/ru/rendering/composite-record.css b/src/main/resources/static/ru/rendering/composite-record.css new file mode 100644 index 0000000..71c268d --- /dev/null +++ b/src/main/resources/static/ru/rendering/composite-record.css @@ -0,0 +1,182 @@ +/* + * Composite records' styles. + * Generated with Stylus CSS preprocessor. + */ +.composite-record { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: flex-start; + align-items: stretch; + margin-top: 1px; + border-width: 0 5px 0 0; + border-style: solid; +} +.composite-record>.marker { + flex-grow: 0; + flex-shrink: 1; + flex-basis: auto; + align-self: stretch; + min-width: 12px; + max-width: 12px; + margin-right: 5px; +} +.composite-record>.payload { + flex-grow: 1; + flex-shrink: 1; + flex-basis: auto; + align-self: auto; +} +.text-nowrap .composite-record { + border-width: 0 0 0 0; +} +/* Next highlighting entry */ +.composite-record.highlight-blue { + border-color: #556497; + position: relative; + z-index: 1; +} +.composite-record.highlight-blue:before { + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + opacity: 0; + content: ''; + background: linear-gradient(to right, #3c476b 0%, rgba(60,71,107,0.4) 2%, rgba(60,71,107,0.4) 98%, #3c476b 100%); + transition: opacity 0.45s; +} +.composite-record.highlight-blue:hover:before { + opacity: 1; +} +.composite-record.highlight-blue .marker { + background: #556497; +} +/* Next highlighting entry */ +.composite-record.highlight-green { + border-color: #627c65; + position: relative; + z-index: 1; +} +.composite-record.highlight-green:before { + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + opacity: 0; + content: ''; + background: linear-gradient(to right, #425444 0%, rgba(66,84,68,0.4) 2%, rgba(66,84,68,0.4) 98%, #425444 100%); + transition: opacity 0.45s; +} +.composite-record.highlight-green:hover:before { + opacity: 1; +} +.composite-record.highlight-green .marker { + background: #627c65; +} +/* Next highlighting entry */ +.composite-record.highlight-orange { + border-color: #af6544; + position: relative; + z-index: 1; +} +.composite-record.highlight-orange:before { + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + opacity: 0; + content: ''; + background: linear-gradient(to right, #7f4931 0%, rgba(127,73,49,0.4) 2%, rgba(127,73,49,0.4) 98%, #7f4931 100%); + transition: opacity 0.45s; +} +.composite-record.highlight-orange:hover:before { + opacity: 1; +} +.composite-record.highlight-orange .marker { + background: #af6544; +} +/* Next highlighting entry */ +.composite-record.highlight-rose { + border-color: #985a6c; + position: relative; + z-index: 1; +} +.composite-record.highlight-rose:before { + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + opacity: 0; + content: ''; + background: linear-gradient(to right, #6e414e 0%, rgba(110,65,78,0.4) 2%, rgba(110,65,78,0.4) 98%, #6e414e 100%); + transition: opacity 0.45s; +} +.composite-record.highlight-rose:hover:before { + opacity: 1; +} +.composite-record.highlight-rose .marker { + background: #985a6c; +} +/* Next highlighting entry */ +.composite-record.highlight-violet { + border-color: #766080; + position: relative; + z-index: 1; +} +.composite-record.highlight-violet:before { + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + opacity: 0; + content: ''; + background: linear-gradient(to right, #504157 0%, rgba(80,65,87,0.4) 2%, rgba(80,65,87,0.4) 98%, #504157 100%); + transition: opacity 0.45s; +} +.composite-record.highlight-violet:hover:before { + opacity: 1; +} +.composite-record.highlight-violet .marker { + background: #766080; +} +/* Next highlighting entry */ +.composite-record.highlight-brown { + border-color: #7b7057; + position: relative; + z-index: 1; +} +.composite-record.highlight-brown:before { + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + opacity: 0; + content: ''; + background: linear-gradient(to right, #4f4838 0%, rgba(79,72,56,0.4) 2%, rgba(79,72,56,0.4) 98%, #4f4838 100%); + transition: opacity 0.45s; +} +.composite-record.highlight-brown:hover:before { + opacity: 1; +} +.composite-record.highlight-brown .marker { + background: #7b7057; +} diff --git a/src/main/resources/static/ru/rendering/rendering.service.js b/src/main/resources/static/ru/rendering/rendering.service.js new file mode 100644 index 0000000..c4230f4 --- /dev/null +++ b/src/main/resources/static/ru/rendering/rendering.service.js @@ -0,0 +1,173 @@ +app.factory('renderingService', ['$log', '$interval', 'config', function($log, $interval, config) { + var $window = $(window); + var $document = $(document); + var $body = $('body'); + var $consolePanel = $('#consolePanel'); + + var renderingQueue = []; + var intervalPromise; + var consoleIsEmpty = true; // a flag indicating that the console is clean (i.e. contains no records) + init(); + + function init() { + intervalPromise = $interval(animate, config.rendering.periodMs, /*count:*/0, /*invokeApply:*/false); + } + + function preRender(newPart) { + if (angular.isDefined(newPart.timestamp)) { + prepareCompositeMessages(newPart) + } else { + preparePlainMessages(newPart); + } + consoleIsEmpty = false; + } + + function prepareCompositeMessages(newPart) { + $log.log("Preparing COMPOSITE record: %o", newPart); + let $newRecord = $('
') + .addClass('composite-record') + .addClass('highlight-' + newPart.highlightColor) + .data('timestamp', newPart.timestamp) + .hide(); + + let $marker = $('
') + .addClass('marker') + .attr('data-balloon', ('[' + newPart.sourceNode + '] ' + newPart.sourcePath)) + .attr('data-balloon-pos', 'right'); + $newRecord.append($marker); + + let $payload = $('
') + .addClass('payload'); + $newRecord.append($payload); + + angular.forEach(newPart.lines, function (line) { + let $messageLine; + if (line.style === 'XML') { + let $code = $("") + .addClass("xml") + .html(line.text); + $messageLine = $("
").append($code);
+                hljs.highlightBlock($messageLine[0]);
+            } else {
+                $messageLine = $("
") + .addClass(line.style) + .html(line.text); + } + $payload.append($messageLine); + }); + // determine correct position to insert new record + let $records = $consolePanel.find("> .composite-record"); + let $precedingRecord; + for (let i = $records.length; i-- > 0;) { + if (jQuery.data($records[i], 'timestamp') <= newPart.timestamp) { + $precedingRecord = $($records[i]); + break; + } + } + // and use the position to insert new record + if ($precedingRecord) { + $precedingRecord.after($newRecord); + } else { + if ($records.length > 0) { + $consolePanel.prepend($newRecord); // for the earliest record + } else { + $consolePanel.append($newRecord); // for the very first insertion only + } + } + + renderingQueue.push($newRecord); + } + + function preparePlainMessages(newPart) { + $log.log("Preparing PLAIN records: %o", newPart); + let $recordsBunch = $("
") + // .addClass('plain-record') // no need for the time being + .hide(); + angular.forEach(newPart.lines, function (line) { + let $messageLine; + if (line.style !== 'XML') { + $messageLine = $("
") + .addClass(line.style) + .html(line.text); + } else { + let $code = $("") + .addClass("xml") + .html(line.text); + $messageLine = $("
")
+                    .append($code);
+                hljs.highlightBlock($messageLine[0]);
+            }
+            $recordsBunch.append($messageLine);
+        });
+        $consolePanel.append($recordsBunch);
+        renderingQueue.push($recordsBunch);
+    }
+
+    /**
+     * Animated output logic
+     */
+    function animate() {
+        // first let's check if it's time to remove the oldest records to avoid client's memory exhaustion
+        var $allRecords = $consolePanel.find("> div");
+        var isComposite = $allRecords.hasClass('composite-record');
+        var threshold = isComposite
+            ? config.rendering.eviction.composite.threshold
+            : config.rendering.eviction.plain.threshold;
+        var partSize = isComposite
+            ? config.rendering.eviction.composite.depth
+            : config.rendering.eviction.plain.depth;
+        var recordsCount = $allRecords.length;
+        if (recordsCount > threshold) {
+            var $recordsToRemove = $allRecords.slice(0, partSize);
+            $recordsToRemove.remove();
+            $log.log('Removed first %d %s records as their total count %d exceeds threshold value %d.',
+                partSize, (isComposite?"composite":"plain"), recordsCount, threshold);
+        }
+
+        // now it's time to show the new records
+        var isConsoleUnScrollable = ($body.height() < $window.height());
+        var isScrolledToBottom = ($window.scrollTop() === ($document.height() - $window.height()));
+        while (renderingQueue.length > 0) {
+            var $newRecord = renderingQueue.shift();
+            if (isConsoleUnScrollable && renderingQueue.length === 1) {// should slide animation to output new record?
+                $newRecord.slideDown(400, scrollDown);
+                /* In most cases scrolling down before the viewport is totally filled has no effect. But if the new
+                 * record comes out of viewport, its end won't be visible. This is the only case that makes AnaLog use
+                 * scrolling animation regardless of actual scrolling presence. */
+
+            } else {
+                // when user manually scrolled up, we just "collect" new records at the bottom
+                $newRecord.show(0, function () {
+                    // and scroll to bottom if necessary
+                    if (renderingQueue.length === 0 && isScrolledToBottom)
+                        scrollDown();
+                });
+            }
+        }
+    }
+
+    function scrollDown() {
+        $window.scrollTo("max", 300, {
+            easing: 'swing',
+            axis: 'y',
+            interrupt: true
+        });
+    }
+
+    function clearConsole() {
+        $consolePanel.empty();
+        consoleIsEmpty = true;
+    }
+
+    function stopTimer() {
+        $interval.cancel(intervalPromise);
+    }
+
+    return {
+        clearConsole: clearConsole,
+        scrollDown: scrollDown,
+        stopTimer: stopTimer,
+        render: preRender,
+        isConsoleEmpty: function () {return consoleIsEmpty;}
+    }
+}]);
\ No newline at end of file