- v1.4.0 JS/CSS build files

This commit is contained in:
Mark Friedrich
2018-07-20 18:02:46 +02:00
parent 98bc071dd3
commit 266703a797
129 changed files with 46 additions and 61210 deletions

Binary file not shown.

View File

@@ -1,188 +1,2 @@
'use strict';
// main script path
var mainScriptPath = document.body.getAttribute('data-script');
// js baseURL. Depends on the environment.
// e.g. use raw files (develop) or build files (production)
var jsBaseUrl = document.body.getAttribute('data-js-path');
// requireJs configuration
requirejs.config({
baseUrl: 'js', // path for baseUrl - dynamically set !below! ("build_js" | "js")
paths: {
layout: 'layout',
conf: 'app/conf', // path for "config" files dir
dialog: 'app/ui/dialog', // path for "dialog" files dir
templates: '../../templates', // template dir
img: '../../img', // images dir
// main views
login: './app/login', // initial start "login page" view
mappage: './app/mappage', // initial start "map page" view
setup: './app/setup', // initial start "setup page" view
admin: './app/admin', // initial start "admin page" view
notification: './app/notification', // "notification" view
jquery: 'lib/jquery-3.3.1.min', // v3.3.1 jQuery
bootstrap: 'lib/bootstrap.min', // v3.3.0 Bootstrap js code - http://getbootstrap.com/javascript
text: 'lib/requirejs/text', // v2.0.12 A RequireJS/AMD loader plugin for loading text resources.
mustache: 'lib/mustache.min', // v1.0.0 Javascript template engine - http://mustache.github.io
localForage: 'lib/localforage.min', // v1.4.2 localStorage library - https://mozilla.github.io/localForage
velocity: 'lib/velocity.min', // v1.5.1 animation engine - http://julian.com/research/velocity
velocityUI: 'lib/velocity.ui.min', // v5.2.0 plugin for velocity - http://julian.com/research/velocity/#uiPack
slidebars: 'lib/slidebars', // v0.10 Slidebars - side menu plugin http://plugins.adchsm.me/slidebars
jsPlumb: 'lib/dom.jsPlumb-1.7.6', // v1.7.6 jsPlumb (Vanilla)- main map draw plugin https://jsplumbtoolkit.com
farahey: 'lib/farahey-0.5', // v0.5 jsPlumb "magnetizing" extension - https://github.com/jsplumb/farahey
customScrollbar: 'lib/jquery.mCustomScrollbar.min', // v3.1.5 Custom scroll bars - http://manos.malihu.gr
mousewheel: 'lib/jquery.mousewheel.min', // v3.1.13 Mousewheel - https://github.com/jquery/jquery-mousewheel
xEditable: 'lib/bootstrap-editable.min', // v1.5.1 X-editable - in placed editing
morris: 'lib/morris.min', // v0.5.1 Morris.js - graphs and charts
raphael: 'lib/raphael-min', // v2.1.2 Raphaël - required for morris (dependency)
bootbox: 'lib/bootbox.min', // v4.4.0 Bootbox.js - custom dialogs - http://bootboxjs.com
easyPieChart: 'lib/jquery.easypiechart.min', // v2.1.6 Easy Pie Chart - HTML 5 pie charts - http://rendro.github.io/easy-pie-chart
peityInlineChart: 'lib/jquery.peity.min', // v3.2.1 Inline Chart - http://benpickles.github.io/peity/
dragToSelect: 'lib/jquery.dragToSelect', // v1.1 Drag to Select - http://andreaslagerkvist.com/jquery/drag-to-select
hoverIntent: 'lib/jquery.hoverIntent.min', // v1.9.0 Hover intention - http://cherne.net/brian/resources/jquery.hoverIntent.html
fullScreen: 'lib/jquery.fullscreen.min', // v0.6.0 Full screen mode - https://github.com/private-face/jquery.fullscreen
select2: 'lib/select2.min', // v4.0.3 Drop Down customization - https://select2.github.io
validator: 'lib/validator.min', // v0.10.1 Validator for Bootstrap 3 - https://github.com/1000hz/bootstrap-validator
lazylinepainter: 'lib/jquery.lazylinepainter-1.5.1.min', // v1.5.1 SVG line animation plugin - http://lazylinepainter.info
blueImpGallery: 'lib/blueimp-gallery', // v2.21.3 Image Gallery - https://github.com/blueimp/Gallery
blueImpGalleryHelper: 'lib/blueimp-helper', // helper function for Blue Imp Gallery
blueImpGalleryBootstrap: 'lib/bootstrap-image-gallery', // v3.4.2 Bootstrap extension for Blue Imp Gallery - https://blueimp.github.io/Bootstrap-Image-Gallery
bootstrapConfirmation: 'lib/bootstrap-confirmation', // v1.0.5 Bootstrap extension for inline confirm dialog - https://github.com/tavicu/bs-confirmation
bootstrapToggle: 'lib/bootstrap-toggle.min', // v2.2.0 Bootstrap Toggle (Checkbox) - http://www.bootstraptoggle.com
lazyload: 'lib/jquery.lazyload.min', // v1.9.5 LazyLoader images - http://www.appelsiini.net/projects/lazyload
sortable: 'lib/sortable.min', // v1.6.0 Sortable - drag&drop reorder - https://github.com/rubaxa/Sortable
// header animation
easePack: 'lib/EasePack.min',
tweenLite: 'lib/TweenLite.min',
// datatables // v1.10.12 DataTables - https://datatables.net
'datatables.loader': './app/datatables.loader',
'datatables.net': 'lib/datatables/DataTables-1.10.12/js/jquery.dataTables.min',
'datatables.net-buttons': 'lib/datatables/Buttons-1.2.1/js/dataTables.buttons.min',
'datatables.net-buttons-html': 'lib/datatables/Buttons-1.2.1/js/buttons.html5.min',
'datatables.net-responsive': 'lib/datatables/Responsive-2.1.0/js/dataTables.responsive.min',
'datatables.net-select': 'lib/datatables/Select-1.2.0/js/dataTables.select.min',
'datatables.plugins.render.ellipsis': 'lib/datatables/plugins/render/ellipsis',
// notification plugin
pnotify: 'lib/pnotify/pnotify', // v3.2.0 PNotify - notification core file - https://sciactive.com/pnotify/
'pnotify.buttons': 'lib/pnotify/pnotify.buttons', // PNotify - buttons notification extension
'pnotify.confirm': 'lib/pnotify/pnotify.confirm', // PNotify - confirmation notification extension
'pnotify.nonblock': 'lib/pnotify/pnotify.nonblock', // PNotify - notification non-block extension (hover effect)
'pnotify.desktop': 'lib/pnotify/pnotify.desktop', // PNotify - desktop push notification extension
'pnotify.history': 'lib/pnotify/pnotify.history', // PNotify - history push notification history extension
'pnotify.callbacks': 'lib/pnotify/pnotify.callbacks', // PNotify - callbacks push notification extension
'pnotify.reference': 'lib/pnotify/pnotify.reference' // PNotify - reference push notification extension
},
shim: {
bootstrap: {
deps: ['jquery']
},
farahey: {
deps: ['jsPlumb']
},
velocity: {
deps: ['jquery']
},
velocityUI: {
deps: ['velocity']
},
slidebars: {
deps: ['jquery']
},
customScrollbar: {
deps: ['jquery', 'mousewheel']
},
'datatables.loader': {
deps: ['jquery']
},
'datatables.net': {
deps: ['jquery']
},
'datatables.net-buttons': {
deps: ['datatables.net']
},
'datatables.net-buttons-html': {
deps: ['datatables.net-buttons']
},
'datatables.net-responsive': {
deps: ['datatables.net']
},
'datatables.net-select': {
deps: ['datatables.net']
},
'datatables.plugins.render.ellipsis': {
deps: ['datatables.net']
},
xEditable: {
deps: ['bootstrap']
},
bootbox: {
deps: ['jquery', 'bootstrap'],
exports: 'bootbox'
},
morris: {
deps: ['jquery', 'raphael'],
exports: 'Morris',
init: function ($, Raphael) {
window.Raphael = Raphael;
}
},
pnotify: {
deps : ['jquery']
},
easyPieChart: {
deps : ['jquery']
},
peityInlineChart: {
deps : ['jquery']
},
dragToSelect: {
deps : ['jquery']
},
hoverIntent: {
deps : ['jquery']
},
fullScreen: {
deps : ['jquery']
},
select2: {
deps : ['jquery', 'mousewheel'],
exports: 'Select2'
},
validator: {
deps : ['jquery', 'bootstrap']
},
lazylinepainter: {
deps : ['jquery', 'bootstrap']
},
blueImpGallery: {
deps : ['jquery']
},
bootstrapConfirmation: {
deps : ['bootstrap']
},
bootstrapToggle: {
deps : ['jquery']
},
lazyload: {
deps : ['jquery']
}
}
});
// switch baseUrl to js "build_js" in production environment
// this has no effect for js build process!
// check build.js for build configuration
require.config({
baseUrl: jsBaseUrl
});
// load the main app module -> initial app start
requirejs( [mainScriptPath] );
"use strict";var mainScriptPath=document.body.getAttribute("data-script"),jsBaseUrl=document.body.getAttribute("data-js-path");requirejs.config({baseUrl:"js",paths:{layout:"layout",conf:"app/conf",dialog:"app/ui/dialog",templates:"../../templates",img:"../../img",login:"./app/login",mappage:"./app/mappage",setup:"./app/setup",admin:"./app/admin",notification:"./app/notification",jquery:"lib/jquery-3.3.1.min",bootstrap:"lib/bootstrap.min",text:"lib/requirejs/text",mustache:"lib/mustache.min",localForage:"lib/localforage.min",velocity:"lib/velocity.min",velocityUI:"lib/velocity.ui.min",slidebars:"lib/slidebars",jsPlumb:"lib/dom.jsPlumb-1.7.6",farahey:"lib/farahey-0.5",customScrollbar:"lib/jquery.mCustomScrollbar.min",mousewheel:"lib/jquery.mousewheel.min",xEditable:"lib/bootstrap-editable.min",morris:"lib/morris.min",raphael:"lib/raphael-min",bootbox:"lib/bootbox.min",easyPieChart:"lib/jquery.easypiechart.min",peityInlineChart:"lib/jquery.peity.min",dragToSelect:"lib/jquery.dragToSelect",hoverIntent:"lib/jquery.hoverIntent.min",fullScreen:"lib/jquery.fullscreen.min",select2:"lib/select2.min",validator:"lib/validator.min",lazylinepainter:"lib/jquery.lazylinepainter-1.5.1.min",blueImpGallery:"lib/blueimp-gallery",blueImpGalleryHelper:"lib/blueimp-helper",blueImpGalleryBootstrap:"lib/bootstrap-image-gallery",bootstrapConfirmation:"lib/bootstrap-confirmation",bootstrapToggle:"lib/bootstrap-toggle.min",lazyload:"lib/jquery.lazyload.min",sortable:"lib/sortable.min",easePack:"lib/EasePack.min",tweenLite:"lib/TweenLite.min","datatables.loader":"./app/datatables.loader","datatables.net":"lib/datatables/DataTables-1.10.12/js/jquery.dataTables.min","datatables.net-buttons":"lib/datatables/Buttons-1.2.1/js/dataTables.buttons.min","datatables.net-buttons-html":"lib/datatables/Buttons-1.2.1/js/buttons.html5.min","datatables.net-responsive":"lib/datatables/Responsive-2.1.0/js/dataTables.responsive.min","datatables.net-select":"lib/datatables/Select-1.2.0/js/dataTables.select.min","datatables.plugins.render.ellipsis":"lib/datatables/plugins/render/ellipsis",pnotify:"lib/pnotify/pnotify","pnotify.buttons":"lib/pnotify/pnotify.buttons","pnotify.confirm":"lib/pnotify/pnotify.confirm","pnotify.nonblock":"lib/pnotify/pnotify.nonblock","pnotify.desktop":"lib/pnotify/pnotify.desktop","pnotify.history":"lib/pnotify/pnotify.history","pnotify.callbacks":"lib/pnotify/pnotify.callbacks","pnotify.reference":"lib/pnotify/pnotify.reference"},shim:{bootstrap:{deps:["jquery"]},farahey:{deps:["jsPlumb"]},velocity:{deps:["jquery"]},velocityUI:{deps:["velocity"]},slidebars:{deps:["jquery"]},customScrollbar:{deps:["jquery","mousewheel"]},"datatables.loader":{deps:["jquery"]},"datatables.net":{deps:["jquery"]},"datatables.net-buttons":{deps:["datatables.net"]},"datatables.net-buttons-html":{deps:["datatables.net-buttons"]},"datatables.net-responsive":{deps:["datatables.net"]},"datatables.net-select":{deps:["datatables.net"]},"datatables.plugins.render.ellipsis":{deps:["datatables.net"]},xEditable:{deps:["bootstrap"]},bootbox:{deps:["jquery","bootstrap"],exports:"bootbox"},morris:{deps:["jquery","raphael"],exports:"Morris",init:function(e,t){window.Raphael=t}},pnotify:{deps:["jquery"]},easyPieChart:{deps:["jquery"]},peityInlineChart:{deps:["jquery"]},dragToSelect:{deps:["jquery"]},hoverIntent:{deps:["jquery"]},fullScreen:{deps:["jquery"]},select2:{deps:["jquery","mousewheel"],exports:"Select2"},validator:{deps:["jquery","bootstrap"]},lazylinepainter:{deps:["jquery","bootstrap"]},blueImpGallery:{deps:["jquery"]},bootstrapConfirmation:{deps:["bootstrap"]},bootstrapToggle:{deps:["jquery"]},lazyload:{deps:["jquery"]}}}),require.config({baseUrl:jsBaseUrl}),requirejs([mainScriptPath]);
//# sourceMappingURL=app.js.map

BIN
public/js/v1.4.0/app.js.br Normal file

Binary file not shown.

View File

@@ -0,0 +1 @@
{"version":3,"sources":["app.js"],"names":["mainScriptPath","document","body","getAttribute","jsBaseUrl","requirejs","config","baseUrl","paths","layout","conf","dialog","templates","img","login","mappage","setup","admin","notification","jquery","bootstrap","text","mustache","localForage","velocity","velocityUI","slidebars","jsPlumb","farahey","customScrollbar","mousewheel","xEditable","morris","raphael","bootbox","easyPieChart","peityInlineChart","dragToSelect","hoverIntent","fullScreen","select2","validator","lazylinepainter","blueImpGallery","blueImpGalleryHelper","blueImpGalleryBootstrap","bootstrapConfirmation","bootstrapToggle","lazyload","sortable","easePack","tweenLite","datatables.loader","datatables.net","datatables.net-buttons","datatables.net-buttons-html","datatables.net-responsive","datatables.net-select","datatables.plugins.render.ellipsis","pnotify","pnotify.buttons","pnotify.confirm","pnotify.nonblock","pnotify.desktop","pnotify.history","pnotify.callbacks","pnotify.reference","shim","deps","exports","init","$","Raphael","window","require"],"mappings":"AAAA,aAGA,IAAIA,eAAiBC,SAASC,KAAKC,aAAa,eAI5CC,UAAYH,SAASC,KAAKC,aAAa,gBAG3CE,UAAUC,QACNC,QAAS,KAETC,OACIC,OAAQ,SACRC,KAAM,WACNC,OAAQ,gBACRC,UAAW,kBACXC,IAAK,YAGLC,MAAO,cACPC,QAAS,gBACTC,MAAO,cACPC,MAAO,cACPC,aAAc,qBAEdC,OAAQ,uBACRC,UAAW,oBACXC,KAAM,qBACNC,SAAU,mBACVC,YAAa,sBACbC,SAAU,mBACVC,WAAY,sBACZC,UAAW,gBACXC,QAAS,wBACTC,QAAS,kBACTC,gBAAiB,kCACjBC,WAAY,4BACZC,UAAW,6BACXC,OAAQ,iBACRC,QAAS,kBACTC,QAAS,kBACTC,aAAc,8BACdC,iBAAkB,uBAClBC,aAAc,0BACdC,YAAa,6BACbC,WAAY,4BACZC,QAAS,kBACTC,UAAW,oBACXC,gBAAiB,uCACjBC,eAAgB,sBAChBC,qBAAsB,qBACtBC,wBAAyB,8BACzBC,sBAAuB,6BACvBC,gBAAiB,2BACjBC,SAAU,0BACVC,SAAU,mBAGVC,SAAU,mBACVC,UAAW,oBAGXC,oBAAqB,0BACrBC,iBAAkB,6DAClBC,yBAA0B,yDAC1BC,8BAA+B,oDAC/BC,4BAA6B,+DAC7BC,wBAAyB,uDACzBC,qCAAsC,yCAGtCC,QAAS,sBACTC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,mBAAoB,+BACpBC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,oBAAqB,gCACrBC,oBAAqB,iCAEzBC,MACI/C,WACIgD,MAAO,WAEXxC,SACIwC,MAAO,YAEX5C,UACI4C,MAAO,WAEX3C,YACI2C,MAAO,aAEX1C,WACI0C,MAAO,WAEXvC,iBACIuC,MAAO,SAAU,eAErBhB,qBACIgB,MAAO,WAEXf,kBACIe,MAAO,WAEXd,0BACIc,MAAO,mBAEXb,+BACIa,MAAO,2BAEXZ,6BACIY,MAAO,mBAEXX,yBACIW,MAAO,mBAEXV,sCACIU,MAAO,mBAEXrC,WACIqC,MAAO,cAEXlC,SACIkC,MAAO,SAAU,aACjBC,QAAS,WAEbrC,QACIoC,MAAO,SAAU,WACjBC,QAAS,SACTC,KAAM,SAAUC,EAAGC,GACfC,OAAOD,QAAUA,IAGzBb,SACIS,MAAQ,WAEZjC,cACIiC,MAAQ,WAEZhC,kBACIgC,MAAQ,WAEZ/B,cACI+B,MAAQ,WAEZ9B,aACI8B,MAAQ,WAEZ7B,YACI6B,MAAQ,WAEZ5B,SACI4B,MAAQ,SAAU,cAClBC,QAAS,WAEb5B,WACI2B,MAAQ,SAAU,cAEtB1B,iBACI0B,MAAQ,SAAU,cAEtBzB,gBACIyB,MAAQ,WAEZtB,uBACIsB,MAAQ,cAEZrB,iBACIqB,MAAQ,WAEZpB,UACIoB,MAAQ,cAQpBM,QAAQpE,QACJC,QAASH,YAIbC,WAAYL","file":"app.js","sourceRoot":"/js"}

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1,422 +0,0 @@
/**
* Created by exodus4d on 06.07.2015.
* static signature types
*
* (*) marked fields are in-game verified and
* proofed, signature names (copy & paste from scanning window)
*/
define(['jquery'], ($) => {
'use strict';
// signature sources
// http://de.sistersprobe.wikia.com/wiki/EVE_Sister_Core_Scanner_Probe_Wiki
// NullSec Relic sites, which can also spawn in C1, C2, C3 wormholes
let nullSecRelicSites = {
10: 'Ruined Angel Crystal Quarry',
11: 'Ruined Angel Monument Site',
12: 'Ruined Angel Science Outpost',
13: 'Ruined Angel Temple Site',
14: 'Ruined Blood Raider Crystal Quarry',
15: 'Ruined Blood Raider Monument Site',
16: 'Ruined Blood Raider Science Outpost',
17: 'Ruined Blood Raider Temple Site',
18: 'Ruined Guristas Crystal Quarry',
19: 'Ruined Guristas Monument Site',
20: 'Ruined Guristas Science Outpost',
21: 'Ruined Guristas Temple Site',
22: 'Ruined Sansha Crystal Quarry',
23: 'Ruined Sansha Monument Site',
24: 'Ruined Sansha Science Outpost',
25: 'Ruined Sansha Temple Site',
26: 'Ruined Serpentis Crystal Quarry',
27: 'Ruined Serpentis Monument Site',
28: 'Ruined Serpentis Science Outpost',
29: 'Ruined Serpentis Temple Site'
};
// NulSec Data sites, which can also spawn in C1, C2, C3 wormholes
let nullSecDataSites = {
10: 'Abandoned Research Complex DA005',
11: 'Abandoned Research Complex DA015',
12: 'Abandoned Research Complex DC007',
13: 'Abandoned Research Complex DC021',
14: 'Abandoned Research Complex DC035',
15: 'Abandoned Research Complex DG003',
16: 'Central Angel Command Center',
17: 'Central Angel Data Mining Site',
18: 'Central Angel Sparking Transmitter',
19: 'Central Angel Survey Site',
20: 'Central Blood Raider Command Center',
21: 'Central Blood Raider Data Mining Site',
22: 'Central Blood Raider Sparking Transmitter',
23: 'Central Blood Raider Survey Site',
24: 'Central Guristas Command Center',
25: 'Central Guristas Data Mining Center',
26: 'Central Guristas Sparking Transmitter',
27: 'Central Guristas Survey Site',
28: 'Central Sansha Command Center',
29: 'Central Sansha Data Mining Site',
30: 'Central Sansha Sparking Transmitter',
31: 'Central Sansha Survey Site',
32: 'Central Serpentis Command Center',
33: 'Central Serpentis Data Mining Site',
34: 'Central Serpentis Sparking Transmitter',
35: 'Central Serpentis Survey Site'
};
// signature types
let signatureTypes = {
1: { // system type (wh)
1: { // C1 (area id)
1: { // Combat
1: 'Perimeter Ambush Point',
2: 'Perimeter Camp',
3: 'Phase Catalyst Node',
4: 'The Line'
},
2: $.extend({}, nullSecRelicSites, { // Relic
1: 'Forgotten Perimeter Coronation Platform', //*
2: 'Forgotten Perimeter Power Array' //*
}),
3: $.extend({}, nullSecDataSites, { // Data
1: 'Unsecured Perimeter Amplifier', //*
2: 'Unsecured Perimeter Information Center' //*
}),
4: { // Gas
1: 'Barren Perimeter Reservoir', //*
2: 'Token Perimeter Reservoir', //*
3: 'Minor Perimeter Reservoir', //*
4: 'Sizeable Perimeter Reservoir', //*
5: 'Ordinary Perimeter Reservoir' //*
},
5: { // Wormhole
// all k-space exits are static or K162
1: 'H121 - C1',
2: 'C125 - C2',
3: 'O883 - C3',
4: 'M609 - C4',
5: 'L614 - C5',
6: 'S804 - C6',
7: 'F353 - Thera'
},
6: { // ORE
1: 'Ordinary Perimeter Deposit', //*
2: 'Common Perimeter Deposit', //*
3: 'Unexceptional Frontier Deposit', //*
4: 'Average Frontier Deposit', //*
5: 'Isolated Core Deposit', //*
6: 'Uncommon Core Deposit' //*
},
7: { // Ghost
}
},
2: { // C2
1: { // Combat
1: 'Perimeter Checkpoint',
2: 'Perimeter Hangar',
3: 'The Ruins of Enclave Cohort 27',
4: 'Sleeper Data Sanctuary'
},
2: $.extend({}, nullSecRelicSites, { // Relic
1: 'Forgotten Perimeter Gateway', //*
2: 'Forgotten Perimeter Habitation Coils' //*
}),
3: $.extend({}, nullSecDataSites, { // Data
1: 'Unsecured Perimeter Comms Relay', //*
2: 'Unsecured Perimeter Transponder Farm' //*
}),
4: { // Gas
1: 'Barren Perimeter Reservoir', //*
2: 'Token Perimeter Reservoir', //*
3: 'Minor Perimeter Reservoir', //*
4: 'Sizeable Perimeter Reservoir', //*
5: 'Ordinary Perimeter Reservoir' //*
},
5: { // Wormhole
// all w-space -> w-space are statics or K162
// all w-space -> k-space are statics or k162
7: 'F135 - Thera'
},
6: { // ORE
1: 'Ordinary Perimeter Deposit', //*
2: 'Common Perimeter Deposit', //*
3: 'Unexceptional Frontier Deposit', //*
4: 'Average Frontier Deposit', //*
5: 'Isolated Core Deposit', //*
6: 'Uncommon Core Deposit' //*
},
7: { // Ghost
}
},
3: { // C3
1: { // Combat
1: 'Fortification Frontier Stronghold',
2: 'Outpost Frontier Stronghold',
3: 'Solar Cell',
4: 'The Oruze Construct'
},
2: $.extend({}, nullSecRelicSites, { // Relic
1: 'Forgotten Frontier Quarantine Outpost', //*
2: 'Forgotten Frontier Recursive Depot' //*
}),
3: $.extend({}, nullSecDataSites, { // Data
1: 'Unsecured Frontier Database', //*
2: 'Unsecured Frontier Receiver' //*
}),
4: { // Gas
1: 'Barren Perimeter Reservoir', //*
2: 'Token Perimeter Reservoir', //*
3: 'Minor Perimeter Reservoir', //*
4: 'Sizeable Perimeter Reservoir', //*
5: 'Ordinary Perimeter Reservoir', //*
6: 'Bountiful Frontier Reservoir', //*
7: 'Vast Frontier Reservoir' //*
},
5: { // Wormhole
// all k-space exits are static or K162
1: 'V301 - C1',
2: 'I182 - C2',
3: 'N968 - C3',
4: 'T405 - C4',
5: 'N770 - C5',
6: 'A982 - C6',
7: 'F135 - Thera'
},
6: { // ORE
1: 'Ordinary Perimeter Deposit', //*
2: 'Common Perimeter Deposit', //*
3: 'Unexceptional Frontier Deposit', //*
4: 'Average Frontier Deposit', //*
5: 'Infrequent Core Deposit', //*
6: 'Unusual Core Deposit' //*
},
7: { // Ghost
}
},
4: { // C4
1: { // Combat
1: 'Frontier Barracks',
2: 'Frontier Command Post',
3: 'Integrated Terminus',
4: 'Sleeper Information Sanctum'
},
2: { // Relic
1: 'Forgotten Frontier Conversion Module',
2: 'Forgotten Frontier Evacuation Center'
},
3: { // Data
1: 'Unsecured Frontier Digital Nexus',
2: 'Unsecured Frontier Trinary Hub'
},
4: { // Gas
1: 'Barren Perimeter Reservoir', //*
2: 'Token Perimeter Reservoir', //*
3: 'Minor Perimeter Reservoir', //*
4: 'Sizeable Perimeter Reservoir', //*
5: 'Ordinary Perimeter Reservoir', //*
6: 'Vast Frontier Reservoir', //*
7: 'Bountiful Frontier Reservoir' //*
},
5: { // Wormhole
// no *wandering* w-space -> w-space
// all holes are statics or K162
1: 'S047 - HS',
2: 'N290 - LS',
3: 'K329 - 0.0'
},
6: { // ORE
1: 'Ordinary Perimeter Deposit', //*
2: 'Common Perimeter Deposit', //*
3: 'Unexceptional Frontier Deposit', //*
4: 'Average Frontier Deposit', //*
5: 'Unusual Core Deposit', //*
6: 'Infrequent Core Deposit' //*
},
7: { // Ghost
}
},
5: { // C5
1: { // Combat
1: 'Core Garrison', //*
2: 'Core Stronghold', //*
3: 'Oruze Osobnyk', //*
4: 'Quarantine Area'
},
2: { // Relic
1: 'Forgotten Core Data Field',
2: 'Forgotten Core Information Pen'
},
3: { // Data
1: 'Unsecured Frontier Enclave Relay',
2: 'Unsecured Frontier Server Bank'
},
4: { // Gas
1: 'Barren Perimeter Reservoir', //*
2: 'Minor Perimeter Reservoir', //*
3: 'Ordinary Perimeter Reservoir', //*
4: 'Sizeable Perimeter Reservoir', //*
5: 'Token Perimeter Reservoir', //*
6: 'Bountiful Frontier Reservoir', //*
7: 'Vast Frontier Reservoir', //*
8: 'Instrumental Core Reservoir', //*
9: 'Vital Core Reservoir' //*
},
5: { // Wormhole
1: 'D792 - HS',
2: 'C140 - LS',
3: 'Z142 - 0.0'
},
6: { // ORE
1: 'Average Frontier Deposit', //*
2: 'Unexceptional Frontier Deposit', //*
3: 'Uncommon Core Deposit', //*
4: 'Ordinary Perimeter Deposit', //*
5: 'Common Perimeter Deposit', //*
6: 'Exceptional Core Deposit', //*
7: 'Infrequent Core Deposit', //*
8: 'Unusual Core Deposit', //*
9: 'Rarified Core Deposit', //*
10: 'Isolated Core Deposit' //*
},
7: { // Ghost
}
},
6: { // C6
1: { // Combat
1: 'Core Citadel', //*
2: 'Core Bastion', //*
3: 'Strange Energy Readings', //*
4: 'The Mirror' //*
},
2: { // Relic
1: 'Forgotten Core Assembly Hall', //*
2: 'Forgotten Core Circuitry Disassembler' //*
},
3: { // Data
1: 'Unsecured Core Backup Array', //*
2: 'Unsecured Core Emergence' //*
},
4: { // Gas
1: 'Barren Perimeter Reservoir', //*
2: 'Minor Perimeter Reservoir', //*
3: 'Ordinary Perimeter Reservoir', //*
4: 'Sizeable Perimeter Reservoir', //*
5: 'Token Perimeter Reservoir', //*
6: 'Bountiful Frontier Reservoir', //*
7: 'Vast Frontier Reservoir', //*
8: 'Instrumental Core Reservoir', //*
9: 'Vital Core Reservoir' //*
},
5: { // Wormhole
1: 'B520 - HS',
2: 'D792 - HS',
3: 'C140 - LS',
4: 'C391 - LS',
5: 'C248 - 0.0',
6: 'Z142 - 0.0'
},
6: { // ORE
1: 'Ordinary Perimeter Deposit', //*
2: 'Common Perimeter Deposit', //*
3: 'Unexceptional Frontier Deposit', //*
4: 'Average Frontier Deposit', //*
5: 'Rarified Core Deposit' //*
},
7: { // Ghost
1: 'Superior Blood Raider Covert Research Facility' //*
}
},
13: { // Shattered Wormholes
5: { // Wormhole (some of them are static)
1: 'P060 - C1',
2: 'Z647 - C1',
3: 'D382 - C2',
4: 'L005 - C2',
5: 'N766 - C2',
6: 'C247 - C3',
7: 'M267 - C3',
8: 'O477 - C3',
9: 'X877 - C4',
10: 'Y683 - C4',
11: 'H296 - C5',
12: 'H900 - C5',
13: 'H296 - C5',
14: 'N062 - C5', // ??
15: 'V911 - C5',
16: 'U574 - C6',
17: 'V753 - C6',
18: 'W237 - C6',
19: 'B274 - HS',
20: 'D792 - HS',
21: 'D845 - HS',
22: 'N110 - HS',
23: 'A239 - LS',
24: 'C391 - LS',
25: 'J244 - LS',
26: 'U201 - LS', // ??
27: 'U210 - LS',
28: 'C248 - 0.0',
29: 'E545 - 0.0',
30: 'K346 - 0.0',
31: 'Z060 - 0.0'
}
}
}, // system type (k-space)
2: {
10: { // High Sec
5: { // Wormhole
1: 'Z971 - C1',
2: 'R943 - C2',
3: 'X702 - C3',
4: 'O128 - C4',
5: 'M555 - C5',
6: 'B041 - C6',
7: 'A641 - HS',
8: 'R051 - LS',
9: 'V283 - 0.0',
10: 'T458 - Thera'
}
},
11: { // Low Sec
5: { // Wormhole
1: 'Z971 - C1',
2: 'R943 - C2',
3: 'X702 - C3',
4: 'O128 - C4',
5: 'N432 - C5',
6: 'U319 - C6',
7: 'B449 - HS',
8: 'N944 - LS',
9: 'S199 - 0.0',
10: 'M164 - Thera'
}
},
12: { // 0.0
5: { // Wormhole
1: 'Z971 - C1',
2: 'R943 - C2',
3: 'X702 - C3',
4: 'O128 - C4',
5: 'N432 - C5',
6: 'U319 - C6',
7: 'B449 - HS',
8: 'N944 - LS',
9: 'S199 - 0.0',
10: 'L031 - Thera'
}
}
}
};
return signatureTypes;
});

View File

@@ -1,733 +0,0 @@
/**
* Created by exodus4d on 06.07.2015.
* static system effects
*/
define([], function() {
'use strict';
// system effects
let systemEffects = {
wh: {
magnetar: {
1: [
{
effect: 'Damage',
value: '+30%'
},{
effect: 'Missile exp. radius',
value: '+15%'
},{
effect: 'Drone tracking',
value: '-15%'
},{
effect: 'Targeting range',
value: '-15%'
},{
effect: 'Tracking speed',
value: '-15%'
},{
effect: 'Target Painter strength',
value: '-15%'
}
],
2: [
{
effect: 'Damage',
value: '+44%'
},{
effect: 'Missile exp. radius',
value: '+22%'
},{
effect: 'Drone tracking',
value: '-22%'
},{
effect: 'Targeting range',
value: '-22%'
},{
effect: 'Tracking speed',
value: '-22%'
},{
effect: 'Target Painter strength',
value: '-22%'
}
],
3: [
{
effect: 'Damage',
value: '+58%'
},{
effect: 'Missile exp. radius',
value: '+29%'
},{
effect: 'Drone tracking',
value: '-29%'
},{
effect: 'Targeting range',
value: '-29%'
},{
effect: 'Tracking speed',
value: '-29%'
},{
effect: 'Target Painter strength',
value: '-29%'
}
],
4: [
{
effect: 'Damage',
value: '+72%'
},{
effect: 'Missile exp. radius',
value: '+36%'
},{
effect: 'Drone tracking',
value: '-36%'
},{
effect: 'Targeting range',
value: '-36%'
},{
effect: 'Tracking speed',
value: '-36%'
},{
effect: 'Target Painter strength',
value: '-36%'
}
],
5: [
{
effect: 'Damage',
value: '+86%'
},{
effect: 'Missile exp. radius',
value: '+43%'
},{
effect: 'Drone tracking',
value: '-43%'
},{
effect: 'Targeting range',
value: '-43%'
},{
effect: 'Tracking speed',
value: '-43%'
},{
effect: 'Target Painter strength',
value: '-43%'
}
],
6: [
{
effect: 'Damage',
value: '+100%'
},{
effect: 'Missile exp. radius',
value: '+50%'
},{
effect: 'Drone tracking',
value: '-50%'
},{
effect: 'Targeting range',
value: '-50%'
},{
effect: 'Tracking speed',
value: '-50%'
},{
effect: 'Target Painter strength',
value: '-50%'
}
]
},
redGiant: {
1: [
{
effect: 'Heat damage',
value: '+15%'
},{
effect: 'Overload bonus',
value: '+30%'
},{
effect: 'Smart Bomb range',
value: '+30%'
},{
effect: 'Smart Bomb damage',
value: '+30%'
},{
effect: 'Bomb damage',
value: '+30%'
}
],
2: [
{
effect: 'Heat damage',
value: '+22%'
},{
effect: 'Overload bonus',
value: '+44%'
},{
effect: 'Smart Bomb range',
value: '+44%'
},{
effect: 'Smart Bomb damage',
value: '+44%'
},{
effect: 'Bomb damage',
value: '+44%'
}
],
3: [
{
effect: 'Heat damage',
value: '+29%'
},{
effect: 'Overload bonus',
value: '+58%'
},{
effect: 'Smart Bomb range',
value: '+58%'
},{
effect: 'Smart Bomb damage',
value: '+58%'
},{
effect: 'Bomb damage',
value: '+58%'
}
],
4: [
{
effect: 'Heat damage',
value: '+36%'
},{
effect: 'Overload bonus',
value: '+72%'
},{
effect: 'Smart Bomb range',
value: '+72%'
},{
effect: 'Smart Bomb damage',
value: '+72%'
},{
effect: 'Bomb damage',
value: '+72%'
}
],
5: [
{
effect: 'Heat damage',
value: '+43%'
},{
effect: 'Overload bonus',
value: '+86%'
},{
effect: 'Smart Bomb range',
value: '+86%'
},{
effect: 'Smart Bomb damage',
value: '+86%'
},{
effect: 'Bomb damage',
value: '+86%'
}
],
6: [
{
effect: 'Heat damage',
value: '+50%'
},{
effect: 'Overload bonus',
value: '+100%'
},{
effect: 'Smart Bomb range',
value: '+100%'
},{
effect: 'Smart Bomb damage',
value: '+100%'
},{
effect: 'Bomb damage',
value: '+100%'
}
]
},
pulsar: {
1: [
{
effect: 'Shield HP',
value: '+30%'
},{
effect: 'Armor resist',
value: '-15%'
},{
effect: 'Capacitor recharge',
value: '-15%'
},{
effect: 'Signature',
value: '+30%'
},{
effect: 'NOS/Neut drain',
value: '+30%'
}
],
2: [
{
effect: 'Shield HP',
value: '+44%'
},{
effect: 'Armor resist',
value: '-22%'
},{
effect: 'Capacitor recharge',
value: '-22%'
},{
effect: 'Signature',
value: '+44%'
},{
effect: 'NOS/Neut drain',
value: '+44%'
}
],
3: [
{
effect: 'Shield HP',
value: '+58%'
},{
effect: 'Armor resist',
value: '-29%'
},{
effect: 'Capacitor recharge',
value: '-29%'
},{
effect: 'Signature',
value: '+58%'
},{
effect: 'NOS/Neut drain',
value: '+58%'
}
],
4: [
{
effect: 'Shield HP',
value: '+72%'
},{
effect: 'Armor resist',
value: '-36%'
},{
effect: 'Capacitor recharge',
value: '-36%'
},{
effect: 'Signature',
value: '+72%'
},{
effect: 'NOS/Neut drain',
value: '+72%'
}
],
5: [
{
effect: 'Shield HP',
value: '+86%'
},{
effect: 'Armor resist',
value: '-43%'
},{
effect: 'Capacitor recharge',
value: '-43%'
},{
effect: 'Signature',
value: '+86%'
},{
effect: 'NOS/Neut drain',
value: '+86%'
}
],
6: [
{
effect: 'Shield HP',
value: '+100%'
},{
effect: 'Armor resist',
value: '-50%'
},{
effect: 'Capacitor recharge',
value: '-50%'
},{
effect: 'Signature',
value: '+100%'
},{
effect: 'NOS/Neut drain',
value: '+100%'
}
]
},
wolfRayet: {
1: [
{
effect: 'Armor HP',
value: '+30%'
},{
effect: 'Shield resist',
value: '-15%'
},{
effect: 'Small Weapon damage',
value: '+60%'
},{
effect: 'Signature size',
value: '-15%'
}
],
2: [
{
effect: 'Armor HP',
value: '+44%'
},{
effect: 'Shield resist',
value: '-22%'
},{
effect: 'Small Weapon damage',
value: '+88%'
},{
effect: 'Signature size',
value: '-22%'
}
],
3: [
{
effect: 'Armor HP',
value: '+58%'
},{
effect: 'Shield resist',
value: '-29%'
},{
effect: 'Small Weapon damage',
value: '+116%'
},{
effect: 'Signature size',
value: '-29%'
}
],
4: [
{
effect: 'Armor HP',
value: '+72%'
},{
effect: 'Shield resist',
value: '-36%'
},{
effect: 'Small Weapon damage',
value: '+144%'
},{
effect: 'Signature size',
value: '-36%'
}
],
5: [
{
effect: 'Armor HP',
value: '+86%'
},{
effect: 'Shield resist',
value: '-43%'
},{
effect: 'Small Weapon damage',
value: '+172%'
},{
effect: 'Signature size',
value: '-43%'
}
],
6: [
{
effect: 'Armor HP',
value: '+100%'
},{
effect: 'Shield resist',
value: '-50%'
},{
effect: 'Small Weapon damage',
value: '+200%'
},{
effect: 'Signature size',
value: '-50%'
}
]
},
cataclysmic: {
1: [
{
effect: 'Local armor repair amount',
value: '-15%'
},{
effect: 'Local shield boost amount',
value: '-15%'
},{
effect: 'Shield transfer amount',
value: '+30%'
},{
effect: 'Remote repair amount',
value: '+30%'
},{
effect: 'Capacitor capacity',
value: '+30%'
},{
effect: 'Capacitor recharge time',
value: '+15%'
},{
effect: 'Remote Capacitor Transmitter amount',
value: '-15%'
}
],
2: [
{
effect: 'Local armor repair amount',
value: '-22%'
},{
effect: 'Local shield boost amount',
value: '-22%'
},{
effect: 'Shield transfer amount',
value: '+44%'
},{
effect: 'Remote repair amount',
value: '+44%'
},{
effect: 'Capacitor capacity',
value: '+44%'
},{
effect: 'Capacitor recharge time',
value: '+22%'
},{
effect: 'Remote Capacitor Transmitter amount',
value: '-22%'
}
],
3: [
{
effect: 'Local armor repair amount',
value: '-29%'
},{
effect: 'Local shield boost amount',
value: '-29%'
},{
effect: 'Shield transfer amount',
value: '+58%'
},{
effect: 'Remote repair amount',
value: '+58%'
},{
effect: 'Capacitor capacity',
value: '+58%'
},{
effect: 'Capacitor recharge time',
value: '+29%'
},{
effect: 'Remote Capacitor Transmitter amount',
value: '-29%'
}
],
4: [
{
effect: 'Local armor repair amount',
value: '-36%'
},{
effect: 'Local shield boost amount',
value: '-36%'
},{
effect: 'Shield transfer amount',
value: '+72%'
},{
effect: 'Remote repair amount',
value: '+72%'
},{
effect: 'Capacitor capacity',
value: '+72%'
},{
effect: 'Capacitor recharge time',
value: '+36%'
},{
effect: 'Remote Capacitor Transmitter amount',
value: '-36%'
}
],
5: [
{
effect: 'Local armor repair amount',
value: '-43%'
},{
effect: 'Local shield boost amount',
value: '-43%'
},{
effect: 'Shield transfer amount',
value: '+86%'
},{
effect: 'Remote repair amount',
value: '+86%'
},{
effect: 'Capacitor capacity',
value: '+86%'
},{
effect: 'Capacitor recharge time',
value: '+43%'
},{
effect: 'Remote Capacitor Transmitter amount',
value: '-43%'
}
],
6: [
{
effect: 'Local armor repair amount',
value: '-50%'
},{
effect: 'Local shield boost amount',
value: '-50%'
},{
effect: 'Shield transfer amount',
value: '+100%'
},{
effect: 'Remote repair amount',
value: '+100%'
},{
effect: 'Capacitor capacity',
value: '+100%'
},{
effect: 'Capacitor recharge time',
value: '+50%'
},{
effect: 'Remote Capacitor Transmitter amount',
value: '-50%'
}
]
},
blackHole: {
1: [
{
effect: 'Missile velocity',
value: '+15%'
},{
effect: 'Missile exp. velocity',
value: '+30%'
},{
effect: 'Ship velocity',
value: '+30%'
},{
effect: 'Stasis Webifier strength',
value: '-15%'
},{
effect: 'Inertia',
value: '+15%'
},{
effect: 'Targeting range',
value: '+30%'
}
],
2: [
{
effect: 'Missile velocity',
value: '+22%'
},{
effect: 'Missile exp. velocity',
value: '+44%'
},{
effect: 'Ship velocity',
value: '+44%'
},{
effect: 'Stasis Webifier strength',
value: '-22%'
},{
effect: 'Inertia',
value: '+22%'
},{
effect: 'Targeting range',
value: '+44%'
}
],
3: [
{
effect: 'Missile velocity',
value: '+29%'
},{
effect: 'Missile exp. velocity',
value: '+58%'
},{
effect: 'Ship velocity',
value: '+58%'
},{
effect: 'Stasis Webifier strength',
value: '-29%'
},{
effect: 'Inertia',
value: '+29%'
},{
effect: 'Targeting range',
value: '+58%'
}
],
4: [
{
effect: 'Missile velocity',
value: '+36%'
},{
effect: 'Missile exp. velocity',
value: '+72%'
},{
effect: 'Ship velocity',
value: '+72%'
},{
effect: 'Stasis Webifier strength',
value: '-36%'
},{
effect: 'Inertia',
value: '+36%'
},{
effect: 'Targeting range',
value: '+72%'
}
],
5: [
{
effect: 'Missile velocity',
value: '+43%'
},{
effect: 'Missile exp. velocity',
value: '+86%'
},{
effect: 'Ship velocity',
value: '+86%'
},{
effect: 'Stasis Webifier strength',
value: '-43%'
},{
effect: 'Inertia',
value: '+43%'
},{
effect: 'Targeting range',
value: '+86%'
}
],
6: [
{
effect: 'Missile velocity',
value: '+50%'
},{
effect: 'Missile exp. velocity',
value: '+100%'
},{
effect: 'Ship velocity',
value: '+100%'
},{
effect: 'Stasis Webifier strength',
value: '-50%'
},{
effect: 'Inertia',
value: '+50%'
},{
effect: 'Targeting range',
value: '+100%'
}
]
}
}
};
return systemEffects;
});

View File

@@ -1,119 +0,0 @@
define([
'jquery',
'app/init',
'app/util'
], function($, Init, Util) {
'use strict';
let config = {
counterDigitSmallClass: 'pf-digit-counter-small',
counterDigitLargeClass: 'pf-digit-counter-large'
};
/**
* update element with time information
* @param element
* @param tempDate
* @param round
*/
let updateDateDiff = function(element, tempDate, round){
let diff = Util.getTimeDiffParts(tempDate, new Date());
let days = diff.days;
let hrs = diff.hours;
let min = diff.min;
let leftSec = diff.sec;
let parts = [];
if(
round === 'd' &&
days >= 1
){
parts.push('<span class="' + config.counterDigitLargeClass + '">' + '&gt;&nbsp;1d' + '</span>');
}else{
if(
days > 0 ||
parts.length > 0
){
parts.push('<span class="' + config.counterDigitLargeClass + '">' + days + 'd' + '</span>');
}
if(
hrs > 0 ||
parts.length > 0
){
parts.push('<span class="' + config.counterDigitSmallClass + '">' + hrs + 'h' + '</span>');
}
if(
min > 0 ||
parts.length > 0
){
parts.push('<span class="' + config.counterDigitSmallClass + '">' + min + 'm' + '</span>');
}
if(
leftSec >= 0 ||
parts.length > 0
){
parts.push('<span class="' + config.counterDigitSmallClass + '">' + leftSec + 's' + '</span>');
}
}
element.html(parts.join(' '));
};
/**
* destroy all active counter recursive
*/
$.fn.destroyTimestampCounter = function(){
return this.each(function(){
let parentElement = $(this);
parentElement.find('[data-counter="init"]').each(function(){
let element = $(this);
let interval = element.data('interval');
if(interval){
clearInterval(interval);
element.removeAttr('data-counter')
.removeData('interval')
.removeClass('stopCounter');
}
});
});
};
/**
* init a live counter based on a unix timestamp
* @param round string e.g. 'd' => round days
*/
$.fn.initTimestampCounter = function(round){
return this.each(function(){
let element = $(this);
let timestamp = parseInt( element.text() );
// do not init twice
if(timestamp > 0){
// mark as init
element.attr('data-counter', 'init');
let date = new Date( timestamp * 1000);
updateDateDiff(element, date, round);
// show element (if invisible) after first update
element.css({'visibility': 'initial'});
let refreshIntervalId = window.setInterval(function(){
// update element with current time
if( !element.hasClass('stopCounter')){
updateDateDiff(element, date, round);
}else{
clearInterval( element.data('interval') );
}
}, 500);
element.data('interval', refreshIntervalId);
}
});
};
});

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1,482 +0,0 @@
/**
* Init
*/
define(['jquery'], ($) => {
'use strict';
let Config = {
path: {
img: '/public/img/', // path for images
// user API
getCaptcha: '/api/user/getCaptcha', // ajax URL - get captcha image
getServerStatus: '/api/user/getEveServerStatus', // ajax URL - get EVE-Online server status
getCookieCharacterData: '/api/user/getCookieCharacter', // ajax URL - get character data from cookie
logIn: '/api/user/logIn', // ajax URL - login
logout: '/api/user/logout', // ajax URL - logout
deleteLog: '/api/user/deleteLog', // ajax URL - delete character log
openIngameWindow: '/api/user/openIngameWindow', // ajax URL - open inGame Window
saveUserConfig: '/api/user/saveAccount', // ajax URL - saves/update user account
deleteAccount: '/api/user/deleteAccount', // ajax URL - delete Account data
// access API
searchAccess: '/api/access/search', // ajax URL - search user/corporation/ally by name
// main config/map ping API
initData: '/api/map/initData', // ajax URL - get static configuration data
getAccessData: '/api/map/getAccessData', // ajax URL - get map access tokens (WebSocket)
updateMapData: '/api/map/updateData', // ajax URL - main map update trigger
updateUserData: '/api/map/updateUserData', // ajax URL - main map user data trigger
// map API
saveMap: '/api/map/save', // ajax URL - save/update map
deleteMap: '/api/map/delete', // ajax URL - delete map
importMap: '/api/map/import', // ajax URL - import map
getMapConnectionData: '/api/map/getConnectionData', // ajax URL - get connection data
getMapLogData: '/api/map/getLogData', // ajax URL - get logs data
// system API
getSystemData: '/api/system/getData', // ajax URL - get system data
saveSystem: '/api/system/save', // ajax URL - saves system to map
deleteSystem: '/api/system/delete', // ajax URL - delete system from map
getSystemGraphData: '/api/system/graphData', // ajax URL - get all system graph data
setDestination: '/api/system/setDestination', // ajax URL - set destination
pokeRally: '/api/system/pokeRally', // ajax URL - send rally point pokes
// connection API
saveConnection: '/api/connection/save', // ajax URL - save new connection to map
deleteConnection: '/api/connection/delete', // ajax URL - delete connection from map
// signature API
saveSignatureData: '/api/signature/save', // ajax URL - save signature data for system
deleteSignatureData: '/api/signature/delete', // ajax URL - delete signature data for system
// structure API
saveStructureData: '/api/structure/save', // ajax URL - save structure data
deleteStructureData: '/api/structure/delete', // ajax URL - delete structure data
// route API
searchRoute: '/api/route/search', // ajax URL - search system routes
// stats API
getStatisticsData: '/api/statistic/getData', // ajax URL - get statistics data (activity log)
// universe API
searchUniverseData: '/api/universe/search', // ajax URL - search universe data by category Ids
searchUniverseSystemData: '/api/universe/systems', // ajax URL - search universe system data by name
getConstellationData: '/api/universe/constellationData', // ajax URL - get system constellation data
// GitHub API
gitHubReleases: '/api/github/releases' // ajax URL - get release info from GitHub
},
breakpoints: [
{ name: 'desktop', width: Infinity },
{ name: 'tablet', width: 1200 },
{ name: 'fablet', width: 780 },
{ name: 'phone', width: 480 }
],
animationSpeed: {
splashOverlay: 300, // "splash" loading overlay
headerLink: 100, // links in head bar
mapOverlay: 200, // show/hide duration for map overlays
mapOverlayLocal: 180, // show/hide duration for map "local" overlay
mapMoveSystem: 180, // system position has changed animation
mapDeleteSystem: 200, // remove system from map
mapModule: 200, // show/hide of an map module
dialogEvents: 180 // dialog events /slide/show/...
},
syncStatus: {
type: 'ajax',
webSocket: {
status: 'closed',
class: 'txt-color-danger',
timestamp: undefined
},
sharedWorker: {
status: 'offline', // SharedWorker status
class: 'txt-color-danger',
timestamp: undefined
},
ajax: {
status: 'enabled',
class: 'txt-color-success',
timestamp: undefined
}
},
performanceLogging: {
keyServerMapData: 'UPDATE_SERVER_MAP', // ajax request update map data
keyClientMapData: 'UPDATE_CLIENT_MAP', // update client map data
keyServerUserData: 'UPDATE_SERVER_USER_DATA', // ajax request update map user data
keyClientUserData: 'UPDATE_CLIENT_USER_DATA', // update client map user data
},
mapIcons: [ // map tab-icons
{
class: 'fa-desktop',
label: 'desktop',
unicode: '&#xf108;'
},{
class: 'fa-space-shuttle',
label: 'space shuttle',
unicode: '&#xf197;'
},{
class: 'fa-anchor',
label: 'anchor',
unicode: '&#xf13d;'
},{
class: 'fa-fire',
label: 'fire',
unicode: '&#xf06d;'
},{
class: 'fa-bookmark',
label: 'bookmark',
unicode: '&#xf02e;'
},{
class: 'fa-cube',
label: 'cube',
unicode: '&#xf1b2;'
},{
class: 'fa-star',
label: 'star',
unicode: '&#xf005;'
},{
class: 'fa-plane',
label: 'plane',
unicode: '&#xf072;'
},{
class: 'fa-globe',
label: 'globe',
unicode: '&#xf0ac;'
},{
class: 'fa-rocket',
label: 'rocket',
unicode: '&#xf135;'
},{
class: 'fa-life-ring',
label: 'life ring',
unicode: '&#xf1cd;'
},{
class: 'fa-heart',
label: 'heart',
unicode: '&#xf004;'
}
],
classes: {
// log types
logTypes: {
info: {
class: 'pf-log-info',
label: 'info'
},
warning: {
class: 'pf-log-warning',
label: 'warning'
},
error: {
class: 'pf-log-error',
label: 'error'
}
},
// system effects
systemEffects: {
effect: {
class: 'pf-system-effect',
name: 'no effect'
},
magnetar: {
class: 'pf-system-effect-magnetar',
name: 'magnetar'
},
redGiant: {
class: 'pf-system-effect-redgiant',
name: 'red giant'
},
pulsar: {
class: 'pf-system-effect-pulsar',
name: 'pulsar'
},
wolfRayet: {
class: 'pf-system-effect-wolfrayet',
name: 'wolf rayet'
},
cataclysmic: {
class: 'pf-system-effect-cataclysmic',
name: 'cataclysmic'
},
blackHole: {
class: 'pf-system-effect-blackhole',
name: 'black hole'
}
},
// system security
systemSecurity: {
security: {
class: 'pf-system-sec'
},
'A': {
class: 'pf-system-sec-abyssal'
},
'SH': {
class: 'pf-system-sec-unknown'
},
'H': {
class: 'pf-system-sec-highSec'
},
'L': {
class: 'pf-system-sec-lowSec'
},
'0.0': {
class: 'pf-system-sec-nullSec'
},
'C6': {
class: 'pf-system-sec-high'
},
'C5': {
class: 'pf-system-sec-high'
},
'C4': {
class: 'pf-system-sec-mid'
},
'C3': {
class: 'pf-system-sec-mid'
},
'C2': {
class: 'pf-system-sec-low'
},
'C1': {
class: 'pf-system-sec-low'
}
},
// true sec
trueSec: {
'0.0': {
class: 'pf-system-security-0-0'
},
'0.1': {
class: 'pf-system-security-0-1'
},
'0.2': {
class: 'pf-system-security-0-2'
},
'0.3': {
class: 'pf-system-security-0-3'
},
'0.4': {
class: 'pf-system-security-0-4'
},
'0.5': {
class: 'pf-system-security-0-5'
},
'0.6': {
class: 'pf-system-security-0-6'
},
'0.7': {
class: 'pf-system-security-0-7'
},
'0.8': {
class: 'pf-system-security-0-8'
},
'0.9': {
class: 'pf-system-security-0-9'
},
'1.0': {
class: 'pf-system-security-1-0'
}
},
// system info
systemInfo: {
rally: {
class: 'pf-system-info-rally',
label: 'rally point'
}
},
// easy-pie-charts
pieChart: {
class: 'pf-pie-chart', // class for all pie charts
pieChartMapCounterClass: 'pf-pie-chart-map-timer' // class for timer chart
}
},
// map scopes
defaultMapScope: 'wh', // default scope for connection
// map connection types
connectionTypes: {
abyssal: {
cssClass: 'pf-map-connection-abyssal',
paintStyle: {
dashstyle: '0.5 2' // dotted line
}
},
jumpbridge: {
cssClass: 'pf-map-connection-jumpbridge',
paintStyle: {
dashstyle: '4 2 1 2'
}
},
stargate: {
cssClass: 'pf-map-connection-stargate',
paintStyle: {
dashstyle: '0' // solid line
}
},
wh_eol: {
cssClass: 'pf-map-connection-wh-eol',
paintStyle: {
dashstyle: '0' // solid line
}
},
wh_fresh: {
cssClass: 'pf-map-connection-wh-fresh',
paintStyle: {
dashstyle: '0' // solid line
}
},
wh_reduced: {
cssClass: 'pf-map-connection-wh-reduced',
paintStyle: {
dashstyle: '0' // solid line
}
},
wh_critical: {
cssClass: 'pf-map-connection-wh-critical',
paintStyle: {
dashstyle: '0' // solid line
}
},
frigate: {
cssClass: 'pf-map-connection-frig',
paintStyle: {
dashstyle: '0.99'
},
overlays:[
['Label',
{
label: 'frig',
cssClass: ['pf-map-connection-overlay', 'frig'].join(' '),
location: 0.6
}]
]
},
preserve_mass: {
cssClass: 'pf-map-connection-preserve-mass',
overlays:[
['Label',
{
label: '<i class="fas fa-fw fa-exclamation-triangle"></i>&nbsp;save mass',
cssClass: ['pf-map-connection-overlay', 'mass'].join(' '),
location: 0.6
}]
]
},
active: {
cssClass: 'pf-map-connection-active'
}
},
// signature groups
signatureGroups: {
1: {
name: '(combat site|kampfgebiet|site de combat)', //*
label: 'Combat'
},
2: {
name: '(relic site|reliktgebiet|site de reliques)', //*
label: 'Relic'
},
3: {
name: '(data site|datengebiet|site de données)',
label: 'Data'
},
4: {
name: '(gas site|gasgebiet|site de collecte de gaz)',
label: 'Gas'
},
5: {
name: '(wormhole|wurmloch|trou de ver)',
label: 'Wormhole'
},
6: {
name: '(ore site|mineraliengebiet|site de minerai)',
label: 'Ore'
},
7: {
name: '(ghost)',
label: 'Ghost'
}
},
// frigate wormholes
frigateWormholes: {
1: { // C1
1: 'E004 - C1',
2: 'L005 - C2',
3: 'Z006 - C3',
4: 'M001 - C4',
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
},
2: { // C2
1: 'E004 - C1',
2: 'L005 - C2',
3: 'Z006 - C3',
4: 'M001 - C4',
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
},
3: { // C3
1: 'E004 - C1',
2: 'L005 - C2',
3: 'Z006 - C3',
4: 'M001 - C4',
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
},
4: { // C4
1: 'E004 - C1',
2: 'L005 - C2',
3: 'Z006 - C3',
4: 'M001 - C4',
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
},
5: { // C5
1: 'E004 - C1',
2: 'L005 - C2',
3: 'Z006 - C3',
4: 'M001 - C4',
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
},
6: { // C6
1: 'E004 - C1',
2: 'L005 - C2',
3: 'Z006 - C3',
4: 'M001 - C4',
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
},
13: { // Shattered Wormholes (some of them are static)
1: 'E004 - C1',
2: 'L005 - C2',
3: 'Z006 - C3',
4: 'M001 - C4',
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
}
},
// incoming wormholes
incomingWormholes: {
1: 'K162 - C1/2/3 (unknown)',
2: 'K162 - C4/5 (dangerous)',
3: 'K162 - C6 (deadly)',
4: 'K162 - HS',
5: 'K162 - LS',
6: 'K162 - 0.0',
7: 'K162 - Thera'
}
};
return Config;
});

View File

@@ -1,453 +0,0 @@
define([
'jquery'
], function($) {
'use strict';
let allCombo = {
// global -------------------------------------------------------------------------------------------
tabReload: {
group: 'global',
label: 'Close open dialog',
keyNames: ['ESC']
},
// signature ----------------------------------------------------------------------------------------
signatureSelect: {
group: 'signatures',
label: 'Select multiple rows',
keyNames: ['CONTROL', 'CLICK']
}
};
let allEvents = {
// global -------------------------------------------------------------------------------------------
tabReload: {
group: 'global',
label: 'Reload tab',
keyNames: ['CONTROL', 'R']
},
clipboardPaste: {
group: 'global',
label: 'Update signatures/D-Scan from clipboard',
keyNames: ['CONTROL', 'V'],
alias: 'paste'
},
// map ----------------------------------------------------------------------------------------------
mapSystemAdd: {
group: 'map',
label: 'Add new system',
keyNames: ['CONTROL', 'S']
},
mapSystemsSelect: {
group: 'map',
label: 'Select all systems',
keyNames: ['CONTROL', 'A']
},
mapSystemsDelete: {
group: 'map',
label: 'Delete selected systems',
keyNames: ['CONTROL', 'D']
}
};
let groups = {
global: {
label: 'Global'
},
map: {
label: 'Map'
},
signatures: {
label: 'Signature'
}
};
/**
* enables some debug output in console
* @type {boolean}
*/
let debug = false;
/**
* check interval for "new" active keys
* @type {number}
*/
let keyWatchPeriod = 100;
/**
* DOM data key for an element that lists all active events (comma separated)
* @type {string}
*/
let dataKeyEvents = 'key-events';
/**
* DOM data key prefix whether domElement that holds the trigger needs to be "focused"
* @type {string}
*/
let dataKeyFocusPrefix = 'key-focus-';
/**
* DOM data key that holds the callback function for that element
* @type {string}
*/
let dataKeyCallbackPrefix = 'key-callback-';
/**
* check if module is initiated
*/
let isInit = false;
/**
* global key map holds all active (hold down) keys
* @type {{}}
*/
let map = {};
/**
* show debug information in console
* @param msg
* @param element
*/
let debugWatchKey = (msg, element) => {
if(debug){
console.info(msg, element);
}
};
/**
* get all active (hold down) keys at this moment
* @returns {Array}
*/
let getActiveKeys = () => {
return Object.keys(map);
};
/**
* callback function that compares two arrays
* @param element
* @param index
* @param array
*/
let compareKeyLists = function(element, index, array) {
return this.find(x => x === element);
};
/**
* get event names that COULD lead to a "full" event (not all keys pressed yet)
* @param keyList
* @returns {Array}
*/
let checkEventNames = (keyList) => {
let incompleteEvents = [];
for(let event in allEvents){
// check if "some" or "all" keys are pressed for en event
if( keyList.every(compareKeyLists, allEvents[event].keyNames) ){
incompleteEvents.push(event);
}
}
return incompleteEvents;
};
/**
* get all event names
* @returns {Array}
*/
let getAllEventNames = () => {
let eventNames = [];
for(let event in allEvents){
eventNames.push(event);
}
return eventNames;
};
/**
* get all event names that matches a given keyList
* @param keyList
* @param checkEvents
* @returns {Array}
*/
let getMatchingEventNames = (keyList, checkEvents) => {
checkEvents = checkEvents || getAllEventNames();
let events = [];
for(let event of checkEvents){
// check if both key arrays are equal
if(
allEvents[event].keyNames.every(compareKeyLists, keyList) &&
keyList.every(compareKeyLists, allEvents[event].keyNames)
){
events.push(event);
}
}
return events;
};
/**
* init global keyWatch interval and check for event trigger (hotKey combinations)
*/
let init = () => {
if( !isInit ){
// key watch loop -------------------------------------------------------------------------------
let prevActiveKeys = [];
/**
*
* @param e
* @returns {number} 0: no keys hold, 1: invalid match, 2: partial match, 3: match, 4: alias match, 5: event(s) fired
*/
let checkForEvents = (e) => {
let status = 0;
// get all pressed keys
let activeKeys = getActiveKeys();
debugWatchKey('activeKeys', activeKeys);
// check if "active" keys has changes since last loop
if(activeKeys.length){
// check for "incomplete" events (not all keys pressed yet)
let incompleteEvents = checkEventNames(activeKeys);
if(incompleteEvents.length){
// "some" event keys pressed OR "all" keys pressed
status = 2;
// check if key combo matches a registered (valid) event
let events = getMatchingEventNames(activeKeys, incompleteEvents);
if(events.length){
status = 3;
// check events if there are attached elements to it
events.forEach((event) => {
// skip events that has an alias and should not be triggered by key combo
if( !allEvents[event].alias ){
if(allEvents[event].elements){
// search for callback functions attached to each element
allEvents[event].elements.forEach((domElement) => {
let domElementObj = $(domElement);
// check if event on this element requires active "focus"
let optFocus = domElementObj.data(dataKeyFocusPrefix + event);
if( !(
optFocus &&
document.activeElement !== domElement
)
){
// execute callback if valid
let callback = domElementObj.data(dataKeyCallbackPrefix + event);
if(typeof callback === 'function'){
status = 5;
callback.call(domElement, domElement, e);
}
}
});
}
}else{
status = 4;
}
});
}
}else{
// invalid combo
status = 1;
}
}
// store current keys for next loop check
prevActiveKeys = activeKeys;
return status;
};
// set key-events -------------------------------------------------------------------------------
let evKeyDown = (e) => {
// exclude some HTML Tags from watcher
if(
e.target.tagName !== 'INPUT' &&
e.target.tagName !== 'TEXTAREA'
){
let key = e.key.toUpperCase();
map[key] = true;
// check for any shortcut combo that triggers an event
let status = checkForEvents(e);
if(
status === 2 ||
status === 3 ||
status === 5
){
// prevent SOME browser default actions -> we want 'Pathfinder' shortcuts :)
e.preventDefault();
}
}
};
let evKeyUp = (e) => {
if(e.key){
let key = e.key.toUpperCase();
if(map.hasOwnProperty(key)){
delete map[key];
}
}
};
let container = $('body');
container.on('keydown', evKeyDown);
container.on('keyup', evKeyUp);
// global dom remove listener -------------------------------------------------------------------
// -> check whether the removed element had an event listener active and removes them.
new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if(mutation.type === 'childList'){
for (let i = 0; i < mutation.removedNodes.length; i++){
let removedNode = mutation.removedNodes[i];
if(typeof removedNode.getAttribute === 'function'){
let eventNames = removedNode.getAttribute(dataKeyEvents);
if(eventNames){
let events = eventNames.split(',');
for(let j = 0; i < events.length; j++){
let event = events[j];
let index = allEvents[event].elements.indexOf(removedNode);
if(index > -1){
// remove element from event list
allEvents[event].elements.splice(index, 1);
}
}
}
}
}
}
});
}).observe(document.body, { childList: true, subtree: true });
isInit = true;
}
};
/**
* add a new "shortCut" combination (event) to a DOM element
* @param event
* @param callback
* @param options
*/
$.fn.watchKey = function(event, callback, options){
// default options for keyWatcher on elements
let defaultOptions = {
focus: false, // element must be focused (active)
bubbling: true // elements deeper (children) in the DOM can bubble the event up
};
let customOptions = $.extend(true, {}, defaultOptions, options );
return this.each((i, domElement) => {
let element = $(domElement);
// init global key events
init();
// check if event is "valid" (exists) and is not already set for this element
let validEvent = false;
if(allEvents[event].elements){
if(allEvents[event].elements.indexOf(domElement) === -1){
validEvent = true;
}else{
console.warn('Event "' + event + '" already set');
}
}else{
validEvent = true;
allEvents[event].elements = [];
}
if(validEvent){
// store callback options to dom element
if(customOptions.focus){
let dataAttr = dataKeyFocusPrefix + event;
element.data(dataAttr, true);
// check if DOM element has "tabindex" attr -> required to manually set focus() to it
if(!domElement.hasAttribute('tabindex')){
domElement.setAttribute('tabindex', 0);
}
// element requires a "focus" listener
element.off('click.focusKeyWatcher').on('click.focusKeyWatcher', function(e){
if(
e.target === this ||
customOptions.bubbling
){
this.focus();
debugWatchKey('focus set:', this);
}
});
}
// check if is key combo has a native JS event that should be used instead
if(allEvents[event].alias){
element.on(allEvents[event].alias, callback);
}else{
// store callback function to dom element
let dataAttr = dataKeyCallbackPrefix + event;
element.data(dataAttr, callback);
}
// add eventName to dom element as attribute ----------------------------------------------------
let currentEventNames = element.attr(dataKeyEvents) ? element.attr(dataKeyEvents).split(',') : [];
currentEventNames.push(event);
element.attr(dataKeyEvents, currentEventNames.join(','));
// store domElement to event (global)
allEvents[event].elements.push(domElement);
debugWatchKey('new event "' + event + '" registered', domElement);
}
});
};
/**
* get a array with all available shortcut groups and their events
* @returns {Array}
*/
let getGroupedShortcuts = () => {
let result = $.extend(true, {}, groups);
// add combos and events to groups
let allEntries = [allCombo, allEvents];
for(let i = 0; i < allEntries.length; i++){
for(let event in allEntries[i]){
let data = allEntries[i][event];
//format keyNames for UI
let keyNames = data.keyNames.map( (key) => {
if(key === 'CONTROL'){
key = 'ctrl';
}
return key;
});
let newEventData = {
label: data.label,
keyNames: keyNames
};
if( result[data.group].events ){
result[data.group].events.push(newEventData);
}else{
result[data.group].events = [newEventData];
}
}
}
// convert obj into array
result = Object.values(result);
return result;
};
return {
getGroupedShortcuts: getGroupedShortcuts
};
});

View File

@@ -1,530 +0,0 @@
/**
* logging
*/
define([
'jquery',
'app/init',
'app/util',
'bootbox'
], function($, Init, Util, bootbox) {
'use strict';
let logData = []; // cache object for all log entries
let logDataTable = null; // "Datatables" Object
// Morris charts data
let maxGraphDataCount = 30; // max date entries for a graph
let chartData = {}; // chart Data object for all Morris Log graphs
let config = {
taskDialogId: 'pf-task-dialog', // id for map "task manager" dialog
dialogDynamicAreaClass: 'pf-dynamic-area', // class for dynamic areas
timestampCounterClass: 'pf-timestamp-counter', // class for "timestamp" counter
taskDialogStatusAreaClass: 'pf-task-dialog-status', // class for "status" dynamic area
taskDialogLogTableAreaClass: 'pf-task-dialog-table', // class for "log table" dynamic area
logGraphClass: 'pf-log-graph', // class for all log Morris graphs
tableToolsClass: 'pf-table-tools' // class for table tools
};
/**
* get log time string
* @returns {string}
*/
let getLogTime = function(){
let serverTime = Util.getServerTime();
let logTime = serverTime.toLocaleTimeString('en-US', { hour12: false });
return logTime;
};
/**
* updated "sync status" dynamic dialog area
*/
let updateSyncStatus = function(){
// check if task manager dialog is open
let logDialog = $('#' + config.taskDialogId);
if(logDialog.length){
// dialog is open
requirejs(['text!templates/modules/sync_status.html', 'mustache'], function(templateSyncStatus, Mustache) {
let data = {
timestampCounterClass: config.timestampCounterClass,
syncStatus: Init.syncStatus,
isWebSocket: () => {
return (Util.getSyncType() === 'webSocket');
},
isAjax: () => {
return (Util.getSyncType() === 'ajax');
}
};
let syncStatusElement = $( Mustache.render(templateSyncStatus, data ) );
logDialog.find('.' + config.taskDialogStatusAreaClass).html( syncStatusElement );
logDialog.find('.' + config.timestampCounterClass).initTimestampCounter();
syncStatusElement.initTooltips({
placement: 'right'
});
});
}
};
/**
* shows the logging dialog
*/
let showDialog = function(){
// dialog content
requirejs(['text!templates/dialog/task_manager.html', 'mustache', 'datatables.loader'], function(templateTaskManagerDialog, Mustache) {
let data = {
id: config.taskDialogId,
dialogDynamicAreaClass: config.dialogDynamicAreaClass,
taskDialogStatusAreaClass: config.taskDialogStatusAreaClass,
taskDialogLogTableAreaClass: config.taskDialogLogTableAreaClass,
tableActionBarClass: config.tableToolsClass
};
let contentTaskManager = $( Mustache.render(templateTaskManagerDialog, data) );
let rowElementGraphs = contentTaskManager.find('.row');
let taskDialogLogTableAreaElement = contentTaskManager.find('.' + config.taskDialogLogTableAreaClass);
let logTable = $('<table>', {
class: ['compact', 'stripe', 'order-column', 'row-border'].join(' ')
});
taskDialogLogTableAreaElement.append(logTable);
// init log table
logDataTable = logTable.DataTable({
paging: true,
ordering: true,
order: [ 1, 'desc' ],
autoWidth: false,
hover: false,
pageLength: 10,
lengthMenu: [[5, 10, 25, 50, 100, -1], [5, 10, 25, 50, 100, 'All']],
data: logData, // load cached logs (if available)
language: {
emptyTable: 'No entries',
zeroRecords: 'No entries found',
lengthMenu: 'Show _MENU_ entries',
info: 'Showing _START_ to _END_ of _TOTAL_ entries'
},
columnDefs: [
{
targets: 0,
title: '<i class="fas fa-tag"></i>',
width: '18px',
searchable: false,
class: ['text-center'].join(' '),
data: 'status'
},{
targets: 1,
title: '<i class="far fa-fw fa-clock"></i>&nbsp;&nbsp;',
width: '50px',
searchable: true,
class: 'text-right',
data: 'time'
},{
targets: 2,
title: '<i class="fas fa-fw fa-history"></i>&nbsp;&nbsp;',
width: '35px',
searchable: false,
class: 'text-right',
sType: 'html',
data: 'duration'
},{
targets: 3,
title: 'description',
searchable: true,
data: 'description'
},{
targets: 4,
title: 'type',
width: '40px',
searchable: true,
class: ['text-center'].join(' '),
data: 'type'
},{
targets: 5,
title: 'Prozess-ID&nbsp;&nbsp;&nbsp;',
width: '80px',
searchable: false,
class: 'text-right',
data: 'key'
}
]
});
// open dialog
let logDialog = bootbox.dialog({
title: 'Task-Manager',
message: contentTaskManager,
size: 'large',
buttons: {
close: {
label: 'close',
className: 'btn-default'
}
}
});
// modal dialog is shown
logDialog.on('shown.bs.modal', function(e) {
updateSyncStatus();
// show Morris graphs ----------------------------------------------------------
// function for chart label formation
let labelYFormat = function(y){
return Math.round(y) + 'ms';
};
for(let key in chartData) {
if(chartData.hasOwnProperty(key)) {
// create a chart for each key
let colElementGraph = $('<div>', {
class: ['col-md-6'].join(' ')
});
// graph element
let graphElement = $('<div>', {
class: config.logGraphClass
});
let graphArea = $('<div>', {
class: config.dialogDynamicAreaClass
}).append( graphElement );
let headline = $('<h4>', {
text: key
}).prepend(
$('<span>', {
class: ['txt-color', 'txt-color-grayLight'].join(' '),
text: 'Prozess-ID: '
})
);
// show update ping between function calls
let updateElement = $('<small>', {
class: ['txt-color', 'txt-color-blue', 'pull-right'].join(' ')
});
headline.append(updateElement).append('<br>');
// show average execution time
let averageElement = $('<small>', {
class: 'pull-right'
});
headline.append(averageElement);
colElementGraph.append( headline );
colElementGraph.append( graphArea );
graphArea.showLoadingAnimation();
rowElementGraphs.append( colElementGraph );
// cache DOM Elements that will be updated frequently
chartData[key].averageElement = averageElement;
chartData[key].updateElement = updateElement;
chartData[key].graph = Morris.Area({
element: graphElement,
data: [],
xkey: 'x',
ykeys: ['y'],
labels: [key],
units: 'ms',
parseTime: false,
ymin: 0,
yLabelFormat: labelYFormat,
padding: 10,
hideHover: true,
pointSize: 3,
lineColors: ['#375959'],
pointFillColors: ['#477372'],
pointStrokeColors: ['#313335'],
lineWidth: 2,
grid: false,
gridStrokeWidth: 0.3,
gridTextSize: 9,
gridTextFamily: 'Oxygen Bold',
gridTextColor: '#63676a',
behaveLikeLine: true,
goals: [],
goalLineColors: ['#66c84f'],
smooth: false,
fillOpacity: 0.3,
resize: true
});
updateLogGraph(key);
graphArea.hideLoadingAnimation();
}
}
// ------------------------------------------------------------------------------
// add dataTable buttons (extension)
let buttons = new $.fn.dataTable.Buttons( logDataTable, {
buttons: [
{
extend: 'copy',
className: 'btn btn-sm btn-default',
text: '<i class="fas fa-fw fa-copy"></i> copy'
},{
extend: 'csv',
className: 'btn btn-sm btn-default',
text: '<i class="fas fa-fw fa-download"></i> csv'
}
]
} );
logDataTable.buttons().container().appendTo( $(this).find('.' + config.tableToolsClass));
});
// modal dialog is closed
logDialog.on('hidden.bs.modal', function(e) {
// clear memory -> destroy all charts
for (let key in chartData) {
if (chartData.hasOwnProperty(key)) {
chartData[key].graph = null;
}
}
});
// modal dialog before hide
logDialog.on('hide.bs.modal', function(e) {
// destroy logTable
logDataTable.destroy(true);
logDataTable= null;
// remove event -> prevent calling this multiple times
$(this).off('hide.bs.modal');
});
});
};
/**
* updates the log graph for a log key
* @param key
* @param duration (if undefined -> just update graph with current data)
*/
let updateLogGraph = function(key, duration){
// check if graph data already exist
if( !(chartData.hasOwnProperty(key))){
chartData[key] = {};
chartData[key].data = [];
chartData[key].graph = null;
chartData[key].averageElement = null;
chartData[key].updateElement = null;
}
// add new value
if(duration !== undefined){
chartData[key].data.unshift(duration);
}
if(chartData[key].data.length > maxGraphDataCount){
chartData[key].data = chartData[key].data.slice(0, maxGraphDataCount);
}
function getGraphData(data) {
let tempChartData = {
data: [],
dataSum: 0,
average: 0
};
for(let x = 0; x < maxGraphDataCount; x++){
let value = 0;
if(data[x]){
value = data[x];
tempChartData.dataSum = Number( (tempChartData.dataSum + value).toFixed(2) );
}
tempChartData.data.push({
x: x,
y: value
});
}
// calculate average
tempChartData.average = Number( ( tempChartData.dataSum / data.length ).toFixed(2) );
return tempChartData;
}
let tempChartData = getGraphData(chartData[key].data);
// add new data to graph (Morris chart) - if is already initialized
if(chartData[key].graph !== null){
let avgElement = chartData[key].averageElement;
let updateElement = chartData[key].updateElement;
let delay = Util.getCurrentTriggerDelay( key, 0 );
if(delay){
updateElement[0].textContent = ' delay: ' + delay + 'ms ';
}
// set/change average line
chartData[key].graph.options.goals = [tempChartData.average];
// change avg. display
avgElement[0].textContent = 'Avg. ' + tempChartData.average + 'ms';
let avgStatus = getLogStatusByDuration(key, tempChartData.average);
let avgStatusClass = Util.getLogInfo( avgStatus, 'class' );
//change avg. display class
if( !avgElement.hasClass(avgStatusClass) ){
// avg status changed!
avgElement.removeClass().addClass('pull-right txt-color ' + avgStatusClass);
// change goals line color
if(avgStatus === 'warning'){
chartData[key].graph.options.goalLineColors = ['#e28a0d'];
$(document).setProgramStatus('slow connection');
}else{
chartData[key].graph.options.goalLineColors = ['#5cb85c'];
}
}
// set new data and redraw
chartData[key].graph.setData( tempChartData.data );
}
return tempChartData.data;
};
/**
* get the log "status" by log duration (ms).
* If duration > warning limit -> show as warning
* @param logKey
* @param logDuration
* @returns {string}
*/
let getLogStatusByDuration = function(logKey, logDuration){
let logStatus = 'info';
if( logDuration > Init.timer[logKey].EXECUTION_LIMIT ){
logStatus = 'warning';
}
return logStatus;
};
/**
* get the css class for a specific log type
* @param logType
* @returns {string}
*/
let getLogTypeIconClass = function(logType){
let logIconClass = '';
switch(logType){
case 'client':
logIconClass = 'fa-user';
break;
case 'server':
logIconClass = 'fa-download';
break;
}
return logIconClass;
};
/**
* init logging -> set global log events
*/
let init = function(){
let maxEntries = 150;
$(window).on('pf:syncStatus', function(){
updateSyncStatus();
});
// set global logging listener
$(window).on('pf:log', function(e, logKey, options){
// check required logging information
if(
options &&
options.duration &&
options.description
){
let logDescription = options.description;
let logDuration = options.duration;
let logType = options.type;
// check log status by duration
let logStatus = getLogStatusByDuration(logKey, logDuration);
let statusClass = Util.getLogInfo( logStatus, 'class' );
let typeIconClass = getLogTypeIconClass(logType);
// update graph data
updateLogGraph(logKey, logDuration);
let logRowData = {
status: '<i class="fas fa-fw fa-circle txt-color ' + statusClass + '"></i>',
time: getLogTime(),
duration: '<span class="txt-color ' + statusClass + '">' + logDuration + '<small>ms</small></span>',
description: logDescription,
type: '<i class="fas ' + typeIconClass + '"></i>',
key: logKey
};
if(logDataTable){
// add row if dataTable is initialized before new log
logDataTable.row.add( logRowData ).draw(false);
}else{
// add row data to cache
logData.push(logRowData);
}
}
// delete old log entries from table ---------------------------------
let rowCount = logData.length;
if( rowCount >= maxEntries ){
if(logDataTable){
logDataTable.rows(0, {order:'index'}).remove().draw(false);
}else{
logData.shift();
}
}
// cache logs in order to keep previous logs in table after reopening the dialog
if(logDataTable){
logData = logDataTable.rows({order:'index'}).data();
}
});
};
return {
init: init,
getLogTime: getLogTime,
showDialog: showDialog
};
});

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1,132 +0,0 @@
/**
* context menu
*/
define([
'jquery'
], function($) {
'use strict';
$.fn.contextMenu = function (settings) {
// animation
let animationInType = 'transition.flipXIn';
let animationInDuration = 150;
let animationOutType = 'transition.flipXOut';
let animationOutDuration = 150;
return this.each(function () {
// Open context menu
$(this).off('pf:openContextMenu').on('pf:openContextMenu', function (e, originalEvent, component, hiddenOptions, activeOptions) {
// hide all other open context menus
$('#pf-dialog-wrapper > .dropdown-menu').hide();
let contextMenu = $(settings.menuSelector);
let menuLiElements = contextMenu.find('li');
// show all menu entries
menuLiElements.show();
// disable specific menu entries
for(let i = 0; i < hiddenOptions.length; i++){
contextMenu.find('li[data-action="' + hiddenOptions[i] + '"]').hide();
}
// deactivate all menu entries
menuLiElements.removeClass('active');
//set active specific menu entries
for(let j = 0; j < activeOptions.length; j++){
contextMenu.find('li[data-action="' + activeOptions[j] + '"]').addClass('active');
}
//open menu
contextMenu.css({
position: 'absolute',
left: getLeftLocation(originalEvent),
top: getTopLocation(originalEvent)
}).velocity(animationInType, {
duration: animationInDuration,
complete: function(){
let posX = 0;
let posY = 0;
if(
originalEvent.offsetX &&
originalEvent.offsetY
){
// Chrome
posX = originalEvent.offsetX;
posY = originalEvent.offsetY ;
}else if(originalEvent.originalEvent){
// Firefox -> #415
posX = originalEvent.originalEvent.layerX;
posY = originalEvent.originalEvent.layerY ;
}
let position = {
x: posX,
y: posY
};
$(this).off('click').one('click', {component: component, position: position}, function (e) {
// hide contextmenu
$(this).hide();
let params = {
selectedMenu: $(e.target),
component: e.data.component,
position: e.data.position
};
settings.menuSelected.call(this, params);
return false;
});
}
});
//make sure menu closes on any click
$(document).one('click.closeContextmenu', function () {
$('.dropdown-menu[role="menu"]').velocity(animationOutType, {
duration: animationOutDuration
});
});
return false;
});
});
function getLeftLocation(e) {
let mouseWidth = e.pageX;
let pageWidth = $(window).width();
let menuWidth = $(settings.menuSelector).width();
// opening menu would pass the side of the page
if (mouseWidth + menuWidth > pageWidth &&
menuWidth < mouseWidth) {
return mouseWidth - menuWidth;
}
return mouseWidth;
}
function getTopLocation(e) {
let mouseHeight = e.pageY;
let pageHeight = $(window).height();
let menuHeight = $(settings.menuSelector).height();
// opening menu would pass the bottom of the page
if (mouseHeight + menuHeight > pageHeight &&
menuHeight < mouseHeight) {
return mouseHeight - menuHeight;
}
return mouseHeight;
}
};
});

View File

@@ -1,400 +0,0 @@
define(() => {
'use strict';
class Position {
constructor(config) {
this._defaultConfig = {
container: null, // parent DOM container element
center: null, // DOM elements that works as center
elementClass: 'pf-system', // class for all elements
defaultGapX: 50,
defaultGapY: 50,
gapX: 50, // leave gap between elements (x-axis)
gapY: 50, // leave gap between elements (y-axis)
loops: 2, // max loops around "center" for search
grid: false, // set to [20, 20] to force grid snapping
newElementWidth: 100, // width for new element
newElementHeight: 22, // height for new element
debug: false, // render debug elements
debugElementClass: 'pf-system-debug' // class for debug elements
};
this._config = Object.assign({}, this._defaultConfig, config);
/**
* convert degree into radial unit
* @param deg
* @returns {number}
* @private
*/
this._degToRad = (deg) => {
return deg * Math.PI / 180;
};
/**
* get element dimension/position of a DOM element
* @param element
* @returns {*}
* @private
*/
this._getElementDimension = (element) => {
let dim = null;
let left = 0;
let top = 0;
let a = 0;
let b = 0;
let width = this._config.newElementWidth;
let height = this._config.newElementHeight;
if(Array.isArray(element)){
// xy coordinates
let point = [
element[0] ? parseInt(element[0], 10) : 0,
element[1] ? parseInt(element[1], 10) : 0
];
if(this._config.grid){
point = this._transformPointToGrid(point);
}
left = point[0];
top = point[1];
a = this._config.gapX ;
b = this._config.gapY ;
}else if(element){
// DOM element
left = element.style.left ? parseInt(element.style.left, 10) : 0;
top = element.style.top ? parseInt(element.style.top, 10) : 0;
a = parseInt((element.offsetWidth / 2).toString(), 10) + this._config.gapX;
b = parseInt((element.offsetHeight / 2).toString(), 10) + this._config.gapY;
width = element.offsetWidth;
height = element.offsetHeight;
}
// add "gap" to a and b in order to have some space around elements
return {
left: left,
top: top,
a: a,
b: b,
width: width,
height: height
};
};
/**
* get x/y coordinate on an eclipse around a 2D area by a given radial angle
* @param dim
* @param angle
* @returns {*}
* @private
*/
this._getEllipseCoordinates = (dim, angle) => {
let coordinates = null;
if(dim){
angle = this._degToRad(angle);
coordinates = {
x: Math.round((dim.a * dim.b) / Math.sqrt(Math.pow(dim.b, 2) + Math.pow(dim.a, 2) * Math.pow(Math.tan(angle), 2) )),
y: Math.round((dim.a * dim.b) / Math.sqrt(Math.pow(dim.a, 2) + Math.pow(dim.b, 2) / Math.pow(Math.tan(angle), 2) ))
};
// invert coordinate based on quadrant ------------------------------------------------------------
if( angle > (Math.PI / 2) && angle < (3 * Math.PI / 2) ){
coordinates.x = coordinates.x * -1;
}
if( angle > Math.PI && angle < (2 * Math.PI) ){
coordinates.y = coordinates.y * -1;
}
}
return coordinates;
};
/**
* get dimensions of all surrounding elements
* @returns {Array}
* @private
*/
this._getAllElementDimensions = () => {
let dimensions = [];
let surroundingElements = this._getContainer().getElementsByClassName(this._config.elementClass);
for(let element of surroundingElements){
dimensions.push(this._getElementDimension(element));
}
return dimensions;
};
/**
* transform a x/y point into a x/y point that snaps to grid
* @param point
* @returns {*}
* @private
*/
this._transformPointToGrid = (point) => {
point[0] = Math.floor(point[0] / this._config.grid[0]) * this._config.grid[0];
point[1] = Math.floor(point[1] / this._config.grid[1]) * this._config.grid[1];
return point;
};
/**
* Transform a x/y coordinate into a 2D element with width/height
* @param centerDimension
* @param coordinate
* @returns {*}
* @private
*/
this._transformCoordinate = (centerDimension, coordinate) => {
let dim = null;
if(centerDimension && coordinate){
let left = 0;
let top = 0;
// calculate left/top based on coordinate system quadrant -----------------------------------------
// -> flip horizontal in Q2 and Q3
if(coordinate.x >= 0 && coordinate.y > 0){
// 1. quadrant
left = centerDimension.left + centerDimension.a - this._config.gapX + coordinate.x;
top = centerDimension.top + 2 * (centerDimension.b - this._config.gapY) - Math.abs(coordinate.y) - this._config.newElementHeight;
}else if(coordinate.x < 0 && coordinate.y > 0){
// 2. quadrant
left = centerDimension.left + centerDimension.a - this._config.gapX + coordinate.x - this._config.newElementWidth;
top = centerDimension.top + 2 * (centerDimension.b - this._config.gapY) - Math.abs(coordinate.y) - this._config.newElementHeight;
}else if(coordinate.x < 0 && coordinate.y <= 0){
// 3. quadrant
left = centerDimension.left + centerDimension.a - this._config.gapX + coordinate.x - this._config.newElementWidth;
top = centerDimension.top + Math.abs(coordinate.y);
}else{
// 4. quadrant
left = centerDimension.left + centerDimension.a - this._config.gapX + coordinate.x;
top = centerDimension.top + Math.abs(coordinate.y);
}
// center horizontal for x = 0 coordinate (top and bottom element) --------------------------------
if(coordinate.x === 0){
left -= Math.round(this._config.newElementWidth / 2);
}
// transform to grid coordinates (if grid snapping is enabled) ------------------------------------
if(this._config.grid){
let point = this._transformPointToGrid([left, top]);
left = point[0];
top = point[1];
}
dim = {
left: left,
top: top,
width: this._config.newElementWidth,
height: this._config.newElementHeight
};
}
return dim;
};
/**
* calc overlapping percent of two given dimensions
* @param dim1
* @param dim2
* @returns {number}
* @private
*/
this._percentCovered = (dim1, dim2) => {
let percent = 0;
if (
(dim1.left <= dim2.left) &&
(dim1.top <= dim2.top) &&
((dim1.left + dim1.width) >= (dim2.left + dim2.width)) &&
((dim1.top + dim1.height) > (dim2.top + dim2.height))
) {
// The whole thing is covering the whole other thing
percent = 100;
}else{
// Only parts may be covered, calculate percentage
dim1.right = dim1.left + dim1.width;
dim1.bottom = dim1.top + dim1.height;
dim2.right = dim2.left + dim2.width;
dim2.bottom = dim2.top + dim2.height;
let l = Math.max(dim1.left, dim2.left);
let r = Math.min(dim1.right, dim2.right);
let t = Math.max(dim1.top, dim2.top);
let b = Math.min(dim1.bottom, dim2.bottom);
if (b >= t && r >= l) {
percent = (((r - l) * (b - t)) / (dim2.width * dim2.height)) * 100;
}
}
return percent;
};
/**
* checks whether dim1 is partially overlapped by any other element
* @param dim1
* @param dimensionContainer
* @param allDimensions
* @returns {boolean}
* @private
*/
this._isOverlapping = (dim1, dimensionContainer, allDimensions) => {
let isOverlapping = false;
if(dim1){
if(this._percentCovered(dimensionContainer, dim1 ) === 100){
// element is within parent container
for(let dim2 of allDimensions){
let percentCovered = this._percentCovered(dim1, dim2);
if(percentCovered){
isOverlapping = true;
// render debug element
this._showDebugElement(dim1, percentCovered);
break;
}
}
}else{
isOverlapping = true;
this._showDebugElement(dim1, 100);
}
}else{
isOverlapping = true;
}
return isOverlapping;
};
/**
* find all dimensions around a centerDimension that are not overlapped by other elements
* @param maxResults
* @param steps
* @param allDimensions
* @param loops
* @returns {Array}
* @private
*/
this._findDimensions = (maxResults, steps, allDimensions, loops) => {
let dimensions = [];
let start = 0;
let end = 360;
let angle = end / steps;
let dimensionContainer = this._getElementDimension(this._getContainer());
steps = steps || 1;
loops = loops || 1;
if(loops === 1){
// check center element
let centerDimension = this._getElementDimension(this._config.center);
if (!this._isOverlapping(centerDimension, dimensionContainer, allDimensions)) {
dimensions.push({
left: centerDimension.left,
top: centerDimension.top,
width: centerDimension.width,
height: centerDimension.height
});
// render debug element
this._showDebugElement(centerDimension, 0);
maxResults--;
}
}
// increase the "gab" between center element and potential found dimensions...
// ... for each recursive loop call, to get an elliptical cycle beyond
this._config.gapX = this._config.defaultGapX + (loops - 1) * 20;
this._config.gapY = this._config.defaultGapY + (loops - 1) * 20;
let centerDimension = this._getElementDimension(this._config.center);
while(maxResults > 0 && start < end){
// get all potential coordinates on an eclipse around a given "centerElementDimension"
let coordinate = this._getEllipseCoordinates(centerDimension, end);
// transform relative x/y coordinate into a absolute 2D area
let checkDimension = this._transformCoordinate(centerDimension, coordinate);
if (!this._isOverlapping(checkDimension, dimensionContainer, allDimensions)) {
dimensions.push({
left: checkDimension.left,
top: checkDimension.top,
width: checkDimension.width,
height: checkDimension.height
});
// render debug element
this._showDebugElement(checkDimension, 0);
maxResults--;
}
end -= angle;
}
if(maxResults > 0 && loops < this._config.loops){
loops++;
steps *= 2;
dimensions = dimensions.concat(this._findDimensions(maxResults, steps, allDimensions, loops));
}
return dimensions;
};
/**
* get container (parent) element
* @returns {*}
* @private
*/
this._getContainer = () => {
return this._config.container ? this._config.container : document.body;
};
/**
* render debug element into parent container
* -> checks overlapping dimension with other elements
* @param dimension
* @param percentCovered
* @private
*/
this._showDebugElement = (dimension, percentCovered) => {
if(this._config.debug){
let element = document.createElement('div');
element.style.left = dimension.left + 'px';
element.style.top = dimension.top + 'px';
element.style.width = dimension.width + 'px';
element.style.height = dimension.height + 'px';
element.style.backgroundColor = Boolean(percentCovered) ? 'rgba(255,0,0,0.1)' : 'rgba(0,255,0,0.1)';
element.innerHTML = Math.round(percentCovered * 100) / 100 + '%';
element.classList.add(this._config.debugElementClass);
this._getContainer().appendChild(element);
}
};
/**
* hide all debug elements
* @private
*/
this._hideDebugElements = () => {
let debugElements = this._getContainer().getElementsByClassName(this._config.debugElementClass);
while(debugElements.length > 0){
debugElements[0].parentNode.removeChild(debugElements[0]);
}
};
// public functions ---------------------------------------------------------------------------------------
/**
* search for surrounding, non overlapping dimensions
* @param maxResults
* @param steps
* @returns {Array}
*/
this.findNonOverlappingDimensions = (maxResults, steps) => {
this._hideDebugElements();
// element dimensions that exist and should be checked for overlapping
let allDimensions = this._getAllElementDimensions();
return this._findDimensions(maxResults, steps, allDimensions);
};
}
}
return {
Position: Position
};
});

View File

@@ -1,595 +0,0 @@
/**
* map overlay functions for "Nearby" table
* Created by Exodus on 13.04.2017.
*/
define([
'jquery',
'app/init',
'app/util',
'app/map/util'
], function($, Init, Util, MapUtil) {
'use strict';
let config = {
overlayClass: 'pf-map-overlay', // class for all map overlays
overlayLocalClass: 'pf-map-overlay-local', // class for "local" overlay
// left section
overlayLocalContentClass: 'pf-map-overlay-local-content', // class for left area - content
overlayLocalHeadlineClass: 'pf-map-overlay-headline', // class for headline
overlayLocalTableClass: 'pf-local-table', // class for local tables
// right section
overlayLocalTriggerClass: 'pf-map-overlay-local-trigger', // class for open/close trigger icon
overlayLocalOpenClass: 'pf-map-overlay-local-open', // class for open status
overlayLocalMainClass: 'pf-map-overlay-local-main', // class for right area (always visible)
overlayLocalUsersClass: 'pf-map-overlay-local-users', // class for active user count
overlayLocalJumpsClass: 'pf-map-overlay-local-jumps', // class for jump distance for table results
// dataTable
tableCellImageClass: 'pf-table-image-cell', // class for table "image" cells
tableCellActionClass: 'pf-table-action-cell', // class for table "action" cells
tableCellActionIconClass: 'pf-table-action-icon-cell', // class for table "action" icon (icon is part of cell content)
// toolbar
toolbarClass: 'pf-map-overlay-toolbar', // class for toolbar - content
toolbarIconClass: 'pf-map-overlay-toolbar-icon', // class for toolbar icon
toolbarCheckboxClass: 'pf-map-overlay-toolbar-checkbox' // class for toolbar checkbox
};
/**
* checks whether overlay is currently open or not
* @param overlay
* @returns {*}
*/
let isOpen = (overlay) => {
return overlay.hasClass(config.overlayLocalOpenClass);
};
/**
* open overlay -> animation
* @param overlay
*/
let openOverlay = (overlay) => {
if( !isOpen(overlay) ){
let overlayMain = overlay.find('.' + config.overlayLocalMainClass);
overlayMain.find('.' + config.overlayLocalTriggerClass).addClass('right');
overlay.addClass(config.overlayLocalOpenClass);
overlay.velocity({
width: '350px'
},{
duration: Init.animationSpeed.mapOverlayLocal,
easing: 'easeOut'
});
}
};
/**
* close overlay -> animation
* @param overlay
*/
let closeOverlay = (overlay) => {
if( isOpen(overlay) ){
let overlayMain = overlay.find('.' + config.overlayLocalMainClass);
overlayMain.find('.' + config.overlayLocalTriggerClass).removeClass('right');
overlay.removeClass(config.overlayLocalOpenClass);
overlay.velocity({
width: '32px'
},{
duration: Init.animationSpeed.mapOverlayLocal,
easing: 'easeOut'
});
}
};
/**
* sets overlay observer
* @param overlay
* @param mapId
*/
let setOverlayObserver = (overlay, mapId) => {
let overlayMain = overlay.find('.' + config.overlayLocalMainClass);
overlayMain.on('click', function(){
let overlayMain = $(this).parent('.' + config.overlayLocalClass);
let isOpenStatus = isOpen(overlayMain);
// store current state in indexDB (client)
MapUtil.storeLocalData('map', mapId, 'showLocal', !isOpenStatus );
// trigger open/close
if( isOpenStatus ){
closeOverlay(overlay);
}else{
openOverlay(overlay);
}
});
overlayMain.initTooltips({
container: 'body',
placement: 'bottom'
});
};
/**
* filter DataTable rows by column data and return rowIds
* @param table
* @param data
* @param values
* @param checkExistence
*/
let filterRows = (table, data = 'id', values = [], checkExistence = true) => {
return table.rows().eq(0).filter( function (rowIdx) {
let rowExists = values.indexOf( table.row(rowIdx ).data()[data] ) !== -1;
if( !checkExistence ){
rowExists = !rowExists;
}
return rowExists;
});
};
/**
* Update the "headline" within the Overlay
* @param overlay
* @param systemData
* @param characterAll
* @param characterLocal
*/
let updateLocaleHeadline = (overlay, systemData, characterAll = 0, characterLocal = 0) => {
let headlineElement = overlay.find('.' + config.overlayLocalHeadlineClass);
let userCountElement = overlay.find('.' + config.overlayLocalUsersClass);
let secClassBase = Util.getSecurityClassForSystem('security');
let secClass = Util.getSecurityClassForSystem(systemData.security);
let childElements = headlineElement.children('span');
childElements.eq(1).removeClass().addClass(
[secClassBase, secClass].join(' ')
).text(systemData.security);
childElements.eq(2).text(systemData.alias ? systemData.alias : systemData.name);
// update userCount for "near by" count -------------------------------------------------------------------
if( characterAll > 0){
userCountElement.toggleClass( 'txt-color-green', true).toggleClass( 'txt-color-red', false);
}else{
userCountElement.toggleClass( 'txt-color-green', false).toggleClass( 'txt-color-red', true);
}
userCountElement.text(characterAll);
// update userCount in current system ---------------------------------------------------------------------
if( characterLocal > 0){
childElements.eq(3).toggleClass( 'txt-color-green', true).toggleClass( 'txt-color-red', false);
}else{
childElements.eq(3).toggleClass( 'txt-color-green', false).toggleClass( 'txt-color-red', true);
}
childElements.eq(3).text(characterLocal);
};
/**
* updates all changed table rows
* @param systemData
* @param userData
*/
$.fn.updateLocalTable = function(systemData, userData){
return this.each(function(){
let overlay = $(this);
let tableElement = overlay.find('.' + config.overlayLocalTableClass);
let localTable = tableElement.DataTable();
let mapId = systemData.mapId;
let characterAllIds = [];
let characterLocalIds = [];
// system is on map (just for security check)
for(let jumps in userData) {
if( userData.hasOwnProperty(jumps) ){
jumps = parseInt(jumps);
for(let j = 0; j < userData[jumps].length; j++){
// add jump distance
userData[jumps][j].jumps = jumps;
let rowData = userData[jumps][j];
// check for existing rows
let indexes = filterRows(localTable, 'id', [rowData.id]);
if(indexes.length > 0){
// row exists -> update
let changedRow = localTable.row( parseInt(indexes[0]) );
let changedRowElement = changedRow.nodes().to$();
// remove tooltips
changedRowElement.find('[title]').tooltip('hide').tooltip('destroy');
// update data
changedRow.data(rowData);
}else{
// new row
localTable.row.add(rowData);
}
if(jumps === 0){
characterLocalIds.push(rowData.id);
}
characterAllIds.push(rowData.id);
}
}
}
// remove rows that no longer exists ----------------------------------------------------------------------
let indexesRemove = filterRows(localTable, 'id', characterAllIds, false);
localTable.rows(indexesRemove).remove();
localTable.draw();
// update system relevant data in overlay -----------------------------------------------------------------
updateLocaleHeadline(overlay, systemData, characterAllIds.length, characterLocalIds.length);
// open Overlay -------------------------------------------------------------------------------------------
if( !isOpen(overlay) ){
let promiseStore = MapUtil.getLocaleData('map', mapId);
promiseStore.then(function(dataStore) {
if(
dataStore &&
dataStore.showLocal
){
openOverlay(overlay);
}
});
}
});
};
/**
* Access a nested JSON object by "dot.notation" syntax
* @param obj
* @param selector
* @returns {*}
*/
let getDescendantProp = (obj, selector) => {
return selector.split('.').reduce(function(a, b) {
return a[b];
}, obj);
};
/**
* init tooltip for a "DataTables" Cell
* @param api
* @param cell
* @param titleSelector
*/
let initCellTooltip = (api, cell, titleSelector = '') => {
$(cell).hover( function(e){
let rowIdx = api.cell(cell).index().row;
let rowData = api.row(rowIdx).data();
$(this).tooltip({
container: 'body',
title: String( getDescendantProp(rowData, titleSelector) ),
placement: 'left',
delay: 100
}).tooltip('show');
}, function(e){
$(this).tooltip('hide');
});
};
/**
* init all map local overlay on a "parent" element
* @returns {*}
*/
$.fn.initLocalOverlay = function(mapId){
let parentElements = $(this);
require(['datatables.loader'], () => {
parentElements.each(function(){
let parentElement = $(this);
let overlay = $('<div>', {
class: [config.overlayClass, config.overlayLocalClass].join(' ')
});
let content = $('<div>', {
class: [ 'text-right', config.overlayLocalContentClass].join(' ')
});
// crate new route table
let table = $('<table>', {
class: ['compact', 'order-column', config.overlayLocalTableClass].join(' ')
});
let overlayMain = $('<div>', {
text: '',
class: config.overlayLocalMainClass
}).append(
$('<i>', {
class: ['fas', 'fa-chevron-down', 'fa-fw', 'pf-animate-rotate', config.overlayLocalTriggerClass].join(' ')
}),
$('<span>', {
class: ['badge', 'txt-color', 'txt-color-red', config.overlayLocalUsersClass].join(' '),
text: 0
}),
$('<div>', {
class: config.overlayLocalJumpsClass
}).append(
$('<span>', {
class: ['badge', 'txt-color', 'txt-color-grayLight'].join(' '),
text: MapUtil.config.defaultLocalJumpRadius
}).attr('title', 'jumps')
)
);
let headline = $('<div>', {
class: config.overlayLocalHeadlineClass
}).append(
$('<span>', {
html: 'Nearby&nbsp;&nbsp;&nbsp;',
class: 'pull-left'
}),
$('<span>'),
$('<span>'),
$('<span>', {
class: ['badge', ' txt-color', 'txt-color-red'].join(' '),
text: 0
})
);
content.append(headline);
content.append(table);
// toolbar not used for now
// content.append(initToolbar());
overlay.append(overlayMain);
overlay.append(content);
// set observer
setOverlayObserver(overlay, mapId);
parentElement.append(overlay);
// init local table ---------------------------------------------------------------------------------------
table.on('draw.dt', function(e, settings){
// init table tooltips
$(this).find('td').initTooltips({
container: 'body',
placement: 'left'
});
// hide pagination in case of only one page
let paginationElement = overlay.find('.dataTables_paginate');
let pageElements = paginationElement.find('span .paginate_button');
if(pageElements.length <= 1){
paginationElement.hide();
}else{
paginationElement.show();
}
});
// table init complete
table.on( 'init.dt', function (){
// init table head tooltips
$(this).initTooltips({
container: 'body',
placement: 'top'
});
});
let localTable = table.DataTable( {
pageLength: 13, // hint: if pagination visible => we need space to show it
paging: true,
lengthChange: false,
ordering: true,
order: [ 0, 'asc' ],
info: false,
searching: false,
hover: false,
autoWidth: false,
rowId: function(rowData) {
return 'pf-local-row_' + rowData.id; // characterId
},
language: {
emptyTable: '<span>You&nbsp;are&nbsp;alone</span>'
},
columnDefs: [
{
targets: 0,
orderable: true,
title: '<span title="jumps" data-toggle="tooltip">&nbsp;</span>',
width: '1px',
className: ['pf-help-default', 'text-center'].join(' '),
data: 'jumps',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
if(value === 0){
value = '<i class="fas fa-map-marker-alt"></i>';
}
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let api = this.DataTable();
initCellTooltip(api, cell, 'log.system.name');
}
},{
targets: 1,
orderable: false,
title: '',
width: '26px',
className: ['pf-help-default', 'text-center', config.tableCellImageClass].join(' '),
data: 'log.ship',
render: {
_: function(data, type, row, meta){
let value = data.typeName;
if(type === 'display'){
value = '<img src="' + Init.url.ccpImageServer + '/Render/' + data.typeId + '_32.png"/>';
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let api = this.DataTable();
initCellTooltip(api, cell, 'log.ship.typeName');
}
}, {
targets: 2,
orderable: true,
title: 'ship&nbsp;name',
width: '80px',
data: 'log.ship',
render: {
_: function(data, type, row, meta){
let value = data.name;
if(type === 'display'){
value = '<div class="' + MapUtil.config.tableCellEllipsisClass + ' ' + MapUtil.config.tableCellEllipsis80Class + '">' + data.name + '</div>';
}
return value;
},
sort: 'name'
}
},{
targets: 3,
orderable: true,
title: 'pilot',
data: 'name',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
value = '<div class="' + MapUtil.config.tableCellEllipsisClass + ' ' + MapUtil.config.tableCellEllipsis90Class + '">' + data + '</div>';
}
return value;
}
}
},{
targets: 4,
orderable: false,
title: '',
width: '10px',
className: ['pf-help-default'].join(' '),
data: 'log',
render: {
_: function(data, type, row, meta){
let value = '';
if(type === 'display'){
if(data.station && data.station.id > 0){
value = '<i class="fas fa-home"></i>';
}else if(data.structure && data.structure.id > 0){
value = '<i class="fas fa-industry"></i>';
}
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let selector = '';
if(cellData.station && cellData.station.id > 0){
selector = 'log.station.name';
}else if(cellData.structure && cellData.structure.id > 0){
selector = 'log.structure.name';
}
let api = this.DataTable();
initCellTooltip(api, cell, selector);
}
},{
targets: 5,
orderable: false,
title: '<i title="open ingame" data-toggle="tooltip" class="fas fa-id-card text-right"></i>',
width: '10px',
className: [config.tableCellActionClass].join(' '),
data: 'id',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
value = '<i class="fas fa-id-card ' + config.tableCellActionIconClass + '"></i>';
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
// open character information window (ingame)
$(cell).on('click', { tableApi: this.DataTable(), cellData: cellData }, function(e){
let cellData = e.data.tableApi.cell(this).data();
Util.openIngameWindow(e.data.cellData);
});
}
}
]
});
});
});
};
let initToolbar = () => {
let getCheckbox = (options) => {
return $('<div>', {
class: [config.toolbarCheckboxClass, 'checkbox'].join(' ')
}).append(
$('<input>', {
type: 'checkbox',
id: options.id,
name: options.name,
value: options.value,
checked: 'checked'
}),
$('<label>',{
'for': options.id,
html: options.label
})
);
};
let toolbar = $('<div>', {
class: [config.toolbarClass].join(' ')
}).append(
$('<i>', {
class: ['fas', 'fa-fw', 'fa-lg', 'fa-filter', config.toolbarIconClass, 'pull-left'].join(' ')
}),
getCheckbox({
id: 'test',
name: 'filter_character_active',
value: 1,
checked: true,
label: 'active'
})
);
return toolbar;
};
/**
* Clear Overlay and "Reset"
* @param mapId
*/
$.fn.clearLocalTable = function(mapId){
return this.each(function(){
let overlay = $(this);
// update locale overlay headline -------------------------------------------------------------------------
updateLocaleHeadline(overlay, {
name: 'unknown',
security: ''
});
// clear all table rows -----------------------------------------------------------------------------------
let tableElement = overlay.find('.' + config.overlayLocalTableClass);
let localTable = tableElement.DataTable();
localTable.rows().remove().draw();
});
};
});

View File

@@ -1,180 +0,0 @@
/**
* Map "magnetizing" feature
* jsPlumb extension used: http://morrisonpitt.com/farahey/
*/
define([
'jquery',
'app/map/util',
'farahey'
], function($, MapUtil) {
'use strict';
/**
* Cached current "Magnetizer" object
* @type {Magnetizer}
*/
let m8 = null;
/**
* init a jsPlumb (map) Element for "magnetised" function.
* this is optional and prevents systems from being overlapped
*/
$.fn.initMagnetizer = function(){
let mapContainer = this;
let systems = mapContainer.getSystems();
/**
* helper function
* get current system offset
* @param system
* @returns {{left, top}}
* @private
*/
let _offset = function(system) {
let _ = function(p) {
let v = system.style[p];
return parseInt(v.substring(0, v.length - 2));
};
return {
left:_('left'),
top:_('top')
};
};
/**
* helper function
* set new system offset
* @param system
* @param o
* @private
*/
let _setOffset = function(system, o) {
let markAsUpdated = false;
// new position must be within parent container
// no negative offset!
if(
o.left >= 0 &&
o.left <= 2300
){
markAsUpdated = true;
system.style.left = o.left + 'px';
}
if(
o.top >= 0 &&
o.top <= 498
){
markAsUpdated = true;
system.style.top = o.top + 'px';
}
if(markAsUpdated === true){
$(system).markAsChanged();
}
};
/**
* helper function
* exclude current dragged element(s) from position update
* @param id
* @returns {boolean}
* @private
*/
let _dragFilter = function(id) {
return !$('#' + id).is('.jsPlumb_dragged, .pf-system-locked');
};
let gridConstrain = function(gridX, gridY) {
return function(id, current, delta) {
if( mapContainer.hasClass(MapUtil.config.mapGridClass) ){
// active grid
return {
left:(gridX * Math.floor( (current[0] + delta.left) / gridX )) - current[0],
top:(gridY * Math.floor( (current[1] + delta.top) / gridY )) - current[1]
};
}else{
// no grid
return delta;
}
};
};
// main init for "magnetize" feature ------------------------------------------------------
m8 = new Magnetizer({
container: mapContainer,
getContainerPosition: function(c) {
return c.offset();
},
getPosition:_offset,
getSize: function(system) {
return [ $(system).outerWidth(), $(system).outerHeight() ];
},
getId : function(system) {
return $(system).attr('id');
},
setPosition:_setOffset,
elements: systems,
filter: _dragFilter,
padding: [6, 6],
constrain: gridConstrain(MapUtil.config.mapSnapToGridDimension, MapUtil.config.mapSnapToGridDimension)
});
};
$.fn.destroyMagnetizer = function(){
let mapContainer = this;
// remove cached "magnetizer" instance
m8 = null;
};
/**
* update system positions for "all" systems that are effected by drag&drop
* @param map
* @param e
*/
let executeAtEvent = function(map, e){
if(m8 !== null && e ){
m8.executeAtEvent(e);
map.repaintEverything();
}
};
/**
* rearrange all systems of a map
* needs "magnetization" to be active
* @param map
*/
let executeAtCenter = function(map){
if(m8 !== null){
m8.executeAtCenter();
map.repaintEverything();
}
};
/**
* set/update elements for "magnetization"
* -> (e.g. new systems was added)
* @param map
*/
let setElements = function(map){
if(m8 !== null){
let mapContainer = $(map.getContainer());
let systems = mapContainer.getSystems();
m8.setElements(systems);
// re-arrange systems
executeAtCenter(map);
}
};
return {
executeAtCenter: executeAtCenter,
executeAtEvent: executeAtEvent,
setElements: setElements
};
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,740 +0,0 @@
/**
* map overlay functions
*/
define([
'jquery',
'app/init',
'app/util',
'app/map/util'
], function($, Init, Util, MapUtil) {
'use strict';
let config = {
logTimerCount: 3, // map log timer in seconds
// map
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
// map overlay positions
mapOverlayClass: 'pf-map-overlay', // class for all map overlays
mapOverlayTimerClass: 'pf-map-overlay-timer', // class for map overlay timer e.g. map timer
mapOverlayInfoClass: 'pf-map-overlay-info', // class for map overlay info e.g. map info
overlayLocalClass: 'pf-map-overlay-local', // class for map overlay "local" table
// system
systemHeadClass: 'pf-system-head', // class for system head
// overlay IDs
connectionOverlayId: 'pf-map-connection-overlay', // connection "normal size" ID (jsPlumb)
connectionOverlayEolId: 'pf-map-connection-eol-overlay', // connection EOL overlay ID (jsPlumb)
connectionOverlayArrowId: 'pf-map-connection-arrow-overlay', // connection Arrows overlay ID (jsPlumb)
connectionOverlaySmallId: 'pf-map-connection-small-overlay', // connection "smaller" overlay ID (jsPlumb)
// overlay classes
connectionOverlayClass: 'pf-map-connection-overlay', // class for "normal size" overlay
connectionArrowOverlayClass: 'pf-map-connection-arrow-overlay', // class for "connection arrow" overlay
connectionDiamondOverlayClass: 'pf-map-connection-diamond-overlay', // class for "connection diamond" overlay
connectionOverlaySmallClass: 'pf-map-connection-small-overlay' // class for "smaller" overlays
};
/**
* get MapObject (jsPlumb) from mapElement
* @param mapElement
* @returns {*}
*/
let getMapObjectFromMapElement = (mapElement) => {
let Map = require('app/map/map');
return Map.getMapInstance( mapElement.data('id') );
};
/**
* get map object (jsPlumb) from iconElement
* @param overlayIcon
* @returns {*}
*/
let getMapObjectFromOverlayIcon = (overlayIcon) => {
let mapElement = Util.getMapElementFromOverlay(overlayIcon);
return getMapObjectFromMapElement( mapElement );
};
/**
* add overlays to connections (signature based data)
* @param connections
* @param connectionsData
*/
let addConnectionsOverlay = (connections, connectionsData) => {
let SystemSignatures = require('app/ui/system_signature');
/**
* add label to endpoint
* @param endpoint
* @param label
*/
let addEndpointOverlay = (endpoint, label) => {
endpoint.addOverlay([
'Label',
{
label: MapUtil.getEndpointOverlayContent(label),
id: config.connectionOverlaySmallId,
cssClass: config.connectionOverlaySmallClass,
location: [ 0.9, 0.9 ]
}
]);
};
// loop through all map connections (get from DOM)
for(let connection of connections) {
let connectionId = connection.getParameter('connectionId');
let sourceEndpoint = connection.endpoints[0];
let targetEndpoint = connection.endpoints[1];
let sourceSystem = $(sourceEndpoint.element);
let targetSystem = $(targetEndpoint.element);
let sourceId = sourceSystem.data('id');
let targetId = targetSystem.data('id');
let signatureTypeNames = {
sourceLabels: [],
targetLabels: []
};
// ... find matching connectionData (from Ajax)
for(let connectionData of connectionsData){
if(connectionData.id === connectionId){
signatureTypeNames = MapUtil.getConnectionDataFromSignatures(connection, connectionData);
// ... connection matched -> continue with next one
break;
}
}
let sourceLabel = signatureTypeNames.sourceLabels;
let targetLabel = signatureTypeNames.targetLabels;
// add endpoint overlays ------------------------------------------------------
addEndpointOverlay(sourceEndpoint, sourceLabel);
addEndpointOverlay(targetEndpoint, targetLabel);
// add arrow (connection) overlay that points from "XXX" => "K162" ------------
let overlayType = 'Diamond'; // not specified
let arrowDirection = 1;
if(
(sourceLabel.indexOf('K162') !== -1 && targetLabel.indexOf('K162') !== -1) ||
(sourceLabel.length === 0 && targetLabel.length === 0) ||
(
sourceLabel.length > 0 && targetLabel.length > 0 &&
sourceLabel.indexOf('K162') === -1 && targetLabel.indexOf('K162') === -1
)
){
// unknown direction
overlayType = 'Diamond'; // not specified
arrowDirection = 1;
}else if(
(sourceLabel.indexOf('K162') !== -1) ||
(sourceLabel.length === 0 && targetLabel.indexOf('K162') === -1)
){
// convert default arrow direction
overlayType = 'Arrow';
arrowDirection = -1;
}else{
// default arrow direction is fine
overlayType = 'Arrow';
arrowDirection = 1;
}
connection.addOverlay([
overlayType,
{
width: 12,
length: 15,
location: 0.5,
foldback: 0.85,
direction: arrowDirection,
id: config.connectionOverlayArrowId,
cssClass: (overlayType === 'Arrow') ? config.connectionArrowOverlayClass : config.connectionDiamondOverlayClass
}
]);
}
};
/**
* remove overviews from a Tooltip
* @param endpoint
* @param i
*/
let removeEndpointOverlay = (endpoint, i) => {
endpoint.removeOverlays(config.connectionOverlaySmallId);
};
/**
* format json object with "time parts" into string
* @param parts
* @returns {string}
*/
let formatTimeParts = (parts) => {
let label = '';
if(parts.days){
label += parts.days + 'd ';
}
label += ('00' + parts.hours).slice(-2);
label += ':' + ('00' + parts.min).slice(-2);
return label;
};
/**
* hide default icon and replace it with "loading" icon
* @param iconElement
*/
let showLoading = (iconElement) => {
iconElement = $(iconElement);
let dataName = 'default-icon';
let defaultIconClass = iconElement.data(dataName);
// get default icon class
if( !defaultIconClass ){
// index 0 == 'fa-fw', index 1 == IconName
defaultIconClass = $(iconElement).attr('class').match(/\bfa-\S*/g)[1];
iconElement.data(dataName, defaultIconClass);
}
iconElement.toggleClass( defaultIconClass + ' fa-sync fa-spin' );
};
/**
* hide "loading" icon and replace with default icon
* @param iconElement
*/
let hideLoading = (iconElement) => {
iconElement = $(iconElement);
let dataName = 'default-icon';
let defaultIconClass = iconElement.data(dataName);
iconElement.toggleClass( defaultIconClass + ' fa-sync fa-spin' );
};
/**
* git signature data that is linked to a connection for a mapId
* @param mapElement
* @param connections
* @param callback
*/
let getConnectionSignatureData = (mapElement, connections, callback) => {
let mapOverlay = $(mapElement).getMapOverlay('info');
let overlayConnectionIcon = mapOverlay.find('.pf-map-overlay-endpoint');
showLoading(overlayConnectionIcon);
let requestData = {
mapId: mapElement.data('id'),
addData : ['signatures'],
filterData : ['signatures']
};
$.ajax({
type: 'POST',
url: Init.path.getMapConnectionData,
data: requestData,
dataType: 'json',
context: {
mapElement: mapElement,
connections: connections,
overlayConnectionIcon: overlayConnectionIcon
}
}).done(function(connectionsData){
// hide all connection before add them (refresh)
this.mapElement.hideEndpointOverlays();
// ... add overlays
callback(this.connections, connectionsData);
}).always(function() {
hideLoading(this.overlayConnectionIcon);
});
};
/**
* showEndpointOverlays
* -> used by "refresh" overlays (hover) AND/OR initial menu trigger
*/
$.fn.showEndpointOverlays = function(){
let mapElement = $(this);
let map = getMapObjectFromMapElement(mapElement);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh', undefined, true);
// get connection signature information ---------------------------------------
getConnectionSignatureData(mapElement, connections, addConnectionsOverlay);
};
/**
* hideEndpointOverlays
* -> see showEndpointOverlays()
*/
$.fn.hideEndpointOverlays = function(){
let map = getMapObjectFromMapElement($(this));
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh');
for (let connection of connections){
connection.removeOverlays(config.connectionOverlayArrowId);
connection.endpoints.forEach(removeEndpointOverlay);
}
};
/**
* Overlay options (all available map options shown in overlay)
* "active": (active || hover) indicated whether an icon/option
* is marked as "active".
* "active": Makes icon active when visible
* "hover": Make icon active on hover
*/
let options = {
filter: {
title: 'active filter',
trigger: 'active',
class: 'pf-map-overlay-filter',
iconClass: ['fas', 'fa-fw', 'fa-filter'],
onClick: function(e){
// clear all filter
let mapElement = Util.getMapElementFromOverlay(this);
let map = getMapObjectFromOverlayIcon(this);
MapUtil.storeLocalData('map', mapElement.data('id'), 'filterScopes', []);
MapUtil.filterMapByScopes(map, []);
}
},
mapSnapToGrid: {
title: 'active grid',
trigger: 'active',
class: 'pf-map-overlay-grid',
iconClass: ['fas', 'fa-fw', 'fa-th']
},
mapMagnetizer: {
title: 'active magnetizer',
trigger: 'active',
class: 'pf-map-overlay-magnetizer',
iconClass: ['fas', 'fa-fw', 'fa-magnet']
},
systemRegion: {
title: 'show regions',
trigger: 'hover',
class: 'pf-map-overlay-region',
iconClass: ['fas', 'fa-fw', 'fa-tags'],
hoverIntent: {
over: function(e){
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.find('.' + config.systemHeadClass).each(function(){
let system = $(this);
// init tooltip if not already exists
if ( !system.data('bs.tooltip') ){
system.tooltip({
container: mapElement,
placement: 'right',
title: function(){
return $(this).parent().data('region');
},
trigger: 'manual'
});
}
system.tooltip('show');
});
},
out: function(e){
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.find('.' + config.systemHeadClass).tooltip('hide');
}
}
},
mapEndpoint: {
title: 'refresh signature overlays',
trigger: 'refresh',
class: 'pf-map-overlay-endpoint',
iconClass: ['fas', 'fa-fw', 'fa-link'],
hoverIntent: {
over: function(e){
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.showEndpointOverlays();
},
out: function(e){
// just "refresh" on hover
}
}
},
mapCompact: {
title: 'compact layout',
trigger: 'active',
class: 'pf-map-overlay-compact',
iconClass: ['fas', 'fa-fw', 'fa-compress']
},
connection: {
title: 'WH data',
trigger: 'hover',
class: 'pf-map-overlay-connection',
iconClass: ['fas', 'fa-fw', 'fa-fighter-jet'],
hoverIntent: {
over: function(e){
let map = getMapObjectFromOverlayIcon(this);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh');
let serverDate = Util.getServerTime();
// show connection overlays ---------------------------------------------------
for (let connection of connections) {
let createdTimestamp = connection.getParameter('created');
let updatedTimestamp = connection.getParameter('updated');
let createdDate = Util.convertTimestampToServerTime(createdTimestamp);
let updatedDate = Util.convertTimestampToServerTime(updatedTimestamp);
let createdDiff = Util.getTimeDiffParts(createdDate, serverDate);
let updatedDiff = Util.getTimeDiffParts(updatedDate, serverDate);
// format overlay label
let labels = [
'<i class="fas fa-fw fa-plus-square"></i>&nbsp;' + formatTimeParts(createdDiff),
'<i class="fas fa-fw fa-pen-square"></i>&nbsp;' + formatTimeParts(updatedDiff)
];
// add label overlay ------------------------------------------------------
connection.addOverlay([
'Label',
{
label: labels.join('<br>'),
id: config.connectionOverlayId,
cssClass: config.connectionOverlaySmallClass,
location: 0.35
}
]);
}
},
out: function(e){
let map = getMapObjectFromOverlayIcon(this);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh');
for (let connection of connections){
connection.removeOverlays(config.connectionOverlayId);
}
}
}
},
connectionEol: {
title: 'EOL timer',
trigger: 'hover',
class: 'pf-map-overlay-connection-eol',
iconClass: ['far', 'fa-fw', 'fa-clock'],
hoverIntent: {
over: function(e){
let map = getMapObjectFromOverlayIcon(this);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh', ['wh_eol']);
let serverDate = Util.getServerTime();
for (let connection of connections) {
let eolTimestamp = connection.getParameter('eolUpdated');
let eolDate = Util.convertTimestampToServerTime(eolTimestamp);
let diff = Util.getTimeDiffParts(eolDate, serverDate);
connection.addOverlay([
'Label',
{
label: '<i class="far fa-fw fa-clock"></i>&nbsp;' + formatTimeParts(diff),
id: config.connectionOverlayEolId,
cssClass: [config.connectionOverlayClass, 'eol'].join(' '),
location: 0.25
}
]);
}
},
out: function(e){
let map = getMapObjectFromOverlayIcon(this);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh', ['wh_eol']);
for (let connection of connections) {
connection.removeOverlay(config.connectionOverlayEolId);
}
}
}
}
};
/**
* get map overlay element by type e.g. timer/counter, info - overlay
* @param overlayType
* @returns {*}
*/
$.fn.getMapOverlay = function(overlayType){
let mapWrapperElement = $(this).parents('.' + config.mapWrapperClass);
let mapOverlay = null;
switch(overlayType){
case 'timer':
mapOverlay = mapWrapperElement.find('.' + config.mapOverlayTimerClass);
break;
case 'info':
mapOverlay = mapWrapperElement.find('.' + config.mapOverlayInfoClass);
break;
case 'local':
mapOverlay = mapWrapperElement.find('.' + config.overlayLocalClass);
break;
}
return mapOverlay;
};
/**
* draws the map update counter to the map overlay timer
* @param percent
* @param value
* @returns {*}
*/
$.fn.setMapUpdateCounter = function(percent, value){
let mapOverlayTimer = $(this);
// check if counter already exists
let counterChart = mapOverlayTimer.getMapCounter();
if(counterChart.length === 0){
// create new counter
counterChart = $('<div>', {
class: [Init.classes.pieChart.class, Init.classes.pieChart.pieChartMapCounterClass].join(' ')
}).attr('data-percent', percent).append(
$('<span>', {
text: value
})
);
mapOverlayTimer.append(counterChart);
// init counter
counterChart.initMapUpdateCounter();
// set tooltip
mapOverlayTimer.attr('data-placement', 'left');
mapOverlayTimer.attr('title', 'update counter');
mapOverlayTimer.tooltip();
}
return counterChart;
};
/**
* get the map counter chart from overlay
* @returns {JQuery|*|T|{}|jQuery}
*/
$.fn.getMapCounter = function(){
return $(this).find('.' + Init.classes.pieChart.pieChartMapCounterClass);
};
$.fn.getMapOverlayInterval = function(){
return $(this).getMapOverlay('timer').getMapCounter().data('interval');
};
/**
* start the map update counter or reset
*/
$.fn.startMapUpdateCounter = function(){
let mapOverlayTimer = $(this);
let counterChart = mapOverlayTimer.getMapCounter();
let maxSeconds = config.logTimerCount;
let counterChartLabel = counterChart.find('span');
let percentPerCount = 100 / maxSeconds;
// update counter
let updateChart = function(tempSeconds){
let pieChart = counterChart.data('easyPieChart');
if(pieChart !== undefined){
counterChart.data('easyPieChart').update( percentPerCount * tempSeconds);
}
counterChartLabel.text(tempSeconds);
};
// main timer function is called on any counter update
let timer = function(mapUpdateCounter){
// decrease timer
let currentSeconds = counterChart.data('currentSeconds');
currentSeconds--;
counterChart.data('currentSeconds', currentSeconds);
if(currentSeconds >= 0){
// update counter
updateChart(currentSeconds);
}else{
// hide counter and reset
clearInterval(mapUpdateCounter);
mapOverlayTimer.velocity('transition.whirlOut', {
duration: Init.animationSpeed.mapOverlay,
complete: function(){
counterChart.data('interval', false);
Util.getMapElementFromOverlay(mapOverlayTimer).trigger('pf:unlocked');
}
});
}
};
// get current seconds (in case the timer is already running)
let currentSeconds = counterChart.data('currentSeconds');
// start values for timer and chart
counterChart.data('currentSeconds', maxSeconds);
updateChart(maxSeconds);
if(
currentSeconds === undefined ||
currentSeconds < 0
){
// start timer
let mapUpdateCounter = setInterval(() => {
timer(mapUpdateCounter);
}, 1000);
// store counter interval
counterChart.data('interval', mapUpdateCounter);
// show overlay
if(mapOverlayTimer.is(':hidden')){
mapOverlayTimer.velocity('stop').velocity('transition.whirlIn', { duration: Init.animationSpeed.mapOverlay });
}
}
};
/**
* update (show/hide) a overlay icon in the "info"-overlay
* show/hide the overlay itself is no icons are visible
* @param option
* @param viewType
*/
$.fn.updateOverlayIcon = function(option, viewType){
let mapOverlayInfo = $(this);
let showOverlay = false;
let mapOverlayIconClass = options[option].class;
// look for the overlay icon that should be updated
let iconElement = mapOverlayInfo.find('.' + mapOverlayIconClass);
if(iconElement){
if(viewType === 'show'){
showOverlay = true;
// check "trigger" and mark as "active"
if(
options[option].trigger === 'active' ||
options[option].trigger === 'refresh'
){
iconElement.addClass('active');
}
// check if icon is not already visible
// -> prevents unnecessary "show" animation
if( !iconElement.data('visible') ){
// display animation for icon
iconElement.velocity({
opacity: [0.8, 0],
scale: [1, 0],
width: ['20px', 0],
height: ['20px', 0],
marginRight: ['10px', 0]
},{
duration: 240,
easing: 'easeInOutQuad'
});
iconElement.data('visible', true);
}
}else if(viewType === 'hide'){
// check if icon is not already visible
// -> prevents unnecessary "hide" animation
if(iconElement.data('visible')){
iconElement.removeClass('active').velocity('reverse');
iconElement.data('visible', false);
}
// check if there is any visible icon remaining
let visibleIcons = mapOverlayInfo.find('i:visible');
if(visibleIcons.length > 0){
showOverlay = true;
}
}
}
// show the entire overlay if there is at least one active icon
if(
showOverlay === true &&
mapOverlayInfo.is(':hidden')
){
// show overlay
mapOverlayInfo.velocity('stop').velocity('transition.whirlIn', { duration: Init.animationSpeed.mapOverlay });
}else if(
showOverlay === false &&
mapOverlayInfo.is(':visible')
){
// hide overlay
mapOverlayInfo.velocity('stop').velocity('transition.whirlOut', { duration: Init.animationSpeed.mapOverlay });
}
};
/**
* init all map overlays on a "parent" element
* @returns {*}
*/
$.fn.initMapOverlays = function(){
return this.each(function(){
let parentElement = $(this);
let mapOverlayTimer = $('<div>', {
class: [config.mapOverlayClass, config.mapOverlayTimerClass].join(' ')
});
parentElement.append(mapOverlayTimer);
// ------------------------------------------------------------------------------------
// add map overlay info. after scrollbar is initialized
let mapOverlayInfo = $('<div>', {
class: [config.mapOverlayClass, config.mapOverlayInfoClass].join(' ')
});
// add all overlay elements
for (let prop in options) {
if(options.hasOwnProperty(prop)){
let icon = $('<i>', {
class: options[prop].iconClass.concat( ['pull-right', options[prop].class] ).join(' ')
}).attr('title', options[prop].title).tooltip({
placement: 'bottom',
container: 'body',
delay: 150
});
// add "hover" action for some icons
if(
options[prop].trigger === 'hover' ||
options[prop].trigger === 'refresh'
){
icon.hoverIntent(options[prop].hoverIntent);
}
// add "click" handler for some icons
if(options[prop].hasOwnProperty('onClick')){
icon.on('click', options[prop].onClick);
}
mapOverlayInfo.append(icon);
}
}
parentElement.append(mapOverlayInfo);
// reset map update timer
mapOverlayTimer.setMapUpdateCounter(100, config.logTimerCount);
});
};
});

View File

@@ -1,80 +0,0 @@
/**
* Created by Exodus on 26.06.2016.
*/
define([
'jquery',
'app/init',
'app/util'
], function($, Init, Util) {
'use strict';
/**
* init map scrollbar
* @param config
*/
$.fn.initCustomScrollbar = function(config){
// default config -------------------------------------------------------------------------
let defaultConfig = {
axis: 'yx',
theme: 'light-3' ,
scrollInertia: 300,
autoExpandScrollbar: false,
scrollButtons:{
enable: true,
scrollAmount: 30,
scrollType: 'stepless'
},
callbacks: {
onTotalScrollOffset: 0,
onTotalScrollBackOffset: 0,
alwaysTriggerOffsets: true
},
advanced: {
updateOnContentResize: true,
autoExpandHorizontalScroll: true,
//autoExpandHorizontalScroll: 2,
autoScrollOnFocus: 'div',
},
mouseWheel: {
enable: false, // scroll wheel currently disabled
scrollAmount: 'auto',
axis: 'x',
preventDefault: true
},
keyboard: {
enable: false, // not working with pathfinder "shortcuts"
scrollType: 'stepless',
scrollAmount: 'auto'
},
scrollbarPosition: 'inside',
autoDraggerLength: true,
autoHideScrollbar: false
};
// init -----------------------------------------------------------------------------------
config = $.extend(true, {}, defaultConfig, config);
return this.each(function(){
let mapWrapperElement = $(this);
// prevent multiple initialization
mapWrapperElement.mCustomScrollbar('destroy');
// init custom scrollbars
mapWrapperElement.mCustomScrollbar(config);
});
};
/**
* scroll to a specific position in the map
* demo: http://manos.malihu.gr/repository/custom-scrollbar/demo/examples/scrollTo_demo.html
* @param position
*/
$.fn.scrollToPosition = function(position){
return this.each(function(){
$(this).mCustomScrollbar('scrollTo', position);
});
};
});

View File

@@ -1,540 +0,0 @@
/**
* map system functions
*/
define([
'jquery',
'app/init',
'app/util',
'bootbox',
'app/map/util',
'app/map/layout'
], ($, Init, Util, bootbox, MapUtil, Layout) => {
'use strict';
let config = {
newSystemOffset: {
x: 130,
y: 0
},
mapClass: 'pf-map', // class for all maps
systemHeadInfoClass: 'pf-system-head-info', // class for system info
systemHeadInfoLeftClass: 'pf-system-head-info-left', // class for left system info
systemHeadInfoRightClass: 'pf-system-head-info-right', // class for right system info
systemActiveClass: 'pf-system-active', // class for an active system on a map
systemTooltipInnerIdPrefix: 'pf-system-tooltip-inner-', // id prefix for system tooltip content
systemTooltipInnerClass: 'pf-system-tooltip-inner', // class for system tooltip content
dialogRallyId: 'pf-rally-dialog', // id for "Rally point" dialog
dialogRallyPokeDesktopId: 'pf-rally-dialog-poke-desktop', // id for "desktop" poke checkbox
dialogRallyPokeSlackId: 'pf-rally-dialog-poke-slack', // id for "Slack" poke checkbox
dialogRallyPokeDiscordId: 'pf-rally-dialog-poke-discord', // id for "Discord" poke checkbox
dialogRallyPokeMailId: 'pf-rally-dialog-poke-mail', // id for "mail" poke checkbox
dialogRallyMessageId: 'pf-rally-dialog-message', // id for "message" textarea
dialogRallyMessageDefault: '' +
'I need some help!\n\n' +
'- Potential PvP options around\n' +
'- DPS and Logistic ships needed'
};
/**
* show "set rally point" dialog for system
* @param system
*/
$.fn.showRallyPointDialog = (system) => {
let mapData = Util.getCurrentMapData(system.data('mapid'));
requirejs(['text!templates/dialog/system_rally.html', 'mustache'], function(template, Mustache) {
let setCheckboxObserver = (checkboxes) => {
checkboxes.each(function(){
$(this).on('change', function(){
// check all others
let allUnchecked = true;
checkboxes.each(function(){
if(this.checked){
allUnchecked = false;
}
});
let textareaElement = $('#' + config.dialogRallyMessageId);
if(allUnchecked){
textareaElement.prop('disabled', true);
}else{
textareaElement.prop('disabled', false);
}
});
});
};
let sendPoke = (requestData, context) => {
// lock dialog
let dialogContent = context.rallyDialog.find('.modal-content');
dialogContent.showLoadingAnimation();
$.ajax({
type: 'POST',
url: Init.path.pokeRally,
data: requestData,
dataType: 'json',
context: context
}).done(function(data){
}).fail(function( jqXHR, status, error) {
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': sendPoke', text: reason, type: 'warning'});
}).always(function(){
this.rallyDialog.find('.modal-content').hideLoadingAnimation();
});
};
let data = {
id: config.dialogRallyId,
dialogRallyPokeDesktopId: config.dialogRallyPokeDesktopId,
dialogRallyPokeSlackId: config.dialogRallyPokeSlackId,
dialogRallyPokeDiscordId: config.dialogRallyPokeDiscordId,
dialogRallyPokeMailId: config.dialogRallyPokeMailId,
dialogRallyMessageId: config.dialogRallyMessageId ,
desktopRallyEnabled: true,
slackRallyEnabled: Boolean(Util.getObjVal(mapData, 'config.logging.slackRally')),
discordRallyEnabled: Boolean(Util.getObjVal(mapData, 'config.logging.discordRally')),
mailRallyEnabled: Boolean(Util.getObjVal(mapData, 'config.logging.mailRally')),
dialogRallyMessageDefault: config.dialogRallyMessageDefault,
systemId: system.data('id')
};
let content = Mustache.render(template, data);
let rallyDialog = bootbox.dialog({
message: content,
title: 'Set rally point in "' + system.getSystemInfo( ['alias'] ) + '"',
buttons: {
close: {
label: 'cancel',
className: 'btn-default'
},
success: {
label: '<i class="fas fa-fw fa-volume-up"></i> set rally point',
className: 'btn-success',
callback: function() {
let form = $('#' + config.dialogRallyId).find('form');
// get form data
let formData = form.getFormValues();
// update map
system.setSystemRally(1, {
poke: Boolean(formData.pokeDesktop)
});
system.markAsChanged();
// send poke data to server
sendPoke(formData, {
rallyDialog: this
});
}
}
}
});
rallyDialog.initTooltips();
// after modal is shown ==================================================================================
rallyDialog.on('shown.bs.modal', function(e){
// set event for checkboxes
setCheckboxObserver(rallyDialog.find(':checkbox'));
});
});
};
/**
* shows delete dialog for systems that should be deleted
* @param map
* @param systems
* @returns {*}
*/
$.fn.showDeleteSystemDialog = (map, systems = []) => {
let mapContainer = $( map.getContainer() );
let validDeleteSystems = [];
let activeCharacters = 0;
// check if systems belong to map -> security check
for (let system of systems) {
let systemElement = $(system);
if(
systemElement.data('mapid') === mapContainer.data('id') &&
!systemElement.data('locked')
){
// system belongs to map -> valid system
validDeleteSystems.push(system);
activeCharacters += (systemElement.data('userCount') ? parseInt( systemElement.data('userCount') ) : 0);
}
}
if(validDeleteSystems.length){
let msg = '';
if(validDeleteSystems.length === 1){
let deleteSystem = $(validDeleteSystems[0]);
let systemName = deleteSystem.data('name');
let systemAlias = deleteSystem.getSystemInfo( ['alias'] );
let systemNameStr = (systemName === systemAlias) ? '"' + systemName + '"' : '"' + systemAlias + '" (' + systemName + ')';
systemNameStr = '<span class="txt-color txt-color-warning">' + systemNameStr + '</span>';
msg = 'Delete system ' + systemNameStr + ' and all its connections?';
}else{
msg = 'Delete ' + validDeleteSystems.length + ' selected systems and their connections?';
}
// add warning for active characters
if(activeCharacters > 0){
msg += ' <span class="txt-color txt-color-warning">Warning: ' + activeCharacters + ' active characters</span>';
}
let systemDeleteDialog = bootbox.confirm(msg, result => {
if(result){
deleteSystems(map, validDeleteSystems, (deletedSystems) => {
// callback function after deleted -> close dialog
systemDeleteDialog.modal('hide');
// check whether all systems were deleted properly
if(deletedSystems.length !== validDeleteSystems.length){
let notDeletedCount = validDeleteSystems.length - deletedSystems.length;
Util.showNotify({
title: 'Failed to delete systems',
text: '(' + notDeletedCount + '/' + validDeleteSystems.length + ') systems could not be deleted',
type: 'warning'}
);
}else if(deletedSystems.length === 1){
Util.showNotify({title: 'System deleted', text: $(deletedSystems[0]).data('name'), type: 'success'});
}else{
Util.showNotify({title: systems.length + ' systems deleted', type: 'success'});
}
});
}
});
}else{
Util.showNotify({title: 'No systems selected', type: 'warning'});
}
return this;
};
/**
* toggle system tooltip (current pilot count)
* @param show
* @param tooltipOptions
* @returns {*}
*/
$.fn.toggleSystemTooltip = function(show, tooltipOptions){
let highlightData = {
good: {
colorClass: 'txt-color-green',
iconClass: 'fa-caret-up'
},
bad: {
colorClass: 'txt-color-red',
iconClass: 'fa-caret-down'
}
};
let getHighlightClass = (highlight) => {
return Util.getObjVal(highlightData, highlight + '.colorClass') || '';
};
let getHighlightIcon = (highlight) => {
return Util.getObjVal(highlightData, highlight + '.iconClass') || '';
};
let getTitle = (userCounter, highlight) => {
return '<i class="fas ' + getHighlightIcon(highlight) + '"></i>&nbsp;' + userCounter + '';
};
return this.each(function(){
let system = $(this);
switch(show){
case 'destroy':
//destroy tooltip and remove some attributes which are not deleted by 'destroy'
system.tooltip('destroy').removeAttr('title data-original-title');
break;
case 'hide':
system.tooltip('hide');
break;
case 'show':
// initial "show" OR "update" open tooltip
// -> do not update tooltips while a system is dragged
let showTooltip = !system.hasClass('jsPlumb_dragged');
if(system.data('bs.tooltip')){
// tooltip initialized but could be hidden
// check for title update
if(
tooltipOptions.hasOwnProperty('userCount') &&
tooltipOptions.hasOwnProperty('highlight')
){
let currentTitle = system.attr('data-original-title');
let newTitle = getTitle(tooltipOptions.userCount, tooltipOptions.highlight);
if(currentTitle !== newTitle){
// update tooltip
let tooltipInner = system.attr('title', newTitle).tooltip('fixTitle').data('bs.tooltip').$tip.find('.tooltip-inner');
tooltipInner.html(newTitle);
// change highlight class
let highlightClass = getHighlightClass(tooltipOptions.highlight);
if( !tooltipInner.hasClass(highlightClass) ){
tooltipInner.removeClass( getHighlightClass('good') + ' ' + getHighlightClass('bad')).addClass(highlightClass);
}
}
}
let tip = system.data('bs.tooltip').tip();
if( !tip.hasClass('in') && showTooltip){
// update tooltip placement based on system position
system.data('bs.tooltip').options.placement = getSystemTooltipPlacement(system);
system.tooltip('show');
}
}else{
// no tooltip initialized
// "some" config data is required
if(
tooltipOptions.hasOwnProperty('systemId') &&
tooltipOptions.hasOwnProperty('userCount') &&
tooltipOptions.hasOwnProperty('highlight')
){
let innerTooltipId = config.systemTooltipInnerIdPrefix + tooltipOptions.systemId;
let template = '<div class="tooltip" role="tooltip">' +
'<div class="tooltip-arrow"></div>' +
'<div id="' + innerTooltipId + '" class="tooltip-inner txt-color ' + config.systemTooltipInnerClass + '"></div>' +
'</div>';
let options = {
trigger: 'manual',
placement: getSystemTooltipPlacement(system),
html: true,
animation: true,
template: template,
viewport: system.closest('.' + config.mapClass)
};
// init new tooltip -> Do not show automatic maybe system is currently dragged
system.attr('title', getTitle(tooltipOptions.userCount, tooltipOptions.highlight));
system.tooltip(options);
system.one('shown.bs.tooltip', function() {
// set highlight only on FIRST show
$('#' + this.innerTooltipId).addClass(this.highlightClass);
}.bind({
highlightClass: getHighlightClass(tooltipOptions.highlight),
innerTooltipId: innerTooltipId
}));
if(showTooltip){
system.tooltip('show');
}
}
}
break;
}
});
};
/**
* get tooltip position (top, bottom) based on system position
* @param system
* @returns {string}
*/
let getSystemTooltipPlacement = (system) => {
let offsetParent = system.parent().offset();
let offsetSystem = system.offset();
return (offsetSystem.top - offsetParent.top < 27) ? 'bottom' : 'top';
};
/**
* delete system(s) with all their connections
* (ajax call) remove system from DB
* @param map
* @param systems
* @param callback function
*/
let deleteSystems = (map, systems = [], callback = (systems) => {}) => {
let mapContainer = $( map.getContainer() );
$.ajax({
type: 'POST',
url: Init.path.deleteSystem,
data: {
mapId: mapContainer.data('id'),
systemIds: systems.map( system => $(system).data('id') )
},
dataType: 'json',
context: {
map: map,
systems: systems
}
}).done(function(data){
// check if all systems were deleted that should get deleted
let deletedSystems = this.systems.filter(
function(system){
return this.indexOf( $(system).data('id') ) !== -1;
}, data.deletedSystemIds
);
// remove systems from map
removeSystems(this.map, deletedSystems);
callback(deletedSystems);
}).fail(function(jqXHR, status, error) {
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': deleteSystem', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
});
};
/**
* remove system(s) from map (no backend requests)
* @param map
* @param systems
*/
let removeSystems = (map, systems) => {
let removeSystemCallbak = deleteSystem => {
map.remove(deleteSystem);
};
for (let system of systems){
system = $(system);
// check if system is "active"
if( system.hasClass(config.systemActiveClass) ){
delete Init.currentSystemData;
// get parent Tab Content and fire clear modules event
let tabContentElement = MapUtil.getTabContentElementByMapElement( system );
$(tabContentElement).trigger('pf:removeSystemModules');
}
// remove endpoints and their connections
// do not fire a "connectionDetached" event
map.detachAllConnections(system, {fireEvent: false});
// destroy tooltip/popover
system.toggleSystemTooltip('destroy', {});
system.destroyPopover(true);
// remove system
system.velocity('transition.whirlOut', {
duration: Init.animationSpeed.mapDeleteSystem,
complete: removeSystemCallbak
});
}
};
/**
* calculate the x/y coordinates for a new system - relativ to a source system
* @param sourceSystem
* @returns {{x: *, y: *}}
*/
let calculateNewSystemPosition = sourceSystem => {
let mapContainer = sourceSystem.parent();
let grid = [MapUtil.config.mapSnapToGridDimension, MapUtil.config.mapSnapToGridDimension];
let x = 0;
let y = 0;
let positionFinder = new Layout.Position({
container: mapContainer[0],
center: sourceSystem[0],
loops: 4,
grid: mapContainer.hasClass(MapUtil.config.mapGridClass) ? grid : false,
debug: false
});
let dimensions = positionFinder.findNonOverlappingDimensions(1, 16);
if(dimensions.length){
//... empty map space found
x = dimensions[0].left;
y = dimensions[0].top;
}else{
//... fallback
// related system is available
let currentX = sourceSystem.css('left');
let currentY = sourceSystem.css('top');
// remove "px"
currentX = parseInt( currentX.substring(0, currentX.length - 2) );
currentY = parseInt( currentY.substring(0, currentY.length - 2) );
x = currentX + config.newSystemOffset.x;
y = currentY + config.newSystemOffset.y;
}
let newPosition = {
x: x,
y: y
};
return newPosition;
};
/**
* get new dom element for systemData that shows "info" data (additional data)
* -> this is show below the system base data on map
* @param data
* @returns {*}
*/
let getHeadInfoElement = (data) => {
let headInfo = null;
let headInfoLeft = [];
let headInfoRight = [];
if(data.shattered){
headInfoLeft.push('<i class="fas fa-fw fa-skull ' + Util.getSecurityClassForSystem('SH') + '" title="shattered"></i>');
}
// check systemData if headInfo element is needed
if(data.statics && data.statics.length){
// format wh statics
for(let wormholeName of data.statics){
let staticData = Object.assign({}, Init.wormholes[wormholeName]);
headInfoRight.push(
'<span class="' +
Util.getSecurityClassForSystem(staticData.security) + ' ' +
Util.config.popoverTriggerClass + '" data-name="' + staticData.name +
'">' + staticData.security + '</span>'
);
}
}
if(headInfoLeft.length || headInfoRight.length){
headInfo = $('<div>', {
class: config.systemHeadInfoClass
}).append(
$('<div>', {
class: config.systemHeadInfoLeftClass,
html: headInfoLeft.join('&nbsp;&nbsp;')
}),
$('<div>', {
class: config.systemHeadInfoRightClass,
html: headInfoRight.join('&nbsp;&nbsp;')
})
);
}
return headInfo;
};
return {
deleteSystems: deleteSystems,
removeSystems: removeSystems,
calculateNewSystemPosition: calculateNewSystemPosition,
getHeadInfoElement: getHeadInfoElement
};
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,127 +0,0 @@
/**
* SharedWorker config for map
*/
define([
'app/util'
], function(Util) {
'use strict';
let config = {
};
let sharedWorker = null;
let MsgWorker = null;
let characterId = null;
/**
* get WebSocket URL for SharedWorker script
* @returns {string}
*/
let getWebSocketURL = () => {
let domain = location.host;
let workerProtocol = (window.location.protocol === 'https:') ? 'wss:' : 'ws:';
return workerProtocol + '//' + domain + '/ws/map/update';
};
/**
* get SharedWorker Script path
* @returns {string}
*/
let getWorkerScript = () => {
return '/public/js/' + Util.getVersion() + '/app/worker/map.js';
};
/**
* get path to message object
* @returns {string}
*/
let getMessageWorkerObjectPath = () => {
return '/public/js/' + Util.getVersion() + '/app/worker/message.js';
};
/**
* init (connect) WebSocket within SharedWorker
*/
let initSocket = () => {
let MsgWorkerInit = new MsgWorker('ws:init');
MsgWorkerInit.data({
uri: getWebSocketURL(),
characterId: characterId,
});
sharedWorker.port.postMessage(MsgWorkerInit);
};
/**
* init (start/connect) to "SharedWorker"
* -> set worker events
*/
let init = (config) => {
// set characterId that is connected with this SharedWorker PORT
characterId = parseInt(config.characterId);
// get message Class for App <=> SharedWorker MessageEvent communication
requirejs([getMessageWorkerObjectPath()], () => {
MsgWorker = window.MsgWorker;
// start/connect to "SharedWorker"
sharedWorker = new SharedWorker( getWorkerScript(), getMessageWorkerObjectPath() );
sharedWorker.port.addEventListener('message', (e) => {
let MsgWorkerMessage = e.data;
Object.setPrototypeOf(MsgWorkerMessage, MsgWorker.prototype);
switch(MsgWorkerMessage.command){
case 'ws:open':
config.callbacks.onOpen(MsgWorkerMessage);
break;
case 'ws:send':
config.callbacks.onGet(MsgWorkerMessage);
break;
case 'ws:closed':
config.callbacks.onClosed(MsgWorkerMessage);
break;
case 'ws:error':
config.callbacks.onError(MsgWorkerMessage);
break;
}
}, false);
sharedWorker.onerror = (e) => {
// could not connect to SharedWorker script -> send error back
let MsgWorkerError = new MsgWorker('sw:error');
MsgWorkerError.meta({
reason: 'Could not connect to SharedWorker: ' + getWorkerScript()
});
config.callbacks.onError(MsgWorkerError);
};
sharedWorker.port.start();
// SharedWorker initialized
let MsgWorkerInit = new MsgWorker('sw:init');
config.callbacks.onInit(MsgWorkerInit);
// startWebSocket
initSocket();
});
};
let send = (task, data) => {
let MsgWorkerSend = new MsgWorker('ws:send');
MsgWorkerSend.task(task);
MsgWorkerSend.data(data);
sharedWorker.port.postMessage(MsgWorkerSend);
};
return {
getWebSocketURL: getWebSocketURL,
init: init,
send: send
};
});

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,186 +0,0 @@
/**
* Render controller
*/
define(['jquery', 'mustache'], function($, Mustache) {
'use strict';
/**
* init function will be called before and after a new module is loaded
* @param functionName
* @param config
*/
let initModule = function(functionName, config){
if(
typeof config.functions === 'object' &&
typeof config.functions[functionName] === 'function'
){
config.functions[functionName](config);
}
};
/**
* load a template and render is with Mustache
* @param config
* @param data
*/
let showModule = function(config, data){
// require module template
requirejs(['text!templates/' + config.name + '.html'], function(template) {
// check for an id, if module already exists, do not insert again
if(
data.id === 'undefined' ||
$('#' + data.id).length === 0
){
let content = Mustache.render(template, data);
// display module
switch(config.link){
case 'prepend':
config.position.prepend(content);
break;
case 'before':
config.position.before(content);
break;
case 'after':
config.position.after(content);
break;
default:
config.position.append(content);
}
}
// init module function after render
initModule('after', config);
});
};
/**
* convert JSON object into HTML highlighted string
* @param obj
*/
let highlightJson = (obj) => {
let multiplyString = (num, str) => {
let sb = [];
for (let i = 0; i < num; i++) {
sb.push(str);
}
return sb.join('');
};
let dateObj = new Date();
let regexpObj = new RegExp();
let tab = multiplyString(1, ' ');
let isCollapsible = true;
let quoteKeys = false;
let expImageClicked = '(() => {let container=this.parentNode.nextSibling; container.style.display=container.style.display===\'none\'?\'inline\':\'none\'})();';
let checkForArray = function (obj) {
return obj &&
typeof obj === 'object' &&
typeof obj.length === 'number' &&
!(obj.propertyIsEnumerable('length'));
};
let getRow = function (indent, data, isPropertyContent) {
let tabs = '';
for (let i = 0; i < indent && !isPropertyContent; i++) tabs += tab;
if (data !== null && data.length > 0 && data.charAt(data.length - 1) !== '\n')
data = data + '\n';
return tabs + data;
};
let formatLiteral = function (literal, quote, comma, indent, isArray, style) {
if (typeof literal === 'string')
literal = literal.split('<').join('&lt;').split('>').join('&gt;');
let str = '<span class="' + style + '">' + quote + literal + quote + comma + '</span>';
if (isArray) str = getRow(indent, str);
return str;
};
let formatFunction = function (indent, obj) {
let tabs = '';
for (let i = 0; i < indent; i++) tabs += tab;
let funcStrArray = obj.toString().split('\n');
let str = '';
for (let i = 0; i < funcStrArray.length; i++) {
str += ((i === 0) ? '' : tabs) + funcStrArray[i] + '\n';
}
return str;
};
let highlight = (obj, indent, addComma, isArray, isPropertyContent) => {
let html = '';
let comma = (addComma) ? '<span class="pf-code-Comma">,</span> ' : '';
let type = typeof obj;
let clpsHtml = '';
if (checkForArray(obj)) {
if (obj.length === 0) {
html += getRow(indent, '<span class="pf-code-ArrayBrace">[ ]</span>' + comma, isPropertyContent);
} else {
clpsHtml = isCollapsible ? '<span><i class="fas fa-fw fa-plus-square" onClick="' + expImageClicked + '"></i></span><span class="collapsible">' : '';
html += getRow(indent, '<span class="pf-code-ArrayBrace">[</span>' + clpsHtml, isPropertyContent);
for (let i = 0; i < obj.length; i++) {
html += highlight(obj[i], indent + 1, i < (obj.length - 1), true, false);
}
clpsHtml = isCollapsible ? '</span>' : '';
html += getRow(indent, clpsHtml + '<span class="pf-code-ArrayBrace">]</span>' + comma);
}
} else if (type === 'object') {
if (obj === null) {
html += formatLiteral('null', '', comma, indent, isArray, 'pf-code-Null');
} else if (obj.constructor === dateObj.constructor) {
html += formatLiteral('new Date(' + obj.getTime() + ') /*' + obj.toLocaleString() + '*/', '', comma, indent, isArray, 'Date');
} else if (obj.constructor === regexpObj.constructor) {
html += formatLiteral('new RegExp(' + obj + ')', '', comma, indent, isArray, 'RegExp');
} else {
let numProps = 0;
for (let prop in obj) numProps++;
if (numProps === 0) {
html += getRow(indent, '<span class="pf-code-ObjectBrace">{ }</span>' + comma, isPropertyContent);
} else {
clpsHtml = isCollapsible ? '<span><i class="fas fa-fw fa-plus-square" onClick="' + expImageClicked + '"></i></span><span class="collapsible">' : '';
html += getRow(indent, '<span class="pf-code-ObjectBrace">{</span>' + clpsHtml, isPropertyContent);
let j = 0;
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
let quote = quoteKeys ? '"' : '';
html += getRow(indent + 1, '<span class="pf-code-PropertyName">' + quote + prop + quote + '</span>: ' + highlight(obj[prop], indent + 1, ++j < numProps, false, true));
}
}
clpsHtml = isCollapsible ? '</span>' : '';
html += getRow(indent, clpsHtml + '<span class="pf-code-ObjectBrace">}</span>' + comma);
}
}
} else if (type === 'number') {
html += formatLiteral(obj, '', comma, indent, isArray, 'pf-code-Number');
} else if (type === 'boolean') {
html += formatLiteral(obj, '', comma, indent, isArray, 'pf-code-Boolean');
} else if (type === 'function') {
if (obj.constructor === regexpObj.constructor) {
html += formatLiteral('new RegExp(' + obj + ')', '', comma, indent, isArray, 'RegExp');
} else {
obj = formatFunction(indent, obj);
html += formatLiteral(obj, '', comma, indent, isArray, 'pf-code-Function');
}
} else if (type === 'undefined') {
html += formatLiteral('undefined', '', comma, indent, isArray, 'pf-code-Null');
} else {
html += formatLiteral(obj.toString().split('\\').join('\\\\').split('"').join('\\"'), '"', comma, indent, isArray, 'pf-code-String');
}
return html;
};
return highlight(obj, 0, false, false, false);
};
return {
showModule: showModule,
highlightJson: highlightJson
};
});

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,314 +0,0 @@
/**
* Demo SVG map
*/
define([
'jquery',
'lazylinepainter'
], function($) {
'use strict';
let config = {
headerSystemsContainerId: 'pf-header-systems', // id for systems layer
headerSystemConnectorsId: 'pf-header-connectors', // id for connectors layer
headerConnectionsContainerId: 'pf-header-connections', // id for connections layer
headerBackgroundContainerId: 'pf-header-background', // id for background layer
headerSystemClass: 'pf-header-system', // class for all header background systems
// map dimensions
mapWidth: 600, // map width (px)
mapHeight: 380 // map height (px)
};
/**
* draw systems layer
* @param callback
*/
let drawSystems = function(callback){
let pathObj = {
systems: {
strokepath: [
// systems =======================================================================
// 1
{
path: 'm 155 30 90 0 c 2.8 0 5 2.2 5 5 l 0 10 c 0 2.8 -2.2 5 -5 5 l -90 0 c -2.8 0 -5 -2.2 -5 -5 l 0 -10 c 0 -2.8 2.2 -5 5 -5 z',
duration: 500,
strokeColor: '#568A89' //teal
},
// 2
{
path: 'm 374 91 110 0 c 2.8 0 5 2.2 5 5 l 0 10 c 0 2.8 -2.2 5 -5 5 l -110 0 c -2.8 0 -5 -2.2 -5 -5 l 0 -10 c 0 -2.8 2.2 -5 5 -5 z',
duration: 500,
strokeColor: '#63676A' //gray
},
// 3
{
path: 'm 15 149 90 0 c 2.8 0 5 2.2 5 5 l 0 30 c 0 2.8 -2.2 5 -5 5 l -90 0 c -2.8 0 -5 -2.2 -5 -5 l 0 -30 c 0 -2.8 2.2 -5 5 -5 z',
duration: 500,
strokeColor: '#D9534F ' //red
},
// 4
{
path: 'm 235 230 90 0 c 2.8 0 5 2.2 5 5 l 0 10 c 0 2.8 -2.2 5 -5 5 l -90 0 c -2.8 0 -5 -2.2 -5 -5 l 0 -10 c 0 -2.8 2.2 -5 5 -5 z',
duration: 500,
strokeColor: '#63676A' //gray
},
// 5
{
path: 'm 175 330 90 0 c 2.8 0 5 2.2 5 5 l 0 30 c 0 2.8 -2.2 5 -5 5 l -90 0 c -2.8 0 -5 -2.2 -5 -5 l 0 -30 c 0 -2.8 2.2 -5 5 -5 z',
duration: 500,
strokeColor: '#E28A0D ' //orange
},
// 6
{
path: 'm 436 312 90 0 c 2.8 0 5 2.2 5 5 l 0 10 c 0 2.8 -2.2 5 -5 5 l -90 0 c -2.8 0 -5 -2.2 -5 -5 l 0 -10 c 0 -2.8 2.2 -5 5 -5 z',
duration: 500,
strokeColor: '#5CB85C ' //green
}
],
dimensions: {
width: config.mapWidth,
height: config.mapHeight
}
}
};
// draw systems into header
$('#' + config.headerSystemsContainerId).lazylinepainter(
{
svgData: pathObj,
strokeWidth: 2,
strokeOpacity: 1,
overrideKey: 'systems',
strokeJoin: 'miter',
strokeCap: 'butt',
delay: 1000,
onComplete: function(){
drawConnectors(callback);
}
}).lazylinepainter('paint');
};
/**
* draw connectors layer
* @param callback
*/
let drawConnectors = function(callback){
let connectorDuration = 150;
let pathObj = {
connectors: {
strokepath: [
// connectors ====================================================================
// 1
{
path: 'm 250.4 34.8 c 1.7 0 3.1 1.3 3.9 2.9 0.8 1.7 0.8 3.7 0 5.3 -0.8 1.7 -2.4 2.7 -4 2.7',
duration: connectorDuration
},
{
path: 'm 150 34.7 c -1.7 0 -3.1 1.3 -3.9 2.9 -0.8 1.7 -0.8 3.7 0 5.3 0.8 1.7 2.4 2.7 4 2.7',
duration: connectorDuration
},
// 2
{
path: 'm 369 96 c -1.7 0 -3.1 1.3 -3.9 2.9 -0.8 1.7 -0.8 3.7 0 5.3 0.8 1.7 2.4 2.7 4 2.7',
duration: connectorDuration
},
// 3
{
path: 'm 110.4 165 c 1.7 0 3.1 1.3 3.9 2.9 0.8 1.7 0.8 3.7 0 5.3 -0.8 1.7 -2.4 2.7 -4 2.7',
duration: connectorDuration
},
{
path: 'm 56 148 c 0 -1.7 1.3 -3.1 2.9 -3.9 1.7 -0.8 3.7 -0.8 5.3 0 1.7 0.8 2.7 2.4 2.7 4',
duration: connectorDuration
},
// 4
{
path: 'm 229 236 c -1.7 0 -3.1 1.3 -3.9 2.9 -0.8 1.7 -0.8 3.7 0 5.3 0.8 1.7 2.4 2.7 4 2.7',
duration: connectorDuration
},
{
path: 'm 331 234.7 c 1.7 0 3.1 1.3 3.9 2.9 0.8 1.7 0.8 3.7 0 5.3 -0.8 1.7 -2.4 2.7 -4 2.7',
duration: connectorDuration
},
{
path: 'm 285 251 c 0 1.7 -1.3 3.1 -2.9 3.9 -1.7 0.8 -3.7 0.8 -5.3 0 -1.7 -0.8 -2.7 -2.4 -2.7 -4',
duration: connectorDuration
},
// 5
{
path: 'm 213 329.5 c 0 -1.7 1.3 -3.1 2.9 -3.9 1.7 -0.8 3.7 -0.8 5.3 0 1.7 0.8 2.7 2.4 2.7 4',
duration: connectorDuration
},
// 6
{
path: 'm 430 316 c -1.7 0 -3.1 1.3 -3.9 2.9 -0.8 1.7 -0.8 3.7 0 5.3 0.8 1.7 2.4 2.7 4 2.7',
duration: connectorDuration
}
],
dimensions: {
width: config.mapWidth,
height: config.mapHeight
}
}
};
// draw systems into header
$('#' + config.headerConnectionsContainerId).lazylinepainter(
{
svgData: pathObj,
strokeWidth: 2,
duration: 600,
drawSequential: false,
strokeOpacity: 1,
overrideKey: 'connectors',
strokeJoin: 'miter',
strokeCap: 'butt',
strokeColor: '#63676A', //gray
onComplete: function(){
drawConnections(callback);
}
}).lazylinepainter('paint');
};
/**
* draw connections layer
* @param callback
*/
let drawConnections = function(callback){
let connectionDuration = 250;
let connectionWidth = 8;
let connectionInnerWidth = 4;
let connectionBorderColor = '#63676A'; //gray
let pathObj = {
connections: {
strokepath: [
// connections ====================================================================
// 1 - 2
{
path: 'm 255,40 c 44.5,0 64.2,61.1 109.0,61.15',
duration: connectionDuration,
strokeWidth: connectionWidth
},
{
path: 'm 255,40 c 44.5,0 64.2,61.1 109.0,61.15',
duration: connectionDuration,
strokeWidth: connectionInnerWidth,
strokeColor: '#3C3F41' // gray
},
// 2 - 3
{
path: 'm 146,40.0 c -51.7,0 -83.8,58.8 -83.8,104.5',
duration: connectionDuration,
strokeWidth: connectionWidth
},
{
path: 'm 146,40.0 c -51.7,0 -83.8,58.8 -83.8,104.5',
duration: connectionDuration,
strokeWidth: connectionInnerWidth,
strokeColor: '#E28A0D' // orange
},
// 3 - 4
{
path: 'm 115,171 c 45.7,0 64.1,71.2 109.6,70.8',
duration: connectionDuration,
strokeWidth: connectionWidth
},
{
path: 'm 115,171 c 45.7,0 64.1,71.2 109.6,70.8',
duration: connectionDuration,
strokeWidth: connectionInnerWidth,
strokeColor: '#A52521' // red
},
// 4 - 5
{
path: 'm 279,256 c 0.5,35.9 -60.1,35.1 -60.1,70.0',
duration: connectionDuration,
strokeWidth: connectionWidth
},
{
path: 'm 279,256 c 0.5,35.9 -60.1,35.1 -60.1,70.0',
duration: connectionDuration,
strokeWidth: connectionInnerWidth,
strokeColor: '#3C3F41' // gray
},
// 4 - 6
{
path: 'm 335,240 c 44.2,0 43.7,81.6 89.9,81.6',
duration: connectionDuration,
strokeWidth: connectionWidth
},
{
path: 'm 335,240 c 44.2,0 43.7,81.6 89.9,81.6',
duration: connectionDuration,
strokeWidth: connectionInnerWidth,
strokeColor: '#3C3F41' // gray
}
],
dimensions: {
width: config.mapWidth,
height: config.mapHeight
}
}
};
// draw systems into header
$('#' + config.headerSystemConnectorsId).lazylinepainter(
{
svgData: pathObj,
strokeWidth: 2,
duration: 600,
// drawSequential: false,
strokeOpacity: 1,
overrideKey: 'connections',
strokeJoin: 'miter',
strokeCap: 'butt',
strokeColor: connectionBorderColor,
onComplete: function(){
drawBackground(callback);
}
}).lazylinepainter('paint');
};
/**
* draw background layer
* @param callback
*/
let drawBackground = function(callback){
$('#' + config.headerBackgroundContainerId + ' .' + config.headerSystemClass).velocity('transition.bounceUpIn', {
stagger: 150,
complete: function(){
if(typeof callback === 'function'){
callback();
}
}
});
};
/**
* draws the demo map
* @param callback
*/
$.fn.drawDemoMap = function(callback){
let canvasElement = $(this);
// draw systems
drawSystems(callback);
};
});

View File

@@ -1,212 +0,0 @@
/**
* user settings/share dialog
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox'
], function($, Init, Util, Render, bootbox) {
'use strict';
let config = {
// select character dialog
settingsDialogId: 'pf-settings-dialog', // id for "settings" dialog
settingsAccountContainerId: 'pf-settings-dialog-account', // id for the "account" container
settingsShareContainerId: 'pf-settings-dialog-share', // id for the "share" container
settingsCharacterContainerId: 'pf-settings-dialog-character', // id for the "character" container
// captcha
captchaKeyUpdateAccount: 'SESSION.CAPTCHA.ACCOUNT.UPDATE', // key for captcha reason
captchaImageWrapperId: 'pf-dialog-captcha-wrapper', // id for "captcha image" wrapper
captchaImageId: 'pf-dialog-captcha-image', // id for "captcha image"
loadingOptions: { // config for loading overlay
icon: {
size: 'fa-2x'
}
}
};
/**
* show "register/settings" dialog
* @returns {boolean}
*/
$.fn.showSettingsDialog = function(){
// check if there are other dialogs open
let openDialogs = Util.getOpenDialogs();
if(openDialogs.length > 0){
return false;
}
requirejs(['text!templates/dialog/settings.html', 'mustache'], function(template, Mustache) {
let data = {
id: config.settingsDialogId,
settingsAccountContainerId: config.settingsAccountContainerId,
settingsShareContainerId: config.settingsShareContainerId,
settingsCharacterContainerId: config.settingsCharacterContainerId,
userData: Init.currentUserData,
captchaImageWrapperId: config.captchaImageWrapperId,
captchaImageId: config.captchaImageId,
formErrorContainerClass: Util.config.formErrorContainerClass,
ccpImageServer: Init.url.ccpImageServer,
roleLabel: Util.getLabelByRole(Util.getObjVal(Util.getCurrentUserData(), 'character.role')).prop('outerHTML'),
};
let content = Mustache.render(template, data);
let accountSettingsDialog = bootbox.dialog({
title: 'Account settings',
message: content,
buttons: {
close: {
label: 'cancel',
className: 'btn-default'
},
success: {
label: '<i class="fas fa-check fa-fw"></i>&nbsp;save',
className: 'btn-success',
callback: function() {
// get the current active form
let form = $('#' + config.settingsDialogId).find('form').filter(':visible');
// validate form
form.validator('validate');
// check whether the form is valid
let formValid = form.isValidForm();
if(formValid === true){
let tabFormValues = form.getFormValues();
// send Tab data and store values
let requestData = {
formData: tabFormValues
};
accountSettingsDialog.find('.modal-content').showLoadingAnimation();
$.ajax({
type: 'POST',
url: Init.path.saveUserConfig,
data: requestData,
dataType: 'json'
}).done(function(responseData){
accountSettingsDialog.find('.modal-content').hideLoadingAnimation();
// set new captcha for any request
// captcha is required for sensitive data (not for all data)
if(
responseData.error &&
responseData.error.length > 0
){
form.showFormMessage(responseData.error);
$('#' + config.captchaImageWrapperId).showCaptchaImage(config.captchaKeyUpdateAccount, function(){
$('#captcha').resetFormFields();
});
}else{
// store new/updated user data -> update head
if(responseData.userData){
Util.setCurrentUserData(responseData.userData);
}
form.find('.alert').velocity('transition.slideDownOut',{
duration: 500,
complete: function(){
$('#' + config.captchaImageWrapperId).showCaptchaImage(config.captchaKeyUpdateAccount, function(){
$('#captcha').resetFormFields();
});
}
});
Util.showNotify({title: 'Account saved', type: 'success'});
// close dialog/menu
$(document).trigger('pf:closeMenu', [{}]);
accountSettingsDialog.modal('hide');
}
}).fail(function( jqXHR, status, error) {
accountSettingsDialog.find('.modal-content').hideLoadingAnimation();
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': saveAccountSettings', text: reason, type: 'error'});
// set new captcha for any request
// captcha is required for sensitive data (not for all)
$('#' + config.captchaImageWrapperId).showCaptchaImage(config.captchaKeyUpdateAccount, function(){
$('#captcha').resetFormFields();
});
// check for DB errors
if(jqXHR.status === 500){
if(jqXHR.responseText){
let errorObj = $.parseJSON(jqXHR.responseText);
if(
errorObj.error &&
errorObj.error.length > 0
){
form.showFormMessage(errorObj.error);
}
}
}
$(document).setProgramStatus('problem');
});
}
return false;
}
}
}
});
// after modal is shown =======================================================================
accountSettingsDialog.on('shown.bs.modal', function(e) {
let dialogElement = $(this);
let form = dialogElement.find('form');
// request captcha image and show
let captchaImageWrapperContainer = $('#' + config.captchaImageWrapperId);
captchaImageWrapperContainer.showCaptchaImage(config.captchaKeyUpdateAccount);
// init captcha refresh button
captchaImageWrapperContainer.find('i').on('click', function(){
captchaImageWrapperContainer.showCaptchaImage(config.captchaKeyUpdateAccount);
});
// init dialog tooltips
dialogElement.initTooltips();
form.initFormValidation();
});
// events for tab change
accountSettingsDialog.find('.navbar a').on('shown.bs.tab', function(e){
// init "toggle" switches on current active tab
accountSettingsDialog.find( $(this).attr('href') ).find('input[data-toggle="toggle"][type="checkbox"]').bootstrapToggle({
on: '<i class="fas fa-fw fa-check"></i>&nbsp;Enable',
off: 'Disable&nbsp;<i class="fas fa-fw fa-ban"></i>',
onstyle: 'success',
offstyle: 'warning',
width: 100,
height: 30
});
});
});
};
});

View File

@@ -1,140 +0,0 @@
/**
* changelog dialog (GitHub API repository information)
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox'
], ($, Init, Util, Render, bootbox) => {
'use strict';
let config = {
changelogDialogClass: 'pf-changelog-dialog', // class for "changelog" dialog
dynamicMessageContainerClass: 'pf-dynamic-message-container', // class for "dynamic" (JS) message container
timelineClass: 'timeline' // class for "timeline"
};
/**
* show version information
* @param changelogDialog
* @param versionData
*/
let showVersion = (changelogDialog, versionData) => {
let type = 'error';
let title = versionData.current;
let text = 'Installed version check failed';
if(versionData.dev){
// developer version
type = 'info';
title = versionData.current + ' (dev)';
text = 'This installation is ahead of current stable version <kbd>' + versionData.last + '</kbd>.';
}else{
// standard version
if(versionData.delta === 0){
// last stable
type = 'success';
title = versionData.current;
text = 'This installation is up2date.';
}else{
// outdated...
type = 'warning';
title = versionData.current;
text = 'This installation is ' + versionData.delta + ' version behind current stable <kbd>' + versionData.last + '</kbd>.';
}
}
changelogDialog.find('.' + config.dynamicMessageContainerClass).showMessage({
dismissible: false,
type: type,
title: title,
text: text
});
};
/**
* load changelog information in dialog
* @param changelogDialog
*/
let loadDialogData = (changelogDialog) => {
// lock dialog
let dialogContent = changelogDialog.find('.modal-content');
dialogContent.showLoadingAnimation();
$.ajax({
type: 'POST',
url: Init.path.gitHubReleases,
dataType: 'json',
context: {
changelogDialog: changelogDialog
}
}).done(function(data){
let changelogDialog = this.changelogDialog;
let versionData = data.version;
let releasesData = data.releasesData;
showVersion(changelogDialog, versionData);
requirejs(['text!templates/ui/timeline_element.html', 'mustache'], function(template, Mustache) {
for(let i = 0; i < releasesData.length; i++){
let releaseData = releasesData[i];
// template vars
let data = {
isFirst: (i === 0),
isOdd: (i % 2 !== 0),
releaseDate: releaseData.published_at.substr(0, 10),
releaseData: releaseData
};
let content = Mustache.render(template, data);
changelogDialog.find('ul.' + config.timelineClass).append(content);
}
changelogDialog.find('.timeline > li').velocity('transition.expandIn', {
stagger: 300,
duration: 240,
//display: 'auto',
complete: function(){}
});
});
}).fail(function( jqXHR, status, error) {
let reason = status + ' ' + jqXHR.status + ': ' + error;
Util.showNotify({title: jqXHR.status + ': login', text: reason, type: 'error'});
}).always(function() {
dialogContent.hideLoadingAnimation();
});
};
/**
* show changelog dialog
*/
$.fn.changelogsDialog = function(){
let content = $('<div>').append(
$('<div>', {
class: config.dynamicMessageContainerClass
}),
$('<ul>', {
class: config.timelineClass
})
);
let changelogDialog = bootbox.dialog({
className: config.changelogDialogClass,
title: 'Changelog',
size: 'large',
message: content
});
// after modal is shown =======================================================================
changelogDialog.on('shown.bs.modal', function(e) {
loadDialogData(changelogDialog);
});
};
});

View File

@@ -1,51 +0,0 @@
/**
* credits dialog
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox',
'app/ui/logo'
], function($, Init, Util, Render, bootbox) {
'use strict';
let config = {
// jump info dialog
creditsDialogClass: 'pf-credits-dialog', // class for credits dialog
creditsDialogLogoContainerId: 'pf-logo-container' // id for logo element
};
/**
* show jump info dialog
*/
$.fn.showCreditsDialog = function(callback, enableHover){
requirejs(['text!templates/dialog/credit.html', 'mustache'], function(template, Mustache) {
let data = {
logoContainerId: config.creditsDialogLogoContainerId,
version: Util.getVersion()
};
let content = Mustache.render(template, data);
let creditDialog = bootbox.dialog({
className: config.creditsDialogClass,
title: 'Licence',
message: content
});
// after modal is shown =======================================================================
creditDialog.on('shown.bs.modal', function(e) {
// load Logo svg
creditDialog.find('#' + config.creditsDialogLogoContainerId).drawLogo(callback, enableHover);
});
});
};
});

View File

@@ -1,116 +0,0 @@
/**
* delete account dialog
*/
define([
'jquery',
'app/init',
'app/util',
'bootbox'
], function($, Init, Util, bootbox) {
'use strict';
let config = {
// global dialog
deleteAccountId: 'pf-dialog-delete-account', // dialog id
// captcha
captchaKeyDeleteAccount: 'SESSION.CAPTCHA.ACCOUNT.DELETE', // key for captcha reason
captchaImageWrapperId: 'pf-dialog-captcha-wrapper' // id for "captcha image" wrapper
};
/**
* shows delete account dialog
*/
$.fn.showDeleteAccountDialog = function(){
requirejs(['text!templates/dialog/delete_account.html', 'mustache'], function(template, Mustache) {
let data = {
deleteAccountId: config.deleteAccountId,
userData: Util.getCurrentUserData(),
captchaImageWrapperId: config.captchaImageWrapperId,
formErrorContainerClass: Util.config.formErrorContainerClass
};
let content = Mustache.render(template, data);
let deleteAccountDialog = bootbox.dialog({
title: 'Delete account',
message: content,
buttons: {
close: {
label: 'cancel',
className: 'btn-default'
},
success: {
label: '<i class="fas fa-user-times fa-fw"></i>&nbsp;delete account',
className: 'btn-danger',
callback: function() {
let dialogElement = $(this);
let form = dialogElement.find('form');
// validate form
form.validator('validate');
let formValid = form.isValidForm();
if(formValid){
let formValues = form.getFormValues();
if(! $.isEmptyObject(formValues) ){
// send Tab data and store values
let requestData = {
formData: formValues
};
dialogElement.find('.modal-content').showLoadingAnimation();
$.ajax({
type: 'POST',
url: Init.path.deleteAccount,
data: requestData,
dataType: 'json'
}).done(function(responseData){
dialogElement.find('.modal-content').hideLoadingAnimation();
if(responseData.reroute !== undefined){
Util.redirect(responseData.reroute, []);
}else if(
responseData.error &&
responseData.error.length > 0
){
form.showFormMessage(responseData.error);
$('#' + config.captchaImageWrapperId).showCaptchaImage(config.captchaKeyDeleteAccount, function(){
form.find('[name="captcha"]').resetFormFields();
});
}
}).fail(function( jqXHR, status, error) {
dialogElement.find('.modal-content').hideLoadingAnimation();
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': deleteAccount', text: reason, type: 'error'});
});
}
}
return false;
}
}
}
});
// after modal is shown =======================================================================
deleteAccountDialog.on('shown.bs.modal', function(e) {
// request captcha image and show
$('#' + config.captchaImageWrapperId).showCaptchaImage(config.captchaKeyDeleteAccount);
});
});
};
});

View File

@@ -1,112 +0,0 @@
/**
* jump info dialog
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox',
], ($, Init, Util, Render, bootbox) => {
'use strict';
let config = {
// jump info dialog
jumpInfoDialogClass: 'pf-jump-info-dialog', // class for jump info dialog
wormholeInfoMassTableClass: 'pf-wormhole-info-mass-table', // class for "wormhole mass" table
wormholeInfoJumpTableClass: 'pf-wormhole-info-jump-table' // class for "wormhole jump" table
};
/**
* show jump info dialog
*/
$.fn.showJumpInfoDialog = function(){
requirejs(['text!templates/dialog/jump_info.html', 'mustache'], (template, Mustache) => {
let data = {
config: config,
wormholes: Object.keys(Init.wormholes).map(function(k) { return Init.wormholes[k]; }), // convert Json to array
securityClass: function(){
return function(value, render){
return this.Util.getSecurityClassForSystem( render(value) );
}.bind(this);
}.bind({
Util: Util
}),
massValue: function(){
return function(value, render){
let mass = render(value);
switch(mass.length){
case 0: return '';
case 1: return 'Yes';
default: return this.Util.formatMassValue(mass);
}
}.bind(this);
}.bind({
Util: Util
}),
formatStatic: function(){
return function(value, render){
let isStatic = render(value) === 'true';
if(isStatic){
return '<i class="fas fa-check"></i>';
}else{
return '';
}
};
},
sigStrengthValue: function(){
return function(value, render){
let float = render(value);
return float.length ? parseFloat(float).toLocaleString() + '&nbsp;&#37;' : 'unknown';
};
}
};
let content = Mustache.render(template, data);
let jumpDialog = bootbox.dialog({
className: config.jumpInfoDialogClass,
title: 'Wormhole jump information',
message: content,
show: false
});
jumpDialog.on('show.bs.modal', function(e) {
// init dataTable
$(this).find('.' + config.wormholeInfoMassTableClass).DataTable({
pageLength: 25,
lengthMenu: [[10, 20, 25, 30, 40, -1], [10, 20, 25, 30, 40, 'All']],
autoWidth: false,
language: {
emptyTable: 'No wormholes',
zeroRecords: 'No wormholes found',
lengthMenu: 'Show _MENU_ wormholes',
info: 'Showing _START_ to _END_ of _TOTAL_ wormholes'
},
columnDefs: []
});
$(this).find('.' + config.wormholeInfoJumpTableClass).DataTable({
pageLength: -1,
paging: false,
lengthChange: false,
ordering: false,
searching: false,
info: false,
autoWidth: false,
language: {
emptyTable: 'No wormholes',
zeroRecords: 'No wormholes found',
lengthMenu: 'Show _MENU_ wormholes',
info: 'Showing _START_ to _END_ of _TOTAL_ wormholes'
},
columnDefs: []
});
});
jumpDialog.initTooltips();
jumpDialog.modal('show');
});
};
});

View File

@@ -1,171 +0,0 @@
/**
* map manual dialog
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox',
], function($, Init, Util, Render, bootbox) {
'use strict';
let config = {
// global dialog
dialogNavigationClass: 'pf-dialog-navigation-list', // class for dialog navigation bar
dialogNavigationListItemClass: 'pf-dialog-navigation-list-item', // class for map manual li main navigation elements
// map manual dialog
mapManualScrollspyId: 'pf-manual-scrollspy' // id for map manual scrollspy
};
/**
* shows the map manual modal dialog
*/
$.fn.showMapManual = function(){
requirejs(['text!templates/dialog/map_manual.html', 'mustache'], function(template, Mustache) {
let data = {
dialogNavigationClass: config.dialogNavigationClass,
dialogNavLiClass: config.dialogNavigationListItemClass,
scrollspyId: config.mapManualScrollspyId,
pieChartClass : Init.classes.pieChart.pieChartMapCounterClass,
mapCounterClass : Init.classes.pieChart.pieChartMapCounterClass
};
let content = Mustache.render(template, data);
// show dialog
let mapManualDialog = bootbox.dialog({
title: 'Manual',
message: content,
size: 'large',
buttons: {
success: {
label: 'close',
className: 'btn-default',
callback: function() {
$(mapManualDialog).modal('hide');
}
}
},
show: true
});
// modal offset top
let modalOffsetTop = 200;
// disable on scroll event
let disableOnScrollEvent = false;
// scroll breakpoints
let scrolLBreakpointElements = null;
// scroll navigation links
let scrollNavLiElements = null;
mapManualDialog.on('shown.bs.modal', function(e) {
// modal on open
scrolLBreakpointElements = $('.pf-manual-scroll-break');
scrollNavLiElements = $('.' + config.dialogNavigationListItemClass);
});
let scrollspyElement = $('#' + config.mapManualScrollspyId);
let whileScrolling = function(){
if(disableOnScrollEvent === false){
for(let i = 0; i < scrolLBreakpointElements.length; i++){
let offset = $(scrolLBreakpointElements[i]).offset().top;
if( (offset - modalOffsetTop) > 0){
if(! $( scrollNavLiElements[i]).hasClass('active')){
// remove all active classes
scrollNavLiElements.removeClass('active');
// remove focus on links
scrollNavLiElements.find('a').blur();
$( scrollNavLiElements[i]).addClass('active');
}
break;
}
}
}
};
// init scrollbar
scrollspyElement.mCustomScrollbar({
axis: 'y',
theme: 'light-3',
scrollInertia: 200,
autoExpandScrollbar: false,
scrollButtons:{
enable: true,
scrollAmount: 30
},
advanced: {
updateOnContentResize: true
},
callbacks:{
onInit: function(){
// init fake-map update counter
scrollspyElement.find('.' + data.mapCounterClass).initMapUpdateCounter();
// set navigation button observer
let mainNavigationLinks = $('.' + config.dialogNavigationClass).find('a');
// text anchor links
let subNavigationLinks = scrollspyElement.find('a[data-target]');
let navigationLinks = mainNavigationLinks.add(subNavigationLinks);
navigationLinks.on('click', function(e){
e.preventDefault();
disableOnScrollEvent = true;
// scroll to anchor
scrollspyElement.mCustomScrollbar('scrollTo', $(this).attr('data-target'));
let mainNavigationLiElement = $(this).parent('.' + config.dialogNavigationListItemClass);
whileScrolling();
// if link is a main navigation link (not an anchor link)
if(mainNavigationLiElement.length > 0){
// remove all active classes
scrollNavLiElements.removeClass('active');
// set new active class
$(this).parent().addClass('active');
}
});
},
onScroll: function(){
disableOnScrollEvent = false;
whileScrolling();
},
whileScrolling: whileScrolling
},
mouseWheel:{
enable: true,
scrollAmount: 200,
axis: 'y',
preventDefault: true // do not scroll parent at the end
},
scrollbarPosition: 'outsite',
autoDraggerLength: true
});
});
};
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,794 +0,0 @@
/**
* map settings dialogs
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox',
'app/map/util',
'app/module_map'
], ($, Init, Util, Render, bootbox, MapUtil, ModuleMap) => {
'use strict';
let config = {
// map dialog
newMapDialogId: 'pf-map-dialog', // id for map settings dialog
dialogMapCreateContainerId: 'pf-map-dialog-create', // id for the "new map" container
dialogMapEditContainerId: 'pf-map-dialog-edit', // id for the "edit" container
dialogMapSettingsContainerId: 'pf-map-dialog-settings', // id for the "settings" container
dialogMapDownloadContainerId: 'pf-map-dialog-download', // id for the "download" container
deleteExpiredConnectionsId: 'pf-map-dialog-delete-connections-expired', // id for "deleteExpiredConnections" checkbox
deleteEolConnectionsId: 'pf-map-dialog-delete-connections-eol', // id for "deleteEOLConnections" checkbox
persistentAliasesId: 'pf-map-dialog-persistent-aliases', // id for "persistentAliases" checkbox
logHistoryId: 'pf-map-dialog-history', // id for "history logging" checkbox
logActivityId: 'pf-map-dialog-activity', // id for "activity" checkbox
slackWebHookURLId: 'pf-map-dialog-slack-url', // id for Slack "webHookUrl"
slackUsernameId: 'pf-map-dialog-slack-username', // id for Slack "username"
slackIconId: 'pf-map-dialog-slack-icon', // id for Slack "icon"
slackChannelHistoryId: 'pf-map-dialog-slack-channel-history', // id for Slack channel "history"
slackChannelRallyId: 'pf-map-dialog-slack-channel-rally', // id for Slack channel "rally"
discordUsernameId: 'pf-map-dialog-discord-username', // id for Discord "username"
discordWebHookURLRallyId: 'pf-map-dialog-discord-url-rally', // id for Discord "rally" webHookUrl
discordWebHookURLHistoryId: 'pf-map-dialog-discord-url-history', // id for Discord "history" webHookUrl
characterSelectId: 'pf-map-dialog-character-select', // id for "character" select
corporationSelectId: 'pf-map-dialog-corporation-select', // id for "corporation" select
allianceSelectId: 'pf-map-dialog-alliance-select', // id for "alliance" select
dialogMapExportFormId: 'pf-map-dialog-form-export', // id for "export" form
dialogMapImportFormId: 'pf-map-dialog-form-import', // id for "import" form
buttonExportId: 'pf-map-dialog-button-export', // id for "export" button
buttonImportId: 'pf-map-dialog-button-import', // id for "import" button
fieldExportId: 'pf-map-filename-export', // id for "export" filename field
fieldImportId: 'pf-map-filename-import', // id for "import" filename field
dialogMapImportInfoId: 'pf-map-import-container', // id for "info" container
dragDropElementClass: 'pf-form-dropzone' // class for "drag&drop" zone
};
/**
* format a given string into a valid filename
* @param filename
* @returns {string}
*/
let formatFilename = function(filename){
filename = filename.replace(/[^a-zA-Z0-9]/g,'_');
let nowDate = new Date();
let filenameDate = nowDate.toISOString().slice(0,10).replace(/-/g, '_');
return (filename + '_' + filenameDate).replace(/__/g,'_');
};
/**
* shows the add/edit map dialog
* @param mapData
* @param options
*/
$.fn.showMapSettingsDialog = function(mapData, options){
// check if dialog is already open
let mapInfoDialogElement = $('#' + config.newMapDialogId);
if(!mapInfoDialogElement.is(':visible')){
requirejs([
'text!templates/dialog/map.html',
'text!templates/form/map.html',
'mustache'
], (templateMapDialog, templateMapForm, Mustache) => {
let dialogTitle = 'Map settings';
// if there are no maps -> hide settings tab
let hideSettingsTab = false;
let hideEditTab = false;
let hideDownloadTab = false;
let hasRightMapCreate = true;
let hasRightMapUpdate = true;
let hasRightMapExport = true;
let hasRightMapImport = true;
if(mapData === false){
hideSettingsTab = true;
hideEditTab = true;
hideDownloadTab = true;
}else{
hasRightMapUpdate = MapUtil.checkRight('map_update', mapData.config);
hasRightMapExport = MapUtil.checkRight('map_export', mapData.config);
hasRightMapImport = MapUtil.checkRight('map_import', mapData.config);
}
// available map "types" for a new or existing map
let mapTypes = MapUtil.getMapTypes(true);
let mapFormData = {
scope: MapUtil.getMapScopes(),
type: mapTypes,
icon: MapUtil.getMapIcons(),
formErrorContainerClass: Util.config.formErrorContainerClass,
formWarningContainerClass: Util.config.formWarningContainerClass,
formInfoContainerClass: Util.config.formInfoContainerClass
};
// render "new map" tab content -----------------------------------------------------------------------
let mapFormDataNew = $.extend({}, mapFormData, {
hasRightMapForm: hasRightMapCreate
});
let contentNewMap = Mustache.render(templateMapForm, mapFormDataNew);
// render "edit map" tab content ----------------------------------------------------------------------
let mapFormDataEdit = $.extend({}, mapFormData, {
hasRightMapForm: hasRightMapUpdate
});
let contentEditMap = Mustache.render(templateMapForm, mapFormDataEdit);
contentEditMap = $(contentEditMap);
// current map access info
let accessCharacter = [];
let accessCorporation = [];
let accessAlliance = [];
let deleteExpiredConnections = true;
let deleteEolConnections = true;
let persistentAliases = true;
let logActivity = true;
let logHistory = true;
let slackWebHookURL = '';
let slackUsername = '';
let slackIcon = '';
let slackChannelHistory = '';
let slackChannelRally = '';
let slackEnabled = false;
let slackHistoryEnabled = false;
let slackRallyEnabled = false;
let slackSectionShow = false;
let discordUsername = '';
let discordWebHookURLRally = '';
let discordWebHookURLHistory = '';
let discordEnabled = false;
let discordRallyEnabled = false;
let discordHistoryEnabled = false;
let discordSectionShow = false;
if(mapData !== false){
// set current map information
contentEditMap.find('input[name="id"]').val( mapData.config.id );
contentEditMap.find('select[name="icon"]').val( mapData.config.icon );
contentEditMap.find('input[name="name"]').val( mapData.config.name );
contentEditMap.find('select[name="scopeId"]').val( mapData.config.scope.id );
contentEditMap.find('select[name="typeId"]').val( mapData.config.type.id );
accessCharacter = mapData.config.access.character;
accessCorporation = mapData.config.access.corporation;
accessAlliance = mapData.config.access.alliance;
deleteExpiredConnections = mapData.config.deleteExpiredConnections;
deleteEolConnections = mapData.config.deleteEolConnections;
persistentAliases = mapData.config.persistentAliases;
logActivity = mapData.config.logging.activity;
logHistory = mapData.config.logging.history;
slackWebHookURL = mapData.config.logging.slackWebHookURL;
slackUsername = mapData.config.logging.slackUsername;
slackIcon = mapData.config.logging.slackIcon;
slackChannelHistory = mapData.config.logging.slackChannelHistory;
slackChannelRally = mapData.config.logging.slackChannelRally;
slackEnabled = Boolean(Util.getObjVal(Init, 'slack.status'));
slackHistoryEnabled = slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_slack_enabled'));
slackRallyEnabled = slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_slack_enabled'));
slackSectionShow = (slackEnabled && slackWebHookURL.length > 0);
discordUsername = Util.getObjVal(mapData, 'config.logging.discordUsername');
discordWebHookURLRally = Util.getObjVal(mapData, 'config.logging.discordWebHookURLRally');
discordWebHookURLHistory = Util.getObjVal(mapData, 'config.logging.discordWebHookURLHistory');
discordEnabled = Boolean(Util.getObjVal(Init, 'discord.status'));
discordRallyEnabled = discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_discord_enabled'));
discordHistoryEnabled = discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_discord_enabled'));
discordSectionShow = (discordEnabled && (discordWebHookURLRally.length > 0 || discordWebHookURLHistory.length > 0));
// remove "#" from Slack channels
slackChannelHistory = slackChannelHistory.indexOf('#') === 0 ? slackChannelHistory.substr(1) : slackChannelHistory;
slackChannelRally = slackChannelRally.indexOf('#') === 0 ? slackChannelRally.substr(1) : slackChannelRally;
}
// render main dialog ---------------------------------------------------------------------------------
let mapDialogData = {
id: config.newMapDialogId,
mapData: mapData,
type: mapTypes,
// message container
formErrorContainerClass: Util.config.formErrorContainerClass,
formWarningContainerClass: Util.config.formWarningContainerClass,
formInfoContainerClass: Util.config.formInfoContainerClass,
// default open tab ----------
openTabNew: options.tab === 'new',
openTabEdit: options.tab === 'edit',
openTabSettings: options.tab === 'settings',
openTabDownload: options.tab === 'download',
dialogMapCreateContainerId: config.dialogMapCreateContainerId,
dialogMapEditContainerId: config.dialogMapEditContainerId,
dialogMapSettingsContainerId: config.dialogMapSettingsContainerId,
dialogMapDownloadContainerId: config.dialogMapDownloadContainerId,
hideEditTab: hideEditTab,
hideSettingsTab: hideSettingsTab,
hideDownloadTab: hideDownloadTab,
// settings tab --------------
deleteExpiredConnectionsId : config.deleteExpiredConnectionsId,
deleteEolConnectionsId : config.deleteEolConnectionsId,
persistentAliasesId : config.persistentAliasesId,
deleteExpiredConnections: deleteExpiredConnections,
deleteEolConnections: deleteEolConnections,
persistentAliases: persistentAliases,
logHistoryId: config.logHistoryId,
logActivityId: config.logActivityId,
logActivity: logActivity,
logHistory: logHistory,
slackWebHookURLId: config.slackWebHookURLId,
slackUsernameId: config.slackUsernameId,
slackIconId: config.slackIconId,
slackChannelHistoryId: config.slackChannelHistoryId,
slackChannelRallyId: config.slackChannelRallyId,
slackWebHookURL: slackWebHookURL,
slackUsername: slackUsername,
slackIcon: slackIcon,
slackChannelHistory: slackChannelHistory,
slackChannelRally: slackChannelRally,
slackEnabled: slackEnabled,
slackHistoryEnabled: slackHistoryEnabled,
slackRallyEnabled: slackRallyEnabled,
slackSectionShow: slackSectionShow,
discordUsernameId: config.discordUsernameId,
discordWebHookURLRallyId: config.discordWebHookURLRallyId,
discordWebHookURLHistoryId: config.discordWebHookURLHistoryId,
discordUsername: discordUsername,
discordWebHookURLRally: discordWebHookURLRally,
discordWebHookURLHistory: discordWebHookURLHistory,
discordEnabled: discordEnabled,
discordRallyEnabled: discordRallyEnabled,
discordHistoryEnabled: discordHistoryEnabled,
discordSectionShow: discordSectionShow,
characterSelectId: config.characterSelectId,
corporationSelectId: config.corporationSelectId,
allianceSelectId: config.allianceSelectId,
// map access objects --------
accessCharacter: accessCharacter,
accessCorporation: accessCorporation,
accessAlliance: accessAlliance,
// access limitations --------
maxCharacter: Init.mapTypes.private.defaultConfig.max_shared,
maxCorporation: Init.mapTypes.corporation.defaultConfig.max_shared,
maxAlliance: Init.mapTypes.alliance.defaultConfig.max_shared,
// download tab --------------
dialogMapExportFormId: config.dialogMapExportFormId,
dialogMapImportFormId: config.dialogMapImportFormId,
buttonExportId: config.buttonExportId,
buttonImportId: config.buttonImportId,
fieldExportId: config.fieldExportId,
fieldImportId: config.fieldImportId,
dialogMapImportInfoId: config.dialogMapImportInfoId,
hasRightMapUpdate: hasRightMapUpdate,
hasRightMapExport: hasRightMapExport,
hasRightMapImport: hasRightMapImport,
formatFilename: function(){
// format filename from "map name" (initial)
return function (mapName, render) {
let filename = render(mapName);
return formatFilename(filename);
};
}
};
let contentDialog = Mustache.render(templateMapDialog, mapDialogData);
contentDialog = $(contentDialog);
// set tab content
$('#' + config.dialogMapCreateContainerId, contentDialog).html(contentNewMap);
$('#' + config.dialogMapEditContainerId, contentDialog).html(contentEditMap);
let mapInfoDialog = bootbox.dialog({
title: dialogTitle,
message: contentDialog,
buttons: {
close: {
label: 'cancel',
className: 'btn-default'
},
success: {
label: '<i class="fas fa-check fa-fw"></i>&nbsp;save',
className: 'btn-success',
callback: function() {
// get the current active form
let form = $('#' + config.newMapDialogId).find('form').filter(':visible');
// validate form
form.validator('validate');
// validate select2 fields (settings tab)
form.find('select').each(function(){
let selectField = $(this);
let selectValues = selectField.val();
if(selectValues && selectValues.length > 0){
selectField.parents('.form-group').removeClass('has-error');
}else{
selectField.parents('.form-group').addClass('has-error');
}
});
// check whether the form is valid
let formValid = form.isValidForm();
if(formValid === true){
// lock dialog
let dialogContent = mapInfoDialog.find('.modal-content');
dialogContent.showLoadingAnimation();
// get form data
let formData = form.getFormValues();
// add value prefixes (Slack channels)
let tmpVal;
if(typeof (tmpVal = Util.getObjVal(formData, 'slackChannelHistory')) === 'string' && tmpVal.length){
formData.slackChannelHistory = '#' + tmpVal;
}
if(typeof (tmpVal = Util.getObjVal(formData, 'slackChannelRally')) === 'string' && tmpVal.length){
formData.slackChannelRally = '#' + tmpVal;
}
// checkbox fix -> settings tab
if( form.find('#' + config.deleteExpiredConnectionsId).length ){
formData.deleteExpiredConnections = formData.hasOwnProperty('deleteExpiredConnections') ? parseInt( formData.deleteExpiredConnections ) : 0;
}
if( form.find('#' + config.deleteEolConnectionsId).length ){
formData.deleteEolConnections = formData.hasOwnProperty('deleteEolConnections') ? parseInt( formData.deleteEolConnections ) : 0;
}
if( form.find('#' + config.persistentAliasesId).length ){
formData.persistentAliases = formData.hasOwnProperty('persistentAliases') ? parseInt( formData.persistentAliases ) : 0;
}
if( form.find('#' + config.persistentAliasesId).length ){
formData.persistentAliases = formData.hasOwnProperty('persistentAliases') ? parseInt( formData.persistentAliases ) : 0;
}
if( form.find('#' + config.logHistoryId).length ){
formData.logHistory = formData.hasOwnProperty('logHistory') ? parseInt( formData.logHistory ) : 0;
}
if( form.find('#' + config.logActivityId).length ){
formData.logActivity = formData.hasOwnProperty('logActivity') ? parseInt( formData.logActivity ) : 0;
}
let requestData = {formData: formData};
$.ajax({
type: 'POST',
url: Init.path.saveMap,
data: requestData,
dataType: 'json'
}).done(function(responseData){
if(responseData.error.length){
form.showFormMessage(responseData.error);
}else{
// success
Util.showNotify({title: dialogTitle, text: 'Map: ' + responseData.mapData.mapData.name, type: 'success'});
// update map-tab Element
let tabLinkElement = Util.getMapModule().getMapTabElements(responseData.mapData.mapData.id);
if(tabLinkElement.length === 1){
ModuleMap.updateTabData(tabLinkElement, responseData.mapData.mapData);
}
$(mapInfoDialog).modal('hide');
$(document).trigger('pf:closeMenu', [{}]);
}
}).fail(function( jqXHR, status, error) {
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': saveMap', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
}).always(function() {
dialogContent.hideLoadingAnimation();
});
}
return false;
}
}
}
});
// after modal is shown ===============================================================================
mapInfoDialog.on('shown.bs.modal', function(e){
mapInfoDialog.initTooltips();
// manually trigger the "show" event for the initial active tab (not triggered by default...)
mapInfoDialog.find('.navbar li.active a[data-toggle=tab]').trigger('shown.bs.tab');
// prevent "disabled" tabs from being clicked... "bootstrap" bugFix...
mapInfoDialog.find('.navbar a[data-toggle=tab]').on('click', function(e){
if ($(this).hasClass('disabled')){
e.preventDefault();
return false;
}
});
// set form validator
mapInfoDialog.find('form').initFormValidation();
// show form messages -------------------------------------
// get current active form(tab)
let form = $('#' + config.newMapDialogId).find('form').filter(':visible');
form.showFormMessage([{type: 'info', message: 'Creating new maps or change settings may take a few seconds'}]);
if(mapData === false){
// no map data found (probably new user
form.showFormMessage([{type: 'warning', message: 'No maps found. Create a new map before you can start'}]);
}
// init "download tab" ============================================================================
let downloadTabElement = mapInfoDialog.find('#' + config.dialogMapDownloadContainerId);
if(downloadTabElement.length){
// tab exists
// export map data ----------------------------------------------------------------------------
downloadTabElement.find('#' + config.buttonExportId).on('click', { mapData: mapData }, function(e){
let exportForm = $('#' + config.dialogMapExportFormId);
let validExportForm = exportForm.isValidForm();
if(validExportForm){
let mapElement = Util.getMapModule().getActiveMap();
if(mapElement){
// IMPORTANT: Get map data from client (NOT from global mapData which is available in here)
// -> This excludes some data (e.g. wh statics)
// -> Bring export inline with main map toggle requests
let exportMapData = mapElement.getMapDataFromClient({
forceData: true,
getAll: true
});
// set map data right before download
$(this).setExportMapData(exportMapData);
// disable button
$(this).attr('disabled', true);
}else{
console.error('Map not found');
}
}else{
e.preventDefault();
}
});
// import map data ----------------------------------------------------------------------------
// check if "FileReader" API is supported
let importFormElement = downloadTabElement.find('#' + config.dialogMapImportFormId);
if(window.File && window.FileReader && window.FileList && window.Blob){
// show file info in UI
downloadTabElement.find('#' + config.fieldImportId).on('change', function(e){
e.stopPropagation();
e.preventDefault();
let infoContainerElement = importFormElement.find('#' + config.dialogMapImportInfoId);
infoContainerElement.hide().empty();
importFormElement.hideFormMessage('all');
let output = [];
let files = e.target.files;
for (let i = 0, f; !!(f = files[i]); i++) {
output.push(( i + 1 ) + '. file: ' + f.name + ' - ' +
f.size + ' bytes; last modified: ' +
f.lastModifiedDate.toLocaleDateString() );
}
if(output.length > 0){
infoContainerElement.html( output ).show();
}
importFormElement.validator('validate');
});
// drag&drop
let importData = {};
importData.mapData = [];
let files = [];
let filesCount = 0;
let filesCountFail = 0;
// onLoad for FileReader API
let readerOnLoad = function(readEvent) {
// get file content
try{
importData.mapData.push( JSON.parse( readEvent.target.result ) );
}catch(error){
filesCountFail++;
importFormElement.showFormMessage([{type: 'error', message: 'File can not be parsed'}]);
}
// start import when all files are parsed
if(
filesCount === files.length &&
filesCountFail === 0
){
importMaps(importData, () => {
mapInfoDialog.modal('hide');
});
}
};
let handleDragOver = function(dragEvent) {
dragEvent.stopPropagation();
dragEvent.preventDefault();
dragEvent.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
};
let handleFileSelect = function(evt){
evt.stopPropagation();
evt.preventDefault();
importData = importFormElement.getFormValues();
importData.mapData = [];
filesCount = 0;
filesCountFail = 0;
files = evt.dataTransfer.files; // FileList object.
for (let file; !!(file = files[filesCount]); filesCount++){
let reader = new FileReader();
reader.onload = readerOnLoad;
reader.readAsText(file);
}
};
let dropZone = downloadTabElement.find('.' + config.dragDropElementClass);
if(dropZone.length){
dropZone[0].addEventListener('dragover', handleDragOver, false);
dropZone[0].addEventListener('drop', handleFileSelect, false);
}
// import "button"
downloadTabElement.find('#' + config.buttonImportId).on('click', function(e) {
importFormElement.validator('validate');
let validImportForm = importFormElement.isValidForm();
if(validImportForm){
importData = importFormElement.getFormValues();
importData.mapData = [];
let fileElement = downloadTabElement.find('#' + config.fieldImportId);
files = fileElement[0].files;
filesCount = 0;
filesCountFail = 0;
for (let file; !!(file = files[filesCount]); filesCount++){
let reader = new FileReader();
reader.onload = readerOnLoad;
reader.readAsText(file);
}
}
});
}else{
importFormElement.showFormMessage([{type: 'error', message: 'The File APIs are not fully supported in this browser.'}]);
}
}
});
// events for tab change ------------------------------------------------------------------------------
mapInfoDialog.find('.navbar a').on('shown.bs.tab', function(e){
let modalDialog = mapInfoDialog.find('div.modal-dialog');
let tabContentId = $(e.target).attr('href');
let tabContentForms = $(tabContentId).find('form.form-horizontal');
let selectElementCharacter = mapInfoDialog.find('#' + config.characterSelectId);
let selectElementCorporation = mapInfoDialog.find('#' + config.corporationSelectId);
let selectElementAlliance = mapInfoDialog.find('#' + config.allianceSelectId);
if(tabContentId === '#' + config.dialogMapSettingsContainerId){
// "settings" tab -> resize modal
modalDialog.toggleClass('modal-lg', true);
initSettingsSelectFields(mapInfoDialog);
}else{
// resize modal
modalDialog.toggleClass('modal-lg', false);
if( $(selectElementCharacter).data('select2') !== undefined ){
$(selectElementCharacter).select2('destroy');
}
if( $(selectElementCorporation).data('select2') !== undefined ){
$(selectElementCorporation).select2('destroy');
}
if( $(selectElementAlliance).data('select2') !== undefined ){
$(selectElementAlliance).select2('destroy');
}
}
// no "save" dialog button on "in/export" tab
if(
tabContentId === '#' + config.dialogMapDownloadContainerId || // no "save" dialog button on "in/export" tab
!tabContentForms.length // no <form> in tab (e.g. restricted by missing right)
){
mapInfoDialog.find('button.btn-success').hide();
}else{
mapInfoDialog.find('button.btn-success').show();
}
});
});
}
};
/**
* import new map(s) data
* @param importData
*/
let importMaps = (importData, callback) => {
let importForm = $('#' + config.dialogMapImportFormId);
importForm.hideFormMessage('all');
// lock dialog
let dialogContent = importForm.parents('.modal-content');
dialogContent.showLoadingAnimation();
$.ajax({
type: 'POST',
url: Init.path.importMap,
data: importData,
dataType: 'json'
}).done(function(responseData){
if(responseData.error.length){
// form.showFormMessage(responseData.error);
importForm.showFormMessage(responseData.error);
}else{
// success
if(responseData.warning.length){
importForm.showFormMessage(responseData.warning);
}
if(callback){
callback();
}
Util.showNotify({title: 'Import finished', text: 'Map(s) imported', type: 'success'});
}
}).fail(function( jqXHR, status, error) {
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': importMap', text: reason, type: 'error'});
}).always(function() {
importForm.find('input, select').resetFormFields().trigger('change');
dialogContent.hideLoadingAnimation();
});
};
/**
* set json map data for export to an element (e.g. <a>-Tag or button) for download
* @param mapData
* @returns {*}
*/
$.fn.setExportMapData = function(mapData){
let fieldExport = $('#' + config.fieldExportId);
let filename = '';
let mapDataEncoded = '';
if(fieldExport.length){
filename = fieldExport.val();
if(filename.length > 0){
mapDataEncoded = 'text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify( mapData ));
}
}
return this.each(function(){
let exportButton = $(this);
exportButton.attr('href', 'data:' + mapDataEncoded);
exportButton.attr('download', filename + '.json');
});
};
/**
* init select2 fields within the settings dialog
* @param mapInfoDialog
*/
let initSettingsSelectFields = function(mapInfoDialog){
let selectElementCharacter = mapInfoDialog.find('#' + config.characterSelectId);
let selectElementCorporation = mapInfoDialog.find('#' + config.corporationSelectId);
let selectElementAlliance = mapInfoDialog.find('#' + config.allianceSelectId);
// init character select live search
selectElementCharacter.initAccessSelect({
type: 'character',
maxSelectionLength: Init.mapTypes.private.defaultConfig.max_shared
});
// init corporation select live search
selectElementCorporation.initAccessSelect({
type: 'corporation',
maxSelectionLength: Init.mapTypes.corporation.defaultConfig.max_shared
});
// init alliance select live search
selectElementAlliance.initAccessSelect({
type: 'alliance',
maxSelectionLength: Init.mapTypes.alliance.defaultConfig.max_shared
});
};
/**
* shows the delete map Dialog
* @param mapData
*/
$.fn.showDeleteMapDialog = function(mapData){
let mapName = mapData.config.name;
let mapNameStr = '<span class="txt-color txt-color-danger">' + mapName + '</span>';
let mapDeleteDialog = bootbox.confirm({
message: 'Delete map "' + mapNameStr + '"?',
buttons: {
confirm: {
label: '<i class="fas fa-trash fa-fw"></i>&nbsp;delete map',
className: 'btn-danger'
}
},
callback: function(result){
if(result){
let data = {mapData: mapData.config};
$.ajax({
type: 'POST',
url: Init.path.deleteMap,
data: data,
dataType: 'json'
}).done(function(data){
Util.showNotify({title: 'Map deleted', text: 'Map: ' + mapName, type: 'success'});
}).fail(function( jqXHR, status, error) {
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': deleteMap', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
}).always(function() {
$(mapDeleteDialog).modal('hide');
});
return false;
}
}
});
};
});

View File

@@ -1,88 +0,0 @@
/**
* notification dialog
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox'
], function($, Init, Util, Render, bootbox) {
'use strict';
let config = {
// shutdown dialog
notificationDialogId: 'pf-notification-dialog', // id for "notification" dialog
notificationDialogClass: 'pf-notification-dialog' // class for "notification" dialog
};
/**
* show/animate dialog page content
* @param dialog
*/
let showPageContent = function(dialog){
let headlineElement = dialog.find('h1');
headlineElement.delay(300).velocity('transition.shrinkIn', {
duration: 500
}).delay(800);
headlineElement.velocity({
scale: 1.05
}, {
duration: 600,
loop: 5
});
};
/**
* show "notification" dialog
* @param dialogData
*/
$.fn.showNotificationDialog = function(dialogData){
// check if there is already a notification dialog open
let notificationDialogClassDialoges = $('.' + config.notificationDialogClass);
if(notificationDialogClassDialoges.length === 0){
// close all modals
$('.modal').modal('hide');
requirejs(['text!templates/dialog/notification.html', 'mustache'], function(template, Mustache) {
let data = {
id: config.notificationDialogId,
content: dialogData.content
};
let content = Mustache.render(template, data);
// show dialog
let shutdownDialog = bootbox.dialog({
title: dialogData.content.title,
message: content,
className: config.notificationDialogClass,
buttons: dialogData.buttons
});
shutdownDialog.on('shown.bs.modal', function(e) {
// remove close button
let dialog = $(this);
dialog.find('.bootbox-close-button').remove();
dialog.find('button').blur();
// show error message
showPageContent(dialog);
});
});
}
};
});

View File

@@ -1,50 +0,0 @@
/**
* shortcuts dialog
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox',
'app/key',
], function($, Init, Util, Render, bootbox, Key) {
'use strict';
let config = {
// map dialog
shortcutsDialogId: 'pf-shortcuts-dialog', // id for shortcuts dialog
};
/**
* shows the map manual modal dialog
*/
$.fn.showShortcutsDialog = function(){
requirejs(['text!templates/dialog/shortcuts.html', 'mustache'], function(template, Mustache){
let data = {
id: config.shortcutsDialogId,
shortcuts: Key.getGroupedShortcuts()
};
let content = Mustache.render(template, data);
// show dialog
let shortcutsDialog = bootbox.dialog({
title: 'Keyboard Shortcuts',
message: content,
size: 'large',
buttons: {
success: {
label: 'close',
className: 'btn-default'
}
},
show: true
});
});
};
});

View File

@@ -1,838 +0,0 @@
/**
* activity stats dialog
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox',
'peityInlineChart'
], function($, Init, Util, Render, bootbox) {
'use strict';
let config = {
// dialog
statsDialogId: 'pf-stats-dialog', // id for "stats" dialog
dialogNavigationClass: 'pf-dialog-navigation-list', // class for dialog navigation bar
dialogNavigationListItemClass: 'pf-dialog-navigation-list-item', // class for map manual li main navigation elements
dialogNavigationOffsetClass : 'pf-dialog-navigation-offset', // class for "current" offset filter
dialogNavigationPrevClass : 'pf-dialog-navigation-prev', // class for "prev" period load
dialogNavigationNextClass : 'pf-dialog-navigation-next', // class for "next" period load
// stats/dataTable
statsContainerId: 'pf-stats-dialog-container', // class for statistics container (dynamic ajax content)
statsTableId: 'pf-stats-table', // id for statistics table element
tableCellImageClass: 'pf-table-image-cell', // class for table "image" cells
// charts
statsLineChartClass: 'pf-line-chart' // class for inline chart elements
};
/**
* init blank statistics dataTable
* @param dialogElement
*/
let initStatsTable = function(dialogElement){
let columnNumberWidth = 28;
let cellPadding = 4;
let lineChartWidth = columnNumberWidth + (2 * cellPadding);
let lineColor = '#477372';
// render function for inline-chart columns
let renderInlineChartColumn = function(data, type, row, meta){
/*
switch(data.type){
case 'C': lineColor = '#5cb85c'; break;
case 'U': lineColor = '#e28a0d'; break;
case 'D': lineColor = '#a52521'; break;
}*/
if( /^\d+$/.test(data.data) ){
// single digit (e.g. single week filter)
return data.data;
}else{
// period -> prepare line chart
return '<span class="' + config.statsLineChartClass + '" data-peity=\'{ "stroke": "' + lineColor + '" }\'>' + data.data + '</span>';
}
};
// render function for numeric columns
let renderNumericColumn = function(data, type, row, meta){
let value = data;
if(type === 'display'){
value = data.toLocaleString();
}
return value;
};
// get table element
// Due to "complex" table headers, they are already rendered and part of the stats.html file
let table = dialogElement.find('#' + config.statsTableId);
let statsTable = table.DataTable({
pageLength: 30,
lengthMenu: [[10, 20, 30, 50], [10, 20, 30, 50]],
paging: true,
ordering: true,
order: [ 20, 'desc' ],
info: true,
searching: true,
hover: false,
autoWidth: false,
language: {
emptyTable: 'No statistics found',
zeroRecords: 'No characters found',
lengthMenu: 'Show _MENU_ characters',
info: 'Showing _START_ to _END_ of _TOTAL_ characters'
},
columnDefs: [
{
targets: 0,
title: '<i class="fas fa-hashtag"></i>',
orderable: false,
searchable: false,
width: 10,
class: 'text-right',
data: 'character.id'
},{
targets: 1,
title: '',
orderable: false,
searchable: false,
width: 26,
className: ['text-center', config.tableCellImageClass].join(' '),
data: 'character',
render: {
_: function(data, type, row, meta){
return '<img src="' + Init.url.ccpImageServer + '/Character/' + data.id + '_32.jpg" />';
}
}
},{
targets: 2,
title: 'name',
width: 200,
data: 'character',
render: {
_: 'name',
sort: 'name'
}
},{
targets: 3,
title: 'last login',
searchable: false,
width: 70,
className: ['text-right', 'separator-right'].join(' '),
data: 'character',
render: {
_: 'lastLogin',
sort: 'lastLogin'
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
$(cell).initTimestampCounter();
}
},{
targets: 4,
title: '<span title="created" data-toggle="tooltip">C&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'mapCreate',
render: {
_: renderInlineChartColumn
}
},{
targets: 5,
title: '<span title="updated" data-toggle="tooltip">U&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'mapUpdate',
render: {
_: renderInlineChartColumn
}
},{
targets: 6,
title: '<span title="deleted" data-toggle="tooltip">D&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'mapDelete',
render: {
_: renderInlineChartColumn
}
},{
targets: 7,
title: 'Σ&nbsp;&nbsp;',
searchable: false,
width: 20,
className: ['text-right', 'separator-right'].join(' ') ,
data: 'mapSum',
render: {
_: renderNumericColumn
}
},{
targets: 8,
title: '<span title="created" data-toggle="tooltip">C&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'systemCreate',
render: {
_: renderInlineChartColumn
}
},{
targets: 9,
title: '<span title="updated" data-toggle="tooltip">U&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'systemUpdate',
render: {
_: renderInlineChartColumn
}
},{
targets: 10,
title: '<span title="deleted" data-toggle="tooltip">D&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'systemDelete',
render: {
_: renderInlineChartColumn
}
},{
targets: 11,
title: 'Σ&nbsp;&nbsp;',
searchable: false,
width: 20,
className: ['text-right', 'separator-right'].join(' ') ,
data: 'systemSum',
render: {
_: renderNumericColumn
}
},{
targets: 12,
title: '<span title="created" data-toggle="tooltip">C&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'connectionCreate',
render: {
_: renderInlineChartColumn
}
},{
targets: 13,
title: '<span title="updated" data-toggle="tooltip">U&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'connectionUpdate',
render: {
_: renderInlineChartColumn
}
},{
targets: 14,
title: '<span title="deleted" data-toggle="tooltip">D&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'connectionDelete',
render: {
_: renderInlineChartColumn
}
},{
targets: 15,
title: 'Σ&nbsp;&nbsp;',
searchable: false,
width: 20,
className: ['text-right', 'separator-right'].join(' '),
data: 'connectionSum',
render: {
_: renderNumericColumn
}
},{
targets: 16,
title: '<span title="created" data-toggle="tooltip">C&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'signatureCreate',
render: {
_: renderInlineChartColumn
}
},{
targets: 17,
title: '<span title="updated" data-toggle="tooltip">U&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'signatureUpdate',
render: {
_: renderInlineChartColumn
}
},{
targets: 18,
title: '<span title="deleted" data-toggle="tooltip">D&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'signatureDelete',
render: {
_: renderInlineChartColumn
}
},{
targets: 19,
title: 'Σ&nbsp;&nbsp;',
searchable: false,
width: 20,
className: ['text-right', 'separator-right'].join(' '),
data: 'signatureSum',
render: {
_: renderNumericColumn
}
},{
targets: 20,
title: 'Σ&nbsp;&nbsp;',
searchable: false,
width: 20,
className: 'text-right',
data: 'totalSum',
render: {
_: renderNumericColumn
}
}
],
initComplete: function(settings){
let tableApi = this.api();
// initial statistics data request
let requestData = getRequestDataFromTabPanels(dialogElement);
getStatsData(requestData, {tableApi: tableApi, callback: drawStatsTable});
},
drawCallback: function(settings){
this.api().rows().nodes().to$().each(function(i, row){
$($(row).find('.' + config.statsLineChartClass)).peity('line', {
fill: 'transparent',
height: 18,
min: 0,
width: lineChartWidth
});
});
},
footerCallback: function ( row, data, start, end, display ) {
let api = this.api();
let sumColumnIndexes = [7, 11, 15, 19, 20];
// column data for "sum" columns over this page
let pageTotalColumns = api
.columns( sumColumnIndexes, { page: 'current'} )
.data();
// sum columns for "total" sum
pageTotalColumns.each(function(colData, index){
pageTotalColumns[index] = colData.reduce(function(a, b){
return a + b;
}, 0);
});
$(sumColumnIndexes).each(function(index, value){
$( api.column( value ).footer() ).text( renderNumericColumn(pageTotalColumns[index], 'display') );
});
},
data: [] // will be added dynamic
});
statsTable.on('order.dt search.dt', function(){
statsTable.column(0, {search:'applied', order:'applied'}).nodes().each(function(cell, i){
let rowCount = i + 1;
let content = '';
switch(rowCount){
case 1: content = '<i class="fas fa-fw fa-trophy txt-color txt-color-gold"></i>'; break;
case 2: content = '<i class="fas fa-fw fa-trophy txt-color txt-color-silver"></i>'; break;
case 3: content = '<i class="fas fa-fw fa-trophy txt-color txt-color-bronze"></i>'; break;
default: content = rowCount + '.&nbsp;&nbsp;';
}
$(cell).html(content);
});
}).draw();
let tooltipElements = dialogElement.find('[data-toggle="tooltip"]');
tooltipElements.tooltip();
};
/**
* request raw statistics data and execute callback
* @param requestData
* @param context
*/
let getStatsData = function(requestData, context){
context.dynamicArea = $('#' + config.statsContainerId + ' .pf-dynamic-area');
context.dynamicArea.showLoadingAnimation();
$.ajax({
type: 'POST',
url: Init.path.getStatisticsData,
data: requestData,
dataType: 'json',
context: context
}).done(function(data){
this.dynamicArea.hideLoadingAnimation();
this.callback(data);
}).fail(function( jqXHR, status, error) {
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': loadStatistics', text: reason, type: 'warning'});
});
};
/**
* update dataTable with response data
* update "header"/"filter" elements in dialog
* @param responseData
*/
let drawStatsTable = function(responseData){
let dialogElement = $('#' + config.statsDialogId);
// update filter/header -----------------------------------------------------------------------------
let navigationListElements = $('.' + config.dialogNavigationClass);
navigationListElements.find('a[data-type="typeId"][data-value="' + responseData.typeId + '"]').tab('show');
navigationListElements.find('a[data-type="period"][data-value="' + responseData.period + '"]').tab('show');
// update period pagination -------------------------------------------------------------------------
let prevButton = dialogElement.find('.' + config.dialogNavigationPrevClass);
prevButton.data('newOffset', responseData.prev);
prevButton.find('span').text('Week ' + responseData.prev.week + ', ' + responseData.prev.year);
prevButton.css('visibility', 'visible');
let nextButton = dialogElement.find('.' + config.dialogNavigationNextClass);
if(responseData.next){
nextButton.data('newOffset', responseData.next);
nextButton.find('span').text('Week ' + responseData.next.week + ', ' + responseData.next.year);
nextButton.css('visibility', 'visible');
}else{
nextButton.css('visibility', 'hidden');
}
// update current period information label ----------------------------------------------------------
// if period == "weekly" there is no "offset" -> just a single week
let offsetText = 'Week ' + responseData.start.week + ', ' + responseData.start.year;
if(responseData.period !== 'weekly'){
offsetText += ' <small><i class="fas fa-fw fa-minus"></i></small> ' +
'Week ' + responseData.offset.week + ', ' + responseData.offset.year;
}
dialogElement.find('.' + config.dialogNavigationOffsetClass)
.data('start', responseData.start)
.data('period', responseData.period)
.html(offsetText);
// clear and (re)-fill table ------------------------------------------------------------------------
let formattedData = formatStatisticsData(responseData);
this.tableApi.clear();
this.tableApi.rows.add(formattedData).draw();
};
/**
* format statistics data for dataTable
* -> e.g. format inline-chart data
* @param statsData
* @returns {Array}
*/
let formatStatisticsData = function(statsData){
let formattedData = [];
let yearStart = statsData.start.year;
let weekStart = statsData.start.week;
let weekCount = statsData.weekCount;
let yearWeeks = statsData.yearWeeks;
let tempRand = function(min, max){
return Math.random() * (max - min) + min;
};
// format/sum week statistics data for inline charts
let formatWeekData = function(weeksData){
let currentYear = yearStart;
let currentWeek = weekStart;
let formattedWeeksData = {
mapCreate: [],
mapUpdate: [],
mapDelete: [],
systemCreate: [],
systemUpdate: [],
systemDelete: [],
connectionCreate: [],
connectionUpdate: [],
connectionDelete: [],
signatureCreate: [],
signatureUpdate: [],
signatureDelete: [],
mapSum: 0,
systemSum: 0,
connectionSum: 0,
signatureSum: 0
};
for(let i = 0; i < weekCount; i++){
let yearWeekProp = currentYear + '' + currentWeek;
if(weeksData.hasOwnProperty( yearWeekProp )){
let weekData = weeksData[ yearWeekProp ];
// map ----------------------------------------------------------------------------------
formattedWeeksData.mapCreate.push( weekData.mapCreate );
formattedWeeksData.mapSum += parseInt( weekData.mapCreate );
formattedWeeksData.mapUpdate.push( weekData.mapUpdate );
formattedWeeksData.mapSum += parseInt( weekData.mapUpdate );
formattedWeeksData.mapDelete.push( weekData.mapDelete );
formattedWeeksData.mapSum += parseInt( weekData.mapDelete );
// system -------------------------------------------------------------------------------
formattedWeeksData.systemCreate.push( weekData.systemCreate );
formattedWeeksData.systemSum += parseInt( weekData.systemCreate );
formattedWeeksData.systemUpdate.push( weekData.systemUpdate );
formattedWeeksData.systemSum += parseInt( weekData.systemUpdate );
formattedWeeksData.systemDelete.push( weekData.systemDelete );
formattedWeeksData.systemSum += parseInt( weekData.systemDelete );
// connection ---------------------------------------------------------------------------
formattedWeeksData.connectionCreate.push( weekData.connectionCreate );
formattedWeeksData.connectionSum += parseInt( weekData.connectionCreate );
formattedWeeksData.connectionUpdate.push( weekData.connectionUpdate );
formattedWeeksData.connectionSum += parseInt( weekData.connectionUpdate );
formattedWeeksData.connectionDelete.push( weekData.connectionDelete );
formattedWeeksData.connectionSum += parseInt( weekData.connectionDelete );
// signature ----------------------------------------------------------------------------
formattedWeeksData.signatureCreate.push( weekData.signatureCreate );
formattedWeeksData.signatureSum += parseInt( weekData.signatureCreate );
formattedWeeksData.signatureUpdate.push( weekData.signatureUpdate );
formattedWeeksData.signatureSum += parseInt( weekData.signatureUpdate );
formattedWeeksData.signatureDelete.push( weekData.signatureDelete );
formattedWeeksData.signatureSum += parseInt( weekData.signatureDelete );
}else{
// map -------------------------------------------------------------------------------
formattedWeeksData.mapCreate.push(0);
formattedWeeksData.mapUpdate.push(0);
formattedWeeksData.mapDelete.push(0);
// system -------------------------------------------------------------------------------
formattedWeeksData.systemCreate.push(0);
formattedWeeksData.systemUpdate.push(0);
formattedWeeksData.systemDelete.push(0);
// connection ---------------------------------------------------------------------------
formattedWeeksData.connectionCreate.push(0);
formattedWeeksData.connectionUpdate.push(0);
formattedWeeksData.connectionDelete.push(0);
// signature ----------------------------------------------------------------------------
formattedWeeksData.signatureCreate.push(0);
formattedWeeksData.signatureUpdate.push(0);
formattedWeeksData.signatureDelete.push(0);
}
currentWeek++;
if( currentWeek > yearWeeks[currentYear] ){
currentWeek = 1;
currentYear++;
}
}
// map ---------------------------------------------------------------------------------------
formattedWeeksData.mapCreate = formattedWeeksData.mapCreate.join(',');
formattedWeeksData.mapUpdate = formattedWeeksData.mapUpdate.join(',');
formattedWeeksData.mapDelete = formattedWeeksData.mapDelete.join(',');
// system ---------------------------------------------------------------------------------------
formattedWeeksData.systemCreate = formattedWeeksData.systemCreate.join(',');
formattedWeeksData.systemUpdate = formattedWeeksData.systemUpdate.join(',');
formattedWeeksData.systemDelete = formattedWeeksData.systemDelete.join(',');
// connection -----------------------------------------------------------------------------------
formattedWeeksData.connectionCreate = formattedWeeksData.connectionCreate.join(',');
formattedWeeksData.connectionUpdate = formattedWeeksData.connectionUpdate.join(',');
formattedWeeksData.connectionDelete = formattedWeeksData.connectionDelete.join(',');
// signature ------------------------------------------------------------------------------------
formattedWeeksData.signatureCreate = formattedWeeksData.signatureCreate.join(',');
formattedWeeksData.signatureUpdate = formattedWeeksData.signatureUpdate.join(',');
formattedWeeksData.signatureDelete = formattedWeeksData.signatureDelete.join(',');
return formattedWeeksData;
};
$.each(statsData.statistics, function(characterId, data){
let formattedWeeksData = formatWeekData(data.weeks);
let rowData = {
character: {
id: characterId,
name: data.name,
lastLogin: data.lastLogin
},
mapCreate: {
type: 'C',
data: formattedWeeksData.mapCreate
},
mapUpdate: {
type: 'U',
data: formattedWeeksData.mapUpdate
},
mapDelete: {
type: 'D',
data: formattedWeeksData.mapDelete
},
mapSum: formattedWeeksData.mapSum,
systemCreate: {
type: 'C',
data: formattedWeeksData.systemCreate
},
systemUpdate: {
type: 'U',
data: formattedWeeksData.systemUpdate
},
systemDelete: {
type: 'D',
data: formattedWeeksData.systemDelete
},
systemSum: formattedWeeksData.systemSum,
connectionCreate: {
type: 'C',
data: formattedWeeksData.connectionCreate
},
connectionUpdate: {
type: 'U',
data: formattedWeeksData.connectionUpdate
},
connectionDelete: {
type: 'D',
data: formattedWeeksData.connectionDelete
},
connectionSum: formattedWeeksData.connectionSum,
signatureCreate: {
type: 'C',
data: formattedWeeksData.signatureCreate
},
signatureUpdate: {
type: 'U',
data: formattedWeeksData.signatureUpdate
},
signatureDelete: {
type: 'D',
data: formattedWeeksData.signatureDelete
},
signatureSum: formattedWeeksData.signatureSum,
totalSum: formattedWeeksData.mapSum + formattedWeeksData.systemSum +
formattedWeeksData.connectionSum + formattedWeeksData.signatureSum
};
formattedData.push(rowData);
});
return formattedData;
};
/**
*
* @param dialogElement
* @returns {{}}
*/
let getRequestDataFromTabPanels = function(dialogElement){
let requestData = {};
// get data from "tab" panel links ------------------------------------------------------------------
let navigationListElements = dialogElement.find('.' + config.dialogNavigationClass);
navigationListElements.find('.' + config.dialogNavigationListItemClass + '.active a').each(function(){
let linkElement = $(this);
requestData[linkElement.data('type')]= linkElement.data('value');
});
// get current period (no offset) data (if available) -----------------------------------------------
let navigationOffsetElement = dialogElement.find('.' + config.dialogNavigationOffsetClass);
let startData = navigationOffsetElement.data('start');
let periodOld = navigationOffsetElement.data('period');
// if period switch was detected
// -> "year" and "week" should not be send
// -> start from "now"
if(
requestData.period === periodOld &&
startData
){
requestData.year = startData.year;
requestData.week = startData.week;
}
return requestData;
};
/**
* check if "activity log" type is enabled for a group
* @param type
* @returns {boolean}
*/
let isTabTypeEnabled = (type) => {
let enabled = false;
switch(type){
case 'private':
if( Boolean(Util.getObjVal(Init.mapTypes, type + '.defaultConfig.log_activity_enabled')) ){
enabled = true;
}
break;
case 'corporation':
if(
Boolean(Util.getObjVal(Init.mapTypes, type + '.defaultConfig.log_activity_enabled')) &&
Util.getCurrentUserInfo('corporationId')
){
enabled = true;
}
break;
case 'alliance':
if(
Boolean(Util.getObjVal(Init.mapTypes, type + '.defaultConfig.log_activity_enabled')) &&
Util.getCurrentUserInfo('allianceId')
){
enabled = true;
}
break;
}
return enabled;
};
/**
* show activity stats dialog
*/
$.fn.showStatsDialog = function(){
requirejs(['text!templates/dialog/stats.html', 'mustache', 'datatables.loader'], function(template, Mustache) {
// get current statistics map settings
let logActivityEnabled = false;
let activeMap = Util.getMapModule().getActiveMap();
if(activeMap){
let activeMapId = activeMap.data('id');
let activeMapData = Util.getCurrentMapData(activeMapId);
if(activeMapData){
logActivityEnabled = Boolean(Util.getObjVal(activeMapData, 'config.logging.activity'));
}
}
// check which dialog tab is default active
let enablePrivateTab = isTabTypeEnabled('private');
let enableCorporationTab = isTabTypeEnabled('corporation');
let enableAllianceTab = isTabTypeEnabled('alliance');
let activePrivateTab = false;
let activeCorporationTab = false;
let activeAllianceTab = false;
if(enableCorporationTab){
activeCorporationTab = true;
}else if(enableAllianceTab){
activeAllianceTab = true;
}else if(enablePrivateTab){
activePrivateTab = true;
}
let data = {
id: config.statsDialogId,
dialogNavigationClass: config.dialogNavigationClass,
dialogNavLiClass: config.dialogNavigationListItemClass,
enablePrivateTab: enablePrivateTab,
enableCorporationTab: enableCorporationTab,
enableAllianceTab: enableAllianceTab,
activePrivateTab: activePrivateTab,
activeCorporationTab: activeCorporationTab,
activeAllianceTab: activeAllianceTab,
logActivityEnabled: logActivityEnabled,
statsContainerId: config.statsContainerId,
statsTableId: config.statsTableId,
dialogNavigationOffsetClass: config.dialogNavigationOffsetClass,
dialogNavigationPrevClass: config.dialogNavigationPrevClass,
dialogNavigationNextClass: config.dialogNavigationNextClass
};
let content = Mustache.render(template, data);
let statsDialog = bootbox.dialog({
title: 'Statistics',
message: content,
size: 'large',
show: false,
buttons: {
close: {
label: 'close',
className: 'btn-default'
}
}
});
// model events
statsDialog.on('show.bs.modal', function(e) {
let dialogElement = $(e.target);
initStatsTable(dialogElement);
});
// Tab module events
statsDialog.find('a[data-toggle="tab"]').on('show.bs.tab', function (e, b, c) {
if( $(e.target).parent().hasClass('disabled') ){
// no action on "disabled" tabs
return false;
}
});
statsDialog.find('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
let requestData = getRequestDataFromTabPanels(statsDialog);
let tableApi = statsDialog.find('#' + config.statsTableId).DataTable();
getStatsData(requestData, {tableApi: tableApi, callback: drawStatsTable});
});
// offset change links
statsDialog.find('.' + config.dialogNavigationPrevClass + ', .' + config.dialogNavigationNextClass).on('click', function(){
let offsetData = $(this).data('newOffset');
if(offsetData){
// this should NEVER fail!
// get "base" request data (e.g. typeId, period)
// --> overwrite period data with new period data
let tmpRequestData = getRequestDataFromTabPanels(statsDialog);
let requestData = $.extend({}, tmpRequestData, offsetData);
let tableApi = statsDialog.find('#' + config.statsTableId).DataTable();
getStatsData(requestData, {tableApi: tableApi, callback: drawStatsTable});
}
});
// show dialog
statsDialog.modal('show');
});
};
});

View File

@@ -1,107 +0,0 @@
/**
* system effects dialog
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox',
'app/map/util'
], function($, Init, Util, Render, bootbox, MapUtil) {
'use strict';
let config = {
// system effect dialog
systemEffectDialogWrapperClass: 'pf-system-effect-dialog-wrapper' // class for system effect dialog
};
let cache = {
systemEffectDialog: false // system effect info dialog
};
/**
* show system effect dialog
*/
$.fn.showSystemEffectInfoDialog = function(){
// cache table structure
if(!cache.systemEffectDialog){
let dialogWrapperElement = $('<div>', {
class: config.systemEffectDialogWrapperClass
});
let systemEffectData = Util.getSystemEffectData();
$.each( systemEffectData.wh, function( effectName, effectData ) {
let table = $('<table>', {
class: ['table', 'table-condensed'].join(' ')
});
let tbody = $('<tbody>');
let thead = $('<thead>');
let rows = [];
// get formatted system effect name
let systemEffectName = MapUtil.getEffectInfoForSystem(effectName, 'name');
let systemEffectClass = MapUtil.getEffectInfoForSystem(effectName, 'class');
$.each( effectData, function( areaId, areaData ) {
let systemType = 'C' + areaId;
let securityClass = Util.getSecurityClassForSystem( systemType );
if(areaId === '1'){
rows.push( $('<tr>') );
thead.append( rows[0] );
rows[0].append(
$('<td>').html( '&nbsp;&nbsp;' + systemEffectName).prepend(
$('<i>', {
class: ['fas', 'fa-square', 'fa-fw', systemEffectClass].join(' ')
})
)
);
}
rows[0].append( $('<td>', {
class: ['text-right', 'col-xs-1', securityClass].join(' ')
}).text( systemType ));
$.each( areaData, function( i, data ) {
if(areaId === '1'){
rows.push( $('<tr>') );
tbody.append(rows[i + 1]);
// add label
rows[i + 1].append( $('<td>').text( data.effect ));
}
rows[i + 1].append( $('<td>', {
class: 'text-right'
}).text( data.value ));
});
});
dialogWrapperElement.append( table.append( thead ).append( tbody ) );
cache.systemEffectDialog = dialogWrapperElement;
});
}
bootbox.dialog({
title: 'System effect information',
message: cache.systemEffectDialog
});
};
});

View File

@@ -1,496 +0,0 @@
/**
* form elements
*/
define([
'jquery',
'app/init',
'app/util',
'app/map/util'
], ($, Init, Util, MapUtil) => {
'use strict';
/**
* format result data
* @param data
* @returns {*}
*/
let formatCategoryTypeResultData = (data) => {
if(data.loading) return data.text;
if(data.placeholder) return data.placeholder;
let markup = '<div class="clearfix">';
if(data.hasOwnProperty('children')){
// category group label
markup += '<div class="col-xs-9">' + data.text + '</div>';
markup += '<div class="col-xs-3 text-right">(' + data.children.length + ')</div>';
}else{
let imagePath = '';
let iconName = '';
let thumb = '';
switch(data.categoryType){
case 'character':
imagePath = Init.url.ccpImageServer + '/Character/' + data.id + '_32.jpg';
break;
case 'corporation':
imagePath = Init.url.ccpImageServer + '/Corporation/' + data.id + '_32.png';
break;
case 'alliance':
imagePath = Init.url.ccpImageServer + '/Alliance/' + data.id + '_32.png';
break;
case 'inventoryType':
imagePath = Init.url.ccpImageServer + '/Type/' + data.id + '_32.png';
break;
case 'render':
imagePath = Init.url.ccpImageServer + '/Render/' + data.id + '_32.png';
break;
case 'station':
iconName = 'fa-home';
break;
case 'system':
iconName = 'fa-sun';
break;
}
if(imagePath){
thumb = '<img src="' + imagePath + '" style="max-width: 100%" />';
}else if(iconName){
thumb = '<i class="fas fa-fw ' + iconName + '" ></i>';
}
markup += '<div class="col-xs-2 text-center">' + thumb + '</div>';
markup += '<div class="col-xs-10">' + data.text + '</div>';
}
markup += '</div>';
return markup;
};
/**
* init a select element as "select2" for map selection
*/
$.fn.initMapSelect = function(){
let selectElement = $(this);
$.when(
selectElement.select2({
dropdownParent: selectElement.parents('.modal-body'),
maximumSelectionLength: 5
})
);
};
/**
* init a select element as an ajax based "select2" object for system search
* @param options
*/
$.fn.initSystemSelect = function(options){
let selectElement = $(this);
let config = {
maxSelectionLength: 1
};
options = $.extend({}, config, options);
let shatteredClass = Util.getSecurityClassForSystem('SH');
// format result data
function formatResultData (data) {
if(data.loading) return data.text;
// abyss system font
let systemNameClass = data.security === 'A' ? Util.config.fontTriglivianClass : '' ;
// show effect info just for wormholes
let hideEffectClass = data.effect === null ? 'hide' : '';
let hideShatteredClass = !data.shattered ? 'hide' : '';
let markup = '<div class="clearfix">';
markup += '<div class="col-sm-4 pf-select-item-anchor ' + systemNameClass + '">' + data.text + '</div>';
markup += '<div class="col-sm-2 text-right ' + data.effectClass + '">';
markup += '<i class="fas fa-fw fa-square ' + hideEffectClass + '"></i>';
markup += '</div>';
markup += '<div class="col-sm-2 text-right ' + data.secClass + '">' + data.security + '</div>';
markup += '<div class="col-sm-2 text-right ' + shatteredClass + '">';
markup += '<i class="fas fa-fw fa-skull ' + hideShatteredClass + '"></i>';
markup += '</div>';
markup += '<div class="col-sm-2 text-right ' + data.trueSecClass + '">' + data.trueSec + '</div></div>';
return markup;
}
$.when(
selectElement.select2({
ajax: {
url: function(params){
// add params to URL
return Init.path.searchUniverseSystemData + '/' + params.term.trim();
},
dataType: 'json',
delay: 250,
timeout: 5000,
cache: true,
data: function(params){
return {
page: params.page || 1
};
},
processResults: function(data, params) {
// parse the results into the format expected by Select2.
return {
results: data.results.map( function(item){
// "id" or "name"
let id = item[options.key];
let disabled = false;
let trueSec = parseFloat(item.trueSec);
let secClass = Util.getSecurityClassForSystem(item.security);
let trueSecClass = Util.getTrueSecClassForSystem( trueSec );
let effectClass = MapUtil.getEffectInfoForSystem(item.effect, 'class');
// check if system is dialed
if(
options.disabledOptions &&
options.disabledOptions.indexOf(parseInt(id, 10)) !== -1
){
disabled = true;
}
// "fix" security level
if(
trueSec > 0 &&
trueSec < 0.1
){
trueSec = 0.1;
}else{
trueSec = Math.round(trueSec * 10) / 10;
}
return {
id: id,
text: item.name,
// systemId: parseInt(item.systemId),
security: item.security,
secClass: secClass,
trueSec: trueSec.toFixed(1),
trueSecClass: trueSecClass,
effect: item.effect,
effectClass: effectClass,
shattered: item.shattered,
disabled: disabled
};
}),
pagination: {
more: data.pagination.more
}
};
},
error: function (jqXHR, status, error) {
if( !Util.isXHRAborted(jqXHR) ){
let reason = status + ' ' + jqXHR.status + ': ' + error;
Util.showNotify({title: 'System select warning', text: reason + ' deleted', type: 'warning'});
}
}
},
dropdownParent: selectElement.parents('.modal-body'),
minimumInputLength: 3,
templateResult: formatResultData,
placeholder: 'System name',
allowClear: true,
maximumSelectionLength: options.maxSelectionLength,
escapeMarkup: function(markup){
// let our custom formatter work
return markup;
}
}).on('change', function(e){
// select changed
}).on('select2:open', function(){
// clear selected system (e.g. default system)
// => improves usability (not necessary). There is a small "x" if field can be cleared manually
if(
options.maxSelectionLength === 1 &&
$(this).val() !== null
){
$(this).val('').trigger('change');
}
})
).done(function(a,b){
// open select if not already pre-selected
if($(this).val() === null){
selectElement.select2('open');
}
});
};
/**
* init a select element as an ajax based "select2" object for Access resources
* character (private map), corporation (corp map), alliance (ally map)
* @param options
*/
$.fn.initAccessSelect = function(options){
return this.each(function(){
let selectElement = $(this);
// format selection data
function formatSelectionData (data){
if (data.loading){
return data.text;
}
let markup = '<div class="clearfix">';
markup += '<div class="col-sm-10">' + data.text + '</div></div>';
return markup;
}
$.when(
selectElement.select2({
ajax: {
url: function(params){
// add params to URL
return Init.path.searchAccess + '/' + options.type + '/' + params.term;
},
dataType: 'json',
delay: 250,
timeout: 5000,
cache: true,
data: function(params) {
// no url params here
return;
},
processResults: function(data, page) {
// parse the results into the format expected by Select2.
return {
results: data.map( function(item){
return {
id: item.id,
text: item.name,
categoryType: options.type
};
})
};
},
error: function (jqXHR, status, error) {
if( !Util.isXHRAborted(jqXHR) ){
let reason = status + ' ' + jqXHR.status + ': ' + error;
Util.showNotify({title: 'Access select warning', text: reason + ' deleted', type: 'warning'});
}
}
},
dropdownParent: selectElement.parents('.modal-body'),
minimumInputLength: 3,
placeholder: options.type + ' names',
allowClear: false,
maximumSelectionLength: options.maxSelectionLength,
templateResult: formatCategoryTypeResultData,
templateSelection: formatSelectionData,
escapeMarkup: function(markup){
// let our custom formatter work
return markup;
}
}).on('change', function(e){
// select changed
})
).done(function(){
// after init finish
});
});
};
/**
* init a select element as an ajax based "select2" object for universeTypes
* e.g. 'alliance', 'corporation', 'character', ...
* @param options
* @returns {*}
*/
$.fn.initUniverseSearch = function(options) {
let showErrorNotification = (reason) => {
Util.showNotify({title: 'Search failed', text: reason + ' deleted', type: 'warning'});
};
/**
* format selection data
* @param data
* @returns {*}
*/
function formatSelectionData (data){
if(data.loading) return data.text;
if(data.placeholder) return data.placeholder;
let markup = '<div class="clearfix">';
markup += '<div class="col-sm-10">' + data.text + '</div></div>';
return markup;
}
return this.each(function() {
let selectElement = $(this);
$.when(
selectElement.select2({
ajax: {
type: 'POST',
url: function(params){
// add params to URL
return Init.path.searchUniverseData + '/' + params.term;
},
dataType: 'json',
delay: 250,
timeout: 5000,
cache: true,
data: function(params){
return {
categories: options.categoryNames
};
},
processResults: function(result, page) {
let data = {results: []};
if(result.hasOwnProperty('error')){
showErrorNotification(result.error);
}else{
let mapChildren = function(item){
return {
id: item.id,
text: item.name,
categoryType: this
};
};
for(let category in result){
// skip custom functions in case result = [] (array functions)
if(result.hasOwnProperty(category)){
data.results.push({
text: category,
children: result[category].map(mapChildren, category)
});
}
}
}
return data;
},
error: function (jqXHR, status, error) {
if( !Util.isXHRAborted(jqXHR) ){
let reason = status + ' ' + jqXHR.status + ': ' + error;
showErrorNotification(reason);
}
}
},
dropdownParent: selectElement.parents('.modal-body') ,
minimumInputLength: 3,
placeholder: '',
allowClear: options.maxSelectionLength <= 1,
maximumSelectionLength: options.maxSelectionLength,
templateResult: formatCategoryTypeResultData,
// templateSelection: formatSelectionData, // some issues with "clear" selection on single selects (empty option is needed)
escapeMarkup: function(markup){
// let our custom formatter work
return markup;
}
}).on('change', function(e){
// select changed
}).on('select2:open', function(){
// clear selected system (e.g. default system)
// => improves usability (not necessary). There is a small "x" if field can be cleared manually
if(
options.maxSelectionLength === 1 &&
$(this).val() !== null
){
$(this).val('').trigger('change');
}
})
).done(function(){
// after init finish
});
});
};
$.fn.initUniverseTypeSelect = function(options) {
/**
* get select option data by categoryIds
* @param categoryIds
* @returns {{results: Array}}
*/
let getOptionsData = categoryIds => {
let data = [];
let mapChildren = function(type){
return {
id: type.id,
text: type.name,
groupId: this.groupId,
categoryId: this.categoryId,
categoryType: this.categoryType
};
};
for(let categoryId of categoryIds){
let categoryData = Util.getObjVal(Init, 'universeCategories.' + categoryId);
if(categoryData && categoryData.groups){
// categoryId data exists and has groups...
for(let groupData of categoryData.groups){
if(groupData && groupData.types){
// groupData exists and has types...
data.push({
text: groupData.name,
children: groupData.types.map(mapChildren, {
groupId: groupData.id,
categoryId: categoryData.id,
categoryType: 'inventoryType',
})
});
}
}
}
}
return data;
};
return this.each(function() {
let selectElement = $(this);
$.when(
selectElement.select2({
data: getOptionsData(options.categoryIds),
dropdownParent: selectElement.parents('.modal-body'),
minimumInputLength: 0, // minimum number of characters required to start a search
maximumInputLength: 100, // maximum number of characters that may be provided for a search term
placeholder: '',
allowClear: options.maxSelectionLength <= 1,
multiple: options.maxSelectionLength > 1,
maximumSelectionLength: options.maxSelectionLength,
// maximumSelectionLength: options.maxSelectionLength > 1 ? options.maxSelectionLength > 1 : 0,
// minimumResultsForSearch: 5, // minimum number of results required to display the search box
templateResult: formatCategoryTypeResultData,
escapeMarkup: function(markup){
return markup;
}
}).on('select2:open', function(){
// clear selected system (e.g. default system)
// => improves usability (not necessary). There is a small "x" if field can be cleared manually
if(
options.maxSelectionLength === 1 &&
$(this).val() !== null
){
$(this).val('').trigger('change');
}
}).val(options.selected).trigger('change')
);
});
};
});

View File

@@ -1,239 +0,0 @@
/**
* Header animation
*/
define([
'jquery',
'easePack',
'tweenLite'
], function($) {
'use strict';
let config = {
previewElementClass: 'pf-header-preview-element' // class for "preview" elements
};
let width, height, largeHeader, canvas, ctx, points, target, animateHeader = true;
let canvasHeight = 355;
let colorRGB = '108, 174, 173';
let connectionCount = 4;
let initHeader = function() {
width = window.innerWidth;
height = canvasHeight;
target = {x: width * 1, y: 230};
largeHeader.style.height = height+'px';
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext('2d');
// create points
points = [];
for(let x = 0; x < width; x = x + width/20) {
for(let y = 0; y < height; y = y + height/15) {
let px = x + Math.random()*width/15;
let py = y + Math.random()*height/15;
let p = {x: px, originX: px, y: py, originY: py };
points.push(p);
}
}
// for each point find the 5 closest points
for(let i = 0; i < points.length; i++) {
let closest = [];
let p1 = points[i];
for(let j = 0; j < points.length; j++) {
let p2 = points[j];
if(p1 !== p2) {
let placed = false;
for(let k = 0; k < connectionCount; k++) {
if(!placed) {
if(closest[k] === undefined) {
closest[k] = p2;
placed = true;
}
}
}
for(let m = 0; m < connectionCount; m++) {
if(!placed) {
if(getDistance(p1, p2) < getDistance(p1, closest[m])) {
closest[m] = p2;
placed = true;
}
}
}
}
}
p1.closest = closest;
}
// assign a circle to each point
for(let n in points) {
let c = new Circle(points[n], 2+Math.random()*2, 'rgba(255,255,255,0.3)');
points[n].circle = c;
}
};
// Event handling
let addListeners = function() {
if(!('ontouchstart' in window)) {
window.addEventListener('mousemove', mouseMove);
}
window.addEventListener('scroll', scrollCheck);
window.addEventListener('resize', resize);
};
let mouseMove = function(e) {
let posx = 0;
let posy = 0;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}else if (e.clientX || e.clientY){
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
target.x = posx;
target.y = posy;
};
let scrollCheck = function() {
if(document.body.scrollTop > height){
animateHeader = false;
}else{
animateHeader = true;
}
};
let resize = function() {
width = window.innerWidth;
height = canvasHeight;
largeHeader.style.height = height+'px';
canvas.width = width;
canvas.height = height;
};
// animation
let initAnimation = function() {
animate();
for(let i in points) {
shiftPoint(points[i]);
}
};
let animate = function animate() {
if(animateHeader) {
ctx.clearRect(0,0,width,height);
for(let i in points) {
// detect points in range
if(Math.abs(getDistance(target, points[i])) < 4000) {
points[i].active = 0.25;
points[i].circle.active = 0.45;
} else if(Math.abs(getDistance(target, points[i])) < 20000) {
points[i].active = 0.1;
points[i].circle.active = 0.3;
} else if(Math.abs(getDistance(target, points[i])) < 40000) {
points[i].active = 0.02;
points[i].circle.active = 0.1;
} else {
points[i].active = 0;
points[i].circle.active = 0;
}
drawLines(points[i]);
points[i].circle.draw();
}
}
requestAnimationFrame(animate);
};
let shiftPoint = function (p) {
TweenLite.to(p, 1 + 1 * Math.random(), {x: p.originX - 50 + Math.random() * 100,
y: p.originY - 50 + Math.random() * 100, ease: Circ.easeInOut,
onComplete: function () {
shiftPoint(p);
}});
};
// Canvas manipulation
let drawLines = function (p) {
if(!p.active) return;
for(let i in p.closest) {
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.lineTo(p.closest[i].x, p.closest[i].y);
ctx.strokeStyle = 'rgba(' + colorRGB +','+ p.active+')';
ctx.stroke();
}
};
let Circle = function(pos,rad,color) {
let _this = this;
// constructor
(function() {
_this.pos = pos || null;
_this.radius = rad || null;
_this.color = color || null;
})();
this.draw = function() {
if(!_this.active) return;
ctx.beginPath();
ctx.arc(_this.pos.x, _this.pos.y, _this.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'rgba(' + colorRGB + ','+ _this.active+')';
ctx.fill();
};
};
// Util
let getDistance = function(p1, p2) {
return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2);
};
/**
* init header animation
* @param callback
*/
$.fn.initHeader = function(callback){
largeHeader = $(this)[0];
canvas = $(this).find('canvas:visible')[0];
// header preview elements
$('.' + config.previewElementClass).velocity('transition.bounceIn', {
duration: 600,
stagger: 60,
delay: 120,
complete: function(){
// show header canvas animation
if(canvas){
// header animation
initHeader();
initAnimation();
addListeners();
$(canvas).velocity('fadeIn', {
duration: 900,
visibility: 'visible',
complete: function(){
if(callback !== undefined){
callback();
}
}
});
}
}
});
};
});

View File

@@ -1,150 +0,0 @@
/**
* Logo
*/
define([
'jquery',
'lazylinepainter'
], function($) {
'use strict';
let config = {
staticLogoId: 'pf-static-logo-svg', // id for "static" logo
logoPartTopRightClass: 'logo-ploygon-top-right', // class for logo part "top right"
logoPartBottomLeftClass: 'logo-ploygon-bottom-left', // class for logo part "bottom left"
logoPartBottomRightClass: 'logo-ploygon-bottom-right', // class for logo part "bottom right"
logoPartTopLeftClass: 'logo-ploygon-top-left'
};
/**
* draws the pathfinder logo to an element and add some animation features
* @param callback
* @param enableHover
*/
$.fn.drawLogo = function(callback, enableHover){
let canvasElement = $(this);
let pathObj = {
logo: {
strokepath: [
{
path: 'M195.9 9.6 226.9 297.1 354.2 365 196.2 9.8 ',
strokeColor: '#477372',
duration: 1600
},
{
path: 'M1.7 361.3 73.9 284.9 178.6 286.7 2.2 361.4 ',
strokeColor: '#5cb85c',
duration: 1000
},
{
path: 'M192.9 286.7 121.2 318.6 335.6 363.5 193.4 286.7 ',
strokeColor: '#375959',
duration: 900
},
{
path: 'M202.8 141.9 0.2 352.6 189.1 0.8 202.7 141.3 ',
strokeColor: '#63676a',
duration: 1500
}
],
dimensions: {
width: 355,
height: 366
}
}
};
// load Logo svg
requirejs(['text!templates/ui/logo.html', 'mustache'], function(template, Mustache) {
let logoData = {
staticLogoId: config.staticLogoId,
logoPartTopRightClass: config.logoPartTopRightClass,
logoPartBottomLeftClass: config.logoPartBottomLeftClass,
logoPartBottomRightClass: config.logoPartBottomRightClass,
logoPartTopLeftClass: config.logoPartTopLeftClass
};
let logoContent = Mustache.render(template, logoData);
canvasElement.html(logoContent);
// draw the logo
canvasElement.lazylinepainter(
{
svgData: pathObj,
strokeWidth: 2,
drawSequential: false,
delay: 300,
overrideKey: 'logo',
strokeJoin: 'bevel',
onComplete: function(){
// hide lines
canvasElement.find('svg:not(#' + config.staticLogoId + ')').velocity({
opacity: 0
},{
delay: 100
});
// show full logo
canvasElement.find('#' + config.staticLogoId + '').velocity({
opacity: 1
},{
delay: 100,
duration: 200,
complete: function(){
// execute callback
if(typeof callback === 'function'){
callback();
}
// init logo animation
if(enableHover === true){
let logoElements = $('#' + config.staticLogoId + ' path');
let animate = [];
logoElements.on('mouseover', function(e){
let currentLogoElement = $(e.target);
let currentLogoElementIndex = logoElements.index(currentLogoElement);
let animationXValue = currentLogoElement.attr('data-animationX');
let animationYValue = currentLogoElement.attr('data-animationY');
let animationConfig = {};
animationConfig.opacity = [1, 1];
animationConfig.translateZ = [0, 0];
animationConfig.translateX = [animationXValue, 0 ];
animationConfig.translateY = [animationYValue, 0];
if(animate[currentLogoElementIndex] !== false){
$(this).velocity(animationConfig,{
duration: 120,
begin: function(){
animate[currentLogoElementIndex] = false;
}
}).velocity('reverse',{
delay: 240,
complete: function(){
animate[currentLogoElementIndex] = true;
}
});
}
});
}
}
});
}
}).lazylinepainter('paint');
});
};
});

View File

@@ -1,248 +0,0 @@
/**
* System graph module
*/
define([
'jquery',
'app/init',
'app/util',
'morris'
], function($, Init, Util, Morris) {
'use strict';
let config = {
// module info
modulePosition: 3,
moduleName: 'systemGraph',
moduleHeadClass: 'pf-module-head', // class for module header
moduleHandlerClass: 'pf-module-handler-drag', // class for "drag" handler
// system graph module
moduleTypeClass: 'pf-system-graph-module', // class for this module
systemGraphClass: 'pf-system-graph', // class for each graph
// system graph labels
systemGraphs: {
jumps: {
headline: 'Jumps',
units: 'jumps',
ykeys: ['y'],
labels: ['jumps'],
lineColors: ['#375959'],
pointFillColors: ['#477372']
},
shipKills: {
headline: 'Ship/POD Kills',
units: 'kills',
ykeys: ['y', 'z'],
labels: ['Ship kills', 'POD kills'],
lineColors: ['#375959', '#477372'],
pointFillColors: ['#477372', '#568a89']
},
factionKills: {
headline: 'NPC Kills',
units: 'kills',
ykeys: ['y'],
labels: ['kills'],
lineColors: ['#375959'],
pointFillColors: ['#477372']
}
}
};
/**
* get info for a given graph key
* @param graphKey
* @param option
* @returns {string}
*/
let getInfoForGraph = function(graphKey, option){
let info = '';
if(config.systemGraphs.hasOwnProperty(graphKey)){
info = config.systemGraphs[graphKey][option];
}
return info;
};
/**
* init Morris Graph
* @param graphElement
* @param graphKey
* @param graphData
* @param eventLine
*/
let initGraph = function(graphElement, graphKey, graphData, eventLine){
if(graphData.length > 0){
let labelYFormat = function(y){
return Math.round(y);
};
let graphConfig = {
element: graphElement,
data: graphData,
xkey: 'x',
ykeys: getInfoForGraph(graphKey, 'ykeys'),
labels: getInfoForGraph(graphKey, 'labels'),
parseTime: false,
ymin: 0,
yLabelFormat: labelYFormat,
padding: 10,
hideHover: true,
pointSize: 3,
lineColors: getInfoForGraph(graphKey, 'lineColors'),
pointFillColors: getInfoForGraph(graphKey, 'pointFillColors'),
pointStrokeColors: ['#141413'],
lineWidth: 2,
grid: true,
gridStrokeWidth: 0.3,
gridTextSize: 9,
gridTextFamily: 'Oxygen Bold',
gridTextColor: '#63676a',
behaveLikeLine: false,
goals: [],
goalLineColors: ['#5cb85c'],
smooth: true,
fillOpacity: 0.2,
resize: true,
redraw: true,
eventStrokeWidth: 2,
eventLineColors: ['#5CB85C']
};
if(eventLine >= 0){
graphConfig.events = [eventLine];
}
Morris.Area(graphConfig);
}
};
/**
* request graphs data
* @param requestData
* @param context
* @param callback
*/
let requestGraphData = (requestData, context, callback) => {
// show loading animation
context.moduleElement.find('.' + config.systemGraphClass).showLoadingAnimation();
$.ajax({
type: 'POST',
url: Init.path.getSystemGraphData,
data: requestData,
dataType: 'json',
context: context
}).done(function(systemGraphsData){
callback(this, systemGraphsData);
}).fail(function( jqXHR, status, error) {
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': System graph data', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
this.moduleElement.hide();
}).always(function(){
// hide loading animation
context.moduleElement.find('.' + config.systemGraphClass).hideLoadingAnimation();
});
};
/**
* update graph elements with data
* @param context
* @param systemGraphsData
*/
let addGraphData = (context, systemGraphsData) => {
// calculate time offset until system created -----------------------------------------------------------------
let serverData = Util.getServerTime();
let timestampNow = Math.floor(serverData.getTime() / 1000);
let timeSinceUpdate = timestampNow - context.systemData.updated.updated;
let timeInHours = Math.floor(timeSinceUpdate / 3600);
let timeInMinutes = Math.floor((timeSinceUpdate % 3600) / 60);
let timeInMinutesPercent = ( timeInMinutes / 60 ).toFixed(2);
let eventLine = timeInHours + timeInMinutesPercent;
// graph is from right to left -> convert event line
eventLine = 23 - eventLine;
// update graph data ------------------------------------------------------------------------------------------
for (let [systemId, graphsData] of Object.entries(systemGraphsData)){
for (let [graphKey, graphData] of Object.entries(graphsData)){
let graphElement = context.moduleElement.find('[data-graph="' + graphKey + '"]');
initGraph(graphElement, graphKey, graphData, eventLine);
}
}
};
/**
* @see requestGraphData
* @param moduleElement
* @param mapId
* @param systemData
*/
let updateGraphPanel = (moduleElement, mapId, systemData) => {
let requestData = {
systemIds: [systemData.systemId]
};
let contextData = {
moduleElement: moduleElement,
systemData: systemData
};
requestGraphData(requestData, contextData, addGraphData);
};
/**
* get module element
* @param parentElement
* @param mapId
* @param systemData
* @returns {*}
*/
let getModule = (parentElement, mapId, systemData) => {
// graph data is available for k-space systems
let moduleElement = null;
if(systemData.type.id === 2){
moduleElement = $('<div>');
let rowElement = $('<div>', {
class: 'row'
});
for (let [graphKey, graphConfig] of Object.entries(config.systemGraphs)){
rowElement.append(
$('<div>', {
class: ['col-xs-12', 'col-sm-6', 'col-md-4'].join(' ')
}).append(
$('<div>', {
class: config.moduleHeadClass
}).append(
$('<h5>', {
class: config.moduleHandlerClass
}),
$('<h5>', {
text: getInfoForGraph(graphKey, 'headline')
})
),
$('<div>', {
class: config.systemGraphClass
}).attr('data-graph', graphKey)
)
);
}
moduleElement.append(rowElement);
updateGraphPanel(moduleElement, mapId, systemData);
}
return moduleElement;
};
return {
config: config,
getModule: getModule
};
});

View File

@@ -1,421 +0,0 @@
/**
* System info module
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'app/map/util'
], function($, Init, Util, Render, MapUtil) {
'use strict';
let config = {
// module info
modulePosition: 2,
moduleName: 'systemInfo',
// system info module
moduleTypeClass: 'pf-system-info-module', // class for this module
// breadcrumb
constellationLinkClass: 'pf-system-info-constellation', // class for "constellation" name
regionLinkClass: 'pf-system-info-region', // class for "region" name
typeLinkClass: 'pf-system-info-type', // class for "type" name
// info table
systemInfoTableClass: 'pf-module-table', // class for system info table
systemInfoNameClass: 'pf-system-info-name', // class for "name" information element
systemInfoEffectClass: 'pf-system-info-effect', // class for "effect" information element
systemInfoPlanetsClass: 'pf-system-info-planets', // class for "planets" information element
systemInfoStatusLabelClass: 'pf-system-info-status-label', // class for "status" information element
systemInfoStatusAttributeName: 'data-status', // attribute name for status label
systemInfoWormholeClass: 'pf-system-info-wormhole-', // class prefix for static wormhole element
// description field
descriptionArea: 'pf-system-info-description-area', // class for "description" area
addDescriptionButtonClass: 'pf-system-info-description-button', // class for "add description" button
moduleElementToolbarClass: 'pf-table-tools', // class for "module toolbar" element
tableToolsActionClass: 'pf-table-tools-action', // class for "edit" action
descriptionTextareaElementClass: 'pf-system-info-description', // class for "description" textarea element (xEditable)
descriptionTextareaCharCounter: 'pf-form-field-char-count', // class for "character counter" element for form field
// fonts
fontTriglivianClass: 'pf-triglivian' // class for "Triglivian" names (e.g. Abyssal systems)
};
// disable Module update temporary (in case e.g. textarea is currently active)
let disableModuleUpdate = false;
// animation speed values
let animationSpeedToolbarAction = 200;
// max character length for system description
let maxDescriptionLength = 512;
/**
* shows the tool action element by animation
* @param toolsActionElement
*/
let showToolsActionElement = (toolsActionElement) => {
toolsActionElement.velocity('stop').velocity({
opacity: 1,
height: '100%'
},{
duration: animationSpeedToolbarAction,
display: 'block',
visibility: 'visible'
});
};
/**
* hides the tool action element by animation
* @param toolsActionElement
*/
let hideToolsActionElement = (toolsActionElement) => {
toolsActionElement.velocity('stop').velocity('reverse', {
display: 'none',
visibility: 'hidden'
});
};
/**
* update trigger function for this module
* compare data and update module
* @param moduleElement
* @param systemData
*/
let updateModule = (moduleElement, systemData) => {
let systemId = moduleElement.data('id');
if(systemId === systemData.id){
// update system status -----------------------------------------------------------------------------------
let systemStatusLabelElement = moduleElement.find('.' + config.systemInfoStatusLabelClass);
let systemStatusId = parseInt( systemStatusLabelElement.attr( config.systemInfoStatusAttributeName ) );
if(systemStatusId !== systemData.status.id){
// status changed
let currentStatusClass = Util.getStatusInfoForSystem(systemStatusId, 'class');
let newStatusClass = Util.getStatusInfoForSystem(systemData.status.id, 'class');
let newStatusLabel = Util.getStatusInfoForSystem(systemData.status.id, 'label');
systemStatusLabelElement.removeClass(currentStatusClass).addClass(newStatusClass).text(newStatusLabel);
// set new status attribute
systemStatusLabelElement.attr( config.systemInfoStatusAttributeName, systemData.status.id);
}
// update description textarea ----------------------------------------------------------------------------
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
let description = descriptionTextareaElement.editable('getValue', true);
if(
!disableModuleUpdate && // don´t update if field is active
description !== systemData.description
){
// description changed
let descriptionButton = moduleElement.find('.' + config.addDescriptionButtonClass);
// set new value
descriptionTextareaElement.editable('setValue', systemData.description);
let actionElement = descriptionButton.siblings('.' + config.tableToolsActionClass);
if(systemData.description.length === 0){
// show/activate description field
// show button if value is empty
descriptionButton.show();
hideToolsActionElement(actionElement);
}else{
// hide/disable description field
// hide tool button
descriptionButton.hide();
showToolsActionElement(actionElement);
}
}
// created/updated tooltip --------------------------------------------------------------------------------
let nameRowElement = moduleElement.find('.' + config.systemInfoNameClass);
let tooltipData = {
created: systemData.created,
updated: systemData.updated
};
nameRowElement.addCharacterInfoTooltip( tooltipData );
}
moduleElement.find('.' + config.descriptionArea).hideLoadingAnimation();
};
/**
* get module element
* @param parentElement
* @param mapId
* @param systemData
*/
let getModule = (parentElement, mapId, systemData) => {
// create new module container
let moduleElement = $('<div>');
// store systemId -> module can be updated with the correct data
moduleElement.data('id', systemData.id);
// system "static" wh data
let staticsData = [];
if(
systemData.statics &&
systemData.statics.length > 0
){
for(let wormholeName of systemData.statics){
let wormholeData = Object.assign({}, Init.wormholes[wormholeName]);
wormholeData.class = Util.getSecurityClassForSystem(wormholeData.security);
staticsData.push(wormholeData);
}
}
let effectName = MapUtil.getEffectInfoForSystem(systemData.effect, 'name');
let effectClass = MapUtil.getEffectInfoForSystem(systemData.effect, 'class');
// systemInfo template config
let moduleConfig = {
name: 'modules/system_info',
position: moduleElement,
link: 'append',
functions: {
after: function(conf){
let tempModuleElement = conf.position;
// lock "description" field until first update
tempModuleElement.find('.' + config.descriptionArea).showLoadingAnimation();
// "add description" button
let descriptionButton = tempModuleElement.find('.' + config.addDescriptionButtonClass);
// description textarea element
let descriptionTextareaElement = tempModuleElement.find('.' + config.descriptionTextareaElementClass);
// init description textarea
descriptionTextareaElement.editable({
url: Init.path.saveSystem,
dataType: 'json',
pk: systemData.id,
type: 'textarea',
mode: 'inline',
emptytext: '',
onblur: 'cancel',
showbuttons: true,
value: '', // value is set by trigger function updateModule()
rows: 5,
name: 'description',
inputclass: config.descriptionTextareaElementClass,
tpl: '<textarea maxlength="' + maxDescriptionLength + '"></textarea>',
params: function(params){
params.mapData = {
id: mapId
};
params.systemData = {};
params.systemData.id = params.pk;
params.systemData[params.name] = params.value;
// clear unnecessary data
delete params.pk;
delete params.name;
delete params.value;
return params;
},
validate: function(value){
if(value.length > 0 && $.trim(value).length === 0) {
return {newValue: ''};
}
},
success: function(response, newValue){
Util.showNotify({title: 'System updated', text: 'Name: ' + response.name, type: 'success'});
},
error: function(jqXHR, newValue){
let reason = '';
let status = '';
if(jqXHR.name){
// save error new sig (mass save)
reason = jqXHR.name;
status = 'Error';
}else{
reason = jqXHR.responseJSON.text;
status = jqXHR.status;
}
Util.showNotify({title: status + ': save system information', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
return reason;
}
});
// on xEditable open ------------------------------------------------------------------------------
descriptionTextareaElement.on('shown', function(e, editable){
let textarea = editable.input.$input;
// disable module update until description field is open
disableModuleUpdate = true;
// create character counter
let charCounter = $('<kbd>', {
class: [config.descriptionTextareaCharCounter, 'txt-color', 'text-right'].join(' ')
});
textarea.parent().next().append(charCounter);
// update character counter
Util.updateCounter(textarea, charCounter, maxDescriptionLength);
textarea.on('keyup', function(){
Util.updateCounter($(this), charCounter, maxDescriptionLength);
});
});
// on xEditable close -----------------------------------------------------------------------------
descriptionTextareaElement.on('hidden', function(e){
let value = $(this).editable('getValue', true);
if(value.length === 0){
// show button if value is empty
hideToolsActionElement(descriptionButton.siblings('.' + config.tableToolsActionClass));
descriptionButton.show();
}
// enable module update
disableModuleUpdate = false;
});
// enable xEditable field on Button click ---------------------------------------------------------
descriptionButton.on('click', function(e){
e.stopPropagation();
let descriptionButton = $(this);
// hide tool buttons
descriptionButton.hide();
// show field *before* showing the element
descriptionTextareaElement.editable('show');
showToolsActionElement(descriptionButton.siblings('.' + config.tableToolsActionClass));
});
// init tooltips ----------------------------------------------------------------------------------
let tooltipElements = tempModuleElement.find('[data-toggle="tooltip"]');
tooltipElements.tooltip();
// init system effect popover ---------------------------------------------------------------------
$(moduleElement).find('.' + config.systemInfoEffectClass).addSystemEffectTooltip(systemData.security, systemData.effect);
// init planets popover ---------------------------------------------------------------------------
$(moduleElement).find('.' + config.systemInfoPlanetsClass).addSystemPlanetsTooltip(systemData.planets);
// init static wormhole information ---------------------------------------------------------------
for(let staticData of staticsData){
let staticRowElement = tempModuleElement.find('.' + config.systemInfoWormholeClass + staticData.name);
staticRowElement.addWormholeInfoTooltip(staticData);
}
// constellation popover --------------------------------------------------------------------------
tempModuleElement.find('a.popup-ajax').popover({
html: true,
trigger: 'hover',
placement: 'top',
delay: 200,
container: 'body',
content: function(){
return details_in_popup(this);
}
});
function details_in_popup(popoverElement){
popoverElement = $(popoverElement);
let popover = popoverElement.data('bs.popover');
$.ajax({
url: popoverElement.data('url'),
success: function(data){
let systemEffectTable = Util.getSystemsInfoTable( data.systemsData );
popover.options.content = systemEffectTable;
// reopen popover (new content size)
popover.show();
}
});
return 'Loading...';
}
}
}
};
let moduleData = {
system: systemData,
static: staticsData,
tableClass: config.systemInfoTableClass,
nameInfoClass: config.systemInfoNameClass,
effectInfoClass: config.systemInfoEffectClass,
planetsInfoClass: config.systemInfoPlanetsClass,
wormholePrefixClass: config.systemInfoWormholeClass,
statusInfoClass: config.systemInfoStatusLabelClass,
systemTypeName: MapUtil.getSystemTypeInfo(systemData.type.id, 'name'),
systemIsWormhole: MapUtil.getSystemTypeInfo(systemData.type.id, 'name') === 'w-space',
systemStatusId: systemData.status.id,
systemStatusClass: Util.getStatusInfoForSystem(systemData.status.id, 'class'),
systemStatusLabel: Util.getStatusInfoForSystem(systemData.status.id, 'label'),
securityClass: Util.getSecurityClassForSystem( systemData.security ),
trueSec: systemData.trueSec.toFixed(1),
trueSecClass: Util.getTrueSecClassForSystem( systemData.trueSec ),
effectName: effectName,
effectClass: effectClass,
moduleToolbarClass: config.moduleElementToolbarClass,
descriptionButtonClass: config.addDescriptionButtonClass,
tableToolsActionClass: config.tableToolsActionClass,
descriptionTextareaClass: config.descriptionTextareaElementClass,
systemNameClass: () => {
return (val, render) => {
return render(val) === 'A' ? config.fontTriglivianClass : '';
};
},
formatUrl: () => {
return (val, render) => render(val).replace(/ /g, '_');
},
planetCount: systemData.planets ? systemData.planets.length : 0,
shatteredClass: Util.getSecurityClassForSystem('SH'),
ajaxConstellationInfoUrl: Init.path.getConstellationData,
systemConstellationLinkClass: config.constellationLinkClass,
systemRegionLinkClass: config.regionLinkClass,
systemTypeLinkClass: config.typeLinkClass
};
Render.showModule(moduleConfig, moduleData);
return moduleElement;
};
/**
* efore module destroy callback
* @param moduleElement
*/
let beforeDestroy = (moduleElement) => {
// remove xEditable description textarea
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
descriptionTextareaElement.editable('destroy');
};
return {
config: config,
getModule: getModule,
updateModule: updateModule,
beforeDestroy: beforeDestroy
};
});

View File

@@ -1,820 +0,0 @@
/**
* system route module
*/
define([
'jquery',
'app/init',
'app/util',
'bootbox'
], ($, Init, Util, bootbox) => {
'use strict';
let config = {
// module info
modulePosition: 1,
moduleName: 'systemIntel',
moduleHeadClass: 'pf-module-head', // class for module header
moduleHandlerClass: 'pf-module-handler-drag', // class for "drag" handler
moduleTypeClass: 'pf-system-intel-module', // class for this module
// headline toolbar
moduleHeadlineIconClass: 'pf-module-icon-button', // class for toolbar icons in the head
moduleHeadlineIconAddClass: 'pf-module-icon-button-add', // class for "add structure" icon
moduleHeadlineIconReaderClass: 'pf-module-icon-button-reader', // class for "dScan reader" icon
moduleHeadlineIconRefreshClass: 'pf-module-icon-button-refresh', // class for "refresh" icon
// system intel module
systemStructuresTableClass: 'pf-system-structure-table', // class for route tables
// structure dialog
structureDialogId: 'pf-structure-dialog', // id for "structure" dialog
statusSelectId: 'pf-structure-dialog-status-select', // id for "status" select
typeSelectId: 'pf-structure-dialog-type-select', // id for "type" select
corporationSelectId: 'pf-structure-dialog-corporation-select', // id for "corporation" select
descriptionTextareaId: 'pf-structure-dialog-description-textarea', // id for "description" textarea
descriptionTextareaCharCounter: 'pf-form-field-char-count', // class for "character counter" element for form field
// dataTable
tableRowIdPrefix: 'pf-structure-row_', // id prefix for table rows
tableCellImageClass: 'pf-table-image-smaller-cell', // class for table "image" cells
tableCellCounterClass: 'pf-table-counter-cell', // class for table "counter" cells
tableCellEllipsisClass: 'pf-table-cell-ellipses-auto', // class for table "ellipsis" cells
dataTableActionCellClass: 'pf-table-action-cell' // class for "action" cells
};
let maxDescriptionLength = 512;
/**
* get status icon for structure
* @param statusData
* @returns {string}
*/
let getStatusData = (statusData) => {
return '<i class="fas fa-fw fa-circle ' + statusData.class + '" title="' + statusData.label + '"></i>';
};
/**
* get <tr> DOM id by id
* @param tableApi
* @param id
* @returns {*}
*/
let getRowId = (tableApi, id) => {
return tableApi.rows().ids().toArray().find(rowId => rowId === config.tableRowIdPrefix + id);
};
/**
* callback -> add structure rows from responseData
* @param context
* @param responseData
*/
let callbackAddStructureRows = (context, responseData) => {
let systemData = Util.getObjVal(responseData, 'system');
callbackUpdateStructureRows(context, systemData);
};
/**
* callback -> add structure rows from systemData
* @param context
* @param systemData
*/
let callbackUpdateStructureRows = (context, systemData) => {
let touchedRows = [];
let hadData = context.tableApi.rows().any();
let notificationCounter = {
added: 0,
changed: 0,
deleted: 0
};
if(systemData){
let corporations = Util.getObjVal(systemData, 'structures');
if(corporations) {
for (let [corporationId, corporationData] of Object.entries(corporations)){
if(corporationData.structures && corporationData.structures.length){
for(let structureData of corporationData.structures){
let rowId = getRowId(context.tableApi, structureData.id);
// add corporation data
structureData.corporation = {
id: corporationData.id,
name: corporationData.name
};
if(rowId){
// update row
let api = context.tableApi.row('#' + rowId);
let rowData = api.data();
// check for update
if(rowData.updated.updated !== structureData.updated.updated){
// row data changed -> update
api.data(structureData);
api.nodes().to$().data('animationStatus', 'changed').destroyTimestampCounter();
notificationCounter.changed++;
}
touchedRows.push(api.id());
}else{
// insert new row
let api = context.tableApi.row.add(structureData);
api.nodes().to$().data('animationStatus', 'added');
notificationCounter.added++;
touchedRows.push(api.id());
}
}
}
}
}
}
if(context.removeMissing){
let api = context.tableApi.rows((idx, data, node) => !touchedRows.includes(node.id));
notificationCounter.deleted += api.ids().count();
api.remove();
}
context.tableApi.draw();
// show notification ------------------------------------------------------------------------------------------
let notification = '';
notification += notificationCounter.added > 0 ? notificationCounter.added + ' added<br>' : '';
notification += notificationCounter.changed > 0 ? notificationCounter.changed + ' changed<br>' : '';
notification += notificationCounter.deleted > 0 ? notificationCounter.deleted + ' deleted<br>' : '';
if(hadData && notification.length){
Util.showNotify({title: 'Structures updated', text: notification, type: 'success'});
}
};
/**
* callback -> delete structure rows
* @param context
* @param responseData
*/
let callbackDeleteStructures = (context, responseData) => {
let structureIds = Util.getObjVal(responseData, 'deletedStructureIds');
let deletedCounter = 0;
if(structureIds && structureIds.length){
for(let structureId of structureIds){
let rowId = getRowId(context.tableApi, structureId);
if(rowId){
context.tableApi.row('#' + rowId).remove();
deletedCounter++;
}
}
}
if(deletedCounter){
context.tableApi.draw();
Util.showNotify({title: 'Structure deleted', text: deletedCounter + ' deleted', type: 'success'});
}
};
/**
* send ajax request
* @param url
* @param requestData
* @param context
* @param callback
*/
let sendRequest = (url, requestData, context, callback) => {
context.moduleElement.showLoadingAnimation();
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
data: requestData,
context: context
}).done(function(data){
callback(this, data);
}).fail(function( jqXHR, status, error) {
let reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': System intel data', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
}).always(function(){
// hide loading animation
this.moduleElement.hideLoadingAnimation();
});
};
/**
* requests system data
* @param requestData
* @param context
* @param callback
*/
let getStructureData = (requestData, context, callback) => {
sendRequest(Init.path.getSystemData, requestData, context, callback);
};
/**
* save structure data
* @param requestData
* @param context
* @param callback
*/
let saveStructureData = (requestData, context, callback) => {
sendRequest(Init.path.saveStructureData, requestData, context, callback);
};
/**
* delete structure
* @param requestData
* @param context
* @param callback
*/
let deleteStructure = (requestData, context, callback) => {
sendRequest(Init.path.deleteStructureData, requestData, context, callback);
};
/**
* show structure dialog
* @param moduleElement
* @param tableApi
* @param systemId
* @param structureData
*/
let showStructureDialog = (moduleElement, tableApi, systemId, structureData) => {
let structureStatusData = Util.getObjVal(Init, 'structureStatus');
let structureTypeData = Util.getObjVal(Init, 'structureStatus');
let data = {
id: config.structureDialogId,
structureData: structureData,
structureStatus: Object.keys(structureStatusData).map((k) => {
let data = structureStatusData[k];
data.selected = data.id === Util.getObjVal(structureData, 'status.id');
return data;
}),
statusSelectId: config.statusSelectId,
typeSelectId: config.typeSelectId,
corporationSelectId: config.corporationSelectId,
descriptionTextareaId: config.descriptionTextareaId,
descriptionTextareaCharCounter: config.descriptionTextareaCharCounter,
maxDescriptionLength: maxDescriptionLength
};
requirejs(['text!templates/dialog/structure.html', 'mustache'], (template, Mustache) => {
let content = Mustache.render(template, data);
let structureDialog = bootbox.dialog({
title: 'Structure',
message: content,
show: true,
buttons: {
close: {
label: 'cancel',
className: 'btn-default'
},
success: {
label: '<i class="fas fa-fw fa-check"></i>&nbsp;save',
className: 'btn-success',
callback: function (){
let form = this.find('form');
// validate form
form.validator('validate');
// check whether the form is valid
let formValid = form.isValidForm();
if(formValid){
// get form data
let formData = form.getFormValues();
formData.id = Util.getObjVal(structureData, 'id') | 0;
formData.structureId = Util.getObjVal(formData, 'structureId') | 0;
formData.corporationId = Util.getObjVal(formData, 'corporationId') | 0;
formData.systemId = systemId | 0;
saveStructureData({
structures: [formData]
}, {
moduleElement: moduleElement,
tableApi: tableApi
}, callbackUpdateStructureRows);
}else{
return false;
}
}
}
}
});
structureDialog.on('shown.bs.modal', function(e) {
// init type select live search
let selectElementType = $(this).find('#' + config.typeSelectId);
selectElementType.initUniverseTypeSelect({
categoryIds: [65],
maxSelectionLength: 1,
selected: [Util.getObjVal(structureData, 'structure.id')]
});
// init corporation select live search
let selectElementCorporation = $(this).find('#' + config.corporationSelectId);
selectElementCorporation.initUniverseSearch({
categoryNames: ['corporation'],
maxSelectionLength: 1
});
$(this).find('#' + config.statusSelectId).select2({
minimumResultsForSearch: -1
});
// init character counter
let textarea = $(this).find('#' + config.descriptionTextareaId);
let charCounter = $(this).find('.' + config.descriptionTextareaCharCounter);
Util.updateCounter(textarea, charCounter, maxDescriptionLength);
textarea.on('keyup', function(){
Util.updateCounter($(this), charCounter, maxDescriptionLength);
});
// set form validator (after select2 init finish)
$(this).find('form').initFormValidation();
});
});
};
/**
* show D-Scan reader dialog
* @param moduleElement
* @param tableApi
* @param systemData
*/
let showDscanReaderDialog = (moduleElement, tableApi, systemData) => {
requirejs(['text!templates/dialog/dscan_reader.html', 'mustache'], (template, Mustache) => {
let structureDialog = bootbox.dialog({
title: 'D-Scan reader',
message: Mustache.render(template, {}),
show: true,
buttons: {
close: {
label: 'cancel',
className: 'btn-default'
},
success: {
label: '<i class="fas fa-fw fa-paste fa-fw"></i>&nbsp;update intel',
className: 'btn-success',
callback: function (){
let form = this.find('form');
let formData = form.getFormValues();
updateStructureTableByClipboard(systemData, formData.clipboard, {
moduleElement: moduleElement,
tableApi: tableApi
});
}
}
}
});
// dialog shown event
structureDialog.on('shown.bs.modal', function(e) {
// set focus on textarea
structureDialog.find('textarea').focus();
});
});
};
/**
* get module element
* @param parentElement
* @param mapId
* @param systemData
* @returns {jQuery}
*/
let getModule = (parentElement, mapId, systemData) => {
let corporationId = Util.getCurrentUserInfo('corporationId');
// create new module container
let moduleElement = $('<div>').append(
$('<div>', {
class: config.moduleHeadClass
}).append(
$('<h5>', {
class: config.moduleHandlerClass
}),
$('<h5>', {
class: 'pull-right'
}).append(
$('<i>', {
class: ['fas', 'fa-fw', 'fa-plus', config.moduleHeadlineIconClass, config.moduleHeadlineIconAddClass].join(' '),
title: 'add'
}).attr('data-html', 'true').attr('data-toggle', 'tooltip'),
$('<i>', {
class: ['fas', 'fa-fw', 'fa-paste', config.moduleHeadlineIconClass, config.moduleHeadlineIconReaderClass].join(' '),
title: 'D-Scan&nbsp;reader'
}).attr('data-html', 'true').attr('data-toggle', 'tooltip'),
$('<i>', {
class: ['fas', 'fa-fw', 'fa-sync', config.moduleHeadlineIconClass, config.moduleHeadlineIconRefreshClass].join(' '),
title: 'refresh&nbsp;all'
}).attr('data-html', 'true').attr('data-toggle', 'tooltip')
),
$('<h5>', {
text: 'Intel'
})
)
);
let table = $('<table>', {
class: ['compact', 'stripe', 'order-column', 'row-border', 'pf-table-fixed', config.systemStructuresTableClass].join(' ')
});
moduleElement.append(table);
let structureTable = table.DataTable({
paging: false,
lengthChange: false,
ordering: true,
order: [[ 10, 'desc' ], [ 0, 'asc' ]],
info: false,
searching: false,
hover: false,
autoWidth: false,
rowId: rowData => config.tableRowIdPrefix + rowData.id,
language: {
emptyTable: 'No structures recorded',
info: '_START_ to _END_ of _MAX_',
infoEmpty: ''
},
rowGroup: {
enable: true,
dataSrc: 'systemId'
},
columnDefs: [
{
targets: 0,
title: '',
width: 2,
class: 'text-center',
data: 'status',
render: {
display: data => getStatusData(data),
sort: data => data.id
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
$(cell).find('i').tooltip();
}
},{
targets: 1,
title: '',
width: 26,
orderable: false,
className: [config.tableCellImageClass, 'text-center'].join(' '),
data: 'structure.id',
defaultContent: '<i class="fas fa-question txt-color txt-color-orangeDark"></i>',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display' && value){
value = '<img src="' + Init.url.ccpImageServer + '/Type/' + value + '_32.png" />';
}
return value;
}
}
},{
targets: 2,
title: 'type',
width: 30,
className: [config.tableCellEllipsisClass].join(' '),
data: 'structure.name',
defaultContent: '<i class="fas fa-question txt-color txt-color-orangeDark"></i>',
},{
targets: 3,
title: 'name',
width: 60,
className: [config.tableCellEllipsisClass].join(' '),
data: 'name'
},{
targets: 4,
title: '',
width: 26,
orderable: false,
className: [config.tableCellImageClass, 'text-center'].join(' '),
data: 'owner.id',
defaultContent: '<i class="fas fa-question txt-color txt-color-orangeDark"></i>',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display' && value){
value = '<a href="https://zkillboard.com/corporation/' + data + '/" target="_blank" rel="noopener">';
value += '<img src="' + Init.url.ccpImageServer + '/Corporation/' + data + '_32.png" />';
value += '</a>';
}
return value;
}
}
},{
targets: 5,
title: 'owner',
width: 50,
className: [config.tableCellEllipsisClass].join(' '),
data: 'owner.name',
defaultContent: '<i class="fas fa-question txt-color txt-color-orangeDark"></i>',
},{
targets: 6,
title: 'note',
className: [config.tableCellEllipsisClass].join(' '),
data: 'description'
},{
targets: 7,
title: 'updated',
width: 60,
className: ['text-right', config.tableCellCounterClass].join(' '),
data: 'updated.updated'
},{
targets: 8,
title: '',
orderable: false,
width: 10,
class: ['text-center', config.dataTableActionCellClass, config.moduleHeadlineIconClass].join(' '),
data: null,
render: {
display: data => {
let icon = '<i class="fas fa-pencil-alt"></i>';
if(data.corporation.id !== corporationId){
icon = '';
}
return icon;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let tableApi = this.api();
if($(cell).is(':empty')){
$(cell).removeClass(config.dataTableActionCellClass + ' ' + config.moduleHeadlineIconClass);
}else{
$(cell).on('click', function(e) {
// get current row data (important!)
// -> "rowData" param is not current state, values are "on createCell()" state
rowData = tableApi.row( $(cell).parents('tr')).data();
showStructureDialog(moduleElement, tableApi, systemData.systemId, rowData);
});
}
}
},{
targets: 9,
title: '',
orderable: false,
width: 10,
class: ['text-center', config.dataTableActionCellClass].join(' '),
data: null,
render: {
display: data => {
let icon = '<i class="fas fa-times txt-color txt-color-redDarker"></i>';
if(data.corporation.id !== corporationId){
icon = '<i class="fas fa-ban txt-color txt-color-grayLight" title="restricted" data-placement="left"></i>';
}
return icon;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let tableApi = this.api();
if($(cell).find('.fa-ban').length){
$(cell).removeClass(config.dataTableActionCellClass + ' ' + config.moduleHeadlineIconClass);
$(cell).find('i').tooltip();
}else{
let confirmationSettings = {
container: 'body',
placement: 'left',
btnCancelClass: 'btn btn-sm btn-default',
btnCancelLabel: 'cancel',
btnCancelIcon: 'fas fa-fw fa-ban',
title: 'delete structure',
btnOkClass: 'btn btn-sm btn-danger',
btnOkLabel: 'delete',
btnOkIcon: 'fas fa-fw fa-times',
onConfirm : function(e, target){
// get current row data (important!)
// -> "rowData" param is not current state, values are "on createCell()" state
rowData = tableApi.row( $(cell).parents('tr')).data();
// let deleteRowElement = $(cell).parents('tr');
// tableApi.rows(deleteRowElement).remove().draw();
deleteStructure({
id: rowData.id
},{
moduleElement: moduleElement,
tableApi: tableApi
}, callbackDeleteStructures);
}
};
// init confirmation dialog
$(cell).confirmation(confirmationSettings);
}
}
},{
targets: 10,
name: 'corporation',
data: 'corporation',
visible: false,
render: {
sort: function(data){
return data.name;
}
}
}
],
drawCallback: function (settings){
let tableApi = this.api();
let columnCount = tableApi.columns(':visible').count();
let rows = tableApi.rows( {page:'current'} ).nodes();
let last= null;
tableApi.column('corporation:name', {page:'current'} ).data().each( function ( group, i ) {
if ( !last || last.id !== group.id ) {
$(rows).eq(i).before(
'<tr class="group">' +
'<td></td>' +
'<td class="' + config.tableCellImageClass + '">' +
'<img src="' + Init.url.ccpImageServer + '/Corporation/' + group.id + '_32.png" />' +
'</td>' +
'<td colspan="' + (columnCount - 2 ) + '">' + group.name + '</td>' +
'</tr>'
);
last = group;
}
});
rows.to$().find('.' + config.tableCellCounterClass + ':not([data-counter])').initTimestampCounter('d');
let animationRows = rows.to$().filter(function() {
return (
$(this).data('animationStatus') ||
$(this).data('animationTimer')
);
});
for(let i = 0; i < animationRows.length; i++){
let animationRow = $(animationRows[i]);
animationRow.pulseTableRow(animationRow.data('animationStatus'));
animationRow.removeData('animationStatus');
}
},
initComplete: function(settings){
// table data is load in updateModule() method
// -> no need to trigger additional ajax call here for data
// -> in case table update failed -> each if this initComplete() function finished before table updata
// e.g. return now promise in getModule() function
}
});
// init tooltips for this module
let tooltipElements = moduleElement.find('[data-toggle="tooltip"]');
tooltipElements.tooltip({
container: 'body'
});
moduleElement.showLoadingAnimation();
return moduleElement;
};
/**
* get universe typeIds for given categoryIds
* @param categoryIds
* @returns {Array}
*/
let getUniverseTypeIdsByCategoryIds = (categoryIds) => {
let typeIds = [];
let mapIds = type => type.id;
for(let categoryId of categoryIds){
let categoryData = Util.getObjVal(Init, 'universeCategories.' + categoryId);
if(categoryData && categoryData.groups){
for(let groupData of categoryData.groups){
if(groupData && groupData.types){
typeIds = typeIds.concat(groupData.types.map(mapIds));
}
}
}
}
return typeIds;
};
/**
* parse a copy&paste string from ingame dScan windows
* @param systemData
* @param clipboard
* @returns {Array}
*/
let parseDscanString = (systemData, clipboard) => {
let dScanData = [];
let structureTypeIds = getUniverseTypeIdsByCategoryIds([65]);
if(clipboard.length){
let dScanRows = clipboard.split(/\r\n|\r|\n/g);
for(let rowData of dScanRows){
rowData = rowData.split(/\t/g);
if(rowData.length === 4){
rowData[0] = parseInt(rowData[0]);
// valid dScan result
if(structureTypeIds.indexOf( rowData[0] ) !== -1){
dScanData.push({
structureId: rowData[0],
name: rowData[1],
systemId: systemData.systemId
});
}
}
}
}
return dScanData;
};
/**
* parse clipboard data for structures and update table
* @param systemData
* @param clipboard
* @param context
*/
let updateStructureTableByClipboard = (systemData, clipboard, context) => {
let structureData = parseDscanString(systemData, clipboard);
if(structureData.length){
saveStructureData({
structures: structureData
}, context, callbackUpdateStructureRows);
}
};
/**
* update trigger function for this module
* compare data and update module
* @param moduleElement
* @param systemData
*/
let updateModule = (moduleElement, systemData) => {
// update structure table data
let structureTableElement = moduleElement.find('.' + config.systemStructuresTableClass);
let tableApi = structureTableElement.DataTable();
let context = {
tableApi: tableApi,
removeMissing: true
};
callbackUpdateStructureRows(context, systemData);
moduleElement.hideLoadingAnimation();
};
/**
* init intel module
* @param moduleElement
* @param mapId
* @param systemData
*/
let initModule = (moduleElement, mapId, systemData) => {
let structureTableElement = moduleElement.find('.' + config.systemStructuresTableClass);
let tableApi = structureTableElement.DataTable();
// init structure dialog --------------------------------------------------------------------------------------
moduleElement.find('.' + config.moduleHeadlineIconAddClass).on('click', function(e){
showStructureDialog(moduleElement, tableApi, systemData.systemId);
});
// init structure dialog --------------------------------------------------------------------------------------
moduleElement.find('.' + config.moduleHeadlineIconReaderClass).on('click', function(e){
showDscanReaderDialog(moduleElement, tableApi, systemData);
});
// init refresh button ----------------------------------------------------------------------------------------
moduleElement.find('.' + config.moduleHeadlineIconRefreshClass).on('click', function(e){
getStructureData({
mapId: mapId,
systemId: systemData.id
},{
moduleElement: moduleElement,
tableApi: tableApi,
removeMissing: true
}, callbackAddStructureRows);
});
// init listener for global "past" dScan into this page -------------------------------------------------------
moduleElement.on('pf:updateIntelModuleByClipboard', function(e, clipboard){
updateStructureTableByClipboard(systemData, clipboard, {
moduleElement: moduleElement,
tableApi: tableApi
});
});
};
return {
config: config,
getModule: getModule,
initModule: initModule,
updateModule: updateModule
};
});

View File

@@ -1,404 +0,0 @@
define([
'jquery',
'app/init',
'app/util',
'morris'
], ($, Init, Util, Morris) => {
'use strict';
let config = {
// module info
modulePosition: 2,
moduleName: 'systemKillboard',
moduleHeadClass: 'pf-module-head', // class for module header
moduleHandlerClass: 'pf-module-handler-drag', // class for "drag" handler
// headline toolbar
moduleHeadlineIconClass: 'pf-module-icon-button', // class for toolbar icons in the head
// system killboard module
moduleTypeClass: 'pf-system-killboard-module', // class for this module
systemKillboardGraphKillsClass: 'pf-system-killboard-graph-kills', // class for system kill graph
// system killboard list
systemKillboardListClass: 'pf-system-killboard-list', // class for a list with kill entries
systemKillboardListEntryClass: 'pf-system-killboard-list-entry', // class for a list entry
systemKillboardListImgShip: 'pf-system-killboard-img-ship', // class for all ship images
systemKillboardListImgChar: 'pf-system-killboard-img-char', // class for all character logos
systemKillboardListImgAlly: 'pf-system-killboard-img-ally', // class for all alliance logos
systemKillboardListImgCorp: 'pf-system-killboard-img-corp' // class for all corp logos
};
let cache = {
systemKillsGraphData: {} // data for system kills info graph
};
/**
*
* @param text
* @param options
* @returns {jQuery}
*/
let getLabel = (text, options) => {
let label = $('<span>', {
class: ['label', options.type, options.align].join(' ')
}).text( text );
return label;
};
/**
* show killMails
* @param moduleElement
* @param killboardData
*/
let showKillmails = (moduleElement, killboardData) => {
// show number of killMails
let killMailCounterMax = 20;
let killMailCounter = 0;
// change order (show right to left)
killboardData.tableData.reverse();
let data = {
tableData: killboardData.tableData,
systemKillboardListClass: config.systemKillboardListClass,
systemKillboardListEntryClass: config.systemKillboardListEntryClass,
systemKillboardListImgShip: config.systemKillboardListImgShip,
systemKillboardListImgChar: config.systemKillboardListImgChar,
systemKillboardListImgAlly: config.systemKillboardListImgAlly,
systemKillboardListImgCorp: config.systemKillboardListImgCorp,
zKillboardUrl: 'https://zkillboard.com',
ccpImageServerUrl: Init.url.ccpImageServer,
dateFormat: () => {
return (val, render) => {
let killDate = Util.convertDateToUTC(new Date(render(val)));
return Util.convertDateToString(killDate);
};
},
iskFormat: () => {
return (val, render) => {
return Util.formatPrice(render(val));
};
},
checkRender : () => {
return (val, render) => {
if(killMailCounter < killMailCounterMax){
return render(val);
}
};
},
increaseCount : () => {
return (val, render) => {
killMailCounter++;
};
}
};
requirejs(['text!templates/modules/killboard.html', 'mustache'], function(template, Mustache) {
let content = Mustache.render(template, data);
moduleElement.append(content);
// animate kill li-elements
$('.' + config.systemKillboardListEntryClass).velocity('transition.expandIn', {
stagger: 50,
complete: function(){
// init tooltips
moduleElement.find('[title]').tooltip({
container: 'body'
});
}
});
});
};
/**
* updates the system info graph
* @param systemData
*/
$.fn.updateSystemInfoGraphs = function(systemData){
let moduleElement = $(this);
let killboardGraphElement = $('<div>', {
class: config.systemKillboardGraphKillsClass
});
moduleElement.append(killboardGraphElement);
let showHours = 24;
let maxKillmailCount = 200; // limited by API
let labelOptions = {
align: 'center-block'
};
let label = '';
// private function draws a "system kills" graph
let drawGraph = function(data){
let tableData = data.tableData;
// change order (show right to left)
tableData.reverse();
if(data.count === 0){
labelOptions.type = 'label-success';
label = getLabel( 'No kills found within the last 24h', labelOptions );
killboardGraphElement.append( label );
minifyKillboardGraphElement(killboardGraphElement);
return;
}
let labelYFormat = function(y){
return Math.round(y);
};
// draw chart
Morris.Bar({
element: killboardGraphElement,
resize: true,
redraw: true,
grid: true,
gridStrokeWidth: 0.3,
gridTextSize: 9,
gridTextColor: '#63676a',
gridTextFamily: 'Oxygen Bold',
hideHover: true,
data: tableData,
xkey: 'label',
ykeys: ['kills'],
labels: ['Kills'],
yLabelFormat: labelYFormat,
xLabelMargin: 10,
padding: 10,
parseTime: false,
barOpacity: 0.8,
barRadius: [2, 2, 0, 0],
barSizeRatio: 0.5,
barGap: 3,
barColors: function (row, series, type) {
if (type === 'bar') {
// highlight last row -> recent kills found
if(this.xmax === row.x){
return '#c2760c';
}
}
return '#375959';
}
});
// show hint for recent kills
if(tableData[tableData.length - 1].kills > 0){
labelOptions.type = 'label-warning';
label = getLabel( tableData[tableData.length - 1].kills + ' kills within the last hour', labelOptions );
killboardGraphElement.prepend( label );
}
};
// get recent KB stats (last 24h))
let localDate = new Date();
// cache result for 5min
let cacheKey = systemData.systemId + '_' + localDate.getHours() + '_' + ( Math.ceil( localDate.getMinutes() / 5 ) * 5);
if(cache.systemKillsGraphData.hasOwnProperty(cacheKey) ){
// cached results
drawGraph( cache.systemKillsGraphData[cacheKey] );
// show killmail information
showKillmails(moduleElement, cache.systemKillsGraphData[cacheKey]);
}else{
// chart data
let chartData = [];
for(let i = 0; i < showHours; i++){
let tempData = {
label: i + 'h',
kills: 0
};
chartData.push(tempData);
}
// get kills within the last 24h
let timeFrameInSeconds = 60 * 60 * 24;
// get current server time
let serverDate= Util.getServerTime();
// if system is w-space system -> add link modifier
let wSpaceLinkModifier = '';
if(systemData.type.id === 1){
wSpaceLinkModifier = 'w-space/';
}
let url = Init.url.zKillboard + '/';
url += 'no-items/' + wSpaceLinkModifier + 'no-attackers/solarSystemID/' + systemData.systemId + '/pastSeconds/' + timeFrameInSeconds + '/';
killboardGraphElement.showLoadingAnimation();
$.ajax({
url: url,
type: 'GET',
dataType: 'json'
}).done(function(kbData) {
// the API wont return more than 200KMs ! - remember last bar block with complete KM information
let lastCompleteDiffHourData = 0;
// loop kills and count kills by hour
for (let i = 0; i < kbData.length; i++) {
let killmailData = kbData[i];
let killDate = Util.convertDateToUTC(new Date(killmailData.killmail_time));
// get time diff
let timeDiffMin = Math.round(( serverDate - killDate ) / 1000 / 60);
let timeDiffHour = Math.floor(timeDiffMin / 60);
// update chart data
if (chartData[timeDiffHour]) {
chartData[timeDiffHour].kills++;
// add kill mail data
if (chartData[timeDiffHour].killmails === undefined) {
chartData[timeDiffHour].killmails = [];
}
chartData[timeDiffHour].killmails.push(killmailData);
if (timeDiffHour > lastCompleteDiffHourData) {
lastCompleteDiffHourData = timeDiffHour;
}
}
}
// remove empty chart Data
if (kbData.length >= maxKillmailCount) {
chartData = chartData.splice(0, lastCompleteDiffHourData + 1);
}
// fill cache
cache.systemKillsGraphData[cacheKey] = {};
cache.systemKillsGraphData[cacheKey].tableData = chartData;
cache.systemKillsGraphData[cacheKey].count = kbData.length;
// draw table
drawGraph(cache.systemKillsGraphData[cacheKey]);
// show killmail information
showKillmails(moduleElement, cache.systemKillsGraphData[cacheKey]);
killboardGraphElement.hideLoadingAnimation();
}).fail(function(e){
labelOptions.type = 'label-danger';
label = getLabel( 'zKillboard is not responding', labelOptions );
killboardGraphElement.prepend( label );
killboardGraphElement.hideLoadingAnimation();
minifyKillboardGraphElement(killboardGraphElement);
Util.showNotify({title: e.status + ': Get system kills', text: 'Loading failed', type: 'error'});
});
}
// init tooltips
let tooltipElements = moduleElement.find('[data-toggle="tooltip"]');
tooltipElements.tooltip({
container: 'body'
});
};
/**
* minify the killboard graph element e.g. if no kills where found, or on error
* @param killboardGraphElement
*/
let minifyKillboardGraphElement = (killboardGraphElement) => {
killboardGraphElement.velocity({
height: '20px',
marginBottom: '0px'
},{
duration: Init.animationSpeed.mapModule
});
};
/**
* get module toolbar element
* @param systemData
* @returns {*|jQuery|HTMLElement|void}
*/
let getHeadlineToolbar = (systemData) => {
let headlineToolbar = $('<h5>', {
class: 'pull-right'
}).append(
$('<i>', {
class: ['fas', 'fa-fw', 'fa-external-link-alt ', config.moduleHeadlineIconClass].join(' '),
title: 'zkillboard.com'
}).on('click', function(e){
window.open(
'//zkillboard.com/system/' + systemData.systemId,
'_blank'
);
}).attr('data-toggle', 'tooltip')
);
headlineToolbar.find('[data-toggle="tooltip"]').tooltip({
container: 'body'
});
return headlineToolbar;
};
/**
* before module "show" callback
* @param moduleElement
* @param systemData
*/
let beforeShow = (moduleElement, systemData) => {
// update graph
moduleElement.updateSystemInfoGraphs(systemData);
};
/**
* get module element
* @param parentElement
* @param mapId
* @param systemData
* @returns {jQuery}
*/
let getModule = (parentElement, mapId, systemData) => {
// create new module container
let moduleElement = $('<div>').append(
$('<div>', {
class: config.moduleHeadClass
}).append(
$('<h5>', {
class: config.moduleHandlerClass
}),
$('<h5>', {
text: 'Killboard'
}),
getHeadlineToolbar(systemData)
)
);
return moduleElement;
};
return {
config: config,
getModule: getModule,
beforeShow: beforeShow
};
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,162 +1,2 @@
'use strict';
// "fake" window object will contain "MsgWorker" after import
let window = {}; // jshint ignore:line
// import "MsgWorker" class
self.importScripts( self.name ); // jshint ignore:line
let MsgWorker = window.MsgWorker;
let socket = null;
let ports = [];
let characterPorts = [];
// init "WebSocket" connection ========================================================================================
let initSocket = (uri) => {
let MsgWorkerOpen = new MsgWorker('ws:open');
if(socket === null){
socket = new WebSocket(uri);
// "WebSocket" open -----------------------------------------------------------------------
socket.onopen = (e) => {
MsgWorkerOpen.meta({
readyState: socket.readyState
});
sendToCurrentPort(MsgWorkerOpen);
};
// "WebSocket message ---------------------------------------------------------------------
socket.onmessage = (e) => {
let response = JSON.parse(e.data);
let MsgWorkerSend = new MsgWorker('ws:send');
MsgWorkerSend.task( response.task );
MsgWorkerSend.meta({
readyState: this.readyState,
characterIds: response.characterIds
});
MsgWorkerSend.data( response.load );
broadcastPorts(MsgWorkerSend);
};
// "WebSocket" close ----------------------------------------------------------------------
socket.onclose = (closeEvent) => {
let MsgWorkerClosed = new MsgWorker('ws:closed');
MsgWorkerClosed.meta({
readyState: socket.readyState,
code: closeEvent.code,
reason: closeEvent.reason,
wasClean: closeEvent.wasClean
});
broadcastPorts(MsgWorkerClosed);
socket = null; // reset WebSocket
};
// "WebSocket" error ----------------------------------------------------------------------
socket.onerror = (e) => {
let MsgWorkerError = new MsgWorker('ws:error');
MsgWorkerError.meta({
readyState: socket.readyState
});
sendToCurrentPort(MsgWorkerError);
};
}else{
// socket still open
MsgWorkerOpen.meta({
readyState: socket.readyState
});
sendToCurrentPort(MsgWorkerOpen);
}
};
// send message to port(s) ============================================================================================
let sendToCurrentPort = (load) => {
ports[ports.length - 1].postMessage(load);
};
let broadcastPorts = (load) => {
// default: sent to all ports
let sentToPorts = ports;
// check if send() is limited to some ports
let meta = load.meta();
if(
meta &&
meta.characterIds &&
meta.characterIds !== 'undefined' &&
meta.characterIds instanceof Array
){
// ... get ports for characterIds
sentToPorts = getPortsByCharacterIds(meta.characterIds);
}
for (let i = 0; i < sentToPorts.length; i++) {
sentToPorts[i].postMessage(load);
}
};
// port functions =====================================================================================================
let addPort = (port, characterId) => {
characterId = parseInt(characterId);
if(characterId > 0){
characterPorts.push({
characterId: characterId,
port: port
});
}else{
ports.push(port);
}
};
let getPortsByCharacterIds = (characterIds) => {
let ports = [];
for(let i = 0; i < characterPorts.length; i++){
for(let j = 0; j < characterIds.length; j++){
if(characterPorts[i].characterId === characterIds[j]){
ports.push(characterPorts[i].port);
}
}
}
return ports;
};
// "SharedWorker" connection ==========================================================================================
self.addEventListener('connect', (event) => { // jshint ignore:line
let port = event.ports[0];
addPort(port);
port.addEventListener('message', (e) => {
let MsgWorkerMessage = e.data;
Object.setPrototypeOf(MsgWorkerMessage, MsgWorker.prototype);
switch(MsgWorkerMessage.command){
case 'ws:init':
let data = MsgWorkerMessage.data();
// add character specific port (for broadcast) to individual ports (tabs)
addPort(port, data.characterId);
initSocket(data.uri);
break;
case 'ws:send':
let MsgSocket = {
task: MsgWorkerMessage.task(),
load: MsgWorkerMessage.data()
};
socket.send(JSON.stringify(MsgSocket));
break;
case 'ws:close':
// closeSocket();
break;
}
}, false);
port.start();
}, false);
"use strict";let window={};self.importScripts(self.name);let MsgWorker=window.MsgWorker,socket=null,ports=[],characterPorts=[],initSocket=e=>{let t=new MsgWorker("ws:open");null===socket?((socket=new WebSocket(e)).onopen=(e=>{t.meta({readyState:socket.readyState}),sendToCurrentPort(t)}),socket.onmessage=(e=>{let t=JSON.parse(e.data),r=new MsgWorker("ws:send");r.task(t.task),r.meta({readyState:this.readyState,characterIds:t.characterIds}),r.data(t.load),broadcastPorts(r)}),socket.onclose=(e=>{let t=new MsgWorker("ws:closed");t.meta({readyState:socket.readyState,code:e.code,reason:e.reason,wasClean:e.wasClean}),broadcastPorts(t),socket=null}),socket.onerror=(e=>{let t=new MsgWorker("ws:error");t.meta({readyState:socket.readyState}),sendToCurrentPort(t)})):(t.meta({readyState:socket.readyState}),sendToCurrentPort(t))},sendToCurrentPort=e=>{ports[ports.length-1].postMessage(e)},broadcastPorts=e=>{let t=ports,r=e.meta();r&&r.characterIds&&"undefined"!==r.characterIds&&r.characterIds instanceof Array&&(t=getPortsByCharacterIds(r.characterIds));for(let r=0;r<t.length;r++)t[r].postMessage(e)},addPort=(e,t)=>{(t=parseInt(t))>0?characterPorts.push({characterId:t,port:e}):ports.push(e)},getPortsByCharacterIds=e=>{let t=[];for(let r=0;r<characterPorts.length;r++)for(let a=0;a<e.length;a++)characterPorts[r].characterId===e[a]&&t.push(characterPorts[r].port);return t};self.addEventListener("connect",e=>{let t=e.ports[0];addPort(t),t.addEventListener("message",e=>{let r=e.data;switch(Object.setPrototypeOf(r,MsgWorker.prototype),r.command){case"ws:init":let e=r.data();addPort(t,e.characterId),initSocket(e.uri);break;case"ws:send":let a={task:r.task(),load:r.data()};socket.send(JSON.stringify(a))}},!1),t.start()},!1);
//# sourceMappingURL=map.js.map

Binary file not shown.

View File

@@ -0,0 +1 @@
{"version":3,"sources":["app/worker/map.js"],"names":["window","self","importScripts","name","MsgWorker","socket","ports","characterPorts","initSocket","uri","MsgWorkerOpen","WebSocket","onopen","e","meta","readyState","sendToCurrentPort","onmessage","response","JSON","parse","data","MsgWorkerSend","task","this","characterIds","load","broadcastPorts","onclose","closeEvent","MsgWorkerClosed","code","reason","wasClean","onerror","MsgWorkerError","length","postMessage","sentToPorts","Array","getPortsByCharacterIds","i","addPort","port","characterId","parseInt","push","j","addEventListener","event","MsgWorkerMessage","Object","setPrototypeOf","prototype","command","MsgSocket","send","stringify","start"],"mappings":"AAAA,aAGA,IAAIA,UAGJC,KAAKC,cAAeD,KAAKE,MAEzB,IAAIC,UAAYJ,OAAOI,UACnBC,OAAS,KACTC,SACAC,kBAGAC,WAAcC,IACd,IAAIC,EAAgB,IAAIN,UAAU,WAEpB,OAAXC,SACCA,OAAS,IAAIM,UAAUF,IAGhBG,OAAS,CAACC,IACbH,EAAcI,MACVC,WAAYV,OAAOU,aAGvBC,kBAAkBN,KAItBL,OAAOY,UAAY,CAACJ,IAChB,IAAIK,EAAWC,KAAKC,MAAMP,EAAEQ,MAExBC,EAAgB,IAAIlB,UAAU,WAClCkB,EAAcC,KAAML,EAASK,MAC7BD,EAAcR,MACVC,WAAYS,KAAKT,WACjBU,aAAcP,EAASO,eAE3BH,EAAcD,KAAMH,EAASQ,MAE7BC,eAAeL,KAInBjB,OAAOuB,QAAU,CAACC,IACd,IAAIC,EAAkB,IAAI1B,UAAU,aACpC0B,EAAgBhB,MACZC,WAAYV,OAAOU,WACnBgB,KAAMF,EAAWE,KACjBC,OAAQH,EAAWG,OACnBC,SAAUJ,EAAWI,WAGzBN,eAAeG,GACfzB,OAAS,OAIbA,OAAO6B,QAAU,CAACrB,IACd,IAAIsB,EAAiB,IAAI/B,UAAU,YACnC+B,EAAerB,MACXC,WAAYV,OAAOU,aAGvBC,kBAAkBmB,OAItBzB,EAAcI,MACVC,WAAYV,OAAOU,aAEvBC,kBAAkBN,KAKtBM,kBAAqBU,IACrBpB,MAAMA,MAAM8B,OAAS,GAAGC,YAAYX,IAGpCC,eAAkBD,IAElB,IAAIY,EAAchC,MAGdQ,EAAOY,EAAKZ,OAEZA,GACAA,EAAKW,cACiB,cAAtBX,EAAKW,cACLX,EAAKW,wBAAwBc,QAG7BD,EAAcE,uBAAuB1B,EAAKW,eAG9C,IAAK,IAAIgB,EAAI,EAAGA,EAAIH,EAAYF,OAAQK,IACpCH,EAAYG,GAAGJ,YAAYX,IAK/BgB,QAAU,CAACC,EAAMC,MACjBA,EAAcC,SAASD,IAEN,EACbrC,eAAeuC,MACXF,YAAaA,EACbD,KAAMA,IAGVrC,MAAMwC,KAAKH,IAIfH,uBAA0Bf,IAC1B,IAAInB,KAEJ,IAAI,IAAImC,EAAI,EAAGA,EAAIlC,eAAe6B,OAAQK,IACtC,IAAI,IAAIM,EAAI,EAAGA,EAAItB,EAAaW,OAAQW,IACjCxC,eAAekC,GAAGG,cAAgBnB,EAAasB,IAC9CzC,EAAMwC,KAAKvC,eAAekC,GAAGE,MAKzC,OAAOrC,GAIXL,KAAK+C,iBAAiB,UAAYC,IAC9B,IAAIN,EAAOM,EAAM3C,MAAM,GACvBoC,QAAQC,GAERA,EAAKK,iBAAiB,UAAYnC,IAC9B,IAAIqC,EAAmBrC,EAAEQ,KAGzB,OAFA8B,OAAOC,eAAeF,EAAkB9C,UAAUiD,WAE3CH,EAAiBI,SACpB,IAAK,UACD,IAAIjC,EAAO6B,EAAiB7B,OAE5BqB,QAAQC,EAAMtB,EAAKuB,aACnBpC,WAAWa,EAAKZ,KAChB,MACJ,IAAK,UACD,IAAI8C,GACAhC,KAAM2B,EAAiB3B,OACvBG,KAAMwB,EAAiB7B,QAG3BhB,OAAOmD,KAAKrC,KAAKsC,UAAUF,OAMpC,GAEHZ,EAAKe,UACN","file":"map.js","sourceRoot":"/js"}

View File

@@ -1,55 +1,2 @@
window.MsgWorker = class MessageWorker {
constructor(cmd){
/**
* "command" type (identifies this message)
*/
this.cmd = cmd;
/**
* "task" what should be done with this message
* @type {string}
*/
this.msgTask = '';
/**
* "message" meta data (e.g. error/close data from WebSocket
* @type {null}
*/
this.msgMeta = null;
/**
* "message" body (load)
* @type {null}
*/
this.msgBody = null;
}
get command(){
return this.cmd;
}
task(task) {
if(task){
this.msgTask = task;
}
return this.msgTask;
}
meta(metaData) {
if(metaData){
this.msgMeta = metaData;
}
return this.msgMeta;
}
data(data) {
if(data){
this.msgBody = data;
}
return this.msgBody;
}
};
window.MsgWorker=class{constructor(s){this.cmd=s,this.msgTask="",this.msgMeta=null,this.msgBody=null}get command(){return this.cmd}task(s){return s&&(this.msgTask=s),this.msgTask}meta(s){return s&&(this.msgMeta=s),this.msgMeta}data(s){return s&&(this.msgBody=s),this.msgBody}};
//# sourceMappingURL=message.js.map

View File

@@ -0,0 +1 @@
9<01>Ĵ9<C4B4>F<EFBFBD>0~y<><18>|uK<75>v0<76>Iw<49><77>.<2E>x<14><><EFBFBD><EFBFBD>(O<><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><12><>zʘL0<4C><05><><EFBFBD><EFBFBD>ů<EFBFBD>r<16>_D<5F>? <1<><31>P(<28>LFj<46><1C><><EFBFBD>H<EFBFBD><48><EFBFBD><EFBFBD><EFBFBD>26hL<68>3<EFBFBD><33>- <0C>0 +<2B> ;<3B><0F>#<23>dMFj=<3D><><EFBFBD><EFBFBD><EFBFBD>`+s$<24>P=.a<>veS<65>r<EFBFBD>z<EFBFBD><7A><EFBFBD>>

View File

@@ -0,0 +1 @@
{"version":3,"sources":["app/worker/message.js"],"names":["window","MsgWorker","[object Object]","cmd","this","msgTask","msgMeta","msgBody","command","task","metaData","data"],"mappings":"AAAAA,OAAOC,gBAEHC,YAAYC,GAIRC,KAAKD,IAAMA,EAMXC,KAAKC,QAAU,GAMfD,KAAKE,QAAU,KAMfF,KAAKG,QAAU,KAGnBC,cACI,OAAOJ,KAAKD,IAGhBD,KAAKO,GAKD,OAJGA,IACCL,KAAKC,QAAUI,GAGZL,KAAKC,QAGhBH,KAAKQ,GAKD,OAJGA,IACCN,KAAKE,QAAUI,GAGZN,KAAKE,QAGhBJ,KAAKS,GAKD,OAJGA,IACCP,KAAKG,QAAUI,GAGZP,KAAKG","file":"message.js","sourceRoot":"/js"}

View File

@@ -1,12 +0,0 @@
/*!
* VERSION: beta 1.9.4
* DATE: 2014-07-17
* UPDATES AND DOCS AT: http://www.greensock.com
*
* @license Copyright (c) 2008-2014, GreenSock. All rights reserved.
* This work is subject to the terms at http://www.greensock.com/terms_of_use.html or for
* Club GreenSock members, the software agreement that was issued with your membership.
*
* @author: Jack Doyle, jack@greensock.com
**/
var _gsScope="undefined"!=typeof module&&module.exports&&"undefined"!=typeof global?global:this||window;(_gsScope._gsQueue||(_gsScope._gsQueue=[])).push(function(){"use strict";_gsScope._gsDefine("easing.Back",["easing.Ease"],function(t){var e,i,s,r=_gsScope.GreenSockGlobals||_gsScope,n=r.com.greensock,a=2*Math.PI,o=Math.PI/2,h=n._class,l=function(e,i){var s=h("easing."+e,function(){},!0),r=s.prototype=new t;return r.constructor=s,r.getRatio=i,s},_=t.register||function(){},u=function(t,e,i,s){var r=h("easing."+t,{easeOut:new e,easeIn:new i,easeInOut:new s},!0);return _(r,t),r},c=function(t,e,i){this.t=t,this.v=e,i&&(this.next=i,i.prev=this,this.c=i.v-e,this.gap=i.t-t)},p=function(e,i){var s=h("easing."+e,function(t){this._p1=t||0===t?t:1.70158,this._p2=1.525*this._p1},!0),r=s.prototype=new t;return r.constructor=s,r.getRatio=i,r.config=function(t){return new s(t)},s},f=u("Back",p("BackOut",function(t){return(t-=1)*t*((this._p1+1)*t+this._p1)+1}),p("BackIn",function(t){return t*t*((this._p1+1)*t-this._p1)}),p("BackInOut",function(t){return 1>(t*=2)?.5*t*t*((this._p2+1)*t-this._p2):.5*((t-=2)*t*((this._p2+1)*t+this._p2)+2)})),m=h("easing.SlowMo",function(t,e,i){e=e||0===e?e:.7,null==t?t=.7:t>1&&(t=1),this._p=1!==t?e:0,this._p1=(1-t)/2,this._p2=t,this._p3=this._p1+this._p2,this._calcEnd=i===!0},!0),d=m.prototype=new t;return d.constructor=m,d.getRatio=function(t){var e=t+(.5-t)*this._p;return this._p1>t?this._calcEnd?1-(t=1-t/this._p1)*t:e-(t=1-t/this._p1)*t*t*t*e:t>this._p3?this._calcEnd?1-(t=(t-this._p3)/this._p1)*t:e+(t-e)*(t=(t-this._p3)/this._p1)*t*t*t:this._calcEnd?1:e},m.ease=new m(.7,.7),d.config=m.config=function(t,e,i){return new m(t,e,i)},e=h("easing.SteppedEase",function(t){t=t||1,this._p1=1/t,this._p2=t+1},!0),d=e.prototype=new t,d.constructor=e,d.getRatio=function(t){return 0>t?t=0:t>=1&&(t=.999999999),(this._p2*t>>0)*this._p1},d.config=e.config=function(t){return new e(t)},i=h("easing.RoughEase",function(e){e=e||{};for(var i,s,r,n,a,o,h=e.taper||"none",l=[],_=0,u=0|(e.points||20),p=u,f=e.randomize!==!1,m=e.clamp===!0,d=e.template instanceof t?e.template:null,g="number"==typeof e.strength?.4*e.strength:.4;--p>-1;)i=f?Math.random():1/u*p,s=d?d.getRatio(i):i,"none"===h?r=g:"out"===h?(n=1-i,r=n*n*g):"in"===h?r=i*i*g:.5>i?(n=2*i,r=.5*n*n*g):(n=2*(1-i),r=.5*n*n*g),f?s+=Math.random()*r-.5*r:p%2?s+=.5*r:s-=.5*r,m&&(s>1?s=1:0>s&&(s=0)),l[_++]={x:i,y:s};for(l.sort(function(t,e){return t.x-e.x}),o=new c(1,1,null),p=u;--p>-1;)a=l[p],o=new c(a.x,a.y,o);this._prev=new c(0,0,0!==o.t?o:o.next)},!0),d=i.prototype=new t,d.constructor=i,d.getRatio=function(t){var e=this._prev;if(t>e.t){for(;e.next&&t>=e.t;)e=e.next;e=e.prev}else for(;e.prev&&e.t>=t;)e=e.prev;return this._prev=e,e.v+(t-e.t)/e.gap*e.c},d.config=function(t){return new i(t)},i.ease=new i,u("Bounce",l("BounceOut",function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}),l("BounceIn",function(t){return 1/2.75>(t=1-t)?1-7.5625*t*t:2/2.75>t?1-(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1-(7.5625*(t-=2.25/2.75)*t+.9375):1-(7.5625*(t-=2.625/2.75)*t+.984375)}),l("BounceInOut",function(t){var e=.5>t;return t=e?1-2*t:2*t-1,t=1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375,e?.5*(1-t):.5*t+.5})),u("Circ",l("CircOut",function(t){return Math.sqrt(1-(t-=1)*t)}),l("CircIn",function(t){return-(Math.sqrt(1-t*t)-1)}),l("CircInOut",function(t){return 1>(t*=2)?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)})),s=function(e,i,s){var r=h("easing."+e,function(t,e){this._p1=t||1,this._p2=e||s,this._p3=this._p2/a*(Math.asin(1/this._p1)||0)},!0),n=r.prototype=new t;return n.constructor=r,n.getRatio=i,n.config=function(t,e){return new r(t,e)},r},u("Elastic",s("ElasticOut",function(t){return this._p1*Math.pow(2,-10*t)*Math.sin((t-this._p3)*a/this._p2)+1},.3),s("ElasticIn",function(t){return-(this._p1*Math.pow(2,10*(t-=1))*Math.sin((t-this._p3)*a/this._p2))},.3),s("ElasticInOut",function(t){return 1>(t*=2)?-.5*this._p1*Math.pow(2,10*(t-=1))*Math.sin((t-this._p3)*a/this._p2):.5*this._p1*Math.pow(2,-10*(t-=1))*Math.sin((t-this._p3)*a/this._p2)+1},.45)),u("Expo",l("ExpoOut",function(t){return 1-Math.pow(2,-10*t)}),l("ExpoIn",function(t){return Math.pow(2,10*(t-1))-.001}),l("ExpoInOut",function(t){return 1>(t*=2)?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*(t-1)))})),u("Sine",l("SineOut",function(t){return Math.sin(t*o)}),l("SineIn",function(t){return-Math.cos(t*o)+1}),l("SineInOut",function(t){return-.5*(Math.cos(Math.PI*t)-1)})),h("easing.EaseLookup",{find:function(e){return t.map[e]}},!0),_(r.SlowMo,"SlowMo","ease,"),_(i,"RoughEase","ease,"),_(e,"SteppedEase","ease,"),f},!0)}),_gsScope._gsDefine&&_gsScope._gsQueue.pop()();

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,190 +0,0 @@
/*
* blueimp helper JS
* https://github.com/blueimp/Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
/* global define, window, document */
;(function () {
'use strict'
function extend (obj1, obj2) {
var prop
for (prop in obj2) {
if (obj2.hasOwnProperty(prop)) {
obj1[prop] = obj2[prop]
}
}
return obj1
}
function Helper (query) {
if (!this || this.find !== Helper.prototype.find) {
// Called as function instead of as constructor,
// so we simply return a new instance:
return new Helper(query)
}
this.length = 0
if (query) {
if (typeof query === 'string') {
query = this.find(query)
}
if (query.nodeType || query === query.window) {
// Single HTML element
this.length = 1
this[0] = query
} else {
// HTML element collection
var i = query.length
this.length = i
while (i) {
i -= 1
this[i] = query[i]
}
}
}
}
Helper.extend = extend
Helper.contains = function (container, element) {
do {
element = element.parentNode
if (element === container) {
return true
}
} while (element)
return false
}
Helper.parseJSON = function (string) {
return window.JSON && JSON.parse(string)
}
extend(Helper.prototype, {
find: function (query) {
var container = this[0] || document
if (typeof query === 'string') {
if (container.querySelectorAll) {
query = container.querySelectorAll(query)
} else if (query.charAt(0) === '#') {
query = container.getElementById(query.slice(1))
} else {
query = container.getElementsByTagName(query)
}
}
return new Helper(query)
},
hasClass: function (className) {
if (!this[0]) {
return false
}
return new RegExp('(^|\\s+)' + className +
'(\\s+|$)').test(this[0].className)
},
addClass: function (className) {
var i = this.length
var element
while (i) {
i -= 1
element = this[i]
if (!element.className) {
element.className = className
return this
}
if (this.hasClass(className)) {
return this
}
element.className += ' ' + className
}
return this
},
removeClass: function (className) {
var regexp = new RegExp('(^|\\s+)' + className + '(\\s+|$)')
var i = this.length
var element
while (i) {
i -= 1
element = this[i]
element.className = element.className.replace(regexp, ' ')
}
return this
},
on: function (eventName, handler) {
var eventNames = eventName.split(/\s+/)
var i
var element
while (eventNames.length) {
eventName = eventNames.shift()
i = this.length
while (i) {
i -= 1
element = this[i]
if (element.addEventListener) {
element.addEventListener(eventName, handler, false)
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, handler)
}
}
}
return this
},
off: function (eventName, handler) {
var eventNames = eventName.split(/\s+/)
var i
var element
while (eventNames.length) {
eventName = eventNames.shift()
i = this.length
while (i) {
i -= 1
element = this[i]
if (element.removeEventListener) {
element.removeEventListener(eventName, handler, false)
} else if (element.detachEvent) {
element.detachEvent('on' + eventName, handler)
}
}
}
return this
},
empty: function () {
var i = this.length
var element
while (i) {
i -= 1
element = this[i]
while (element.hasChildNodes()) {
element.removeChild(element.lastChild)
}
}
return this
},
first: function () {
return new Helper(this[0])
}
})
if (typeof define === 'function' && define.amd) {
define(function () {
return Helper
})
} else {
window.blueimp = window.blueimp || {}
window.blueimp.helper = Helper
}
}())

File diff suppressed because one or more lines are too long

View File

@@ -1,256 +0,0 @@
/*!
* Bootstrap Confirmation v1.0.7
* https://github.com/tavicu/bs-confirmation
*/
+function ($) {
'use strict';
//var for check event at body can have only one.
var event_body = false;
// CONFIRMATION PUBLIC CLASS DEFINITION
// ===============================
var Confirmation = function (element, options) {
var that = this;
this.init('confirmation', element, options);
if (options.selector) {
$(element).on('click.bs.confirmation', options.selector, function(e) {
e.preventDefault();
});
} else {
$(element).on('show.bs.confirmation', function(event) {
that.runCallback(that.options.onShow, event, that.$element);
that.$element.addClass('open');
if (that.options.singleton) {
$(that.options.all_selector).not(that.$element).each(function() {
if ($(this).hasClass('open')) {
$(this).confirmation('hide');
}
});
}
}).on('hide.bs.confirmation', function(event) {
that.runCallback(that.options.onHide, event, that.$element);
that.$element.removeClass('open');
}).on('shown.bs.confirmation', function(e) {
if (!that.isPopout() && !event_body) {
return;
}
event_body = $('body').on('click', function (e) {
if (that.$element.is(e.target)) return;
if (that.$element.has(e.target).length) return;
if ($('.popover').has(e.target).length) return;
that.hide();
that.inState.click = false;
$('body').unbind(e);
event_body = false;
return;
});
}).on('click.bs.confirmation', function(e) {
e.preventDefault();
});
}
}
if (!$.fn.popover || !$.fn.tooltip) throw new Error('Confirmation requires popover.js and tooltip.js');
Confirmation.VERSION = '1.0.7'
Confirmation.DEFAULTS = $.extend({}, $.fn.popover.Constructor.DEFAULTS, {
placement : 'right',
title : 'Are you sure?',
btnOkClass : 'btn btn-sm btn-danger',
btnOkLabel : 'Delete',
btnOkIcon : 'glyphicon glyphicon-ok',
btnCancelClass : 'btn btn-sm btn-default',
btnCancelLabel : 'Cancel',
btnCancelIcon : 'glyphicon glyphicon-remove',
href : '#',
target : '_self',
singleton : true,
popout : true,
onShow : function(event, element) {},
onHide : function(event, element) {},
onConfirm : function(event, element) {},
onCancel : function(event, element) {},
template : '<div class="popover"><div class="arrow"></div>'
+ '<h3 class="popover-title"></h3>'
+ '<div class="popover-content">'
+ ' <a data-apply="confirmation">Yes</a>'
+ ' <a data-dismiss="confirmation">No</a>'
+ '</div>'
+ '</div>'
});
// NOTE: CONFIRMATION EXTENDS popover.js
// ================================
Confirmation.prototype = $.extend({}, $.fn.popover.Constructor.prototype);
Confirmation.prototype.constructor = Confirmation;
Confirmation.prototype.getDefaults = function () {
return Confirmation.DEFAULTS;
}
Confirmation.prototype.setContent = function () {
var that = this;
var $tip = this.tip();
var title = this.getTitle();
var $btnOk = $tip.find('[data-apply="confirmation"]');
var $btnCancel = $tip.find('[data-dismiss="confirmation"]');
var options = this.options
$btnOk.addClass(this.getBtnOkClass())
.html(this.getBtnOkLabel())
.prepend($('<i></i>').addClass(this.getBtnOkIcon()), " ")
.attr('href', this.getHref())
.attr('target', this.getTarget())
.off('click').on('click', function(event) {
that.runCallback(that.options.onConfirm, event, that.$element);
// If the button is a submit one
if (that.$element.attr('type') == 'submit') {
var form = that.$element.closest('form');
var novalidate = form.attr('novalidate') !== undefined;
if (novalidate || form[0].checkValidity()) {
form.submit();
}
}
that.hide();
that.inState.click = false;
that.$element.trigger($.Event('confirm.bs.confirmation'));
});
$btnCancel.addClass(this.getBtnCancelClass())
.html(this.getBtnCancelLabel())
.prepend($('<i></i>').addClass(this.getBtnCancelIcon()), " ")
.off('click').on('click', function(event) {
that.runCallback(that.options.onCancel, event, that.$element);
that.hide();
that.inState.click = false;
that.$element.trigger($.Event('cancel.bs.confirmation'));
});
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title);
$tip.removeClass('fade top bottom left right in');
// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
// this manually by checking the contents.
if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide();
}
Confirmation.prototype.getBtnOkClass = function () {
return this.$element.data('btnOkClass') ||
(typeof this.options.btnOkClass == 'function' ? this.options.btnOkClass.call(this, this.$element) : this.options.btnOkClass);
}
Confirmation.prototype.getBtnOkLabel = function () {
return this.$element.data('btnOkLabel') ||
(typeof this.options.btnOkLabel == 'function' ? this.options.btnOkLabel.call(this, this.$element) : this.options.btnOkLabel);
}
Confirmation.prototype.getBtnOkIcon = function () {
return this.$element.data('btnOkIcon') ||
(typeof this.options.btnOkIcon == 'function' ? this.options.btnOkIcon.call(this, this.$element) : this.options.btnOkIcon);
}
Confirmation.prototype.getBtnCancelClass = function () {
return this.$element.data('btnCancelClass') ||
(typeof this.options.btnCancelClass == 'function' ? this.options.btnCancelClass.call(this, this.$element) : this.options.btnCancelClass);
}
Confirmation.prototype.getBtnCancelLabel = function () {
return this.$element.data('btnCancelLabel') ||
(typeof this.options.btnCancelLabel == 'function' ? this.options.btnCancelLabel.call(this, this.$element) : this.options.btnCancelLabel);
}
Confirmation.prototype.getBtnCancelIcon = function () {
return this.$element.data('btnCancelIcon') ||
(typeof this.options.btnCancelIcon == 'function' ? this.options.btnCancelIcon.call(this, this.$element) : this.options.btnCancelIcon);
}
Confirmation.prototype.getTitle = function () {
return this.$element.data('confirmation-title') ||
this.$element.data('title') ||
this.$element.attr('title') ||
(typeof this.options.title == 'function' ? this.options.title.call(this, this.$element) : this.options.title);
}
Confirmation.prototype.getHref = function () {
return this.$element.data('href') ||
this.$element.attr('href') ||
(typeof this.options.href == 'function' ? this.options.href.call(this, this.$element) : this.options.href);
}
Confirmation.prototype.getTarget = function () {
return this.$element.data('target') ||
this.$element.attr('target') ||
(typeof this.options.target == 'function' ? this.options.target.call(this, this.$element) : this.options.target);
}
Confirmation.prototype.isPopout = function () {
var popout = this.$element.data('popout') ||
(typeof this.options.popout == 'function' ? this.options.popout.call(this, this.$element) : this.options.popout);
if (popout == 'false') popout = false;
return popout
}
Confirmation.prototype.runCallback = function (callback, event, element) {
if (typeof callback == 'function') {
callback.call(this, event, element);
} else if (typeof callback == 'string') {
eval(callback);
}
}
// CONFIRMATION PLUGIN DEFINITION
// =========================
var old = $.fn.confirmation;
$.fn.confirmation = function (option) {
var that = this;
return this.each(function () {
var $this = $(this);
var data = $this.data('bs.confirmation');
var options = typeof option == 'object' && option;
options = options || {};
options.all_selector = that.selector;
if (!data && option == 'destroy') return;
if (!data) $this.data('bs.confirmation', (data = new Confirmation(this, options)));
if (typeof option == 'string') data[option]();
});
}
$.fn.confirmation.Constructor = Confirmation
// CONFIRMATION NO CONFLICT
// ===================
$.fn.confirmation.noConflict = function () {
$.fn.confirmation = old;
return this;
}
}(jQuery);

File diff suppressed because one or more lines are too long

View File

@@ -1,87 +1,2 @@
/*
* Bootstrap Image Gallery
* https://github.com/blueimp/Bootstrap-Image-Gallery
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
/*global define, window */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
define([
'jquery',
'blueImpGallery'
], factory)
} else {
factory(
window.jQuery,
window.blueimp.Gallery
)
}
}(function ($, Gallery) {
'use strict'
$.extend(Gallery.prototype.options, {
useBootstrapModal: true
})
var close = Gallery.prototype.close
var imageFactory = Gallery.prototype.imageFactory
var videoFactory = Gallery.prototype.videoFactory
var textFactory = Gallery.prototype.textFactory
$.extend(Gallery.prototype, {
modalFactory: function (obj, callback, factoryInterface, factory) {
if (!this.options.useBootstrapModal || factoryInterface) {
return factory.call(this, obj, callback, factoryInterface)
}
var that = this
var modalTemplate = $(this.container).children('.modal')
var modal = modalTemplate.clone().css('display', 'block').on('click', function (event) {
//var modal = modalTemplate.clone().show().on('click', function (event) {
// Close modal if click is outside of modal-content:
if (event.target === modal[0] ||
event.target === modal.children()[0]) {
event.preventDefault()
event.stopPropagation()
that.close()
}
})
var element = factory.call(this, obj, function (event) {
callback({
type: event.type,
target: modal[0]
})
modal.addClass('in')
}, factoryInterface)
modal.find('.modal-title').text(element.title || String.fromCharCode(160))
modal.find('.modal-body').append(element)
return modal[0]
},
imageFactory: function (obj, callback, factoryInterface) {
return this.modalFactory(obj, callback, factoryInterface, imageFactory)
},
videoFactory: function (obj, callback, factoryInterface) {
return this.modalFactory(obj, callback, factoryInterface, videoFactory)
},
textFactory: function (obj, callback, factoryInterface) {
return this.modalFactory(obj, callback, factoryInterface, textFactory)
},
close: function () {
this.container.find('.modal').removeClass('in')
close.call(this)
}
})
}))
!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery","blueImpGallery"],t):t(window.jQuery,window.blueimp.Gallery)}(function(t,o){"use strict";t.extend(o.prototype.options,{useBootstrapModal:!0});var e=o.prototype.close,n=o.prototype.imageFactory,i=o.prototype.videoFactory,r=o.prototype.textFactory;t.extend(o.prototype,{modalFactory:function(o,e,n,i){if(!this.options.useBootstrapModal||n)return i.call(this,o,e,n);var r=this,a=t(this.container).children(".modal").clone().css("display","block").on("click",function(t){t.target!==a[0]&&t.target!==a.children()[0]||(t.preventDefault(),t.stopPropagation(),r.close())}),c=i.call(this,o,function(t){e({type:t.type,target:a[0]}),a.addClass("in")},n);return a.find(".modal-title").text(c.title||String.fromCharCode(160)),a.find(".modal-body").append(c),a[0]},imageFactory:function(t,o,e){return this.modalFactory(t,o,e,n)},videoFactory:function(t,o,e){return this.modalFactory(t,o,e,i)},textFactory:function(t,o,e){return this.modalFactory(t,o,e,r)},close:function(){this.container.find(".modal").removeClass("in"),e.call(this)}})});
//# sourceMappingURL=bootstrap-image-gallery.js.map

Binary file not shown.

View File

@@ -0,0 +1 @@
{"version":3,"sources":["lib/bootstrap-image-gallery.js"],"names":["factory","define","amd","window","jQuery","blueimp","Gallery","$","extend","prototype","options","useBootstrapModal","close","imageFactory","videoFactory","textFactory","modalFactory","obj","callback","factoryInterface","this","call","that","modal","container","children","clone","css","on","event","target","preventDefault","stopPropagation","element","type","addClass","find","text","title","String","fromCharCode","append","removeClass"],"mappings":"CAaE,SAAUA,GACR,aACsB,mBAAXC,QAAyBA,OAAOC,IACvCD,QACI,SACA,kBACDD,GAEHA,EACIG,OAAOC,OACPD,OAAOE,QAAQC,SAV1B,CAaC,SAAUC,EAAGD,GACX,aAEAC,EAAEC,OAAOF,EAAQG,UAAUC,SACvBC,mBAAmB,IAGvB,IAAIC,EAAQN,EAAQG,UAAUG,MAC1BC,EAAeP,EAAQG,UAAUI,aACjCC,EAAeR,EAAQG,UAAUK,aACjCC,EAAcT,EAAQG,UAAUM,YAEpCR,EAAEC,OAAOF,EAAQG,WACbO,aAAc,SAAUC,EAAKC,EAAUC,EAAkBnB,GACrD,IAAKoB,KAAKV,QAAQC,mBAAqBQ,EACnC,OAAOnB,EAAQqB,KAAKD,KAAMH,EAAKC,EAAUC,GAE7C,IAAIG,EAAOF,KAEPG,EADgBhB,EAAEa,KAAKI,WAAWC,SAAS,UACrBC,QAAQC,IAAI,UAAW,SAASC,GAAG,QAAS,SAAUC,GAGxEA,EAAMC,SAAWP,EAAM,IACvBM,EAAMC,SAAWP,EAAME,WAAW,KAClCI,EAAME,iBACNF,EAAMG,kBACNV,EAAKV,WAGTqB,EAAUjC,EAAQqB,KAAKD,KAAMH,EAAK,SAAUY,GAC5CX,GACIgB,KAAML,EAAMK,KACZJ,OAAQP,EAAM,KAElBA,EAAMY,SAAS,OAChBhB,GAIH,OAHAI,EAAMa,KAAK,gBAAgBC,KAAKJ,EAAQK,OAASC,OAAOC,aAAa,MACrEjB,EAAMa,KAAK,eAAeK,OAAOR,GAE1BV,EAAM,IAGjBV,aAAc,SAAUI,EAAKC,EAAUC,GACnC,OAAOC,KAAKJ,aAAaC,EAAKC,EAAUC,EAAkBN,IAG9DC,aAAc,SAAUG,EAAKC,EAAUC,GACnC,OAAOC,KAAKJ,aAAaC,EAAKC,EAAUC,EAAkBL,IAG9DC,YAAa,SAAUE,EAAKC,EAAUC,GAClC,OAAOC,KAAKJ,aAAaC,EAAKC,EAAUC,EAAkBJ,IAG9DH,MAAO,WACHQ,KAAKI,UAAUY,KAAK,UAAUM,YAAY,MAC1C9B,EAAMS,KAAKD","file":"bootstrap-image-gallery.js","sourceRoot":"/js"}

View File

@@ -1,8 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap-toggle.js v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="2.2.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"default",size:"normal",style:"",width:null,height:null},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style,width:this.$element.attr("data-width")||c.DEFAULTS.width,height:this.$element.attr("data-height")||c.DEFAULTS.height}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size?"btn-lg":"small"===this.options.size?"btn-sm":"mini"===this.options.size?"btn-xs":"",c=a('<label class="btn">').html(this.options.on).addClass(this._onstyle+" "+b),d=a('<label class="btn">').html(this.options.off).addClass(this._offstyle+" "+b+" active"),e=a('<span class="toggle-handle btn btn-default">').addClass(b),f=a('<div class="toggle-group">').append(c,d,e),g=a('<div class="toggle btn" data-toggle="toggle">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.outerWidth(),d.outerWidth())+e.outerWidth()/2,i=this.options.height||Math.max(c.outerHeight(),d.outerHeight());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),void(a||this.trigger()))},c.prototype.off=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),void(a||this.trigger()))},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){var c=a(this).find("input[type=checkbox]");c.bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,35 +0,0 @@
/*!
Buttons for DataTables 1.2.1
©2016 SpryMedia Ltd - datatables.net/license
*/
(function(d){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(o){return d(o,window,document)}):"object"===typeof exports?module.exports=function(o,n){o||(o=window);if(!n||!n.fn.dataTable)n=require("datatables.net")(o,n).$;return d(n,o,o.document)}:d(jQuery,window,document)})(function(d,o,n,l){var i=d.fn.dataTable,u=0,v=0,k=i.ext.buttons,m=function(a,b){!0===b&&(b={});d.isArray(b)&&(b={buttons:b});this.c=d.extend(!0,{},m.defaults,b);b.buttons&&(this.c.buttons=b.buttons);
this.s={dt:new i.Api(a),buttons:[],listenKeys:"",namespace:"dtb"+u++};this.dom={container:d("<"+this.c.dom.container.tag+"/>").addClass(this.c.dom.container.className)};this._constructor()};d.extend(m.prototype,{action:function(a,b){var c=this._nodeToButton(a);if(b===l)return c.conf.action;c.conf.action=b;return this},active:function(a,b){var c=this._nodeToButton(a),e=this.c.dom.button.active,c=d(c.node);if(b===l)return c.hasClass(e);c.toggleClass(e,b===l?!0:b);return this},add:function(a,b){var c=
this.s.buttons;if("string"===typeof b){for(var e=b.split("-"),c=this.s,d=0,h=e.length-1;d<h;d++)c=c.buttons[1*e[d]];c=c.buttons;b=1*e[e.length-1]}this._expandButton(c,a,!1,b);this._draw();return this},container:function(){return this.dom.container},disable:function(a){a=this._nodeToButton(a);d(a.node).addClass(this.c.dom.button.disabled);return this},destroy:function(){d("body").off("keyup."+this.s.namespace);var a=this.s.buttons.slice(),b,c;b=0;for(c=a.length;b<c;b++)this.remove(a[b].node);this.dom.container.remove();
a=this.s.dt.settings()[0];b=0;for(c=a.length;b<c;b++)if(a.inst===this){a.splice(b,1);break}return this},enable:function(a,b){if(!1===b)return this.disable(a);var c=this._nodeToButton(a);d(c.node).removeClass(this.c.dom.button.disabled);return this},name:function(){return this.c.name},node:function(a){a=this._nodeToButton(a);return d(a.node)},remove:function(a){var b=this._nodeToButton(a),c=this._nodeToHost(a),e=this.s.dt;if(b.buttons.length)for(var g=b.buttons.length-1;0<=g;g--)this.remove(b.buttons[g].node);
b.conf.destroy&&b.conf.destroy.call(e.button(a),e,d(a),b.conf);this._removeKey(b.conf);d(b.node).remove();a=d.inArray(b,c);c.splice(a,1);return this},text:function(a,b){var c=this._nodeToButton(a),e=this.c.dom.collection.buttonLiner,e=c.inCollection&&e&&e.tag?e.tag:this.c.dom.buttonLiner.tag,g=this.s.dt,h=d(c.node),f=function(a){return"function"===typeof a?a(g,h,c.conf):a};if(b===l)return f(c.conf.text);c.conf.text=b;e?h.children(e).html(f(b)):h.html(f(b));return this},_constructor:function(){var a=
this,b=this.s.dt,c=b.settings()[0],e=this.c.buttons;c._buttons||(c._buttons=[]);c._buttons.push({inst:this,name:this.c.name});for(var c=0,g=e.length;c<g;c++)this.add(e[c]);b.on("destroy",function(){a.destroy()});d("body").on("keyup."+this.s.namespace,function(b){if(!n.activeElement||n.activeElement===n.body){var c=String.fromCharCode(b.keyCode).toLowerCase();a.s.listenKeys.toLowerCase().indexOf(c)!==-1&&a._keypress(c,b)}})},_addKey:function(a){a.key&&(this.s.listenKeys+=d.isPlainObject(a.key)?a.key.key:
a.key)},_draw:function(a,b){a||(a=this.dom.container,b=this.s.buttons);a.children().detach();for(var c=0,d=b.length;c<d;c++)a.append(b[c].inserter),b[c].buttons&&b[c].buttons.length&&this._draw(b[c].collection,b[c].buttons)},_expandButton:function(a,b,c,e){for(var g=this.s.dt,h=0,b=!d.isArray(b)?[b]:b,f=0,q=b.length;f<q;f++){var j=this._resolveExtends(b[f]);if(j)if(d.isArray(j))this._expandButton(a,j,c,e);else{var p=this._buildButton(j,c);if(p){e!==l?(a.splice(e,0,p),e++):a.push(p);if(p.conf.buttons){var s=
this.c.dom.collection;p.collection=d("<"+s.tag+"/>").addClass(s.className);p.conf._collection=p.collection;this._expandButton(p.buttons,p.conf.buttons,!0,e)}j.init&&j.init.call(g.button(p.node),g,d(p.node),j);h++}}}},_buildButton:function(a,b){var c=this.c.dom.button,e=this.c.dom.buttonLiner,g=this.c.dom.collection,h=this.s.dt,f=function(b){return"function"===typeof b?b(h,j,a):b};b&&g.button&&(c=g.button);b&&g.buttonLiner&&(e=g.buttonLiner);if(a.available&&!a.available(h,a))return!1;var q=function(a,
b,c,e){e.action.call(b.button(c),a,b,c,e);d(b.table().node()).triggerHandler("buttons-action.dt",[b.button(c),b,c,e])},j=d("<"+c.tag+"/>").addClass(c.className).attr("tabindex",this.s.dt.settings()[0].iTabIndex).attr("aria-controls",this.s.dt.table().node().id).on("click.dtb",function(b){b.preventDefault();!j.hasClass(c.disabled)&&a.action&&q(b,h,j,a);j.blur()}).on("keyup.dtb",function(b){b.keyCode===13&&!j.hasClass(c.disabled)&&a.action&&q(b,h,j,a)});"a"===c.tag.toLowerCase()&&j.attr("href","#");
e.tag?(g=d("<"+e.tag+"/>").html(f(a.text)).addClass(e.className),"a"===e.tag.toLowerCase()&&g.attr("href","#"),j.append(g)):j.html(f(a.text));!1===a.enabled&&j.addClass(c.disabled);a.className&&j.addClass(a.className);a.titleAttr&&j.attr("title",a.titleAttr);a.namespace||(a.namespace=".dt-button-"+v++);e=(e=this.c.dom.buttonContainer)&&e.tag?d("<"+e.tag+"/>").addClass(e.className).append(j):j;this._addKey(a);return{conf:a,node:j.get(0),inserter:e,buttons:[],inCollection:b,collection:null}},_nodeToButton:function(a,
b){b||(b=this.s.buttons);for(var c=0,d=b.length;c<d;c++){if(b[c].node===a)return b[c];if(b[c].buttons.length){var g=this._nodeToButton(a,b[c].buttons);if(g)return g}}},_nodeToHost:function(a,b){b||(b=this.s.buttons);for(var c=0,d=b.length;c<d;c++){if(b[c].node===a)return b;if(b[c].buttons.length){var g=this._nodeToHost(a,b[c].buttons);if(g)return g}}},_keypress:function(a,b){var c=function(e){for(var g=0,h=e.length;g<h;g++){var f=e[g].conf,q=e[g].node;if(f.key)if(f.key===a)d(q).click();else if(d.isPlainObject(f.key)&&
f.key.key===a&&(!f.key.shiftKey||b.shiftKey))if(!f.key.altKey||b.altKey)if(!f.key.ctrlKey||b.ctrlKey)(!f.key.metaKey||b.metaKey)&&d(q).click();e[g].buttons.length&&c(e[g].buttons)}};c(this.s.buttons)},_removeKey:function(a){if(a.key){var b=d.isPlainObject(a.key)?a.key.key:a.key,a=this.s.listenKeys.split(""),b=d.inArray(b,a);a.splice(b,1);this.s.listenKeys=a.join("")}},_resolveExtends:function(a){for(var b=this.s.dt,c,e,g=function(c){for(var e=0;!d.isPlainObject(c)&&!d.isArray(c);){if(c===l)return;
if("function"===typeof c){if(c=c(b,a),!c)return!1}else if("string"===typeof c){if(!k[c])throw"Unknown button type: "+c;c=k[c]}e++;if(30<e)throw"Buttons: Too many iterations";}return d.isArray(c)?c:d.extend({},c)},a=g(a);a&&a.extend;){if(!k[a.extend])throw"Cannot extend unknown button type: "+a.extend;var h=g(k[a.extend]);if(d.isArray(h))return h;if(!h)return!1;c=h.className;a=d.extend({},h,a);c&&a.className!==c&&(a.className=c+" "+a.className);var f=a.postfixButtons;if(f){a.buttons||(a.buttons=[]);
c=0;for(e=f.length;c<e;c++)a.buttons.push(f[c]);a.postfixButtons=null}if(f=a.prefixButtons){a.buttons||(a.buttons=[]);c=0;for(e=f.length;c<e;c++)a.buttons.splice(c,0,f[c]);a.prefixButtons=null}a.extend=h.extend}return a}});m.background=function(a,b,c){c===l&&(c=400);a?d("<div/>").addClass(b).css("display","none").appendTo("body").fadeIn(c):d("body > div."+b).fadeOut(c,function(){d(this).remove()})};m.instanceSelector=function(a,b){if(!a)return d.map(b,function(a){return a.inst});var c=[],e=d.map(b,
function(a){return a.name}),g=function(a){if(d.isArray(a))for(var f=0,q=a.length;f<q;f++)g(a[f]);else"string"===typeof a?-1!==a.indexOf(",")?g(a.split(",")):(a=d.inArray(d.trim(a),e),-1!==a&&c.push(b[a].inst)):"number"===typeof a&&c.push(b[a].inst)};g(a);return c};m.buttonSelector=function(a,b){for(var c=[],e=function(a,b,c){for(var d,g,f=0,h=b.length;f<h;f++)if(d=b[f])g=c!==l?c+f:f+"",a.push({node:d.node,name:d.conf.name,idx:g}),d.buttons&&e(a,d.buttons,g+"-")},g=function(a,b){var f,h,i=[];e(i,b.s.buttons);
f=d.map(i,function(a){return a.node});if(d.isArray(a)||a instanceof d){f=0;for(h=a.length;f<h;f++)g(a[f],b)}else if(null===a||a===l||"*"===a){f=0;for(h=i.length;f<h;f++)c.push({inst:b,node:i[f].node})}else if("number"===typeof a)c.push({inst:b,node:b.s.buttons[a].node});else if("string"===typeof a)if(-1!==a.indexOf(",")){i=a.split(",");f=0;for(h=i.length;f<h;f++)g(d.trim(i[f]),b)}else if(a.match(/^\d+(\-\d+)*$/))f=d.map(i,function(a){return a.idx}),c.push({inst:b,node:i[d.inArray(a,f)].node});else if(-1!==
a.indexOf(":name")){var k=a.replace(":name","");f=0;for(h=i.length;f<h;f++)i[f].name===k&&c.push({inst:b,node:i[f].node})}else d(f).filter(a).each(function(){c.push({inst:b,node:this})});else"object"===typeof a&&a.nodeName&&(i=d.inArray(a,f),-1!==i&&c.push({inst:b,node:f[i]}))},h=0,f=a.length;h<f;h++)g(b,a[h]);return c};m.defaults={buttons:["copy","excel","csv","pdf","print"],name:"main",tabIndex:0,dom:{container:{tag:"div",className:"dt-buttons"},collection:{tag:"div",className:"dt-button-collection"},
button:{tag:"a",className:"dt-button",active:"active",disabled:"disabled"},buttonLiner:{tag:"span",className:""}}};m.version="1.2.1";d.extend(k,{collection:{text:function(a){return a.i18n("buttons.collection","Collection")},className:"buttons-collection",action:function(a,b,c,e){var a=c.offset(),g=d(b.table().container()),h=!1;d("div.dt-button-background").length&&(h=d("div.dt-button-collection").offset(),d("body").trigger("click.dtb-collection"));e._collection.addClass(e.collectionLayout).css("display",
"none").appendTo("body").fadeIn(e.fade);var f=e._collection.css("position");h&&"absolute"===f?e._collection.css({top:h.top+5,left:h.left+5}):"absolute"===f?(e._collection.css({top:a.top+c.outerHeight(),left:a.left}),c=a.left+e._collection.outerWidth(),g=g.offset().left+g.width(),c>g&&e._collection.css("left",a.left-(c-g))):(a=e._collection.height()/2,a>d(o).height()/2&&(a=d(o).height()/2),e._collection.css("marginTop",-1*a));e.background&&m.background(!0,e.backgroundClassName,e.fade);setTimeout(function(){d("div.dt-button-background").on("click.dtb-collection",
function(){});d("body").on("click.dtb-collection",function(a){if(!d(a.target).parents().andSelf().filter(e._collection).length){e._collection.fadeOut(e.fade,function(){e._collection.detach()});d("div.dt-button-background").off("click.dtb-collection");m.background(false,e.backgroundClassName,e.fade);d("body").off("click.dtb-collection");b.off("buttons-action.b-internal")}})},10);if(e.autoClose)b.on("buttons-action.b-internal",function(){d("div.dt-button-background").click()})},background:!0,collectionLayout:"",
backgroundClassName:"dt-button-background",autoClose:!1,fade:400},copy:function(a,b){if(k.copyHtml5)return"copyHtml5";if(k.copyFlash&&k.copyFlash.available(a,b))return"copyFlash"},csv:function(a,b){if(k.csvHtml5&&k.csvHtml5.available(a,b))return"csvHtml5";if(k.csvFlash&&k.csvFlash.available(a,b))return"csvFlash"},excel:function(a,b){if(k.excelHtml5&&k.excelHtml5.available(a,b))return"excelHtml5";if(k.excelFlash&&k.excelFlash.available(a,b))return"excelFlash"},pdf:function(a,b){if(k.pdfHtml5&&k.pdfHtml5.available(a,
b))return"pdfHtml5";if(k.pdfFlash&&k.pdfFlash.available(a,b))return"pdfFlash"},pageLength:function(a){var a=a.settings()[0].aLengthMenu,b=d.isArray(a[0])?a[0]:a,c=d.isArray(a[0])?a[1]:a,e=function(a){return a.i18n("buttons.pageLength",{"-1":"Show all rows",_:"Show %d rows"},a.page.len())};return{extend:"collection",text:e,className:"buttons-page-length",autoClose:!0,buttons:d.map(b,function(a,b){return{text:c[b],action:function(b,c){c.page.len(a).draw()},init:function(b,c,d){var e=this,c=function(){e.active(b.page.len()===
a)};b.on("length.dt"+d.namespace,c);c()},destroy:function(a,b,c){a.off("length.dt"+c.namespace)}}}),init:function(a,b,c){var d=this;a.on("length.dt"+c.namespace,function(){d.text(e(a))})},destroy:function(a,b,c){a.off("length.dt"+c.namespace)}}}});i.Api.register("buttons()",function(a,b){b===l&&(b=a,a=l);return this.iterator(!0,"table",function(c){if(c._buttons)return m.buttonSelector(m.instanceSelector(a,c._buttons),b)},!0)});i.Api.register("button()",function(a,b){var c=this.buttons(a,b);1<c.length&&
c.splice(1,c.length);return c});i.Api.registerPlural("buttons().active()","button().active()",function(a){return a===l?this.map(function(a){return a.inst.active(a.node)}):this.each(function(b){b.inst.active(b.node,a)})});i.Api.registerPlural("buttons().action()","button().action()",function(a){return a===l?this.map(function(a){return a.inst.action(a.node)}):this.each(function(b){b.inst.action(b.node,a)})});i.Api.register(["buttons().enable()","button().enable()"],function(a){return this.each(function(b){b.inst.enable(b.node,
a)})});i.Api.register(["buttons().disable()","button().disable()"],function(){return this.each(function(a){a.inst.disable(a.node)})});i.Api.registerPlural("buttons().nodes()","button().node()",function(){var a=d();d(this.each(function(b){a=a.add(b.inst.node(b.node))}));return a});i.Api.registerPlural("buttons().text()","button().text()",function(a){return a===l?this.map(function(a){return a.inst.text(a.node)}):this.each(function(b){b.inst.text(b.node,a)})});i.Api.registerPlural("buttons().trigger()",
"button().trigger()",function(){return this.each(function(a){a.inst.node(a.node).trigger("click")})});i.Api.registerPlural("buttons().containers()","buttons().container()",function(){var a=d();d(this.each(function(b){a=a.add(b.inst.container())}));return a});i.Api.register("button().add()",function(a,b){1===this.length&&this[0].inst.add(b,a);return this.button(a)});i.Api.register("buttons().destroy()",function(){this.pluck("inst").unique().each(function(a){a.destroy()});return this});i.Api.registerPlural("buttons().remove()",
"buttons().remove()",function(){this.each(function(a){a.inst.remove(a.node)});return this});var r;i.Api.register("buttons.info()",function(a,b,c){var e=this;if(!1===a)return d("#datatables_buttons_info").fadeOut(function(){d(this).remove()}),clearTimeout(r),r=null,this;r&&clearTimeout(r);d("#datatables_buttons_info").length&&d("#datatables_buttons_info").remove();d('<div id="datatables_buttons_info" class="dt-button-info"/>').html(a?"<h2>"+a+"</h2>":"").append(d("<div/>")["string"===typeof b?"html":
"append"](b)).css("display","none").appendTo("body").fadeIn();c!==l&&0!==c&&(r=setTimeout(function(){e.buttons.info(!1)},c));return this});i.Api.register("buttons.exportData()",function(a){if(this.context.length){for(var b=new i.Api(this.context[0]),c=d.extend(!0,{},{rows:null,columns:"",modifier:{search:"applied",order:"applied"},orthogonal:"display",stripHtml:!0,stripNewlines:!0,decodeEntities:!0,trim:!0,format:{header:function(a){return e(a)},footer:function(a){return e(a)},body:function(a){return e(a)}}},
a),e=function(a){if("string"!==typeof a)return a;c.stripHtml&&(a=a.replace(/<[^>]*>/g,""));c.trim&&(a=a.replace(/^\s+|\s+$/g,""));c.stripNewlines&&(a=a.replace(/\n/g," "));c.decodeEntities&&(t.innerHTML=a,a=t.value);return a},a=b.columns(c.columns).indexes().map(function(a){return c.format.header(b.column(a).header().innerHTML,a)}).toArray(),g=b.table().footer()?b.columns(c.columns).indexes().map(function(a){var d=b.column(a).footer();return c.format.footer(d?d.innerHTML:"",a)}).toArray():null,h=
b.rows(c.rows,c.modifier).indexes().toArray(),h=b.cells(h,c.columns).render(c.orthogonal).toArray(),f=a.length,k=0<f?h.length/f:0,j=Array(k),m=0,l=0;l<k;l++){for(var o=Array(f),n=0;n<f;n++)o[n]=c.format.body(h[m],n,l),m++;j[l]=o}return{header:a,footer:g,body:j}}});var t=d("<textarea/>")[0];d.fn.dataTable.Buttons=m;d.fn.DataTable.Buttons=m;d(n).on("init.dt plugin-init.dt",function(a,b){if("dt"===a.namespace){var c=b.oInit.buttons||i.defaults.buttons;c&&!b._buttons&&(new m(b,c)).container()}});i.ext.feature.push({fnInit:function(a){var a=
new i.Api(a),b=a.init().buttons||i.defaults.buttons;return(new m(a,b)).container()},cFeature:"B"});return m});

View File

@@ -1,166 +0,0 @@
/*!
DataTables 1.10.12
©2008-2015 SpryMedia Ltd - datatables.net/license
*/
(function(h){"function"===typeof define&&define.amd?define(["jquery"],function(D){return h(D,window,document)}):"object"===typeof exports?module.exports=function(D,I){D||(D=window);I||(I="undefined"!==typeof window?require("jquery"):require("jquery")(D));return h(I,D,D.document)}:h(jQuery,window,document)})(function(h,D,I,k){function X(a){var b,c,d={};h.each(a,function(e){if((b=e.match(/^([^A-Z]+?)([A-Z])/))&&-1!=="a aa ai ao as b fn i m o s ".indexOf(b[1]+" "))c=e.replace(b[0],b[2].toLowerCase()),
d[c]=e,"o"===b[1]&&X(a[e])});a._hungarianMap=d}function K(a,b,c){a._hungarianMap||X(a);var d;h.each(b,function(e){d=a._hungarianMap[e];if(d!==k&&(c||b[d]===k))"o"===d.charAt(0)?(b[d]||(b[d]={}),h.extend(!0,b[d],b[e]),K(a[d],b[d],c)):b[d]=b[e]})}function Da(a){var b=m.defaults.oLanguage,c=a.sZeroRecords;!a.sEmptyTable&&(c&&"No data available in table"===b.sEmptyTable)&&E(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&(c&&"Loading..."===b.sLoadingRecords)&&E(a,a,"sZeroRecords","sLoadingRecords");
a.sInfoThousands&&(a.sThousands=a.sInfoThousands);(a=a.sDecimal)&&db(a)}function eb(a){A(a,"ordering","bSort");A(a,"orderMulti","bSortMulti");A(a,"orderClasses","bSortClasses");A(a,"orderCellsTop","bSortCellsTop");A(a,"order","aaSorting");A(a,"orderFixed","aaSortingFixed");A(a,"paging","bPaginate");A(a,"pagingType","sPaginationType");A(a,"pageLength","iDisplayLength");A(a,"searching","bFilter");"boolean"===typeof a.sScrollX&&(a.sScrollX=a.sScrollX?"100%":"");"boolean"===typeof a.scrollX&&(a.scrollX=
a.scrollX?"100%":"");if(a=a.aoSearchCols)for(var b=0,c=a.length;b<c;b++)a[b]&&K(m.models.oSearch,a[b])}function fb(a){A(a,"orderable","bSortable");A(a,"orderData","aDataSort");A(a,"orderSequence","asSorting");A(a,"orderDataType","sortDataType");var b=a.aDataSort;b&&!h.isArray(b)&&(a.aDataSort=[b])}function gb(a){if(!m.__browser){var b={};m.__browser=b;var c=h("<div/>").css({position:"fixed",top:0,left:0,height:1,width:1,overflow:"hidden"}).append(h("<div/>").css({position:"absolute",top:1,left:1,
width:100,overflow:"scroll"}).append(h("<div/>").css({width:"100%",height:10}))).appendTo("body"),d=c.children(),e=d.children();b.barWidth=d[0].offsetWidth-d[0].clientWidth;b.bScrollOversize=100===e[0].offsetWidth&&100!==d[0].clientWidth;b.bScrollbarLeft=1!==Math.round(e.offset().left);b.bBounding=c[0].getBoundingClientRect().width?!0:!1;c.remove()}h.extend(a.oBrowser,m.__browser);a.oScroll.iBarWidth=m.__browser.barWidth}function hb(a,b,c,d,e,f){var g,j=!1;c!==k&&(g=c,j=!0);for(;d!==e;)a.hasOwnProperty(d)&&
(g=j?b(g,a[d],d,a):a[d],j=!0,d+=f);return g}function Ea(a,b){var c=m.defaults.column,d=a.aoColumns.length,c=h.extend({},m.models.oColumn,c,{nTh:b?b:I.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.mData:d,idx:d});a.aoColumns.push(c);c=a.aoPreSearchCols;c[d]=h.extend({},m.models.oSearch,c[d]);ja(a,d,h(b).data())}function ja(a,b,c){var b=a.aoColumns[b],d=a.oClasses,e=h(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=e.attr("width")||null;var f=
(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);f&&(b.sWidthOrig=f[1])}c!==k&&null!==c&&(fb(c),K(m.defaults.column,c),c.mDataProp!==k&&!c.mData&&(c.mData=c.mDataProp),c.sType&&(b._sManualType=c.sType),c.className&&!c.sClass&&(c.sClass=c.className),h.extend(b,c),E(b,c,"sWidth","sWidthOrig"),c.iDataSort!==k&&(b.aDataSort=[c.iDataSort]),E(b,c,"aDataSort"));var g=b.mData,j=Q(g),i=b.mRender?Q(b.mRender):null,c=function(a){return"string"===typeof a&&-1!==a.indexOf("@")};b._bAttrSrc=h.isPlainObject(g)&&
(c(g.sort)||c(g.type)||c(g.filter));b._setter=null;b.fnGetData=function(a,b,c){var d=j(a,b,k,c);return i&&b?i(d,b,a,c):d};b.fnSetData=function(a,b,c){return R(g)(a,b,c)};"number"!==typeof g&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==h.inArray("asc",b.asSorting);c=-1!==h.inArray("desc",b.asSorting);!b.bSortable||!a&&!c?(b.sSortingClass=d.sSortableNone,b.sSortingClassJUI=""):a&&!c?(b.sSortingClass=d.sSortableAsc,b.sSortingClassJUI=d.sSortJUIAscAllowed):
!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=d.sSortJUIDescAllowed):(b.sSortingClass=d.sSortable,b.sSortingClassJUI=d.sSortJUI)}function Y(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Fa(a);for(var c=0,d=b.length;c<d;c++)b[c].nTh.style.width=b[c].sWidth}b=a.oScroll;(""!==b.sY||""!==b.sX)&&ka(a);u(a,null,"column-sizing",[a])}function Z(a,b){var c=la(a,"bVisible");return"number"===typeof c[b]?c[b]:null}function $(a,b){var c=la(a,"bVisible"),c=h.inArray(b,c);return-1!==c?c:null}
function aa(a){var b=0;h.each(a.aoColumns,function(a,d){d.bVisible&&"none"!==h(d.nTh).css("display")&&b++});return b}function la(a,b){var c=[];h.map(a.aoColumns,function(a,e){a[b]&&c.push(e)});return c}function Ga(a){var b=a.aoColumns,c=a.aoData,d=m.ext.type.detect,e,f,g,j,i,h,l,q,t;e=0;for(f=b.length;e<f;e++)if(l=b[e],t=[],!l.sType&&l._sManualType)l.sType=l._sManualType;else if(!l.sType){g=0;for(j=d.length;g<j;g++){i=0;for(h=c.length;i<h;i++){t[i]===k&&(t[i]=B(a,i,e,"type"));q=d[g](t[i],a);if(!q&&
g!==d.length-1)break;if("html"===q)break}if(q){l.sType=q;break}}l.sType||(l.sType="string")}}function ib(a,b,c,d){var e,f,g,j,i,n,l=a.aoColumns;if(b)for(e=b.length-1;0<=e;e--){n=b[e];var q=n.targets!==k?n.targets:n.aTargets;h.isArray(q)||(q=[q]);f=0;for(g=q.length;f<g;f++)if("number"===typeof q[f]&&0<=q[f]){for(;l.length<=q[f];)Ea(a);d(q[f],n)}else if("number"===typeof q[f]&&0>q[f])d(l.length+q[f],n);else if("string"===typeof q[f]){j=0;for(i=l.length;j<i;j++)("_all"==q[f]||h(l[j].nTh).hasClass(q[f]))&&
d(j,n)}}if(c){e=0;for(a=c.length;e<a;e++)d(e,c[e])}}function N(a,b,c,d){var e=a.aoData.length,f=h.extend(!0,{},m.models.oRow,{src:c?"dom":"data",idx:e});f._aData=b;a.aoData.push(f);for(var g=a.aoColumns,j=0,i=g.length;j<i;j++)g[j].sType=null;a.aiDisplayMaster.push(e);b=a.rowIdFn(b);b!==k&&(a.aIds[b]=f);(c||!a.oFeatures.bDeferRender)&&Ha(a,e,c,d);return e}function ma(a,b){var c;b instanceof h||(b=h(b));return b.map(function(b,e){c=Ia(a,e);return N(a,c.data,e,c.cells)})}function B(a,b,c,d){var e=a.iDraw,
f=a.aoColumns[c],g=a.aoData[b]._aData,j=f.sDefaultContent,i=f.fnGetData(g,d,{settings:a,row:b,col:c});if(i===k)return a.iDrawError!=e&&null===j&&(L(a,0,"Requested unknown parameter "+("function"==typeof f.mData?"{function}":"'"+f.mData+"'")+" for row "+b+", column "+c,4),a.iDrawError=e),j;if((i===g||null===i)&&null!==j&&d!==k)i=j;else if("function"===typeof i)return i.call(g);return null===i&&"display"==d?"":i}function jb(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d,{settings:a,row:b,col:c})}
function Ja(a){return h.map(a.match(/(\\.|[^\.])+/g)||[""],function(a){return a.replace(/\\./g,".")})}function Q(a){if(h.isPlainObject(a)){var b={};h.each(a,function(a,c){c&&(b[a]=Q(c))});return function(a,c,f,g){var j=b[c]||b._;return j!==k?j(a,c,f,g):a}}if(null===a)return function(a){return a};if("function"===typeof a)return function(b,c,f,g){return a(b,c,f,g)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var c=function(a,b,f){var g,j;if(""!==f){j=Ja(f);
for(var i=0,n=j.length;i<n;i++){f=j[i].match(ba);g=j[i].match(U);if(f){j[i]=j[i].replace(ba,"");""!==j[i]&&(a=a[j[i]]);g=[];j.splice(0,i+1);j=j.join(".");if(h.isArray(a)){i=0;for(n=a.length;i<n;i++)g.push(c(a[i],b,j))}a=f[0].substring(1,f[0].length-1);a=""===a?g:g.join(a);break}else if(g){j[i]=j[i].replace(U,"");a=a[j[i]]();continue}if(null===a||a[j[i]]===k)return k;a=a[j[i]]}}return a};return function(b,e){return c(b,e,a)}}return function(b){return b[a]}}function R(a){if(h.isPlainObject(a))return R(a._);
if(null===a)return function(){};if("function"===typeof a)return function(b,d,e){a(b,"set",d,e)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var b=function(a,d,e){var e=Ja(e),f;f=e[e.length-1];for(var g,j,i=0,n=e.length-1;i<n;i++){g=e[i].match(ba);j=e[i].match(U);if(g){e[i]=e[i].replace(ba,"");a[e[i]]=[];f=e.slice();f.splice(0,i+1);g=f.join(".");if(h.isArray(d)){j=0;for(n=d.length;j<n;j++)f={},b(f,d[j],g),a[e[i]].push(f)}else a[e[i]]=d;return}j&&(e[i]=e[i].replace(U,
""),a=a[e[i]](d));if(null===a[e[i]]||a[e[i]]===k)a[e[i]]={};a=a[e[i]]}if(f.match(U))a[f.replace(U,"")](d);else a[f.replace(ba,"")]=d};return function(c,d){return b(c,d,a)}}return function(b,d){b[a]=d}}function Ka(a){return G(a.aoData,"_aData")}function na(a){a.aoData.length=0;a.aiDisplayMaster.length=0;a.aiDisplay.length=0;a.aIds={}}function oa(a,b,c){for(var d=-1,e=0,f=a.length;e<f;e++)a[e]==b?d=e:a[e]>b&&a[e]--; -1!=d&&c===k&&a.splice(d,1)}function ca(a,b,c,d){var e=a.aoData[b],f,g=function(c,d){for(;c.childNodes.length;)c.removeChild(c.firstChild);
c.innerHTML=B(a,b,d,"display")};if("dom"===c||(!c||"auto"===c)&&"dom"===e.src)e._aData=Ia(a,e,d,d===k?k:e._aData).data;else{var j=e.anCells;if(j)if(d!==k)g(j[d],d);else{c=0;for(f=j.length;c<f;c++)g(j[c],c)}}e._aSortData=null;e._aFilterData=null;g=a.aoColumns;if(d!==k)g[d].sType=null;else{c=0;for(f=g.length;c<f;c++)g[c].sType=null;La(a,e)}}function Ia(a,b,c,d){var e=[],f=b.firstChild,g,j,i=0,n,l=a.aoColumns,q=a._rowReadObject,d=d!==k?d:q?{}:[],t=function(a,b){if("string"===typeof a){var c=a.indexOf("@");
-1!==c&&(c=a.substring(c+1),R(a)(d,b.getAttribute(c)))}},S=function(a){if(c===k||c===i)j=l[i],n=h.trim(a.innerHTML),j&&j._bAttrSrc?(R(j.mData._)(d,n),t(j.mData.sort,a),t(j.mData.type,a),t(j.mData.filter,a)):q?(j._setter||(j._setter=R(j.mData)),j._setter(d,n)):d[i]=n;i++};if(f)for(;f;){g=f.nodeName.toUpperCase();if("TD"==g||"TH"==g)S(f),e.push(f);f=f.nextSibling}else{e=b.anCells;f=0;for(g=e.length;f<g;f++)S(e[f])}if(b=b.firstChild?b:b.nTr)(b=b.getAttribute("id"))&&R(a.rowId)(d,b);return{data:d,cells:e}}
function Ha(a,b,c,d){var e=a.aoData[b],f=e._aData,g=[],j,i,n,l,q;if(null===e.nTr){j=c||I.createElement("tr");e.nTr=j;e.anCells=g;j._DT_RowIndex=b;La(a,e);l=0;for(q=a.aoColumns.length;l<q;l++){n=a.aoColumns[l];i=c?d[l]:I.createElement(n.sCellType);i._DT_CellIndex={row:b,column:l};g.push(i);if((!c||n.mRender||n.mData!==l)&&(!h.isPlainObject(n.mData)||n.mData._!==l+".display"))i.innerHTML=B(a,b,l,"display");n.sClass&&(i.className+=" "+n.sClass);n.bVisible&&!c?j.appendChild(i):!n.bVisible&&c&&i.parentNode.removeChild(i);
n.fnCreatedCell&&n.fnCreatedCell.call(a.oInstance,i,B(a,b,l),f,b,l)}u(a,"aoRowCreatedCallback",null,[j,f,b])}e.nTr.setAttribute("role","row")}function La(a,b){var c=b.nTr,d=b._aData;if(c){var e=a.rowIdFn(d);e&&(c.id=e);d.DT_RowClass&&(e=d.DT_RowClass.split(" "),b.__rowc=b.__rowc?pa(b.__rowc.concat(e)):e,h(c).removeClass(b.__rowc.join(" ")).addClass(d.DT_RowClass));d.DT_RowAttr&&h(c).attr(d.DT_RowAttr);d.DT_RowData&&h(c).data(d.DT_RowData)}}function kb(a){var b,c,d,e,f,g=a.nTHead,j=a.nTFoot,i=0===
h("th, td",g).length,n=a.oClasses,l=a.aoColumns;i&&(e=h("<tr/>").appendTo(g));b=0;for(c=l.length;b<c;b++)f=l[b],d=h(f.nTh).addClass(f.sClass),i&&d.appendTo(e),a.oFeatures.bSort&&(d.addClass(f.sSortingClass),!1!==f.bSortable&&(d.attr("tabindex",a.iTabIndex).attr("aria-controls",a.sTableId),Ma(a,f.nTh,b))),f.sTitle!=d[0].innerHTML&&d.html(f.sTitle),Na(a,"header")(a,d,f,n);i&&da(a.aoHeader,g);h(g).find(">tr").attr("role","row");h(g).find(">tr>th, >tr>td").addClass(n.sHeaderTH);h(j).find(">tr>th, >tr>td").addClass(n.sFooterTH);
if(null!==j){a=a.aoFooter[0];b=0;for(c=a.length;b<c;b++)f=l[b],f.nTf=a[b].cell,f.sClass&&h(f.nTf).addClass(f.sClass)}}function ea(a,b,c){var d,e,f,g=[],j=[],i=a.aoColumns.length,n;if(b){c===k&&(c=!1);d=0;for(e=b.length;d<e;d++){g[d]=b[d].slice();g[d].nTr=b[d].nTr;for(f=i-1;0<=f;f--)!a.aoColumns[f].bVisible&&!c&&g[d].splice(f,1);j.push([])}d=0;for(e=g.length;d<e;d++){if(a=g[d].nTr)for(;f=a.firstChild;)a.removeChild(f);f=0;for(b=g[d].length;f<b;f++)if(n=i=1,j[d][f]===k){a.appendChild(g[d][f].cell);
for(j[d][f]=1;g[d+i]!==k&&g[d][f].cell==g[d+i][f].cell;)j[d+i][f]=1,i++;for(;g[d][f+n]!==k&&g[d][f].cell==g[d][f+n].cell;){for(c=0;c<i;c++)j[d+c][f+n]=1;n++}h(g[d][f].cell).attr("rowspan",i).attr("colspan",n)}}}}function O(a){var b=u(a,"aoPreDrawCallback","preDraw",[a]);if(-1!==h.inArray(!1,b))C(a,!1);else{var b=[],c=0,d=a.asStripeClasses,e=d.length,f=a.oLanguage,g=a.iInitDisplayStart,j="ssp"==y(a),i=a.aiDisplay;a.bDrawing=!0;g!==k&&-1!==g&&(a._iDisplayStart=j?g:g>=a.fnRecordsDisplay()?0:g,a.iInitDisplayStart=
-1);var g=a._iDisplayStart,n=a.fnDisplayEnd();if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,C(a,!1);else if(j){if(!a.bDestroying&&!lb(a))return}else a.iDraw++;if(0!==i.length){f=j?a.aoData.length:n;for(j=j?0:g;j<f;j++){var l=i[j],q=a.aoData[l];null===q.nTr&&Ha(a,l);l=q.nTr;if(0!==e){var t=d[c%e];q._sRowStripe!=t&&(h(l).removeClass(q._sRowStripe).addClass(t),q._sRowStripe=t)}u(a,"aoRowCallback",null,[l,q._aData,c,j]);b.push(l);c++}}else c=f.sZeroRecords,1==a.iDraw&&"ajax"==y(a)?c=f.sLoadingRecords:
f.sEmptyTable&&0===a.fnRecordsTotal()&&(c=f.sEmptyTable),b[0]=h("<tr/>",{"class":e?d[0]:""}).append(h("<td />",{valign:"top",colSpan:aa(a),"class":a.oClasses.sRowEmpty}).html(c))[0];u(a,"aoHeaderCallback","header",[h(a.nTHead).children("tr")[0],Ka(a),g,n,i]);u(a,"aoFooterCallback","footer",[h(a.nTFoot).children("tr")[0],Ka(a),g,n,i]);d=h(a.nTBody);d.children().detach();d.append(h(b));u(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1}}function T(a,b){var c=a.oFeatures,d=c.bFilter;
c.bSort&&mb(a);d?fa(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;O(a);a._drawHold=!1}function nb(a){var b=a.oClasses,c=h(a.nTable),c=h("<div/>").insertBefore(c),d=a.oFeatures,e=h("<div/>",{id:a.sTableId+"_wrapper","class":b.sWrapper+(a.nTFoot?"":" "+b.sNoFooter)});a.nHolding=c[0];a.nTableWrapper=e[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var f=a.sDom.split(""),g,j,i,n,l,q,t=0;t<f.length;t++){g=null;j=f[t];if("<"==j){i=h("<div/>")[0];
n=f[t+1];if("'"==n||'"'==n){l="";for(q=2;f[t+q]!=n;)l+=f[t+q],q++;"H"==l?l=b.sJUIHeader:"F"==l&&(l=b.sJUIFooter);-1!=l.indexOf(".")?(n=l.split("."),i.id=n[0].substr(1,n[0].length-1),i.className=n[1]):"#"==l.charAt(0)?i.id=l.substr(1,l.length-1):i.className=l;t+=q}e.append(i);e=h(i)}else if(">"==j)e=e.parent();else if("l"==j&&d.bPaginate&&d.bLengthChange)g=ob(a);else if("f"==j&&d.bFilter)g=pb(a);else if("r"==j&&d.bProcessing)g=qb(a);else if("t"==j)g=rb(a);else if("i"==j&&d.bInfo)g=sb(a);else if("p"==
j&&d.bPaginate)g=tb(a);else if(0!==m.ext.feature.length){i=m.ext.feature;q=0;for(n=i.length;q<n;q++)if(j==i[q].cFeature){g=i[q].fnInit(a);break}}g&&(i=a.aanFeatures,i[j]||(i[j]=[]),i[j].push(g),e.append(g))}c.replaceWith(e);a.nHolding=null}function da(a,b){var c=h(b).children("tr"),d,e,f,g,j,i,n,l,q,t;a.splice(0,a.length);f=0;for(i=c.length;f<i;f++)a.push([]);f=0;for(i=c.length;f<i;f++){d=c[f];for(e=d.firstChild;e;){if("TD"==e.nodeName.toUpperCase()||"TH"==e.nodeName.toUpperCase()){l=1*e.getAttribute("colspan");
q=1*e.getAttribute("rowspan");l=!l||0===l||1===l?1:l;q=!q||0===q||1===q?1:q;g=0;for(j=a[f];j[g];)g++;n=g;t=1===l?!0:!1;for(j=0;j<l;j++)for(g=0;g<q;g++)a[f+g][n+j]={cell:e,unique:t},a[f+g].nTr=d}e=e.nextSibling}}}function qa(a,b,c){var d=[];c||(c=a.aoHeader,b&&(c=[],da(c,b)));for(var b=0,e=c.length;b<e;b++)for(var f=0,g=c[b].length;f<g;f++)if(c[b][f].unique&&(!d[f]||!a.bSortCellsTop))d[f]=c[b][f].cell;return d}function ra(a,b,c){u(a,"aoServerParams","serverParams",[b]);if(b&&h.isArray(b)){var d={},
e=/(.*?)\[\]$/;h.each(b,function(a,b){var c=b.name.match(e);c?(c=c[0],d[c]||(d[c]=[]),d[c].push(b.value)):d[b.name]=b.value});b=d}var f,g=a.ajax,j=a.oInstance,i=function(b){u(a,null,"xhr",[a,b,a.jqXHR]);c(b)};if(h.isPlainObject(g)&&g.data){f=g.data;var n=h.isFunction(f)?f(b,a):f,b=h.isFunction(f)&&n?n:h.extend(!0,b,n);delete g.data}n={data:b,success:function(b){var c=b.error||b.sError;c&&L(a,0,c);a.json=b;i(b)},dataType:"json",cache:!1,type:a.sServerMethod,error:function(b,c){var d=u(a,null,"xhr",
[a,null,a.jqXHR]);-1===h.inArray(!0,d)&&("parsererror"==c?L(a,0,"Invalid JSON response",1):4===b.readyState&&L(a,0,"Ajax error",7));C(a,!1)}};a.oAjaxData=b;u(a,null,"preXhr",[a,b]);a.fnServerData?a.fnServerData.call(j,a.sAjaxSource,h.map(b,function(a,b){return{name:b,value:a}}),i,a):a.sAjaxSource||"string"===typeof g?a.jqXHR=h.ajax(h.extend(n,{url:g||a.sAjaxSource})):h.isFunction(g)?a.jqXHR=g.call(j,b,i,a):(a.jqXHR=h.ajax(h.extend(n,g)),g.data=f)}function lb(a){return a.bAjaxDataGet?(a.iDraw++,C(a,
!0),ra(a,ub(a),function(b){vb(a,b)}),!1):!0}function ub(a){var b=a.aoColumns,c=b.length,d=a.oFeatures,e=a.oPreviousSearch,f=a.aoPreSearchCols,g,j=[],i,n,l,q=V(a);g=a._iDisplayStart;i=!1!==d.bPaginate?a._iDisplayLength:-1;var k=function(a,b){j.push({name:a,value:b})};k("sEcho",a.iDraw);k("iColumns",c);k("sColumns",G(b,"sName").join(","));k("iDisplayStart",g);k("iDisplayLength",i);var S={draw:a.iDraw,columns:[],order:[],start:g,length:i,search:{value:e.sSearch,regex:e.bRegex}};for(g=0;g<c;g++)n=b[g],
l=f[g],i="function"==typeof n.mData?"function":n.mData,S.columns.push({data:i,name:n.sName,searchable:n.bSearchable,orderable:n.bSortable,search:{value:l.sSearch,regex:l.bRegex}}),k("mDataProp_"+g,i),d.bFilter&&(k("sSearch_"+g,l.sSearch),k("bRegex_"+g,l.bRegex),k("bSearchable_"+g,n.bSearchable)),d.bSort&&k("bSortable_"+g,n.bSortable);d.bFilter&&(k("sSearch",e.sSearch),k("bRegex",e.bRegex));d.bSort&&(h.each(q,function(a,b){S.order.push({column:b.col,dir:b.dir});k("iSortCol_"+a,b.col);k("sSortDir_"+
a,b.dir)}),k("iSortingCols",q.length));b=m.ext.legacy.ajax;return null===b?a.sAjaxSource?j:S:b?j:S}function vb(a,b){var c=sa(a,b),d=b.sEcho!==k?b.sEcho:b.draw,e=b.iTotalRecords!==k?b.iTotalRecords:b.recordsTotal,f=b.iTotalDisplayRecords!==k?b.iTotalDisplayRecords:b.recordsFiltered;if(d){if(1*d<a.iDraw)return;a.iDraw=1*d}na(a);a._iRecordsTotal=parseInt(e,10);a._iRecordsDisplay=parseInt(f,10);d=0;for(e=c.length;d<e;d++)N(a,c[d]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=!1;O(a);a._bInitComplete||
ta(a,b);a.bAjaxDataGet=!0;C(a,!1)}function sa(a,b){var c=h.isPlainObject(a.ajax)&&a.ajax.dataSrc!==k?a.ajax.dataSrc:a.sAjaxDataProp;return"data"===c?b.aaData||b[c]:""!==c?Q(c)(b):b}function pb(a){var b=a.oClasses,c=a.sTableId,d=a.oLanguage,e=a.oPreviousSearch,f=a.aanFeatures,g='<input type="search" class="'+b.sFilterInput+'"/>',j=d.sSearch,j=j.match(/_INPUT_/)?j.replace("_INPUT_",g):j+g,b=h("<div/>",{id:!f.f?c+"_filter":null,"class":b.sFilter}).append(h("<label/>").append(j)),f=function(){var b=!this.value?
"":this.value;b!=e.sSearch&&(fa(a,{sSearch:b,bRegex:e.bRegex,bSmart:e.bSmart,bCaseInsensitive:e.bCaseInsensitive}),a._iDisplayStart=0,O(a))},g=null!==a.searchDelay?a.searchDelay:"ssp"===y(a)?400:0,i=h("input",b).val(e.sSearch).attr("placeholder",d.sSearchPlaceholder).bind("keyup.DT search.DT input.DT paste.DT cut.DT",g?Oa(f,g):f).bind("keypress.DT",function(a){if(13==a.keyCode)return!1}).attr("aria-controls",c);h(a.nTable).on("search.dt.DT",function(b,c){if(a===c)try{i[0]!==I.activeElement&&i.val(e.sSearch)}catch(d){}});
return b[0]}function fa(a,b,c){var d=a.oPreviousSearch,e=a.aoPreSearchCols,f=function(a){d.sSearch=a.sSearch;d.bRegex=a.bRegex;d.bSmart=a.bSmart;d.bCaseInsensitive=a.bCaseInsensitive};Ga(a);if("ssp"!=y(a)){wb(a,b.sSearch,c,b.bEscapeRegex!==k?!b.bEscapeRegex:b.bRegex,b.bSmart,b.bCaseInsensitive);f(b);for(b=0;b<e.length;b++)xb(a,e[b].sSearch,b,e[b].bEscapeRegex!==k?!e[b].bEscapeRegex:e[b].bRegex,e[b].bSmart,e[b].bCaseInsensitive);yb(a)}else f(b);a.bFiltered=!0;u(a,null,"search",[a])}function yb(a){for(var b=
m.ext.search,c=a.aiDisplay,d,e,f=0,g=b.length;f<g;f++){for(var j=[],i=0,n=c.length;i<n;i++)e=c[i],d=a.aoData[e],b[f](a,d._aFilterData,e,d._aData,i)&&j.push(e);c.length=0;h.merge(c,j)}}function xb(a,b,c,d,e,f){if(""!==b)for(var g=a.aiDisplay,d=Pa(b,d,e,f),e=g.length-1;0<=e;e--)b=a.aoData[g[e]]._aFilterData[c],d.test(b)||g.splice(e,1)}function wb(a,b,c,d,e,f){var d=Pa(b,d,e,f),e=a.oPreviousSearch.sSearch,f=a.aiDisplayMaster,g;0!==m.ext.search.length&&(c=!0);g=zb(a);if(0>=b.length)a.aiDisplay=f.slice();
else{if(g||c||e.length>b.length||0!==b.indexOf(e)||a.bSorted)a.aiDisplay=f.slice();b=a.aiDisplay;for(c=b.length-1;0<=c;c--)d.test(a.aoData[b[c]]._sFilterRow)||b.splice(c,1)}}function Pa(a,b,c,d){a=b?a:Qa(a);c&&(a="^(?=.*?"+h.map(a.match(/"[^"]+"|[^ ]+/g)||[""],function(a){if('"'===a.charAt(0))var b=a.match(/^"(.*)"$/),a=b?b[1]:a;return a.replace('"',"")}).join(")(?=.*?")+").*$");return RegExp(a,d?"i":"")}function zb(a){var b=a.aoColumns,c,d,e,f,g,j,i,h,l=m.ext.type.search;c=!1;d=0;for(f=a.aoData.length;d<
f;d++)if(h=a.aoData[d],!h._aFilterData){j=[];e=0;for(g=b.length;e<g;e++)c=b[e],c.bSearchable?(i=B(a,d,e,"filter"),l[c.sType]&&(i=l[c.sType](i)),null===i&&(i=""),"string"!==typeof i&&i.toString&&(i=i.toString())):i="",i.indexOf&&-1!==i.indexOf("&")&&(ua.innerHTML=i,i=Zb?ua.textContent:ua.innerText),i.replace&&(i=i.replace(/[\r\n]/g,"")),j.push(i);h._aFilterData=j;h._sFilterRow=j.join(" ");c=!0}return c}function Ab(a){return{search:a.sSearch,smart:a.bSmart,regex:a.bRegex,caseInsensitive:a.bCaseInsensitive}}
function Bb(a){return{sSearch:a.search,bSmart:a.smart,bRegex:a.regex,bCaseInsensitive:a.caseInsensitive}}function sb(a){var b=a.sTableId,c=a.aanFeatures.i,d=h("<div/>",{"class":a.oClasses.sInfo,id:!c?b+"_info":null});c||(a.aoDrawCallback.push({fn:Cb,sName:"information"}),d.attr("role","status").attr("aria-live","polite"),h(a.nTable).attr("aria-describedby",b+"_info"));return d[0]}function Cb(a){var b=a.aanFeatures.i;if(0!==b.length){var c=a.oLanguage,d=a._iDisplayStart+1,e=a.fnDisplayEnd(),f=a.fnRecordsTotal(),
g=a.fnRecordsDisplay(),j=g?c.sInfo:c.sInfoEmpty;g!==f&&(j+=" "+c.sInfoFiltered);j+=c.sInfoPostFix;j=Db(a,j);c=c.fnInfoCallback;null!==c&&(j=c.call(a.oInstance,a,d,e,f,g,j));h(b).html(j)}}function Db(a,b){var c=a.fnFormatNumber,d=a._iDisplayStart+1,e=a._iDisplayLength,f=a.fnRecordsDisplay(),g=-1===e;return b.replace(/_START_/g,c.call(a,d)).replace(/_END_/g,c.call(a,a.fnDisplayEnd())).replace(/_MAX_/g,c.call(a,a.fnRecordsTotal())).replace(/_TOTAL_/g,c.call(a,f)).replace(/_PAGE_/g,c.call(a,g?1:Math.ceil(d/
e))).replace(/_PAGES_/g,c.call(a,g?1:Math.ceil(f/e)))}function ga(a){var b,c,d=a.iInitDisplayStart,e=a.aoColumns,f;c=a.oFeatures;var g=a.bDeferLoading;if(a.bInitialised){nb(a);kb(a);ea(a,a.aoHeader);ea(a,a.aoFooter);C(a,!0);c.bAutoWidth&&Fa(a);b=0;for(c=e.length;b<c;b++)f=e[b],f.sWidth&&(f.nTh.style.width=x(f.sWidth));u(a,null,"preInit",[a]);T(a);e=y(a);if("ssp"!=e||g)"ajax"==e?ra(a,[],function(c){var f=sa(a,c);for(b=0;b<f.length;b++)N(a,f[b]);a.iInitDisplayStart=d;T(a);C(a,!1);ta(a,c)},a):(C(a,!1),
ta(a))}else setTimeout(function(){ga(a)},200)}function ta(a,b){a._bInitComplete=!0;(b||a.oInit.aaData)&&Y(a);u(a,null,"plugin-init",[a,b]);u(a,"aoInitComplete","init",[a,b])}function Ra(a,b){var c=parseInt(b,10);a._iDisplayLength=c;Sa(a);u(a,null,"length",[a,c])}function ob(a){for(var b=a.oClasses,c=a.sTableId,d=a.aLengthMenu,e=h.isArray(d[0]),f=e?d[0]:d,d=e?d[1]:d,e=h("<select/>",{name:c+"_length","aria-controls":c,"class":b.sLengthSelect}),g=0,j=f.length;g<j;g++)e[0][g]=new Option(d[g],f[g]);var i=
h("<div><label/></div>").addClass(b.sLength);a.aanFeatures.l||(i[0].id=c+"_length");i.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));h("select",i).val(a._iDisplayLength).bind("change.DT",function(){Ra(a,h(this).val());O(a)});h(a.nTable).bind("length.dt.DT",function(b,c,d){a===c&&h("select",i).val(d)});return i[0]}function tb(a){var b=a.sPaginationType,c=m.ext.pager[b],d="function"===typeof c,e=function(a){O(a)},b=h("<div/>").addClass(a.oClasses.sPaging+b)[0],f=a.aanFeatures;
d||c.fnInit(a,b,e);f.p||(b.id=a.sTableId+"_paginate",a.aoDrawCallback.push({fn:function(a){if(d){var b=a._iDisplayStart,i=a._iDisplayLength,h=a.fnRecordsDisplay(),l=-1===i,b=l?0:Math.ceil(b/i),i=l?1:Math.ceil(h/i),h=c(b,i),k,l=0;for(k=f.p.length;l<k;l++)Na(a,"pageButton")(a,f.p[l],l,h,b,i)}else c.fnUpdate(a,e)},sName:"pagination"}));return b}function Ta(a,b,c){var d=a._iDisplayStart,e=a._iDisplayLength,f=a.fnRecordsDisplay();0===f||-1===e?d=0:"number"===typeof b?(d=b*e,d>f&&(d=0)):"first"==b?d=0:
"previous"==b?(d=0<=e?d-e:0,0>d&&(d=0)):"next"==b?d+e<f&&(d+=e):"last"==b?d=Math.floor((f-1)/e)*e:L(a,0,"Unknown paging action: "+b,5);b=a._iDisplayStart!==d;a._iDisplayStart=d;b&&(u(a,null,"page",[a]),c&&O(a));return b}function qb(a){return h("<div/>",{id:!a.aanFeatures.r?a.sTableId+"_processing":null,"class":a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]}function C(a,b){a.oFeatures.bProcessing&&h(a.aanFeatures.r).css("display",b?"block":"none");u(a,null,"processing",
[a,b])}function rb(a){var b=h(a.nTable);b.attr("role","grid");var c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,f=a.oClasses,g=b.children("caption"),j=g.length?g[0]._captionSide:null,i=h(b[0].cloneNode(!1)),n=h(b[0].cloneNode(!1)),l=b.children("tfoot");l.length||(l=null);i=h("<div/>",{"class":f.sScrollWrapper}).append(h("<div/>",{"class":f.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:d?!d?null:x(d):"100%"}).append(h("<div/>",{"class":f.sScrollHeadInner}).css({"box-sizing":"content-box",
width:c.sXInner||"100%"}).append(i.removeAttr("id").css("margin-left",0).append("top"===j?g:null).append(b.children("thead"))))).append(h("<div/>",{"class":f.sScrollBody}).css({position:"relative",overflow:"auto",width:!d?null:x(d)}).append(b));l&&i.append(h("<div/>",{"class":f.sScrollFoot}).css({overflow:"hidden",border:0,width:d?!d?null:x(d):"100%"}).append(h("<div/>",{"class":f.sScrollFootInner}).append(n.removeAttr("id").css("margin-left",0).append("bottom"===j?g:null).append(b.children("tfoot")))));
var b=i.children(),k=b[0],f=b[1],t=l?b[2]:null;if(d)h(f).on("scroll.DT",function(){var a=this.scrollLeft;k.scrollLeft=a;l&&(t.scrollLeft=a)});h(f).css(e&&c.bCollapse?"max-height":"height",e);a.nScrollHead=k;a.nScrollBody=f;a.nScrollFoot=t;a.aoDrawCallback.push({fn:ka,sName:"scrolling"});return i[0]}function ka(a){var b=a.oScroll,c=b.sX,d=b.sXInner,e=b.sY,b=b.iBarWidth,f=h(a.nScrollHead),g=f[0].style,j=f.children("div"),i=j[0].style,n=j.children("table"),j=a.nScrollBody,l=h(j),q=j.style,t=h(a.nScrollFoot).children("div"),
m=t.children("table"),o=h(a.nTHead),F=h(a.nTable),p=F[0],r=p.style,u=a.nTFoot?h(a.nTFoot):null,Eb=a.oBrowser,Ua=Eb.bScrollOversize,s=G(a.aoColumns,"nTh"),P,v,w,y,z=[],A=[],B=[],C=[],D,E=function(a){a=a.style;a.paddingTop="0";a.paddingBottom="0";a.borderTopWidth="0";a.borderBottomWidth="0";a.height=0};v=j.scrollHeight>j.clientHeight;if(a.scrollBarVis!==v&&a.scrollBarVis!==k)a.scrollBarVis=v,Y(a);else{a.scrollBarVis=v;F.children("thead, tfoot").remove();u&&(w=u.clone().prependTo(F),P=u.find("tr"),w=
w.find("tr"));y=o.clone().prependTo(F);o=o.find("tr");v=y.find("tr");y.find("th, td").removeAttr("tabindex");c||(q.width="100%",f[0].style.width="100%");h.each(qa(a,y),function(b,c){D=Z(a,b);c.style.width=a.aoColumns[D].sWidth});u&&J(function(a){a.style.width=""},w);f=F.outerWidth();if(""===c){r.width="100%";if(Ua&&(F.find("tbody").height()>j.offsetHeight||"scroll"==l.css("overflow-y")))r.width=x(F.outerWidth()-b);f=F.outerWidth()}else""!==d&&(r.width=x(d),f=F.outerWidth());J(E,v);J(function(a){B.push(a.innerHTML);
z.push(x(h(a).css("width")))},v);J(function(a,b){if(h.inArray(a,s)!==-1)a.style.width=z[b]},o);h(v).height(0);u&&(J(E,w),J(function(a){C.push(a.innerHTML);A.push(x(h(a).css("width")))},w),J(function(a,b){a.style.width=A[b]},P),h(w).height(0));J(function(a,b){a.innerHTML='<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+B[b]+"</div>";a.style.width=z[b]},v);u&&J(function(a,b){a.innerHTML='<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+C[b]+"</div>";a.style.width=
A[b]},w);if(F.outerWidth()<f){P=j.scrollHeight>j.offsetHeight||"scroll"==l.css("overflow-y")?f+b:f;if(Ua&&(j.scrollHeight>j.offsetHeight||"scroll"==l.css("overflow-y")))r.width=x(P-b);(""===c||""!==d)&&L(a,1,"Possible column misalignment",6)}else P="100%";q.width=x(P);g.width=x(P);u&&(a.nScrollFoot.style.width=x(P));!e&&Ua&&(q.height=x(p.offsetHeight+b));c=F.outerWidth();n[0].style.width=x(c);i.width=x(c);d=F.height()>j.clientHeight||"scroll"==l.css("overflow-y");e="padding"+(Eb.bScrollbarLeft?"Left":
"Right");i[e]=d?b+"px":"0px";u&&(m[0].style.width=x(c),t[0].style.width=x(c),t[0].style[e]=d?b+"px":"0px");F.children("colgroup").insertBefore(F.children("thead"));l.scroll();if((a.bSorted||a.bFiltered)&&!a._drawHold)j.scrollTop=0}}function J(a,b,c){for(var d=0,e=0,f=b.length,g,j;e<f;){g=b[e].firstChild;for(j=c?c[e].firstChild:null;g;)1===g.nodeType&&(c?a(g,j,d):a(g,d),d++),g=g.nextSibling,j=c?j.nextSibling:null;e++}}function Fa(a){var b=a.nTable,c=a.aoColumns,d=a.oScroll,e=d.sY,f=d.sX,g=d.sXInner,
j=c.length,i=la(a,"bVisible"),n=h("th",a.nTHead),l=b.getAttribute("width"),k=b.parentNode,t=!1,m,o,p=a.oBrowser,d=p.bScrollOversize;(m=b.style.width)&&-1!==m.indexOf("%")&&(l=m);for(m=0;m<i.length;m++)o=c[i[m]],null!==o.sWidth&&(o.sWidth=Fb(o.sWidthOrig,k),t=!0);if(d||!t&&!f&&!e&&j==aa(a)&&j==n.length)for(m=0;m<j;m++)i=Z(a,m),null!==i&&(c[i].sWidth=x(n.eq(m).width()));else{j=h(b).clone().css("visibility","hidden").removeAttr("id");j.find("tbody tr").remove();var r=h("<tr/>").appendTo(j.find("tbody"));
j.find("thead, tfoot").remove();j.append(h(a.nTHead).clone()).append(h(a.nTFoot).clone());j.find("tfoot th, tfoot td").css("width","");n=qa(a,j.find("thead")[0]);for(m=0;m<i.length;m++)o=c[i[m]],n[m].style.width=null!==o.sWidthOrig&&""!==o.sWidthOrig?x(o.sWidthOrig):"",o.sWidthOrig&&f&&h(n[m]).append(h("<div/>").css({width:o.sWidthOrig,margin:0,padding:0,border:0,height:1}));if(a.aoData.length)for(m=0;m<i.length;m++)t=i[m],o=c[t],h(Gb(a,t)).clone(!1).append(o.sContentPadding).appendTo(r);h("[name]",
j).removeAttr("name");o=h("<div/>").css(f||e?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(j).appendTo(k);f&&g?j.width(g):f?(j.css("width","auto"),j.removeAttr("width"),j.width()<k.clientWidth&&l&&j.width(k.clientWidth)):e?j.width(k.clientWidth):l&&j.width(l);for(m=e=0;m<i.length;m++)k=h(n[m]),g=k.outerWidth()-k.width(),k=p.bBounding?Math.ceil(n[m].getBoundingClientRect().width):k.outerWidth(),e+=k,c[i[m]].sWidth=x(k-g);b.style.width=x(e);o.remove()}l&&(b.style.width=
x(l));if((l||f)&&!a._reszEvt)b=function(){h(D).bind("resize.DT-"+a.sInstance,Oa(function(){Y(a)}))},d?setTimeout(b,1E3):b(),a._reszEvt=!0}function Fb(a,b){if(!a)return 0;var c=h("<div/>").css("width",x(a)).appendTo(b||I.body),d=c[0].offsetWidth;c.remove();return d}function Gb(a,b){var c=Hb(a,b);if(0>c)return null;var d=a.aoData[c];return!d.nTr?h("<td/>").html(B(a,c,b,"display"))[0]:d.anCells[b]}function Hb(a,b){for(var c,d=-1,e=-1,f=0,g=a.aoData.length;f<g;f++)c=B(a,f,b,"display")+"",c=c.replace($b,
""),c=c.replace(/&nbsp;/g," "),c.length>d&&(d=c.length,e=f);return e}function x(a){return null===a?"0px":"number"==typeof a?0>a?"0px":a+"px":a.match(/\d$/)?a+"px":a}function V(a){var b,c,d=[],e=a.aoColumns,f,g,j,i;b=a.aaSortingFixed;c=h.isPlainObject(b);var n=[];f=function(a){a.length&&!h.isArray(a[0])?n.push(a):h.merge(n,a)};h.isArray(b)&&f(b);c&&b.pre&&f(b.pre);f(a.aaSorting);c&&b.post&&f(b.post);for(a=0;a<n.length;a++){i=n[a][0];f=e[i].aDataSort;b=0;for(c=f.length;b<c;b++)g=f[b],j=e[g].sType||
"string",n[a]._idx===k&&(n[a]._idx=h.inArray(n[a][1],e[g].asSorting)),d.push({src:i,col:g,dir:n[a][1],index:n[a]._idx,type:j,formatter:m.ext.type.order[j+"-pre"]})}return d}function mb(a){var b,c,d=[],e=m.ext.type.order,f=a.aoData,g=0,j,i=a.aiDisplayMaster,h;Ga(a);h=V(a);b=0;for(c=h.length;b<c;b++)j=h[b],j.formatter&&g++,Ib(a,j.col);if("ssp"!=y(a)&&0!==h.length){b=0;for(c=i.length;b<c;b++)d[i[b]]=b;g===h.length?i.sort(function(a,b){var c,e,g,j,i=h.length,k=f[a]._aSortData,m=f[b]._aSortData;for(g=
0;g<i;g++)if(j=h[g],c=k[j.col],e=m[j.col],c=c<e?-1:c>e?1:0,0!==c)return"asc"===j.dir?c:-c;c=d[a];e=d[b];return c<e?-1:c>e?1:0}):i.sort(function(a,b){var c,g,j,i,k=h.length,m=f[a]._aSortData,p=f[b]._aSortData;for(j=0;j<k;j++)if(i=h[j],c=m[i.col],g=p[i.col],i=e[i.type+"-"+i.dir]||e["string-"+i.dir],c=i(c,g),0!==c)return c;c=d[a];g=d[b];return c<g?-1:c>g?1:0})}a.bSorted=!0}function Jb(a){for(var b,c,d=a.aoColumns,e=V(a),a=a.oLanguage.oAria,f=0,g=d.length;f<g;f++){c=d[f];var j=c.asSorting;b=c.sTitle.replace(/<.*?>/g,
"");var i=c.nTh;i.removeAttribute("aria-sort");c.bSortable&&(0<e.length&&e[0].col==f?(i.setAttribute("aria-sort","asc"==e[0].dir?"ascending":"descending"),c=j[e[0].index+1]||j[0]):c=j[0],b+="asc"===c?a.sSortAscending:a.sSortDescending);i.setAttribute("aria-label",b)}}function Va(a,b,c,d){var e=a.aaSorting,f=a.aoColumns[b].asSorting,g=function(a,b){var c=a._idx;c===k&&(c=h.inArray(a[1],f));return c+1<f.length?c+1:b?null:0};"number"===typeof e[0]&&(e=a.aaSorting=[e]);c&&a.oFeatures.bSortMulti?(c=h.inArray(b,
G(e,"0")),-1!==c?(b=g(e[c],!0),null===b&&1===e.length&&(b=0),null===b?e.splice(c,1):(e[c][1]=f[b],e[c]._idx=b)):(e.push([b,f[0],0]),e[e.length-1]._idx=0)):e.length&&e[0][0]==b?(b=g(e[0]),e.length=1,e[0][1]=f[b],e[0]._idx=b):(e.length=0,e.push([b,f[0]]),e[0]._idx=0);T(a);"function"==typeof d&&d(a)}function Ma(a,b,c,d){var e=a.aoColumns[c];Wa(b,{},function(b){!1!==e.bSortable&&(a.oFeatures.bProcessing?(C(a,!0),setTimeout(function(){Va(a,c,b.shiftKey,d);"ssp"!==y(a)&&C(a,!1)},0)):Va(a,c,b.shiftKey,d))})}
function va(a){var b=a.aLastSort,c=a.oClasses.sSortColumn,d=V(a),e=a.oFeatures,f,g;if(e.bSort&&e.bSortClasses){e=0;for(f=b.length;e<f;e++)g=b[e].src,h(G(a.aoData,"anCells",g)).removeClass(c+(2>e?e+1:3));e=0;for(f=d.length;e<f;e++)g=d[e].src,h(G(a.aoData,"anCells",g)).addClass(c+(2>e?e+1:3))}a.aLastSort=d}function Ib(a,b){var c=a.aoColumns[b],d=m.ext.order[c.sSortDataType],e;d&&(e=d.call(a.oInstance,a,b,$(a,b)));for(var f,g=m.ext.type.order[c.sType+"-pre"],j=0,i=a.aoData.length;j<i;j++)if(c=a.aoData[j],
c._aSortData||(c._aSortData=[]),!c._aSortData[b]||d)f=d?e[j]:B(a,j,b,"sort"),c._aSortData[b]=g?g(f):f}function wa(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b={time:+new Date,start:a._iDisplayStart,length:a._iDisplayLength,order:h.extend(!0,[],a.aaSorting),search:Ab(a.oPreviousSearch),columns:h.map(a.aoColumns,function(b,d){return{visible:b.bVisible,search:Ab(a.aoPreSearchCols[d])}})};u(a,"aoStateSaveParams","stateSaveParams",[a,b]);a.oSavedState=b;a.fnStateSaveCallback.call(a.oInstance,a,
b)}}function Kb(a){var b,c,d=a.aoColumns;if(a.oFeatures.bStateSave){var e=a.fnStateLoadCallback.call(a.oInstance,a);if(e&&e.time&&(b=u(a,"aoStateLoadParams","stateLoadParams",[a,e]),-1===h.inArray(!1,b)&&(b=a.iStateDuration,!(0<b&&e.time<+new Date-1E3*b)&&d.length===e.columns.length))){a.oLoadedState=h.extend(!0,{},e);e.start!==k&&(a._iDisplayStart=e.start,a.iInitDisplayStart=e.start);e.length!==k&&(a._iDisplayLength=e.length);e.order!==k&&(a.aaSorting=[],h.each(e.order,function(b,c){a.aaSorting.push(c[0]>=
d.length?[0,c[1]]:c)}));e.search!==k&&h.extend(a.oPreviousSearch,Bb(e.search));b=0;for(c=e.columns.length;b<c;b++){var f=e.columns[b];f.visible!==k&&(d[b].bVisible=f.visible);f.search!==k&&h.extend(a.aoPreSearchCols[b],Bb(f.search))}u(a,"aoStateLoaded","stateLoaded",[a,e])}}}function xa(a){var b=m.settings,a=h.inArray(a,G(b,"nTable"));return-1!==a?b[a]:null}function L(a,b,c,d){c="DataTables warning: "+(a?"table id="+a.sTableId+" - ":"")+c;d&&(c+=". For more information about this error, please see http://datatables.net/tn/"+
d);if(b)D.console&&console.log&&console.log(c);else if(b=m.ext,b=b.sErrMode||b.errMode,a&&u(a,null,"error",[a,d,c]),"alert"==b)alert(c);else{if("throw"==b)throw Error(c);"function"==typeof b&&b(a,d,c)}}function E(a,b,c,d){h.isArray(c)?h.each(c,function(c,d){h.isArray(d)?E(a,b,d[0],d[1]):E(a,b,d)}):(d===k&&(d=c),b[c]!==k&&(a[d]=b[c]))}function Lb(a,b,c){var d,e;for(e in b)b.hasOwnProperty(e)&&(d=b[e],h.isPlainObject(d)?(h.isPlainObject(a[e])||(a[e]={}),h.extend(!0,a[e],d)):a[e]=c&&"data"!==e&&"aaData"!==
e&&h.isArray(d)?d.slice():d);return a}function Wa(a,b,c){h(a).bind("click.DT",b,function(b){a.blur();c(b)}).bind("keypress.DT",b,function(a){13===a.which&&(a.preventDefault(),c(a))}).bind("selectstart.DT",function(){return!1})}function z(a,b,c,d){c&&a[b].push({fn:c,sName:d})}function u(a,b,c,d){var e=[];b&&(e=h.map(a[b].slice().reverse(),function(b){return b.fn.apply(a.oInstance,d)}));null!==c&&(b=h.Event(c+".dt"),h(a.nTable).trigger(b,d),e.push(b.result));return e}function Sa(a){var b=a._iDisplayStart,
c=a.fnDisplayEnd(),d=a._iDisplayLength;b>=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function Na(a,b){var c=a.renderer,d=m.ext.renderer[b];return h.isPlainObject(c)&&c[b]?d[c[b]]||d._:"string"===typeof c?d[c]||d._:d._}function y(a){return a.oFeatures.bServerSide?"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function ya(a,b){var c=[],c=Mb.numbers_length,d=Math.floor(c/2);b<=c?c=W(0,b):a<=d?(c=W(0,c-2),c.push("ellipsis"),c.push(b-1)):(a>=b-1-d?c=W(b-(c-2),b):(c=W(a-d+2,a+d-1),c.push("ellipsis"),
c.push(b-1)),c.splice(0,0,"ellipsis"),c.splice(0,0,0));c.DT_el="span";return c}function db(a){h.each({num:function(b){return za(b,a)},"num-fmt":function(b){return za(b,a,Xa)},"html-num":function(b){return za(b,a,Aa)},"html-num-fmt":function(b){return za(b,a,Aa,Xa)}},function(b,c){v.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(v.type.search[b+a]=v.type.search.html)})}function Nb(a){return function(){var b=[xa(this[m.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return m.ext.internal[a].apply(this,
b)}}var m=function(a){this.$=function(a,b){return this.api(!0).$(a,b)};this._=function(a,b){return this.api(!0).rows(a,b).data()};this.api=function(a){return a?new r(xa(this[v.iApiIndex])):new r(this)};this.fnAddData=function(a,b){var c=this.api(!0),d=h.isArray(a)&&(h.isArray(a[0])||h.isPlainObject(a[0]))?c.rows.add(a):c.row.add(a);(b===k||b)&&c.draw();return d.flatten().toArray()};this.fnAdjustColumnSizing=function(a){var b=this.api(!0).columns.adjust(),c=b.settings()[0],d=c.oScroll;a===k||a?b.draw(!1):
(""!==d.sX||""!==d.sY)&&ka(c)};this.fnClearTable=function(a){var b=this.api(!0).clear();(a===k||a)&&b.draw()};this.fnClose=function(a){this.api(!0).row(a).child.hide()};this.fnDeleteRow=function(a,b,c){var d=this.api(!0),a=d.rows(a),e=a.settings()[0],h=e.aoData[a[0][0]];a.remove();b&&b.call(this,e,h);(c===k||c)&&d.draw();return h};this.fnDestroy=function(a){this.api(!0).destroy(a)};this.fnDraw=function(a){this.api(!0).draw(a)};this.fnFilter=function(a,b,c,d,e,h){e=this.api(!0);null===b||b===k?e.search(a,
c,d,h):e.column(b).search(a,c,d,h);e.draw()};this.fnGetData=function(a,b){var c=this.api(!0);if(a!==k){var d=a.nodeName?a.nodeName.toLowerCase():"";return b!==k||"td"==d||"th"==d?c.cell(a,b).data():c.row(a).data()||null}return c.data().toArray()};this.fnGetNodes=function(a){var b=this.api(!0);return a!==k?b.row(a).node():b.rows().nodes().flatten().toArray()};this.fnGetPosition=function(a){var b=this.api(!0),c=a.nodeName.toUpperCase();return"TR"==c?b.row(a).index():"TD"==c||"TH"==c?(a=b.cell(a).index(),
[a.row,a.columnVisible,a.column]):null};this.fnIsOpen=function(a){return this.api(!0).row(a).child.isShown()};this.fnOpen=function(a,b,c){return this.api(!0).row(a).child(b,c).show().child()[0]};this.fnPageChange=function(a,b){var c=this.api(!0).page(a);(b===k||b)&&c.draw(!1)};this.fnSetColumnVis=function(a,b,c){a=this.api(!0).column(a).visible(b);(c===k||c)&&a.columns.adjust().draw()};this.fnSettings=function(){return xa(this[v.iApiIndex])};this.fnSort=function(a){this.api(!0).order(a).draw()};this.fnSortListener=
function(a,b,c){this.api(!0).order.listener(a,b,c)};this.fnUpdate=function(a,b,c,d,e){var h=this.api(!0);c===k||null===c?h.row(b).data(a):h.cell(b,c).data(a);(e===k||e)&&h.columns.adjust();(d===k||d)&&h.draw();return 0};this.fnVersionCheck=v.fnVersionCheck;var b=this,c=a===k,d=this.length;c&&(a={});this.oApi=this.internal=v.internal;for(var e in m.ext.internal)e&&(this[e]=Nb(e));this.each(function(){var e={},e=1<d?Lb(e,a,!0):a,g=0,j,i=this.getAttribute("id"),n=!1,l=m.defaults,q=h(this);if("table"!=
this.nodeName.toLowerCase())L(null,0,"Non-table node initialisation ("+this.nodeName+")",2);else{eb(l);fb(l.column);K(l,l,!0);K(l.column,l.column,!0);K(l,h.extend(e,q.data()));var t=m.settings,g=0;for(j=t.length;g<j;g++){var p=t[g];if(p.nTable==this||p.nTHead.parentNode==this||p.nTFoot&&p.nTFoot.parentNode==this){g=e.bRetrieve!==k?e.bRetrieve:l.bRetrieve;if(c||g)return p.oInstance;if(e.bDestroy!==k?e.bDestroy:l.bDestroy){p.oInstance.fnDestroy();break}else{L(p,0,"Cannot reinitialise DataTable",3);
return}}if(p.sTableId==this.id){t.splice(g,1);break}}if(null===i||""===i)this.id=i="DataTables_Table_"+m.ext._unique++;var o=h.extend(!0,{},m.models.oSettings,{sDestroyWidth:q[0].style.width,sInstance:i,sTableId:i});o.nTable=this;o.oApi=b.internal;o.oInit=e;t.push(o);o.oInstance=1===b.length?b:q.dataTable();eb(e);e.oLanguage&&Da(e.oLanguage);e.aLengthMenu&&!e.iDisplayLength&&(e.iDisplayLength=h.isArray(e.aLengthMenu[0])?e.aLengthMenu[0][0]:e.aLengthMenu[0]);e=Lb(h.extend(!0,{},l),e);E(o.oFeatures,
e,"bPaginate bLengthChange bFilter bSort bSortMulti bInfo bProcessing bAutoWidth bSortClasses bServerSide bDeferRender".split(" "));E(o,e,["asStripeClasses","ajax","fnServerData","fnFormatNumber","sServerMethod","aaSorting","aaSortingFixed","aLengthMenu","sPaginationType","sAjaxSource","sAjaxDataProp","iStateDuration","sDom","bSortCellsTop","iTabIndex","fnStateLoadCallback","fnStateSaveCallback","renderer","searchDelay","rowId",["iCookieDuration","iStateDuration"],["oSearch","oPreviousSearch"],["aoSearchCols",
"aoPreSearchCols"],["iDisplayLength","_iDisplayLength"],["bJQueryUI","bJUI"]]);E(o.oScroll,e,[["sScrollX","sX"],["sScrollXInner","sXInner"],["sScrollY","sY"],["bScrollCollapse","bCollapse"]]);E(o.oLanguage,e,"fnInfoCallback");z(o,"aoDrawCallback",e.fnDrawCallback,"user");z(o,"aoServerParams",e.fnServerParams,"user");z(o,"aoStateSaveParams",e.fnStateSaveParams,"user");z(o,"aoStateLoadParams",e.fnStateLoadParams,"user");z(o,"aoStateLoaded",e.fnStateLoaded,"user");z(o,"aoRowCallback",e.fnRowCallback,
"user");z(o,"aoRowCreatedCallback",e.fnCreatedRow,"user");z(o,"aoHeaderCallback",e.fnHeaderCallback,"user");z(o,"aoFooterCallback",e.fnFooterCallback,"user");z(o,"aoInitComplete",e.fnInitComplete,"user");z(o,"aoPreDrawCallback",e.fnPreDrawCallback,"user");o.rowIdFn=Q(e.rowId);gb(o);i=o.oClasses;e.bJQueryUI?(h.extend(i,m.ext.oJUIClasses,e.oClasses),e.sDom===l.sDom&&"lfrtip"===l.sDom&&(o.sDom='<"H"lfr>t<"F"ip>'),o.renderer)?h.isPlainObject(o.renderer)&&!o.renderer.header&&(o.renderer.header="jqueryui"):
o.renderer="jqueryui":h.extend(i,m.ext.classes,e.oClasses);q.addClass(i.sTable);o.iInitDisplayStart===k&&(o.iInitDisplayStart=e.iDisplayStart,o._iDisplayStart=e.iDisplayStart);null!==e.iDeferLoading&&(o.bDeferLoading=!0,g=h.isArray(e.iDeferLoading),o._iRecordsDisplay=g?e.iDeferLoading[0]:e.iDeferLoading,o._iRecordsTotal=g?e.iDeferLoading[1]:e.iDeferLoading);var r=o.oLanguage;h.extend(!0,r,e.oLanguage);""!==r.sUrl&&(h.ajax({dataType:"json",url:r.sUrl,success:function(a){Da(a);K(l.oLanguage,a);h.extend(true,
r,a);ga(o)},error:function(){ga(o)}}),n=!0);null===e.asStripeClasses&&(o.asStripeClasses=[i.sStripeOdd,i.sStripeEven]);var g=o.asStripeClasses,v=q.children("tbody").find("tr").eq(0);-1!==h.inArray(!0,h.map(g,function(a){return v.hasClass(a)}))&&(h("tbody tr",this).removeClass(g.join(" ")),o.asDestroyStripes=g.slice());t=[];g=this.getElementsByTagName("thead");0!==g.length&&(da(o.aoHeader,g[0]),t=qa(o));if(null===e.aoColumns){p=[];g=0;for(j=t.length;g<j;g++)p.push(null)}else p=e.aoColumns;g=0;for(j=
p.length;g<j;g++)Ea(o,t?t[g]:null);ib(o,e.aoColumnDefs,p,function(a,b){ja(o,a,b)});if(v.length){var s=function(a,b){return a.getAttribute("data-"+b)!==null?b:null};h(v[0]).children("th, td").each(function(a,b){var c=o.aoColumns[a];if(c.mData===a){var d=s(b,"sort")||s(b,"order"),e=s(b,"filter")||s(b,"search");if(d!==null||e!==null){c.mData={_:a+".display",sort:d!==null?a+".@data-"+d:k,type:d!==null?a+".@data-"+d:k,filter:e!==null?a+".@data-"+e:k};ja(o,a)}}})}var w=o.oFeatures;e.bStateSave&&(w.bStateSave=
!0,Kb(o,e),z(o,"aoDrawCallback",wa,"state_save"));if(e.aaSorting===k){t=o.aaSorting;g=0;for(j=t.length;g<j;g++)t[g][1]=o.aoColumns[g].asSorting[0]}va(o);w.bSort&&z(o,"aoDrawCallback",function(){if(o.bSorted){var a=V(o),b={};h.each(a,function(a,c){b[c.src]=c.dir});u(o,null,"order",[o,a,b]);Jb(o)}});z(o,"aoDrawCallback",function(){(o.bSorted||y(o)==="ssp"||w.bDeferRender)&&va(o)},"sc");g=q.children("caption").each(function(){this._captionSide=q.css("caption-side")});j=q.children("thead");0===j.length&&
(j=h("<thead/>").appendTo(this));o.nTHead=j[0];j=q.children("tbody");0===j.length&&(j=h("<tbody/>").appendTo(this));o.nTBody=j[0];j=q.children("tfoot");if(0===j.length&&0<g.length&&(""!==o.oScroll.sX||""!==o.oScroll.sY))j=h("<tfoot/>").appendTo(this);0===j.length||0===j.children().length?q.addClass(i.sNoFooter):0<j.length&&(o.nTFoot=j[0],da(o.aoFooter,o.nTFoot));if(e.aaData)for(g=0;g<e.aaData.length;g++)N(o,e.aaData[g]);else(o.bDeferLoading||"dom"==y(o))&&ma(o,h(o.nTBody).children("tr"));o.aiDisplay=
o.aiDisplayMaster.slice();o.bInitialised=!0;!1===n&&ga(o)}});b=null;return this},v,r,p,s,Ya={},Ob=/[\r\n]/g,Aa=/<.*?>/g,ac=/^[\w\+\-]/,bc=/[\w\+\-]$/,cc=RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"),Xa=/[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi,M=function(a){return!a||!0===a||"-"===a?!0:!1},Pb=function(a){var b=parseInt(a,10);return!isNaN(b)&&isFinite(a)?b:null},Qb=function(a,b){Ya[b]||(Ya[b]=RegExp(Qa(b),"g"));return"string"===typeof a&&"."!==b?a.replace(/\./g,
"").replace(Ya[b],"."):a},Za=function(a,b,c){var d="string"===typeof a;if(M(a))return!0;b&&d&&(a=Qb(a,b));c&&d&&(a=a.replace(Xa,""));return!isNaN(parseFloat(a))&&isFinite(a)},Rb=function(a,b,c){return M(a)?!0:!(M(a)||"string"===typeof a)?null:Za(a.replace(Aa,""),b,c)?!0:null},G=function(a,b,c){var d=[],e=0,f=a.length;if(c!==k)for(;e<f;e++)a[e]&&a[e][b]&&d.push(a[e][b][c]);else for(;e<f;e++)a[e]&&d.push(a[e][b]);return d},ha=function(a,b,c,d){var e=[],f=0,g=b.length;if(d!==k)for(;f<g;f++)a[b[f]][c]&&
e.push(a[b[f]][c][d]);else for(;f<g;f++)e.push(a[b[f]][c]);return e},W=function(a,b){var c=[],d;b===k?(b=0,d=a):(d=b,b=a);for(var e=b;e<d;e++)c.push(e);return c},Sb=function(a){for(var b=[],c=0,d=a.length;c<d;c++)a[c]&&b.push(a[c]);return b},pa=function(a){var b=[],c,d,e=a.length,f,g=0;d=0;a:for(;d<e;d++){c=a[d];for(f=0;f<g;f++)if(b[f]===c)continue a;b.push(c);g++}return b};m.util={throttle:function(a,b){var c=b!==k?b:200,d,e;return function(){var b=this,g=+new Date,h=arguments;d&&g<d+c?(clearTimeout(e),
e=setTimeout(function(){d=k;a.apply(b,h)},c)):(d=g,a.apply(b,h))}},escapeRegex:function(a){return a.replace(cc,"\\$1")}};var A=function(a,b,c){a[b]!==k&&(a[c]=a[b])},ba=/\[.*?\]$/,U=/\(\)$/,Qa=m.util.escapeRegex,ua=h("<div>")[0],Zb=ua.textContent!==k,$b=/<.*?>/g,Oa=m.util.throttle,Tb=[],w=Array.prototype,dc=function(a){var b,c,d=m.settings,e=h.map(d,function(a){return a.nTable});if(a){if(a.nTable&&a.oApi)return[a];if(a.nodeName&&"table"===a.nodeName.toLowerCase())return b=h.inArray(a,e),-1!==b?[d[b]]:
null;if(a&&"function"===typeof a.settings)return a.settings().toArray();"string"===typeof a?c=h(a):a instanceof h&&(c=a)}else return[];if(c)return c.map(function(){b=h.inArray(this,e);return-1!==b?d[b]:null}).toArray()};r=function(a,b){if(!(this instanceof r))return new r(a,b);var c=[],d=function(a){(a=dc(a))&&(c=c.concat(a))};if(h.isArray(a))for(var e=0,f=a.length;e<f;e++)d(a[e]);else d(a);this.context=pa(c);b&&h.merge(this,b);this.selector={rows:null,cols:null,opts:null};r.extend(this,this,Tb)};
m.Api=r;h.extend(r.prototype,{any:function(){return 0!==this.count()},concat:w.concat,context:[],count:function(){return this.flatten().length},each:function(a){for(var b=0,c=this.length;b<c;b++)a.call(this,this[b],b,this);return this},eq:function(a){var b=this.context;return b.length>a?new r(b[a],this[a]):null},filter:function(a){var b=[];if(w.filter)b=w.filter.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)a.call(this,this[c],c,this)&&b.push(this[c]);return new r(this.context,b)},flatten:function(){var a=
[];return new r(this.context,a.concat.apply(a,this.toArray()))},join:w.join,indexOf:w.indexOf||function(a,b){for(var c=b||0,d=this.length;c<d;c++)if(this[c]===a)return c;return-1},iterator:function(a,b,c,d){var e=[],f,g,h,i,n,l=this.context,m,t,p=this.selector;"string"===typeof a&&(d=c,c=b,b=a,a=!1);g=0;for(h=l.length;g<h;g++){var o=new r(l[g]);if("table"===b)f=c.call(o,l[g],g),f!==k&&e.push(f);else if("columns"===b||"rows"===b)f=c.call(o,l[g],this[g],g),f!==k&&e.push(f);else if("column"===b||"column-rows"===
b||"row"===b||"cell"===b){t=this[g];"column-rows"===b&&(m=Ba(l[g],p.opts));i=0;for(n=t.length;i<n;i++)f=t[i],f="cell"===b?c.call(o,l[g],f.row,f.column,g,i):c.call(o,l[g],f,g,i,m),f!==k&&e.push(f)}}return e.length||d?(a=new r(l,a?e.concat.apply([],e):e),b=a.selector,b.rows=p.rows,b.cols=p.cols,b.opts=p.opts,a):this},lastIndexOf:w.lastIndexOf||function(a,b){return this.indexOf.apply(this.toArray.reverse(),arguments)},length:0,map:function(a){var b=[];if(w.map)b=w.map.call(this,a,this);else for(var c=
0,d=this.length;c<d;c++)b.push(a.call(this,this[c],c));return new r(this.context,b)},pluck:function(a){return this.map(function(b){return b[a]})},pop:w.pop,push:w.push,reduce:w.reduce||function(a,b){return hb(this,a,b,0,this.length,1)},reduceRight:w.reduceRight||function(a,b){return hb(this,a,b,this.length-1,-1,-1)},reverse:w.reverse,selector:null,shift:w.shift,sort:w.sort,splice:w.splice,toArray:function(){return w.slice.call(this)},to$:function(){return h(this)},toJQuery:function(){return h(this)},
unique:function(){return new r(this.context,pa(this))},unshift:w.unshift});r.extend=function(a,b,c){if(c.length&&b&&(b instanceof r||b.__dt_wrapper)){var d,e,f,g=function(a,b,c){return function(){var d=b.apply(a,arguments);r.extend(d,d,c.methodExt);return d}};d=0;for(e=c.length;d<e;d++)f=c[d],b[f.name]="function"===typeof f.val?g(a,f.val,f):h.isPlainObject(f.val)?{}:f.val,b[f.name].__dt_wrapper=!0,r.extend(a,b[f.name],f.propExt)}};r.register=p=function(a,b){if(h.isArray(a))for(var c=0,d=a.length;c<
d;c++)r.register(a[c],b);else for(var e=a.split("."),f=Tb,g,j,c=0,d=e.length;c<d;c++){g=(j=-1!==e[c].indexOf("()"))?e[c].replace("()",""):e[c];var i;a:{i=0;for(var n=f.length;i<n;i++)if(f[i].name===g){i=f[i];break a}i=null}i||(i={name:g,val:{},methodExt:[],propExt:[]},f.push(i));c===d-1?i.val=b:f=j?i.methodExt:i.propExt}};r.registerPlural=s=function(a,b,c){r.register(a,c);r.register(b,function(){var a=c.apply(this,arguments);return a===this?this:a instanceof r?a.length?h.isArray(a[0])?new r(a.context,
a[0]):a[0]:k:a})};p("tables()",function(a){var b;if(a){b=r;var c=this.context;if("number"===typeof a)a=[c[a]];else var d=h.map(c,function(a){return a.nTable}),a=h(d).filter(a).map(function(){var a=h.inArray(this,d);return c[a]}).toArray();b=new b(a)}else b=this;return b});p("table()",function(a){var a=this.tables(a),b=a.context;return b.length?new r(b[0]):a});s("tables().nodes()","table().node()",function(){return this.iterator("table",function(a){return a.nTable},1)});s("tables().body()","table().body()",
function(){return this.iterator("table",function(a){return a.nTBody},1)});s("tables().header()","table().header()",function(){return this.iterator("table",function(a){return a.nTHead},1)});s("tables().footer()","table().footer()",function(){return this.iterator("table",function(a){return a.nTFoot},1)});s("tables().containers()","table().container()",function(){return this.iterator("table",function(a){return a.nTableWrapper},1)});p("draw()",function(a){return this.iterator("table",function(b){"page"===
a?O(b):("string"===typeof a&&(a="full-hold"===a?!1:!0),T(b,!1===a))})});p("page()",function(a){return a===k?this.page.info().page:this.iterator("table",function(b){Ta(b,a)})});p("page.info()",function(){if(0===this.context.length)return k;var a=this.context[0],b=a._iDisplayStart,c=a.oFeatures.bPaginate?a._iDisplayLength:-1,d=a.fnRecordsDisplay(),e=-1===c;return{page:e?0:Math.floor(b/c),pages:e?1:Math.ceil(d/c),start:b,end:a.fnDisplayEnd(),length:c,recordsTotal:a.fnRecordsTotal(),recordsDisplay:d,
serverSide:"ssp"===y(a)}});p("page.len()",function(a){return a===k?0!==this.context.length?this.context[0]._iDisplayLength:k:this.iterator("table",function(b){Ra(b,a)})});var Ub=function(a,b,c){if(c){var d=new r(a);d.one("draw",function(){c(d.ajax.json())})}if("ssp"==y(a))T(a,b);else{C(a,!0);var e=a.jqXHR;e&&4!==e.readyState&&e.abort();ra(a,[],function(c){na(a);for(var c=sa(a,c),d=0,e=c.length;d<e;d++)N(a,c[d]);T(a,b);C(a,!1)})}};p("ajax.json()",function(){var a=this.context;if(0<a.length)return a[0].json});
p("ajax.params()",function(){var a=this.context;if(0<a.length)return a[0].oAjaxData});p("ajax.reload()",function(a,b){return this.iterator("table",function(c){Ub(c,!1===b,a)})});p("ajax.url()",function(a){var b=this.context;if(a===k){if(0===b.length)return k;b=b[0];return b.ajax?h.isPlainObject(b.ajax)?b.ajax.url:b.ajax:b.sAjaxSource}return this.iterator("table",function(b){h.isPlainObject(b.ajax)?b.ajax.url=a:b.ajax=a})});p("ajax.url().load()",function(a,b){return this.iterator("table",function(c){Ub(c,
!1===b,a)})});var $a=function(a,b,c,d,e){var f=[],g,j,i,n,l,m;i=typeof b;if(!b||"string"===i||"function"===i||b.length===k)b=[b];i=0;for(n=b.length;i<n;i++){j=b[i]&&b[i].split?b[i].split(","):[b[i]];l=0;for(m=j.length;l<m;l++)(g=c("string"===typeof j[l]?h.trim(j[l]):j[l]))&&g.length&&(f=f.concat(g))}a=v.selector[a];if(a.length){i=0;for(n=a.length;i<n;i++)f=a[i](d,e,f)}return pa(f)},ab=function(a){a||(a={});a.filter&&a.search===k&&(a.search=a.filter);return h.extend({search:"none",order:"current",
page:"all"},a)},bb=function(a){for(var b=0,c=a.length;b<c;b++)if(0<a[b].length)return a[0]=a[b],a[0].length=1,a.length=1,a.context=[a.context[b]],a;a.length=0;return a},Ba=function(a,b){var c,d,e,f=[],g=a.aiDisplay;c=a.aiDisplayMaster;var j=b.search;d=b.order;e=b.page;if("ssp"==y(a))return"removed"===j?[]:W(0,c.length);if("current"==e){c=a._iDisplayStart;for(d=a.fnDisplayEnd();c<d;c++)f.push(g[c])}else if("current"==d||"applied"==d)f="none"==j?c.slice():"applied"==j?g.slice():h.map(c,function(a){return-1===
h.inArray(a,g)?a:null});else if("index"==d||"original"==d){c=0;for(d=a.aoData.length;c<d;c++)"none"==j?f.push(c):(e=h.inArray(c,g),(-1===e&&"removed"==j||0<=e&&"applied"==j)&&f.push(c))}return f};p("rows()",function(a,b){a===k?a="":h.isPlainObject(a)&&(b=a,a="");var b=ab(b),c=this.iterator("table",function(c){var e=b;return $a("row",a,function(a){var b=Pb(a);if(b!==null&&!e)return[b];var j=Ba(c,e);if(b!==null&&h.inArray(b,j)!==-1)return[b];if(!a)return j;if(typeof a==="function")return h.map(j,function(b){var e=
c.aoData[b];return a(b,e._aData,e.nTr)?b:null});b=Sb(ha(c.aoData,j,"nTr"));if(a.nodeName){if(a._DT_RowIndex!==k)return[a._DT_RowIndex];if(a._DT_CellIndex)return[a._DT_CellIndex.row];b=h(a).closest("*[data-dt-row]");return b.length?[b.data("dt-row")]:[]}if(typeof a==="string"&&a.charAt(0)==="#"){j=c.aIds[a.replace(/^#/,"")];if(j!==k)return[j.idx]}return h(b).filter(a).map(function(){return this._DT_RowIndex}).toArray()},c,e)},1);c.selector.rows=a;c.selector.opts=b;return c});p("rows().nodes()",function(){return this.iterator("row",
function(a,b){return a.aoData[b].nTr||k},1)});p("rows().data()",function(){return this.iterator(!0,"rows",function(a,b){return ha(a.aoData,b,"_aData")},1)});s("rows().cache()","row().cache()",function(a){return this.iterator("row",function(b,c){var d=b.aoData[c];return"search"===a?d._aFilterData:d._aSortData},1)});s("rows().invalidate()","row().invalidate()",function(a){return this.iterator("row",function(b,c){ca(b,c,a)})});s("rows().indexes()","row().index()",function(){return this.iterator("row",
function(a,b){return b},1)});s("rows().ids()","row().id()",function(a){for(var b=[],c=this.context,d=0,e=c.length;d<e;d++)for(var f=0,g=this[d].length;f<g;f++){var h=c[d].rowIdFn(c[d].aoData[this[d][f]]._aData);b.push((!0===a?"#":"")+h)}return new r(c,b)});s("rows().remove()","row().remove()",function(){var a=this;this.iterator("row",function(b,c,d){var e=b.aoData,f=e[c],g,h,i,n,l;e.splice(c,1);g=0;for(h=e.length;g<h;g++)if(i=e[g],l=i.anCells,null!==i.nTr&&(i.nTr._DT_RowIndex=g),null!==l){i=0;for(n=
l.length;i<n;i++)l[i]._DT_CellIndex.row=g}oa(b.aiDisplayMaster,c);oa(b.aiDisplay,c);oa(a[d],c,!1);Sa(b);c=b.rowIdFn(f._aData);c!==k&&delete b.aIds[c]});this.iterator("table",function(a){for(var c=0,d=a.aoData.length;c<d;c++)a.aoData[c].idx=c});return this});p("rows.add()",function(a){var b=this.iterator("table",function(b){var c,f,g,h=[];f=0;for(g=a.length;f<g;f++)c=a[f],c.nodeName&&"TR"===c.nodeName.toUpperCase()?h.push(ma(b,c)[0]):h.push(N(b,c));return h},1),c=this.rows(-1);c.pop();h.merge(c,b);
return c});p("row()",function(a,b){return bb(this.rows(a,b))});p("row().data()",function(a){var b=this.context;if(a===k)return b.length&&this.length?b[0].aoData[this[0]]._aData:k;b[0].aoData[this[0]]._aData=a;ca(b[0],this[0],"data");return this});p("row().node()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]].nTr||null:null});p("row.add()",function(a){a instanceof h&&a.length&&(a=a[0]);var b=this.iterator("table",function(b){return a.nodeName&&"TR"===a.nodeName.toUpperCase()?
ma(b,a)[0]:N(b,a)});return this.row(b[0])});var cb=function(a,b){var c=a.context;if(c.length&&(c=c[0].aoData[b!==k?b:a[0]])&&c._details)c._details.remove(),c._detailsShow=k,c._details=k},Vb=function(a,b){var c=a.context;if(c.length&&a.length){var d=c[0].aoData[a[0]];if(d._details){(d._detailsShow=b)?d._details.insertAfter(d.nTr):d._details.detach();var e=c[0],f=new r(e),g=e.aoData;f.off("draw.dt.DT_details column-visibility.dt.DT_details destroy.dt.DT_details");0<G(g,"_details").length&&(f.on("draw.dt.DT_details",
function(a,b){e===b&&f.rows({page:"current"}).eq(0).each(function(a){a=g[a];a._detailsShow&&a._details.insertAfter(a.nTr)})}),f.on("column-visibility.dt.DT_details",function(a,b){if(e===b)for(var c,d=aa(b),f=0,h=g.length;f<h;f++)c=g[f],c._details&&c._details.children("td[colspan]").attr("colspan",d)}),f.on("destroy.dt.DT_details",function(a,b){if(e===b)for(var c=0,d=g.length;c<d;c++)g[c]._details&&cb(f,c)}))}}};p("row().child()",function(a,b){var c=this.context;if(a===k)return c.length&&this.length?
c[0].aoData[this[0]]._details:k;if(!0===a)this.child.show();else if(!1===a)cb(this);else if(c.length&&this.length){var d=c[0],c=c[0].aoData[this[0]],e=[],f=function(a,b){if(h.isArray(a)||a instanceof h)for(var c=0,k=a.length;c<k;c++)f(a[c],b);else a.nodeName&&"tr"===a.nodeName.toLowerCase()?e.push(a):(c=h("<tr><td/></tr>").addClass(b),h("td",c).addClass(b).html(a)[0].colSpan=aa(d),e.push(c[0]))};f(a,b);c._details&&c._details.remove();c._details=h(e);c._detailsShow&&c._details.insertAfter(c.nTr)}return this});
p(["row().child.show()","row().child().show()"],function(){Vb(this,!0);return this});p(["row().child.hide()","row().child().hide()"],function(){Vb(this,!1);return this});p(["row().child.remove()","row().child().remove()"],function(){cb(this);return this});p("row().child.isShown()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]]._detailsShow||!1:!1});var ec=/^(.+):(name|visIdx|visible)$/,Wb=function(a,b,c,d,e){for(var c=[],d=0,f=e.length;d<f;d++)c.push(B(a,e[d],b));
return c};p("columns()",function(a,b){a===k?a="":h.isPlainObject(a)&&(b=a,a="");var b=ab(b),c=this.iterator("table",function(c){var e=a,f=b,g=c.aoColumns,j=G(g,"sName"),i=G(g,"nTh");return $a("column",e,function(a){var b=Pb(a);if(a==="")return W(g.length);if(b!==null)return[b>=0?b:g.length+b];if(typeof a==="function"){var e=Ba(c,f);return h.map(g,function(b,f){return a(f,Wb(c,f,0,0,e),i[f])?f:null})}var k=typeof a==="string"?a.match(ec):"";if(k)switch(k[2]){case "visIdx":case "visible":b=parseInt(k[1],
10);if(b<0){var m=h.map(g,function(a,b){return a.bVisible?b:null});return[m[m.length+b]]}return[Z(c,b)];case "name":return h.map(j,function(a,b){return a===k[1]?b:null});default:return[]}if(a.nodeName&&a._DT_CellIndex)return[a._DT_CellIndex.column];b=h(i).filter(a).map(function(){return h.inArray(this,i)}).toArray();if(b.length||!a.nodeName)return b;b=h(a).closest("*[data-dt-column]");return b.length?[b.data("dt-column")]:[]},c,f)},1);c.selector.cols=a;c.selector.opts=b;return c});s("columns().header()",
"column().header()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTh},1)});s("columns().footer()","column().footer()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTf},1)});s("columns().data()","column().data()",function(){return this.iterator("column-rows",Wb,1)});s("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData},1)});s("columns().cache()","column().cache()",
function(a){return this.iterator("column-rows",function(b,c,d,e,f){return ha(b.aoData,f,"search"===a?"_aFilterData":"_aSortData",c)},1)});s("columns().nodes()","column().nodes()",function(){return this.iterator("column-rows",function(a,b,c,d,e){return ha(a.aoData,e,"anCells",b)},1)});s("columns().visible()","column().visible()",function(a,b){var c=this.iterator("column",function(b,c){if(a===k)return b.aoColumns[c].bVisible;var f=b.aoColumns,g=f[c],j=b.aoData,i,n,l;if(a!==k&&g.bVisible!==a){if(a){var m=
h.inArray(!0,G(f,"bVisible"),c+1);i=0;for(n=j.length;i<n;i++)l=j[i].nTr,f=j[i].anCells,l&&l.insertBefore(f[c],f[m]||null)}else h(G(b.aoData,"anCells",c)).detach();g.bVisible=a;ea(b,b.aoHeader);ea(b,b.aoFooter);wa(b)}});a!==k&&(this.iterator("column",function(c,e){u(c,null,"column-visibility",[c,e,a,b])}),(b===k||b)&&this.columns.adjust());return c});s("columns().indexes()","column().index()",function(a){return this.iterator("column",function(b,c){return"visible"===a?$(b,c):c},1)});p("columns.adjust()",
function(){return this.iterator("table",function(a){Y(a)},1)});p("column.index()",function(a,b){if(0!==this.context.length){var c=this.context[0];if("fromVisible"===a||"toData"===a)return Z(c,b);if("fromData"===a||"toVisible"===a)return $(c,b)}});p("column()",function(a,b){return bb(this.columns(a,b))});p("cells()",function(a,b,c){h.isPlainObject(a)&&(a.row===k?(c=a,a=null):(c=b,b=null));h.isPlainObject(b)&&(c=b,b=null);if(null===b||b===k)return this.iterator("table",function(b){var d=a,e=ab(c),f=
b.aoData,g=Ba(b,e),j=Sb(ha(f,g,"anCells")),i=h([].concat.apply([],j)),l,n=b.aoColumns.length,m,p,r,u,v,s;return $a("cell",d,function(a){var c=typeof a==="function";if(a===null||a===k||c){m=[];p=0;for(r=g.length;p<r;p++){l=g[p];for(u=0;u<n;u++){v={row:l,column:u};if(c){s=f[l];a(v,B(b,l,u),s.anCells?s.anCells[u]:null)&&m.push(v)}else m.push(v)}}return m}if(h.isPlainObject(a))return[a];c=i.filter(a).map(function(a,b){return{row:b._DT_CellIndex.row,column:b._DT_CellIndex.column}}).toArray();if(c.length||
!a.nodeName)return c;s=h(a).closest("*[data-dt-row]");return s.length?[{row:s.data("dt-row"),column:s.data("dt-column")}]:[]},b,e)});var d=this.columns(b,c),e=this.rows(a,c),f,g,j,i,n,l=this.iterator("table",function(a,b){f=[];g=0;for(j=e[b].length;g<j;g++){i=0;for(n=d[b].length;i<n;i++)f.push({row:e[b][g],column:d[b][i]})}return f},1);h.extend(l.selector,{cols:b,rows:a,opts:c});return l});s("cells().nodes()","cell().node()",function(){return this.iterator("cell",function(a,b,c){return(a=a.aoData[b])&&
a.anCells?a.anCells[c]:k},1)});p("cells().data()",function(){return this.iterator("cell",function(a,b,c){return B(a,b,c)},1)});s("cells().cache()","cell().cache()",function(a){a="search"===a?"_aFilterData":"_aSortData";return this.iterator("cell",function(b,c,d){return b.aoData[c][a][d]},1)});s("cells().render()","cell().render()",function(a){return this.iterator("cell",function(b,c,d){return B(b,c,d,a)},1)});s("cells().indexes()","cell().index()",function(){return this.iterator("cell",function(a,
b,c){return{row:b,column:c,columnVisible:$(a,c)}},1)});s("cells().invalidate()","cell().invalidate()",function(a){return this.iterator("cell",function(b,c,d){ca(b,c,a,d)})});p("cell()",function(a,b,c){return bb(this.cells(a,b,c))});p("cell().data()",function(a){var b=this.context,c=this[0];if(a===k)return b.length&&c.length?B(b[0],c[0].row,c[0].column):k;jb(b[0],c[0].row,c[0].column,a);ca(b[0],c[0].row,"data",c[0].column);return this});p("order()",function(a,b){var c=this.context;if(a===k)return 0!==
c.length?c[0].aaSorting:k;"number"===typeof a?a=[[a,b]]:a.length&&!h.isArray(a[0])&&(a=Array.prototype.slice.call(arguments));return this.iterator("table",function(b){b.aaSorting=a.slice()})});p("order.listener()",function(a,b,c){return this.iterator("table",function(d){Ma(d,a,b,c)})});p("order.fixed()",function(a){if(!a){var b=this.context,b=b.length?b[0].aaSortingFixed:k;return h.isArray(b)?{pre:b}:b}return this.iterator("table",function(b){b.aaSortingFixed=h.extend(!0,{},a)})});p(["columns().order()",
"column().order()"],function(a){var b=this;return this.iterator("table",function(c,d){var e=[];h.each(b[d],function(b,c){e.push([c,a])});c.aaSorting=e})});p("search()",function(a,b,c,d){var e=this.context;return a===k?0!==e.length?e[0].oPreviousSearch.sSearch:k:this.iterator("table",function(e){e.oFeatures.bFilter&&fa(e,h.extend({},e.oPreviousSearch,{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===c?!0:c,bCaseInsensitive:null===d?!0:d}),1)})});s("columns().search()","column().search()",function(a,
b,c,d){return this.iterator("column",function(e,f){var g=e.aoPreSearchCols;if(a===k)return g[f].sSearch;e.oFeatures.bFilter&&(h.extend(g[f],{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===c?!0:c,bCaseInsensitive:null===d?!0:d}),fa(e,e.oPreviousSearch,1))})});p("state()",function(){return this.context.length?this.context[0].oSavedState:null});p("state.clear()",function(){return this.iterator("table",function(a){a.fnStateSaveCallback.call(a.oInstance,a,{})})});p("state.loaded()",function(){return this.context.length?
this.context[0].oLoadedState:null});p("state.save()",function(){return this.iterator("table",function(a){wa(a)})});m.versionCheck=m.fnVersionCheck=function(a){for(var b=m.version.split("."),a=a.split("."),c,d,e=0,f=a.length;e<f;e++)if(c=parseInt(b[e],10)||0,d=parseInt(a[e],10)||0,c!==d)return c>d;return!0};m.isDataTable=m.fnIsDataTable=function(a){var b=h(a).get(0),c=!1;h.each(m.settings,function(a,e){var f=e.nScrollHead?h("table",e.nScrollHead)[0]:null,g=e.nScrollFoot?h("table",e.nScrollFoot)[0]:
null;if(e.nTable===b||f===b||g===b)c=!0});return c};m.tables=m.fnTables=function(a){var b=!1;h.isPlainObject(a)&&(b=a.api,a=a.visible);var c=h.map(m.settings,function(b){if(!a||a&&h(b.nTable).is(":visible"))return b.nTable});return b?new r(c):c};m.camelToHungarian=K;p("$()",function(a,b){var c=this.rows(b).nodes(),c=h(c);return h([].concat(c.filter(a).toArray(),c.find(a).toArray()))});h.each(["on","one","off"],function(a,b){p(b+"()",function(){var a=Array.prototype.slice.call(arguments);a[0].match(/\.dt\b/)||
(a[0]+=".dt");var d=h(this.tables().nodes());d[b].apply(d,a);return this})});p("clear()",function(){return this.iterator("table",function(a){na(a)})});p("settings()",function(){return new r(this.context,this.context)});p("init()",function(){var a=this.context;return a.length?a[0].oInit:null});p("data()",function(){return this.iterator("table",function(a){return G(a.aoData,"_aData")}).flatten()});p("destroy()",function(a){a=a||!1;return this.iterator("table",function(b){var c=b.nTableWrapper.parentNode,
d=b.oClasses,e=b.nTable,f=b.nTBody,g=b.nTHead,j=b.nTFoot,i=h(e),f=h(f),k=h(b.nTableWrapper),l=h.map(b.aoData,function(a){return a.nTr}),p;b.bDestroying=!0;u(b,"aoDestroyCallback","destroy",[b]);a||(new r(b)).columns().visible(!0);k.unbind(".DT").find(":not(tbody *)").unbind(".DT");h(D).unbind(".DT-"+b.sInstance);e!=g.parentNode&&(i.children("thead").detach(),i.append(g));j&&e!=j.parentNode&&(i.children("tfoot").detach(),i.append(j));b.aaSorting=[];b.aaSortingFixed=[];va(b);h(l).removeClass(b.asStripeClasses.join(" "));
h("th, td",g).removeClass(d.sSortable+" "+d.sSortableAsc+" "+d.sSortableDesc+" "+d.sSortableNone);b.bJUI&&(h("th span."+d.sSortIcon+", td span."+d.sSortIcon,g).detach(),h("th, td",g).each(function(){var a=h("div."+d.sSortJUIWrapper,this);h(this).append(a.contents());a.detach()}));f.children().detach();f.append(l);g=a?"remove":"detach";i[g]();k[g]();!a&&c&&(c.insertBefore(e,b.nTableReinsertBefore),i.css("width",b.sDestroyWidth).removeClass(d.sTable),(p=b.asDestroyStripes.length)&&f.children().each(function(a){h(this).addClass(b.asDestroyStripes[a%
p])}));c=h.inArray(b,m.settings);-1!==c&&m.settings.splice(c,1)})});h.each(["column","row","cell"],function(a,b){p(b+"s().every()",function(a){var d=this.selector.opts,e=this;return this.iterator(b,function(f,g,h,i,n){a.call(e[b](g,"cell"===b?h:d,"cell"===b?d:k),g,h,i,n)})})});p("i18n()",function(a,b,c){var d=this.context[0],a=Q(a)(d.oLanguage);a===k&&(a=b);c!==k&&h.isPlainObject(a)&&(a=a[c]!==k?a[c]:a._);return a.replace("%d",c)});m.version="1.10.12";m.settings=[];m.models={};m.models.oSearch={bCaseInsensitive:!0,
sSearch:"",bRegex:!1,bSmart:!0};m.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1};m.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,
sTitle:null,sType:null,sWidth:null,sWidthOrig:null};m.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bJQueryUI:!1,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,
fnFormatNumber:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(a){try{return JSON.parse((-1===a.iStateDuration?sessionStorage:localStorage).getItem("DataTables_"+a.sInstance+"_"+location.pathname))}catch(b){}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(a,b){try{(-1===
a.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+a.sInstance+"_"+location.pathname,JSON.stringify(b))}catch(c){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",
sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:h.extend({},m.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",
renderer:null,rowId:"DT_RowId"};X(m.defaults);m.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null};X(m.defaults.column);m.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,
bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],
aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button",iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:k,oAjaxData:k,
fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,bJUI:null,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==y(this)?1*this._iRecordsTotal:this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==y(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=
this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};m.ext=v={buttons:{},classes:{},builder:"-source-",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},
header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:m.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:m.version};h.extend(v,{afnFiltering:v.search,aTypes:v.type.detect,ofnSearch:v.type.search,oSort:v.type.order,afnSortData:v.order,aoFeatures:v.feature,oApi:v.internal,oStdClasses:v.classes,oPagination:v.pager});h.extend(m.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",
sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",
sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sJUIHeader:"",sJUIFooter:""});var Ca="",Ca="",H=Ca+"ui-state-default",ia=Ca+"css_right ui-icon ui-icon-",Xb=Ca+"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix";h.extend(m.ext.oJUIClasses,
m.ext.classes,{sPageButton:"fg-button ui-button "+H,sPageButtonActive:"ui-state-disabled",sPageButtonDisabled:"ui-state-disabled",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sSortAsc:H+" sorting_asc",sSortDesc:H+" sorting_desc",sSortable:H+" sorting",sSortableAsc:H+" sorting_asc_disabled",sSortableDesc:H+" sorting_desc_disabled",sSortableNone:H+" sorting_disabled",sSortJUIAsc:ia+"triangle-1-n",sSortJUIDesc:ia+"triangle-1-s",sSortJUI:ia+"carat-2-n-s",
sSortJUIAscAllowed:ia+"carat-1-n",sSortJUIDescAllowed:ia+"carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",sScrollHead:"dataTables_scrollHead "+H,sScrollFoot:"dataTables_scrollFoot "+H,sHeaderTH:H,sFooterTH:H,sJUIHeader:Xb+" ui-corner-tl ui-corner-tr",sJUIFooter:Xb+" ui-corner-bl ui-corner-br"});var Mb=m.ext.pager;h.extend(Mb,{simple:function(){return["previous","next"]},full:function(){return["first","previous","next","last"]},numbers:function(a,b){return[ya(a,
b)]},simple_numbers:function(a,b){return["previous",ya(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ya(a,b),"next","last"]},_numbers:ya,numbers_length:7});h.extend(!0,m.ext.renderer,{pageButton:{_:function(a,b,c,d,e,f){var g=a.oClasses,j=a.oLanguage.oPaginate,i=a.oLanguage.oAria.paginate||{},k,l,m=0,p=function(b,d){var o,r,u,s,v=function(b){Ta(a,b.data.action,true)};o=0;for(r=d.length;o<r;o++){s=d[o];if(h.isArray(s)){u=h("<"+(s.DT_el||"div")+"/>").appendTo(b);p(u,s)}else{k=null;
l="";switch(s){case "ellipsis":b.append('<span class="ellipsis">&#x2026;</span>');break;case "first":k=j.sFirst;l=s+(e>0?"":" "+g.sPageButtonDisabled);break;case "previous":k=j.sPrevious;l=s+(e>0?"":" "+g.sPageButtonDisabled);break;case "next":k=j.sNext;l=s+(e<f-1?"":" "+g.sPageButtonDisabled);break;case "last":k=j.sLast;l=s+(e<f-1?"":" "+g.sPageButtonDisabled);break;default:k=s+1;l=e===s?g.sPageButtonActive:""}if(k!==null){u=h("<a>",{"class":g.sPageButton+" "+l,"aria-controls":a.sTableId,"aria-label":i[s],
"data-dt-idx":m,tabindex:a.iTabIndex,id:c===0&&typeof s==="string"?a.sTableId+"_"+s:null}).html(k).appendTo(b);Wa(u,{action:s},v);m++}}}},r;try{r=h(b).find(I.activeElement).data("dt-idx")}catch(o){}p(h(b).empty(),d);r&&h(b).find("[data-dt-idx="+r+"]").focus()}}});h.extend(m.ext.type.detect,[function(a,b){var c=b.oLanguage.sDecimal;return Za(a,c)?"num"+c:null},function(a){if(a&&!(a instanceof Date)&&(!ac.test(a)||!bc.test(a)))return null;var b=Date.parse(a);return null!==b&&!isNaN(b)||M(a)?"date":
null},function(a,b){var c=b.oLanguage.sDecimal;return Za(a,c,!0)?"num-fmt"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Rb(a,c)?"html-num"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Rb(a,c,!0)?"html-num-fmt"+c:null},function(a){return M(a)||"string"===typeof a&&-1!==a.indexOf("<")?"html":null}]);h.extend(m.ext.type.search,{html:function(a){return M(a)?a:"string"===typeof a?a.replace(Ob," ").replace(Aa,""):""},string:function(a){return M(a)?a:"string"===typeof a?a.replace(Ob,
" "):a}});var za=function(a,b,c,d){if(0!==a&&(!a||"-"===a))return-Infinity;b&&(a=Qb(a,b));a.replace&&(c&&(a=a.replace(c,"")),d&&(a=a.replace(d,"")));return 1*a};h.extend(v.type.order,{"date-pre":function(a){return Date.parse(a)||0},"html-pre":function(a){return M(a)?"":a.replace?a.replace(/<.*?>/g,"").toLowerCase():a+""},"string-pre":function(a){return M(a)?"":"string"===typeof a?a.toLowerCase():!a.toString?"":a.toString()},"string-asc":function(a,b){return a<b?-1:a>b?1:0},"string-desc":function(a,
b){return a<b?1:a>b?-1:0}});db("");h.extend(!0,m.ext.renderer,{header:{_:function(a,b,c,d){h(a.nTable).on("order.dt.DT",function(e,f,g,h){if(a===f){e=c.idx;b.removeClass(c.sSortingClass+" "+d.sSortAsc+" "+d.sSortDesc).addClass(h[e]=="asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc:c.sSortingClass)}})},jqueryui:function(a,b,c,d){h("<div/>").addClass(d.sSortJUIWrapper).append(b.contents()).append(h("<span/>").addClass(d.sSortIcon+" "+c.sSortingClassJUI)).appendTo(b);h(a.nTable).on("order.dt.DT",function(e,
f,g,h){if(a===f){e=c.idx;b.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass(h[e]=="asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc:c.sSortingClass);b.find("span."+d.sSortIcon).removeClass(d.sSortJUIAsc+" "+d.sSortJUIDesc+" "+d.sSortJUI+" "+d.sSortJUIAscAllowed+" "+d.sSortJUIDescAllowed).addClass(h[e]=="asc"?d.sSortJUIAsc:h[e]=="desc"?d.sSortJUIDesc:c.sSortingClassJUI)}})}}});var Yb=function(a){return"string"===typeof a?a.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):a};m.render={number:function(a,
b,c,d,e){return{display:function(f){if("number"!==typeof f&&"string"!==typeof f)return f;var g=0>f?"-":"",h=parseFloat(f);if(isNaN(h))return Yb(f);f=Math.abs(h);h=parseInt(f,10);f=c?b+(f-h).toFixed(c).substring(2):"";return g+(d||"")+h.toString().replace(/\B(?=(\d{3})+(?!\d))/g,a)+f+(e||"")}}},text:function(){return{display:Yb}}};h.extend(m.ext.internal,{_fnExternApiFunc:Nb,_fnBuildAjax:ra,_fnAjaxUpdate:lb,_fnAjaxParameters:ub,_fnAjaxUpdateDraw:vb,_fnAjaxDataSrc:sa,_fnAddColumn:Ea,_fnColumnOptions:ja,
_fnAdjustColumnSizing:Y,_fnVisibleToColumnIndex:Z,_fnColumnIndexToVisible:$,_fnVisbleColumns:aa,_fnGetColumns:la,_fnColumnTypes:Ga,_fnApplyColumnDefs:ib,_fnHungarianMap:X,_fnCamelToHungarian:K,_fnLanguageCompat:Da,_fnBrowserDetect:gb,_fnAddData:N,_fnAddTr:ma,_fnNodeToDataIndex:function(a,b){return b._DT_RowIndex!==k?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return h.inArray(c,a.aoData[b].anCells)},_fnGetCellData:B,_fnSetCellData:jb,_fnSplitObjNotation:Ja,_fnGetObjectDataFn:Q,_fnSetObjectDataFn:R,
_fnGetDataMaster:Ka,_fnClearTable:na,_fnDeleteIndex:oa,_fnInvalidate:ca,_fnGetRowElements:Ia,_fnCreateTr:Ha,_fnBuildHead:kb,_fnDrawHead:ea,_fnDraw:O,_fnReDraw:T,_fnAddOptionsHtml:nb,_fnDetectHeader:da,_fnGetUniqueThs:qa,_fnFeatureHtmlFilter:pb,_fnFilterComplete:fa,_fnFilterCustom:yb,_fnFilterColumn:xb,_fnFilter:wb,_fnFilterCreateSearch:Pa,_fnEscapeRegex:Qa,_fnFilterData:zb,_fnFeatureHtmlInfo:sb,_fnUpdateInfo:Cb,_fnInfoMacros:Db,_fnInitialise:ga,_fnInitComplete:ta,_fnLengthChange:Ra,_fnFeatureHtmlLength:ob,
_fnFeatureHtmlPaginate:tb,_fnPageChange:Ta,_fnFeatureHtmlProcessing:qb,_fnProcessingDisplay:C,_fnFeatureHtmlTable:rb,_fnScrollDraw:ka,_fnApplyToChildren:J,_fnCalculateColumnWidths:Fa,_fnThrottle:Oa,_fnConvertToWidth:Fb,_fnGetWidestNode:Gb,_fnGetMaxLenString:Hb,_fnStringToCss:x,_fnSortFlatten:V,_fnSort:mb,_fnSortAria:Jb,_fnSortListener:Va,_fnSortAttachListener:Ma,_fnSortingClasses:va,_fnSortData:Ib,_fnSaveState:wa,_fnLoadState:Kb,_fnSettingsFromNode:xa,_fnLog:L,_fnMap:E,_fnBindAction:Wa,_fnCallbackReg:z,
_fnCallbackFire:u,_fnLengthOverflow:Sa,_fnRenderer:Na,_fnDataSource:y,_fnRowAttributes:La,_fnCalculateEnd:function(){}});h.fn.dataTable=m;m.$=h;h.fn.dataTableSettings=m.settings;h.fn.dataTableExt=m.ext;h.fn.DataTable=function(a){return h(this).dataTable(a).api()};h.each(m,function(a,b){h.fn.DataTable[a]=b});return h.fn.dataTable});

View File

@@ -1,26 +0,0 @@
/*!
Responsive 2.1.0
2014-2016 SpryMedia Ltd - datatables.net/license
*/
(function(c){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(l){return c(l,window,document)}):"object"===typeof exports?module.exports=function(l,k){l||(l=window);if(!k||!k.fn.dataTable)k=require("datatables.net")(l,k).$;return c(k,l,l.document)}:c(jQuery,window,document)})(function(c,l,k,p){var m=c.fn.dataTable,j=function(a,b){if(!m.versionCheck||!m.versionCheck("1.10.3"))throw"DataTables Responsive requires DataTables 1.10.3 or newer";this.s={dt:new m.Api(a),columns:[],
current:[]};this.s.dt.settings()[0].responsive||(b&&"string"===typeof b.details?b.details={type:b.details}:b&&!1===b.details?b.details={type:!1}:b&&!0===b.details&&(b.details={type:"inline"}),this.c=c.extend(!0,{},j.defaults,m.defaults.responsive,b),a.responsive=this,this._constructor())};c.extend(j.prototype,{_constructor:function(){var a=this,b=this.s.dt,d=b.settings()[0],e=c(l).width();b.settings()[0]._responsive=this;c(l).on("resize.dtr orientationchange.dtr",m.util.throttle(function(){var b=
c(l).width();b!==e&&(a._resize(),e=b)}));d.oApi._fnCallbackReg(d,"aoRowCreatedCallback",function(e){-1!==c.inArray(!1,a.s.current)&&c("td, th",e).each(function(e){e=b.column.index("toData",e);!1===a.s.current[e]&&c(this).css("display","none")})});b.on("destroy.dtr",function(){b.off(".dtr");c(b.table().body()).off(".dtr");c(l).off("resize.dtr orientationchange.dtr");c.each(a.s.current,function(b,e){!1===e&&a._setColumnVis(b,!0)})});this.c.breakpoints.sort(function(a,b){return a.width<b.width?1:a.width>
b.width?-1:0});this._classLogic();this._resizeAuto();d=this.c.details;!1!==d.type&&(a._detailsInit(),b.on("column-visibility.dtr",function(){a._classLogic();a._resizeAuto();a._resize()}),b.on("draw.dtr",function(){a._redrawChildren()}),c(b.table().node()).addClass("dtr-"+d.type));b.on("column-reorder.dtr",function(){a._classLogic();a._resizeAuto();a._resize()});b.on("column-sizing.dtr",function(){a._resizeAuto();a._resize()});b.on("init.dtr",function(){a._resizeAuto();a._resize();c.inArray(false,
a.s.current)&&b.columns.adjust()});this._resize()},_columnsVisiblity:function(a){var b=this.s.dt,d=this.s.columns,e,f,g=d.map(function(a,b){return{columnIdx:b,priority:a.priority}}).sort(function(a,b){return a.priority!==b.priority?a.priority-b.priority:a.columnIdx-b.columnIdx}),h=c.map(d,function(b){return b.auto&&null===b.minWidth?!1:!0===b.auto?"-":-1!==c.inArray(a,b.includeIn)}),n=0;e=0;for(f=h.length;e<f;e++)!0===h[e]&&(n+=d[e].minWidth);e=b.settings()[0].oScroll;e=e.sY||e.sX?e.iBarWidth:0;b=
b.table().container().offsetWidth-e-n;e=0;for(f=h.length;e<f;e++)d[e].control&&(b-=d[e].minWidth);n=!1;e=0;for(f=g.length;e<f;e++){var i=g[e].columnIdx;"-"===h[i]&&(!d[i].control&&d[i].minWidth)&&(n||0>b-d[i].minWidth?(n=!0,h[i]=!1):h[i]=!0,b-=d[i].minWidth)}g=!1;e=0;for(f=d.length;e<f;e++)if(!d[e].control&&!d[e].never&&!h[e]){g=!0;break}e=0;for(f=d.length;e<f;e++)d[e].control&&(h[e]=g);-1===c.inArray(!0,h)&&(h[0]=!0);return h},_classLogic:function(){var a=this,b=this.c.breakpoints,d=this.s.dt,e=
d.columns().eq(0).map(function(a){var b=this.column(a),e=b.header().className,a=d.settings()[0].aoColumns[a].responsivePriority;a===p&&(b=c(b.header()).data("priority"),a=b!==p?1*b:1E4);return{className:e,includeIn:[],auto:!1,control:!1,never:e.match(/\bnever\b/)?!0:!1,priority:a}}),f=function(a,b){var d=e[a].includeIn;-1===c.inArray(b,d)&&d.push(b)},g=function(c,d,i,g){if(i)if("max-"===i){g=a._find(d).width;d=0;for(i=b.length;d<i;d++)b[d].width<=g&&f(c,b[d].name)}else if("min-"===i){g=a._find(d).width;
d=0;for(i=b.length;d<i;d++)b[d].width>=g&&f(c,b[d].name)}else{if("not-"===i){d=0;for(i=b.length;d<i;d++)-1===b[d].name.indexOf(g)&&f(c,b[d].name)}}else e[c].includeIn.push(d)};e.each(function(a,e){for(var d=a.className.split(" "),f=!1,j=0,l=d.length;j<l;j++){var k=c.trim(d[j]);if("all"===k){f=!0;a.includeIn=c.map(b,function(a){return a.name});return}if("none"===k||a.never){f=!0;return}if("control"===k){f=!0;a.control=!0;return}c.each(b,function(a,b){var d=b.name.split("-"),c=k.match(RegExp("(min\\-|max\\-|not\\-)?("+
d[0]+")(\\-[_a-zA-Z0-9])?"));c&&(f=!0,c[2]===d[0]&&c[3]==="-"+d[1]?g(e,b.name,c[1],c[2]+c[3]):c[2]===d[0]&&!c[3]&&g(e,b.name,c[1],c[2]))})}f||(a.auto=!0)});this.s.columns=e},_detailsDisplay:function(a,b){var d=this,e=this.s.dt,f=this.c.details;if(f&&!1!==f.type){var g=f.display(a,b,function(){return f.renderer(e,a[0],d._detailsObj(a[0]))});(!0===g||!1===g)&&c(e.table().node()).triggerHandler("responsive-display.dt",[e,a,g,b])}},_detailsInit:function(){var a=this,b=this.s.dt,d=this.c.details;"inline"===
d.type&&(d.target="td:first-child, th:first-child");b.on("draw.dtr",function(){a._tabIndexes()});a._tabIndexes();c(b.table().body()).on("keyup.dtr","td, th",function(a){a.keyCode===13&&c(this).data("dtr-keyboard")&&c(this).click()});var e=d.target;c(b.table().body()).on("click.dtr mousedown.dtr mouseup.dtr","string"===typeof e?e:"td, th",function(d){if(c(b.table().node()).hasClass("collapsed")&&b.row(c(this).closest("tr")).length){if(typeof e==="number"){var g=e<0?b.columns().eq(0).length+e:e;if(b.cell(this).index().column!==
g)return}g=b.row(c(this).closest("tr"));d.type==="click"?a._detailsDisplay(g,false):d.type==="mousedown"?c(this).css("outline","none"):d.type==="mouseup"&&c(this).blur().css("outline","")}})},_detailsObj:function(a){var b=this,d=this.s.dt;return c.map(this.s.columns,function(e,c){if(!e.never&&!e.control)return{title:d.settings()[0].aoColumns[c].sTitle,data:d.cell(a,c).render(b.c.orthogonal),hidden:d.column(c).visible()&&!b.s.current[c],columnIndex:c,rowIndex:a}})},_find:function(a){for(var b=this.c.breakpoints,
d=0,c=b.length;d<c;d++)if(b[d].name===a)return b[d]},_redrawChildren:function(){var a=this,b=this.s.dt;b.rows({page:"current"}).iterator("row",function(c,e){b.row(e);a._detailsDisplay(b.row(e),!0)})},_resize:function(){var a=this,b=this.s.dt,d=c(l).width(),e=this.c.breakpoints,f=e[0].name,g=this.s.columns,h,j=this.s.current.slice();for(h=e.length-1;0<=h;h--)if(d<=e[h].width){f=e[h].name;break}var i=this._columnsVisiblity(f);this.s.current=i;e=!1;h=0;for(d=g.length;h<d;h++)if(!1===i[h]&&!g[h].never&&
!g[h].control){e=!0;break}c(b.table().node()).toggleClass("collapsed",e);var k=!1;b.columns().eq(0).each(function(b,c){i[c]!==j[c]&&(k=!0,a._setColumnVis(b,i[c]))});k&&(this._redrawChildren(),c(b.table().node()).trigger("responsive-resize.dt",[b,this.s.current]))},_resizeAuto:function(){var a=this.s.dt,b=this.s.columns;if(this.c.auto&&-1!==c.inArray(!0,c.map(b,function(a){return a.auto}))){a.table().node();var d=a.table().node().cloneNode(!1),e=c(a.table().header().cloneNode(!1)).appendTo(d),f=c(a.table().body()).clone(!1,
!1).empty().appendTo(d),g=a.columns().header().filter(function(b){return a.column(b).visible()}).to$().clone(!1).css("display","table-cell");c(f).append(c(a.rows({page:"current"}).nodes()).clone(!1)).find("th, td").css("display","");if(f=a.table().footer()){var f=c(f.cloneNode(!1)).appendTo(d),h=a.columns().footer().filter(function(b){return a.column(b).visible()}).to$().clone(!1).css("display","table-cell");c("<tr/>").append(h).appendTo(f)}c("<tr/>").append(g).appendTo(e);"inline"===this.c.details.type&&
c(d).addClass("dtr-inline collapsed");c(d).find("[name]").removeAttr("name");d=c("<div/>").css({width:1,height:1,overflow:"hidden"}).append(d);d.insertBefore(a.table().node());g.each(function(c){c=a.column.index("fromVisible",c);b[c].minWidth=this.offsetWidth||0});d.remove()}},_setColumnVis:function(a,b){var d=this.s.dt,e=b?"":"none";c(d.column(a).header()).css("display",e);c(d.column(a).footer()).css("display",e);d.column(a).nodes().to$().css("display",e)},_tabIndexes:function(){var a=this.s.dt,
b=a.cells({page:"current"}).nodes().to$(),d=a.settings()[0],e=this.c.details.target;b.filter("[data-dtr-keyboard]").removeData("[data-dtr-keyboard]");c("number"===typeof e?":eq("+e+")":e,a.rows({page:"current"}).nodes()).attr("tabIndex",d.iTabIndex).data("dtr-keyboard",1)}});j.breakpoints=[{name:"desktop",width:Infinity},{name:"tablet-l",width:1024},{name:"tablet-p",width:768},{name:"mobile-l",width:480},{name:"mobile-p",width:320}];j.display={childRow:function(a,b,d){if(b){if(c(a.node()).hasClass("parent"))return a.child(d(),
"child").show(),!0}else{if(a.child.isShown())return a.child(!1),c(a.node()).removeClass("parent"),!1;a.child(d(),"child").show();c(a.node()).addClass("parent");return!0}},childRowImmediate:function(a,b,d){if(!b&&a.child.isShown()||!a.responsive.hasHidden())return a.child(!1),c(a.node()).removeClass("parent"),!1;a.child(d(),"child").show();c(a.node()).addClass("parent");return!0},modal:function(a){return function(b,d,e){if(d)c("div.dtr-modal-content").empty().append(e());else{var f=function(){g.remove();
c(k).off("keypress.dtr")},g=c('<div class="dtr-modal"/>').append(c('<div class="dtr-modal-display"/>').append(c('<div class="dtr-modal-content"/>').append(e())).append(c('<div class="dtr-modal-close">&times;</div>').click(function(){f()}))).append(c('<div class="dtr-modal-background"/>').click(function(){f()})).appendTo("body");c(k).on("keyup.dtr",function(a){27===a.keyCode&&(a.stopPropagation(),f())})}a&&a.header&&c("div.dtr-modal-content").prepend("<h2>"+a.header(b)+"</h2>")}}};j.renderer={listHidden:function(){return function(a,
b,d){return(a=c.map(d,function(a){return a.hidden?'<li data-dtr-index="'+a.columnIndex+'" data-dt-row="'+a.rowIndex+'" data-dt-column="'+a.columnIndex+'"><span class="dtr-title">'+a.title+'</span> <span class="dtr-data">'+a.data+"</span></li>":""}).join(""))?c('<ul data-dtr-index="'+b+'"/>').append(a):!1}},tableAll:function(a){a=c.extend({tableClass:""},a);return function(b,d,e){b=c.map(e,function(a){return'<tr data-dt-row="'+a.rowIndex+'" data-dt-column="'+a.columnIndex+'"><td>'+a.title+":</td> <td>"+
a.data+"</td></tr>"}).join("");return c('<table class="'+a.tableClass+'" width="100%"/>').append(b)}}};j.defaults={breakpoints:j.breakpoints,auto:!0,details:{display:j.display.childRow,renderer:j.renderer.listHidden(),target:0,type:"inline"},orthogonal:"display"};var o=c.fn.dataTable.Api;o.register("responsive()",function(){return this});o.register("responsive.index()",function(a){a=c(a);return{column:a.data("dtr-index"),row:a.parent().data("dtr-index")}});o.register("responsive.rebuild()",function(){return this.iterator("table",
function(a){a._responsive&&a._responsive._classLogic()})});o.register("responsive.recalc()",function(){return this.iterator("table",function(a){a._responsive&&(a._responsive._resizeAuto(),a._responsive._resize())})});o.register("responsive.hasHidden()",function(){var a=this.context[0];return a._responsive?-1!==c.inArray(!1,a._responsive.s.current):!1});j.version="2.1.0";c.fn.dataTable.Responsive=j;c.fn.DataTable.Responsive=j;c(k).on("preInit.dt.dtr",function(a,b){if("dt"===a.namespace&&(c(b.nTable).hasClass("responsive")||
c(b.nTable).hasClass("dt-responsive")||b.oInit.responsive||m.defaults.responsive)){var d=b.oInit.responsive;!1!==d&&new j(b,c.isPlainObject(d)?d:{})}});return j});

View File

@@ -1,26 +0,0 @@
/*!
Select for DataTables 1.2.0
2015-2016 SpryMedia Ltd - datatables.net/license/mit
*/
(function(e){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(i){return e(i,window,document)}):"object"===typeof exports?module.exports=function(i,l){i||(i=window);if(!l||!l.fn.dataTable)l=require("datatables.net")(i,l).$;return e(l,i,i.document)}:e(jQuery,window,document)})(function(e,i,l,h){function t(b,a,c){var d;d=function(c,a){if(c>a)var d=a,a=c,c=d;var f=!1;return b.columns(":visible").indexes().filter(function(b){b===c&&(f=!0);return b===a?(f=!1,!0):f})};var f=
function(c,a){var d=b.rows({search:"applied"}).indexes();if(d.indexOf(c)>d.indexOf(a))var f=a,a=c,c=f;var e=!1;return d.filter(function(b){b===c&&(e=!0);return b===a?(e=!1,!0):e})};!b.cells({selected:!0}).any()&&!c?(d=d(0,a.column),c=f(0,a.row)):(d=d(c.column,a.column),c=f(c.row,a.row));c=b.cells(c,d).flatten();b.cells(a,{selected:!0}).any()?b.cells(c).deselect():b.cells(c).select()}function r(b){var a=b.settings()[0]._select.selector;e(b.table().body()).off("mousedown.dtSelect",a).off("mouseup.dtSelect",
a).off("click.dtSelect",a);e("body").off("click.dtSelect")}function v(b){var a=e(b.table().body()),c=b.settings()[0],d=c._select.selector;a.on("mousedown.dtSelect",d,function(c){if(c.shiftKey||c.metaKey||c.ctrlKey)a.css("-moz-user-select","none").one("selectstart.dtSelect",d,function(){return!1})}).on("mouseup.dtSelect",d,function(){a.css("-moz-user-select","")}).on("click.dtSelect",d,function(c){var a=b.select.items();if(!i.getSelection||!i.getSelection().toString()){var d=b.settings()[0];if(e(c.target).closest("div.dataTables_wrapper")[0]==
b.table().container()){var g=b.cell(e(c.target).closest("td, th"));if(g.any()){var h=e.Event("user-select.dt");k(b,h,[a,g,c]);h.isDefaultPrevented()||(h=g.index(),"row"===a?(a=h.row,s(c,b,d,"row",a)):"column"===a?(a=g.index().column,s(c,b,d,"column",a)):"cell"===a&&(a=g.index(),s(c,b,d,"cell",a)),d._select_lastCell=h)}}}});e("body").on("click.dtSelect",function(a){c._select.blurable&&!e(a.target).parents().filter(b.table().container()).length&&(e(a.target).parents("div.DTE").length||p(c,!0))})}function k(b,
a,c,d){if(!d||b.flatten().length)"string"===typeof a&&(a+=".dt"),c.unshift(b),e(b.table().node()).triggerHandler(a,c)}function w(b){var a=b.settings()[0];if(a._select.info&&a.aanFeatures.i){var c=e('<span class="select-info"/>'),d=function(a,d){c.append(e('<span class="select-item"/>').append(b.i18n("select."+a+"s",{_:"%d "+a+"s selected","0":"",1:"1 "+a+" selected"},d)))};d("row",b.rows({selected:!0}).flatten().length);d("column",b.columns({selected:!0}).flatten().length);d("cell",b.cells({selected:!0}).flatten().length);
e.each(a.aanFeatures.i,function(a,b){var b=e(b),d=b.children("span.select-info");d.length&&d.remove();""!==c.text()&&b.append(c)})}}function x(b,a,c,d){var f=b[a+"s"]({search:"applied"}).indexes(),d=e.inArray(d,f),m=e.inArray(c,f);if(!b[a+"s"]({selected:!0}).any()&&-1===d)f.splice(e.inArray(c,f)+1,f.length);else{if(d>m)var j=m,m=d,d=j;f.splice(m+1,f.length);f.splice(0,d)}b[a](c,{selected:!0}).any()?(f.splice(e.inArray(c,f),1),b[a+"s"](f).deselect()):b[a+"s"](f).select()}function p(b,a){if(a||"single"===
b._select.style){var c=new g.Api(b);c.rows({selected:!0}).deselect();c.columns({selected:!0}).deselect();c.cells({selected:!0}).deselect()}}function s(b,a,c,d,f){var e=a.select.style(),j=a[d](f,{selected:!0}).any();"os"===e?b.ctrlKey||b.metaKey?a[d](f).select(!j):b.shiftKey?"cell"===d?t(a,f,c._select_lastCell||null):x(a,d,f,c._select_lastCell?c._select_lastCell[d]:null):(b=a[d+"s"]({selected:!0}),j&&1===b.flatten().length?a[d](f).deselect():(b.deselect(),a[d](f).select())):"multi+shift"==e?b.shiftKey?
"cell"===d?t(a,f,c._select_lastCell||null):x(a,d,f,c._select_lastCell?c._select_lastCell[d]:null):a[d](f).select(!j):a[d](f).select(!j)}function q(b,a){return function(c){return c.i18n("buttons."+b,a)}}var g=e.fn.dataTable;g.select={};g.select.version="1.2.0";g.select.init=function(b){var a=b.settings()[0],c=a.oInit.select,d=g.defaults.select,c=c===h?d:c,d="row",f="api",m=!1,j=!0,u="td, th",i="selected";a._select={};if(!0===c)f="os";else if("string"===typeof c)f=c;else if(e.isPlainObject(c)&&(c.blurable!==
h&&(m=c.blurable),c.info!==h&&(j=c.info),c.items!==h&&(d=c.items),c.style!==h&&(f=c.style),c.selector!==h&&(u=c.selector),c.className!==h))i=c.className;b.select.selector(u);b.select.items(d);b.select.style(f);b.select.blurable(m);b.select.info(j);a._select.className=i;e.fn.dataTable.ext.order["select-checkbox"]=function(a,c){return this.api().column(c,{order:"index"}).nodes().map(function(c){return"row"===a._select.items?e(c).parent().hasClass(a._select.className):"cell"===a._select.items?e(c).hasClass(a._select.className):
!1})};e(b.table().node()).hasClass("selectable")&&b.select.style("os")};e.each([{type:"row",prop:"aoData"},{type:"column",prop:"aoColumns"}],function(b,a){g.ext.selector[a.type].push(function(c,b,f){var b=b.selected,e,j=[];if(b===h)return f;for(var g=0,i=f.length;g<i;g++)e=c[a.prop][f[g]],(!0===b&&!0===e._select_selected||!1===b&&!e._select_selected)&&j.push(f[g]);return j})});g.ext.selector.cell.push(function(b,a,c){var a=a.selected,d,f=[];if(a===h)return c;for(var e=0,g=c.length;e<g;e++)d=b.aoData[c[e].row],
(!0===a&&d._selected_cells&&!0===d._selected_cells[c[e].column]||!1===a&&(!d._selected_cells||!d._selected_cells[c[e].column]))&&f.push(c[e]);return f});var n=g.Api.register,o=g.Api.registerPlural;n("select()",function(){return this.iterator("table",function(b){g.select.init(new g.Api(b))})});n("select.blurable()",function(b){return b===h?this.context[0]._select.blurable:this.iterator("table",function(a){a._select.blurable=b})});n("select.info()",function(b){return w===h?this.context[0]._select.info:
this.iterator("table",function(a){a._select.info=b})});n("select.items()",function(b){return b===h?this.context[0]._select.items:this.iterator("table",function(a){a._select.items=b;k(new g.Api(a),"selectItems",[b])})});n("select.style()",function(b){return b===h?this.context[0]._select.style:this.iterator("table",function(a){a._select.style=b;if(!a._select_init){var c=new g.Api(a);a.aoRowCreatedCallback.push({fn:function(c,b,d){b=a.aoData[d];b._select_selected&&e(c).addClass(a._select.className);
c=0;for(d=a.aoColumns.length;c<d;c++)(a.aoColumns[c]._select_selected||b._selected_cells&&b._selected_cells[c])&&e(b.anCells[c]).addClass(a._select.className)},sName:"select-deferRender"});c.on("preXhr.dt.dtSelect",function(){var a=c.rows({selected:!0}).ids(!0).filter(function(c){return c!==h}),b=c.cells({selected:!0}).eq(0).map(function(a){var b=c.row(a.row).id(!0);return b?{row:b,column:a.column}:h}).filter(function(c){return c!==h});c.one("draw.dt.dtSelect",function(){c.rows(a).select();b.any()&&
b.each(function(a){c.cells(a.row,a.column).select()})})});c.on("draw.dtSelect.dt select.dtSelect.dt deselect.dtSelect.dt info.dt",function(){w(c)});c.on("destroy.dtSelect",function(){r(c);c.off(".dtSelect")})}var d=new g.Api(a);r(d);"api"!==b&&v(d);k(new g.Api(a),"selectStyle",[b])})});n("select.selector()",function(b){return b===h?this.context[0]._select.selector:this.iterator("table",function(a){r(new g.Api(a));a._select.selector=b;"api"!==a._select.style&&v(new g.Api(a))})});o("rows().select()",
"row().select()",function(b){var a=this;if(!1===b)return this.deselect();this.iterator("row",function(c,a){p(c);c.aoData[a]._select_selected=!0;e(c.aoData[a].nTr).addClass(c._select.className)});this.iterator("table",function(c,b){k(a,"select",["row",a[b]],!0)});return this});o("columns().select()","column().select()",function(b){var a=this;if(!1===b)return this.deselect();this.iterator("column",function(a,b){p(a);a.aoColumns[b]._select_selected=!0;var f=(new g.Api(a)).column(b);e(f.header()).addClass(a._select.className);
e(f.footer()).addClass(a._select.className);f.nodes().to$().addClass(a._select.className)});this.iterator("table",function(c,b){k(a,"select",["column",a[b]],!0)});return this});o("cells().select()","cell().select()",function(b){var a=this;if(!1===b)return this.deselect();this.iterator("cell",function(a,b,f){p(a);b=a.aoData[b];b._selected_cells===h&&(b._selected_cells=[]);b._selected_cells[f]=!0;b.anCells&&e(b.anCells[f]).addClass(a._select.className)});this.iterator("table",function(b,d){k(a,"select",
["cell",a[d]],!0)});return this});o("rows().deselect()","row().deselect()",function(){var b=this;this.iterator("row",function(a,b){a.aoData[b]._select_selected=!1;e(a.aoData[b].nTr).removeClass(a._select.className)});this.iterator("table",function(a,c){k(b,"deselect",["row",b[c]],!0)});return this});o("columns().deselect()","column().deselect()",function(){var b=this;this.iterator("column",function(a,b){a.aoColumns[b]._select_selected=!1;var d=new g.Api(a),f=d.column(b);e(f.header()).removeClass(a._select.className);
e(f.footer()).removeClass(a._select.className);d.cells(null,b).indexes().each(function(b){var c=a.aoData[b.row],d=c._selected_cells;c.anCells&&(!d||!d[b.column])&&e(c.anCells[b.column]).removeClass(a._select.className)})});this.iterator("table",function(a,c){k(b,"deselect",["column",b[c]],!0)});return this});o("cells().deselect()","cell().deselect()",function(){var b=this;this.iterator("cell",function(a,b,d){b=a.aoData[b];b._selected_cells[d]=!1;b.anCells&&!a.aoColumns[d]._select_selected&&e(b.anCells[d]).removeClass(a._select.className)});
this.iterator("table",function(a,c){k(b,"deselect",["cell",b[c]],!0)});return this});e.extend(g.ext.buttons,{selected:{text:q("selected","Selected"),className:"buttons-selected",init:function(b){var a=this;b.on("draw.dt.DT select.dt.DT deselect.dt.DT",function(){var b=a.rows({selected:!0}).any()||a.columns({selected:!0}).any()||a.cells({selected:!0}).any();a.enable(b)});this.disable()}},selectedSingle:{text:q("selectedSingle","Selected single"),className:"buttons-selected-single",init:function(b){var a=
this;b.on("draw.dt.DT select.dt.DT deselect.dt.DT",function(){var c=b.rows({selected:!0}).flatten().length+b.columns({selected:!0}).flatten().length+b.cells({selected:!0}).flatten().length;a.enable(1===c)});this.disable()}},selectAll:{text:q("selectAll","Select all"),className:"buttons-select-all",action:function(){this[this.select.items()+"s"]().select()}},selectNone:{text:q("selectNone","Deselect all"),className:"buttons-select-none",action:function(){p(this.settings()[0],!0)},init:function(b){var a=
this;b.on("draw.dt.DT select.dt.DT deselect.dt.DT",function(){var c=b.rows({selected:!0}).flatten().length+b.columns({selected:!0}).flatten().length+b.cells({selected:!0}).flatten().length;a.enable(0<c)});this.disable()}}});e.each(["Row","Column","Cell"],function(b,a){var c=a.toLowerCase();g.ext.buttons["select"+a+"s"]={text:q("select"+a+"s","Select "+c+"s"),className:"buttons-select-"+c+"s",action:function(){this.select.items(c)},init:function(a){var b=this;a.on("selectItems.dt.DT",function(a,d,
e){b.active(e===c)})}}});e(l).on("preInit.dt.dtSelect",function(b,a){"dt"===b.namespace&&g.select.init(new g.Api(a))});return g.select});

File diff suppressed because it is too large Load Diff

View File

@@ -1,350 +0,0 @@
;(function() {
var root = this;
var Farahey;
if (typeof exports !== 'undefined') {
Farahey = exports;
} else {
Farahey = root.Farahey = {};
}
var findInsertionPoint = function(sortedArr, val, comparator) {
var low = 0, high = sortedArr.length;
var mid = -1, c = 0;
while(low < high) {
mid = parseInt((low + high)/2);
c = comparator(sortedArr[mid], val);
if(c < 0) {
low = mid + 1;
}else if(c > 0) {
high = mid;
}else {
return mid;
}
}
return low;
},
geomSupport = typeof jsPlumbGeom !== "undefined" ? jsPlumbGeom : Biltong,
insertSorted = function(array, value, comparator) {
var ip = findInsertionPoint(array, value, comparator);
array.splice(ip, 0, value);
},
distanceFromOriginComparator = function(r1, r2, origin) {
var d1 = geomSupport.lineLength(origin, [ r1.x + (r1.w / 2), r1.y + (r1.h / 2)]),
d2 = geomSupport.lineLength(origin, [ r2.x + (r2.w / 2), r2.y + (r2.h / 2)]);
return d1 < d2 ? -1 : d1 == d2 ? 0 : 1;
},
EntryComparator = function(origin, getSize) {
var _origin = origin,
_cache = {},
_get = function(entry) {
if (!_cache[entry[1]]) {
var s = getSize(entry[2]);
_cache[entry[1]] = {
l:entry[0][0],
t:entry[0][1],
w:s[0],
h:s[1],
center:[entry[0][0] + (s[0] / 2), entry[0][1] + (s[1] / 2) ]
};
}
return _cache[entry[1]];
}
this.setOrigin = function(o) {
_origin = o;
_cache = {};
};
this.compare = function(e1, e2) {
var d1 = geomSupport.lineLength(_origin, _get(e1).center),
d2 = geomSupport.lineLength(_origin, _get(e2).center);
return d1 < d2 ? -1 : d1 == d2 ? 0 : 1;
};
};
var _isOnEdge = function(r, axis, dim, v) { return (r[axis] <= v && v <= r[axis] + r[dim]); },
_xAdj = [ function(r1, r2) { return r1.x + r1.w - r2.x; }, function(r1, r2) { return r1.x - (r2.x + r2.w); } ],
_yAdj = [ function(r1, r2) { return r1.y + r1.h - r2.y; }, function(r1, r2) { return r1.y - (r2.y + r2.h); } ],
_adj = [ null, [ _xAdj[0], _yAdj[1] ], [ _xAdj[0], _yAdj[0] ], [ _xAdj[1], _yAdj[0] ], [ _xAdj[1], _yAdj[1] ] ],
_genAdj = function(r1, r2, m, b, s) {
if (isNaN(m)) m = 0;
var y = r2.y + r2.h,
x = (m == Infinity || m == -Infinity) ? r2.x + (r2.w / 2) : (y - b) / m,
theta = Math.atan(m);
if (_isOnEdge(r2, "x", "w", x)) {
var rise = _adj[s][1](r1, r2),
hyp = rise / Math.sin(theta),
run = hyp * Math.cos(theta);
return { left:run, top:rise };
}
else {
var run = _adj[s][0](r1, r2),
hyp = run / Math.cos(theta),
rise = hyp * Math.sin(theta);
return { left:run, top:rise };
}
},
/*
* Calculates how far to move r2 from r1 so that it no longer overlaps.
* if origin is supplied, then it means we want r2 to move along a vector joining r2's center to that point.
* otherwise we want it to move along a vector joining the two rectangle centers.
*/
_calculateSpacingAdjustment = Farahey.calculateSpacingAdjustment = function(r1, r2) {
var c1 = r1.center || [ r1.x + (r1.w / 2), r1.y + (r1.h / 2) ],
c2 = r2.center || [ r2.x + (r2.w / 2), r2.y + (r2.h / 2) ],
m = geomSupport.gradient(c1, c2),
s = geomSupport.quadrant(c1, c2),
b = (m == Infinity || m == -Infinity || isNaN(m)) ? 0 : c1[1] - (m * c1[0]);
return _genAdj(r1, r2, m, b, s);
},
// calculate a padded rectangle for the given element with offset & size, and desired padding.
_paddedRectangle = Farahey.paddedRectangle = function(o, s, p) {
return { x:o[0] - p[0], y: o[1] - p[1], w:s[0] + (2 * p[0]), h:s[1] + (2 * p[1]) };
},
_magnetize = function(positionArray, positions, sizes, padding,
constrain, origin, filter,
updateOnStep, stepInterval, stepCallback)
{
origin = origin || [0,0];
stepCallback = stepCallback || function() { };
var focus = _paddedRectangle(origin, [1,1], padding),
iterations = 100, iteration = 1, uncleanRun = true, adjustBy, constrainedAdjustment,
_movedElements = {},
_move = function(id, o, x, y) {
_movedElements[id] = true;
o[0] += x;
o[1] += y;
},
step = function() {
for (var i = 0; i < positionArray.length; i++) {
var o1 = positions[positionArray[i][1]],
oid = positionArray[i][1],
a1 = positionArray[i][2], // angle to node from magnet origin
s1 = sizes[positionArray[i][1]],
// create a rectangle for first element: this encompasses the element and padding on each
//side
r1 = _paddedRectangle(o1, s1, padding);
if (filter(positionArray[i][1]) && geomSupport.intersects(focus, r1)) {
adjustBy = _calculateSpacingAdjustment(focus, r1);
constrainedAdjustment = constrain(positionArray[i][1], o1, adjustBy);
_move(oid, o1, constrainedAdjustment.left, constrainedAdjustment.top);
}
// now move others to account for this one, if necessary.
// reset rectangle for node
r1 = _paddedRectangle(o1, s1, padding);
for (var j = 0; j < positionArray.length; j++) {
if (i != j) {
var o2 = positions[positionArray[j][1]],
a2 = positionArray[j][2], // angle to node from magnet origin
s2 = sizes[positionArray[j][1]],
// create a rectangle for the second element, again by putting padding of the desired
// amount around the bounds of the element.
r2 = _paddedRectangle(o2, s2, padding);
// if the two rectangles intersect then figure out how much to move the second one by.
if (geomSupport.intersects(r1, r2)) {
// TODO in 0.3, instead of moving neither, the other node should move.
if (filter(positionArray[j][1])) {
uncleanRun = true;
adjustBy = _calculateSpacingAdjustment(r1, r2),
constrainedAdjustment = constrain(positionArray[j][1], o2, adjustBy);
_move(positionArray[j][1], o2, constrainedAdjustment.left, constrainedAdjustment.top);
}
}
}
}
}
if (updateOnStep)
stepCallback();
if (uncleanRun && iteration < iterations) {
uncleanRun = false;
iteration++;
if (updateOnStep) {
window.setTimeout(step, stepInterval);
}
else
step();
}
};
step();
return _movedElements;
};
/**
* @name Magnetizer
* @classdesc Applies repulsive magnetism to a set of elements relative to a given point, with a specified
* amount of padding around the point.
*/
/**
* @name Magnetizer#constructor
* @function
* @param {Selector|Element} [container] Element that contains the elements to magnetize. Only required if you intend to use the `executeAtEvent` method.
* @param {Function} [getContainerPosition] Function that returns the position of the container (as an object of the form `{left:.., top:..}`) when requested. Only required if you intend to use the `executeAtEvent` method.
* @param {Function} getPosition A function that takes an element id and returns its position. It does not matter to which element this position is computed as long as you remain consistent with this method, `setPosition` and the `origin` property.
* @param {Function} setPosition A function that takes an element id and position, and sets it. See note about offset parent above.
* @param {Function} getSize A function that takes an element id and returns its size, in pixels.
* @param {Integer[]} [padding] Optional padding for x and y directions. Defaults to 20 pixels in each direction.
* @param {Function} [constrain] Optional function that takes an id and a proposed amount of movement in each axis, and returns the allowed amount of movement in each axis. You can use this to constrain your elements to a grid, for instance, or a path, etc.
* @param {Integer[]} [origin] The origin of magnetization, in pixels. Defaults to 0,0. You can also supply this to the `execute` call.
* @param {Selector|String[]|Element[]} elements List of elements on which to operate.
* @param {Boolean} [executeNow=false] Whether or not to execute the routine immediately.
* @param {Function} [filter] Optional function that takes an element id and returns whether or not that element can be moved.
* @param {Boolean} [orderByDistanceFromOrigin=false] Whether or not to sort elements first by distance from origin. Can have better results but takes more time.
*/
root.Magnetizer = function(params) {
var getPosition = params.getPosition,
getSize = params.getSize,
getId = params.getId,
setPosition = params.setPosition,
padding = params.padding || [20, 20],
// expects a { left:.., top:... } object. returns how far it can actually go.
constrain = params.constrain || function(id, current, delta) { return delta; },
positionArray = [],
positions = {},
sizes = {},
elements = params.elements || [],
origin = params.origin || [0,0],
executeNow = params.executeNow,
minx, miny, maxx, maxy,
getOrigin = this.getOrigin = function() { return origin; },
filter = params.filter || function(_) { return true; },
orderByDistanceFromOrigin = params.orderByDistanceFromOrigin,
comparator = new EntryComparator(origin, getSize),
updateOnStep = params.updateOnStep,
stepInterval = params.stepInterval || 350,
originDebugMarker,
debug = params.debug,
createOriginDebugger = function() {
var d = document.createElement("div");
d.style.position = "absolute";
d.style.width = "10px";
d.style.height = "10px";
d.style.backgroundColor = "red";
document.body.appendChild(d);
originDebugMarker = d;
},
_addToPositionArray = function(p) {
if (!orderByDistanceFromOrigin || positionArray.length == 0)
positionArray.push(p);
else {
insertSorted(positionArray, p, comparator.compare);
}
},
_updatePositions = function() {
comparator.setOrigin(origin);
positionArray = []; positions = {}; sizes = {};
minx = miny = Infinity;
maxx = maxy = -Infinity;
for (var i = 0; i < elements.length; i++) {
var p = getPosition(elements[i]),
s = getSize(elements[i]),
id = getId(elements[i]);
positions[id] = [p.left, p.top];
_addToPositionArray([ [p.left, p.top], id, elements[i]]);
sizes[id] = s;
minx = Math.min(minx, p.left);
miny = Math.min(miny, p.top);
maxx = Math.max(maxx, p.left + s[0]);
maxy = Math.max(maxy, p.top + s[1]);
}
},
_run = function() {
if (elements.length > 1) {
var _movedElements = _magnetize(positionArray, positions, sizes, padding, constrain, origin, filter, updateOnStep, stepInterval, _positionElements);
_positionElements(_movedElements);
}
},
_positionElements = function(_movedElements) {
for (var i = 0; i < elements.length; i++) {
var id = getId(elements[i]);
if (_movedElements[id])
setPosition(elements[i], { left:positions[id][0], top:positions[id][1] });
}
},
setOrigin = function(o) {
if (o != null) {
origin = o;
comparator.setOrigin(o);
}
};
/**
* @name Magnetizer#execute
* @function
* @desc Runs the magnetize routine.
* @param {Integer[]} [o] Optional origin to use. You may have set this in the constructor and do not wish to supply it, or you may be happy with the default of [0,0].
*/
this.execute = function(o) {
setOrigin(o);
_updatePositions();
_run();
};
/**
* @name Magnetizer#executeAtCenter
* @function
* @desc Computes the center of all the nodes and then uses that as the magnetization origin when it runs the routine.
*/
this.executeAtCenter = function() {
_updatePositions();
setOrigin([
(minx + maxx) / 2,
(miny + maxy) / 2
]);
_run();
};
/**
* @name Magnetizer#executeAtEvent
* @function
* @desc Runs the magnetize routine using the location of the given event as the origin. To use this
* method you need to have provided a `container`, and a `getContainerPosition` function to the
* constructor.
* @param {Event} e Event to get origin location from.
*/
this.executeAtEvent = function(e) {
var c = params.container,
o = params.getContainerPosition(c),
x = e.pageX - o.left + c[0].scrollLeft,
y = e.pageY - o.top + c[0].scrollTop;
if (debug) {
originDebugMarker.style.left = e.pageX + "px";
originDebugMarker.style.top = e.pageY + "px";
}
this.execute([x,y]);
};
/**
* @name Magnetize#setElements
* @function
* @desc Sets the current list of elements.
* @param {Object[]} _els List of elements, in whatever format the magnetizer is setup to use.
*/
this.setElements = function(_els) {
elements = _els;
};
if (debug)
createOriginDebugger();
if (executeNow) this.execute();
};
}).call(this);

File diff suppressed because one or more lines are too long

View File

@@ -1,392 +0,0 @@
/*
@title:
Drag to Select
@version:
1.1
@author:
Andreas Lagerkvist
@date:
2009-04-06
@url:
http://andreaslagerkvist.com/jquery/drag-to-select/
@license:
http://creativecommons.org/licenses/by/3.0/
@copyright:
2008 Andreas Lagerkvist (andreaslagerkvist.com)
@requires:
jquery, jquery.dragToSelect.css
@does:
Use this plug-in to allow your users to select certain elements by dragging a "select box". Works very similar to how you can drag-n-select files and folders in most OS:es.
@howto:
$('#my-files').dragToSelect(selectables: 'li'); would make every li in the #my-files-element selectable by dragging. The li:s will recieve a "selected"-class when they are within range of the select box when user drops.
Make sure a parent-element of the selectables has position: relative as well as overflow: auto or scroll.
@exampleHTML:
<ul>
<li><img src="http://exscale.se/__files/3d/lamp-and-mates/lamp-and-mates-01_small.jpg" alt="Lamp and Mates" /></li>
<li><img src="http://exscale.se/__files/3d/stugan-winter_small.jpg" alt="The Cottage - Winter time" /></li>
<li><img src="http://exscale.se/__files/3d/ps2_small.jpg" alt="PS2" /></li>
</ul>
@exampleJS:
$('#jquery-drag-to-select-example').dragToSelect({
selectables: 'li',
onHide: function () {
alert($('#jquery-drag-to-select-example li.selected').length + ' selected');
}
});
*/
$.fn.dragToSelect = function (conf) {
var c = typeof(conf) == 'object' ? conf : {};
// Config
var config = $.extend({
className: 'pf-map-drag-to-select',
activeClass: 'active',
disabledClass: 'disabled',
selectedClass: 'pf-system-selected',
ignoreLockedClass: 'pf-system-locked', // do not select locked systems
ignoreVisibleClass: 'pf-system-hidden', // do not select invisible systems
scrollTH: 10,
percentCovered: 25,
selectables: false,
autoScroll: false,
selectOnMove: false,
onShow: function () {return true;},
onHide: function () {return true;},
onRefresh: function () {return true;}
}, c);
var realParent = $(this);
var parent = realParent;
var animationFrameId;
var mouseIsDown = false;
var lastMousePosition = { x: 0, y: 0 };
// deselected items
var deselectedItems = $();
do {
if (/auto|scroll|hidden/.test(parent.css('overflow'))) {
break;
}
parent = parent.parent();
} while (parent[0].parentNode);
// Does user want to disable dragToSelect
if (conf == 'disable') {
parent.addClass(config.disabledClass);
return this;
}
else if (conf == 'enable') {
parent.removeClass(config.disabledClass);
return this;
}
var parentDim = {
left: 0,
top: 0,
width: 10,
height: 10
};
// set parent dimensions
// -> should be updated in case of left/right menu is open
var setParentDimensions = (parent) => {
var parentOffset = parent.offset();
parentDim = {
left: parentOffset.left,
top: parentOffset.top,
width: parent.width(),
height: parent.height()
};
}
setParentDimensions(parent);
// Current origin of select box
var selectBoxOrigin = {
left: 0,
top: 0
};
// Create select box
var selectBox = $('<div>')
.appendTo(parent)
.attr('class', config.className)
.css('position', 'absolute');
// Shows the select box
var showSelectBox = function (e) {
if (parent.is('.' + config.disabledClass)) {
return;
}
selectBoxOrigin.left = e.pageX - parentDim.left + parent[0].scrollLeft - 5;
selectBoxOrigin.top = e.pageY - parentDim.top + parent[0].scrollTop - 5;
var css = {
left: selectBoxOrigin.left + 'px',
top: selectBoxOrigin.top + 'px',
width: '1px',
height: '1px'
};
selectBox.addClass(config.activeClass).css(css);
config.onShow();
};
// Refreshes the select box dimensions and possibly position
var refreshSelectBox = function () {
var refreshed = false;
if (!selectBox.is('.' + config.activeClass) || parent.is('.' + config.disabledClass)) {
return refreshed;
}
// get scroll position
/*
var leftScroll = 0;
var topScroll = 0;
if(realParent.attr('data-scroll-left')){
leftScroll = parseInt(realParent.attr('data-scroll-left'));
}
if(realParent.attr('data-scroll-top')){
topScroll = parseInt(realParent.attr('data-scroll-top'));
}
*/
var left = lastMousePosition.x - parentDim.left + parent[0].scrollLeft;
var top = lastMousePosition.y - parentDim.top + parent[0].scrollTop;
var tempWidth = selectBoxOrigin.left - left;
var tempHeight = selectBoxOrigin.top - top;
let newLeft = selectBoxOrigin.left;// - leftScroll;
let newTop = selectBoxOrigin.top;// - topScroll;
var newWidth = left - selectBoxOrigin.left;
var newHeight = top - selectBoxOrigin.top;
if(newWidth < 0){
newLeft = newLeft - tempWidth;
newWidth = newWidth * -1;
}
if(newHeight < 0){
newTop = newTop - tempHeight;
newHeight = newHeight * -1;
}
// check if dimension has changed -> save performance
var dimensionHash = [newWidth, newHeight].join('_');
if(selectBox.data('dimension-hash') !== dimensionHash){
selectBox.data('dimension-hash', dimensionHash);
var css = {
left: newLeft + 'px',
top: newTop + 'px',
width: newWidth + 'px',
height: newHeight + 'px'
};
selectBox.css(css);
config.onRefresh();
refreshed = true;
}
return refreshed;
};
// Hides the select box
var hideSelectBox = function () {
if (!selectBox.is('.' + config.activeClass) || parent.is('.' + config.disabledClass)) {
return;
}
if (config.onHide(selectBox, deselectedItems) !== false) {
selectBox.removeClass(config.activeClass);
}
};
// Scrolls parent if needed
var scrollPerhaps = function (e) {
if (!selectBox.is('.' + config.activeClass) || parent.is('.' + config.disabledClass)) {
return;
}
// Scroll down
if ((e.pageY + config.scrollTH) > (parentDim.top + parentDim.height)) {
parent[0].scrollTop += config.scrollTH;
}
// Scroll up
if ((e.pageY - config.scrollTH) < parentDim.top) {
parent[0].scrollTop -= config.scrollTH;
}
// Scroll right
if ((e.pageX + config.scrollTH) > (parentDim.left + parentDim.width)) {
parent[0].scrollLeft += config.scrollTH;
}
// Scroll left
if ((e.pageX - config.scrollTH) < parentDim.left) {
parent[0].scrollLeft -= config.scrollTH;
}
};
// Selects all the elements in the select box's range
var selectElementsInRange = function () {
if (!selectBox.is('.' + config.activeClass) || parent.is('.' + config.disabledClass)) {
return;
}
var selectables = realParent.find(config.selectables + ':not(.' + config.ignoreLockedClass + ')'+ ':not(.' + config.ignoreVisibleClass + ')');
var selectBoxOffset = selectBox.offset();
var selectBoxDim = {
left: selectBoxOffset.left,
top: selectBoxOffset.top,
width: selectBox.width(),
height: selectBox.height()
};
selectables.each(function (i) {
var el = $(this);
var elOffset = el.offset();
var elDim = {
left: elOffset.left,
top: elOffset.top,
width: el.width(),
height: el.height()
};
if (percentCovered(selectBoxDim, elDim) > config.percentCovered) {
el.addClass(config.selectedClass);
// remove element from "deselected" elements (e.g on add -> remove -> add scenario)
deselectedItems = deselectedItems.not(el);
}else {
if(el.hasClass(config.selectedClass)){
el.removeClass(config.selectedClass);
deselectedItems = deselectedItems.add(el);
}
}
});
};
// Returns the amount (in %) that dim1 covers dim2
var percentCovered = function (dim1, dim2) {
// The whole thing is covering the whole other thing
if (
(dim1.left <= dim2.left) &&
(dim1.top <= dim2.top) &&
((dim1.left + dim1.width) >= (dim2.left + dim2.width)) &&
((dim1.top + dim1.height) > (dim2.top + dim2.height))
) {
return 100;
}
// Only parts may be covered, calculate percentage
else {
dim1.right = dim1.left + dim1.width;
dim1.bottom = dim1.top + dim1.height;
dim2.right = dim2.left + dim2.width;
dim2.bottom = dim2.top + dim2.height;
var l = Math.max(dim1.left, dim2.left);
var r = Math.min(dim1.right, dim2.right);
var t = Math.max(dim1.top, dim2.top);
var b = Math.min(dim1.bottom, dim2.bottom);
if (b >= t && r >= l) {
/* $('<div/>').appendTo(document.body).css({
background: 'red',
position: 'absolute',
left: l + 'px',
top: t + 'px',
width: (r - l) + 'px',
height: (b - t) + 'px',
zIndex: 100
}); */
var percent = (((r - l) * (b - t)) / (dim2.width * dim2.height)) * 100;
// alert(percent + '% covered')
return percent;
}
}
// Nothing covered, return 0
return 0;
};
// Event functions ----------------------------------------------------------------------------
var mousemoveCallback = function(){
if(mouseIsDown){
var refreshed = refreshSelectBox();
if(refreshed && config.selectables && config.selectOnMove){
selectElementsInRange();
}
// recursive re-call on next render
animationFrameId = requestAnimationFrame(mousemoveCallback);
}
}
var mouseupCallback = function(){
if (config.selectables){
selectElementsInRange();
}
hideSelectBox();
// stop animation frame and "reset" to default
cancelAnimationFrame(animationFrameId);
mouseIsDown = false;
// reset deselected item array
deselectedItems = $();
}
// Do the right stuff then return this --------------------------------------------------------
selectBox.mousemove(function(e){
setParentDimensions(parent);
lastMousePosition.x = e.pageX;
lastMousePosition.y = e.pageY;
e.preventDefault();
}).mouseup(mouseupCallback);
parent.mousedown(function(e){
if (
e.which === 1 && // left mouse down
e.target === realParent[0] // prevent while dragging a system :)
) {
// Make sure user isn't clicking scrollbar (or disallow clicks far to the right actually)
if ((e.pageX + 20) > $(document.body).width()) {
return;
}
showSelectBox(e);
mouseIsDown = true;
animationFrameId = requestAnimationFrame(mousemoveCallback);
}
e.preventDefault();
}).mousemove(function(e){
setParentDimensions(parent);
lastMousePosition.x = e.pageX;
lastMousePosition.y = e.pageY;
e.preventDefault();
}).mouseup(mouseupCallback);
// Be nice
return this;
};

View File

@@ -1,9 +0,0 @@
/**!
* easyPieChart
* Lightweight plugin to render simple, animated and retina optimized pie charts
*
* @license
* @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)
* @version 2.1.6
**/
!function(a,b){"object"==typeof exports?module.exports=b(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],b):b(a.jQuery)}(this,function(a){var b=function(a,b){var c,d=document.createElement("canvas");a.appendChild(d),"undefined"!=typeof G_vmlCanvasManager&&G_vmlCanvasManager.initElement(d);var e=d.getContext("2d");d.width=d.height=b.size;var f=1;window.devicePixelRatio>1&&(f=window.devicePixelRatio,d.style.width=d.style.height=[b.size,"px"].join(""),d.width=d.height=b.size*f,e.scale(f,f)),e.translate(b.size/2,b.size/2),e.rotate((-0.5+b.rotate/180)*Math.PI);var g=(b.size-b.lineWidth)/2;b.scaleColor&&b.scaleLength&&(g-=b.scaleLength+2),Date.now=Date.now||function(){return+new Date};var h=function(a,b,c){c=Math.min(Math.max(-1,c||0),1);var d=0>=c?!0:!1;e.beginPath(),e.arc(0,0,g,0,2*Math.PI*c,d),e.strokeStyle=a,e.lineWidth=b,e.stroke()},i=function(){var a,c;e.lineWidth=1,e.fillStyle=b.scaleColor,e.save();for(var d=24;d>0;--d)d%6===0?(c=b.scaleLength,a=0):(c=.6*b.scaleLength,a=b.scaleLength-c),e.fillRect(-b.size/2+a,0,c,1),e.rotate(Math.PI/12);e.restore()},j=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(a){window.setTimeout(a,1e3/60)}}(),k=function(){b.scaleColor&&i(),b.trackColor&&h(b.trackColor,b.trackWidth||b.lineWidth,1)};this.getCanvas=function(){return d},this.getCtx=function(){return e},this.clear=function(){e.clearRect(b.size/-2,b.size/-2,b.size,b.size)},this.draw=function(a){b.scaleColor||b.trackColor?e.getImageData&&e.putImageData?c?e.putImageData(c,0,0):(k(),c=e.getImageData(0,0,b.size*f,b.size*f)):(this.clear(),k()):this.clear(),e.lineCap=b.lineCap;var d;d="function"==typeof b.barColor?b.barColor(a):b.barColor,h(d,b.lineWidth,a/100)}.bind(this),this.animate=function(a,c){var d=Date.now();b.onStart(a,c);var e=function(){var f=Math.min(Date.now()-d,b.animate.duration),g=b.easing(this,f,a,c-a,b.animate.duration);this.draw(g),b.onStep(a,c,g),f>=b.animate.duration?b.onStop(a,c):j(e)}.bind(this);j(e)}.bind(this)},c=function(a,c){var d={barColor:"#ef1e25",trackColor:"#f9f9f9",scaleColor:"#dfe0e0",scaleLength:5,lineCap:"round",lineWidth:3,trackWidth:void 0,size:110,rotate:0,animate:{duration:1e3,enabled:!0},easing:function(a,b,c,d,e){return b/=e/2,1>b?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},onStart:function(){},onStep:function(){},onStop:function(){}};if("undefined"!=typeof b)d.renderer=b;else{if("undefined"==typeof SVGRenderer)throw new Error("Please load either the SVG- or the CanvasRenderer");d.renderer=SVGRenderer}var e={},f=0,g=function(){this.el=a,this.options=e;for(var b in d)d.hasOwnProperty(b)&&(e[b]=c&&"undefined"!=typeof c[b]?c[b]:d[b],"function"==typeof e[b]&&(e[b]=e[b].bind(this)));e.easing="string"==typeof e.easing&&"undefined"!=typeof jQuery&&jQuery.isFunction(jQuery.easing[e.easing])?jQuery.easing[e.easing]:d.easing,"number"==typeof e.animate&&(e.animate={duration:e.animate,enabled:!0}),"boolean"!=typeof e.animate||e.animate||(e.animate={duration:1e3,enabled:e.animate}),this.renderer=new e.renderer(a,e),this.renderer.draw(f),a.dataset&&a.dataset.percent?this.update(parseFloat(a.dataset.percent)):a.getAttribute&&a.getAttribute("data-percent")&&this.update(parseFloat(a.getAttribute("data-percent")))}.bind(this);this.update=function(a){return a=parseFloat(a),e.animate.enabled?this.renderer.animate(f,a):this.renderer.draw(a),f=a,this}.bind(this),this.disableAnimation=function(){return e.animate.enabled=!1,this},this.enableAnimation=function(){return e.animate.enabled=!0,this},g()};a.fn.easyPieChart=function(b){return this.each(function(){var d;a.data(this,"easyPieChart")||(d=a.extend({},b,a(this).data()),a.data(this,"easyPieChart",new c(this,d)))})}});

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +0,0 @@
/*!
* hoverIntent v1.9.0 // 2017.09.01 // jQuery v1.7.0+
* http://briancherne.github.io/jquery-hoverIntent/
*
* You may use hoverIntent under the terms of the MIT license. Basically that
* means you are free to use hoverIntent as long as this header is left intact.
* Copyright 2007-2017 Brian Cherne
*/
!function(factory){"use strict";"function"==typeof define&&define.amd?define(["jquery"],factory):jQuery&&!jQuery.fn.hoverIntent&&factory(jQuery)}(function($){"use strict";var cX,cY,_cfg={interval:100,sensitivity:6,timeout:0},INSTANCE_COUNT=0,track=function(ev){cX=ev.pageX,cY=ev.pageY},compare=function(ev,$el,s,cfg){if(Math.sqrt((s.pX-cX)*(s.pX-cX)+(s.pY-cY)*(s.pY-cY))<cfg.sensitivity)return $el.off(s.event,track),delete s.timeoutId,s.isActive=!0,ev.pageX=cX,ev.pageY=cY,delete s.pX,delete s.pY,cfg.over.apply($el[0],[ev]);s.pX=cX,s.pY=cY,s.timeoutId=setTimeout(function(){compare(ev,$el,s,cfg)},cfg.interval)},delay=function(ev,$el,s,out){return delete $el.data("hoverIntent")[s.id],out.apply($el[0],[ev])};$.fn.hoverIntent=function(handlerIn,handlerOut,selector){var instanceId=INSTANCE_COUNT++,cfg=$.extend({},_cfg);$.isPlainObject(handlerIn)?(cfg=$.extend(cfg,handlerIn),$.isFunction(cfg.out)||(cfg.out=cfg.over)):cfg=$.isFunction(handlerOut)?$.extend(cfg,{over:handlerIn,out:handlerOut,selector:selector}):$.extend(cfg,{over:handlerIn,out:handlerIn,selector:handlerOut});var handleHover=function(e){var ev=$.extend({},e),$el=$(this),hoverIntentData=$el.data("hoverIntent");hoverIntentData||$el.data("hoverIntent",hoverIntentData={});var state=hoverIntentData[instanceId];state||(hoverIntentData[instanceId]=state={id:instanceId}),state.timeoutId&&(state.timeoutId=clearTimeout(state.timeoutId));var mousemove=state.event="mousemove.hoverIntent.hoverIntent"+instanceId;if("mouseenter"===e.type){if(state.isActive)return;state.pX=ev.pageX,state.pY=ev.pageY,$el.off(mousemove,track).on(mousemove,track),state.timeoutId=setTimeout(function(){compare(ev,$el,state,cfg)},cfg.interval)}else{if(!state.isActive)return;$el.off(mousemove,track),state.timeoutId=setTimeout(function(){delay(ev,$el,state,cfg.out)},cfg.timeout)}};return this.on({"mouseenter.hoverIntent":handleHover,"mouseleave.hoverIntent":handleHover},cfg.selector)}});

View File

@@ -1,9 +1,2 @@
/*!
* hoverIntent v1.8.0 // 2014.06.29 // jQuery v1.9.1+
* http://cherne.net/brian/resources/jquery.hoverIntent.html
*
* You may use hoverIntent under the terms of the MIT license. Basically that
* means you are free to use hoverIntent as long as this header is left intact.
* Copyright 2007, 2014 Brian Cherne
*/
(function($){$.fn.hoverIntent=function(handlerIn,handlerOut,selector){var cfg={interval:100,sensitivity:6,timeout:0};if(typeof handlerIn==="object"){cfg=$.extend(cfg,handlerIn)}else{if($.isFunction(handlerOut)){cfg=$.extend(cfg,{over:handlerIn,out:handlerOut,selector:selector})}else{cfg=$.extend(cfg,{over:handlerIn,out:handlerIn,selector:handlerOut})}}var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if(Math.sqrt((pX-cX)*(pX-cX)+(pY-cY)*(pY-cY))<cfg.sensitivity){$(ob).off("mousemove.hoverIntent",track);ob.hoverIntent_s=true;return cfg.over.apply(ob,[ev])}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=false;return cfg.out.apply(ob,[ev])};var handleHover=function(e){var ev=$.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t)}if(e.type==="mouseenter"){pX=ev.pageX;pY=ev.pageY;$(ob).on("mousemove.hoverIntent",track);if(!ob.hoverIntent_s){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}}else{$(ob).off("mousemove.hoverIntent",track);if(ob.hoverIntent_s){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob)},cfg.timeout)}}};return this.on({"mouseenter.hoverIntent":handleHover,"mouseleave.hoverIntent":handleHover},cfg.selector)}})(jQuery);
!function(e){e.fn.hoverIntent=function(t,n,o){var r,v,i,u,s={interval:100,sensitivity:6,timeout:0};s="object"==typeof t?e.extend(s,t):e.isFunction(n)?e.extend(s,{over:t,out:n,selector:o}):e.extend(s,{over:t,out:t,selector:n});var h=function(e){r=e.pageX,v=e.pageY},I=function(t,n){if(n.hoverIntent_t=clearTimeout(n.hoverIntent_t),Math.sqrt((i-r)*(i-r)+(u-v)*(u-v))<s.sensitivity)return e(n).off("mousemove.hoverIntent",h),n.hoverIntent_s=!0,s.over.apply(n,[t]);i=r,u=v,n.hoverIntent_t=setTimeout(function(){I(t,n)},s.interval)},a=function(t){var n=e.extend({},t),o=this;o.hoverIntent_t&&(o.hoverIntent_t=clearTimeout(o.hoverIntent_t)),"mouseenter"===t.type?(i=n.pageX,u=n.pageY,e(o).on("mousemove.hoverIntent",h),o.hoverIntent_s||(o.hoverIntent_t=setTimeout(function(){I(n,o)},s.interval))):(e(o).off("mousemove.hoverIntent",h),o.hoverIntent_s&&(o.hoverIntent_t=setTimeout(function(){!function(e,t){t.hoverIntent_t=clearTimeout(t.hoverIntent_t),t.hoverIntent_s=!1,s.out.apply(t,[e])}(n,o)},s.timeout)))};return this.on({"mouseenter.hoverIntent":a,"mouseleave.hoverIntent":a},s.selector)}}(jQuery);
//# sourceMappingURL=jquery.hoverIntent.minified.js.map

Binary file not shown.

View File

@@ -0,0 +1 @@
{"version":3,"sources":["lib/jquery.hoverIntent.minified.js"],"names":["$","fn","hoverIntent","handlerIn","handlerOut","selector","cX","cY","pX","pY","cfg","interval","sensitivity","timeout","extend","isFunction","over","out","track","ev","pageX","pageY","compare","ob","hoverIntent_t","clearTimeout","Math","sqrt","off","hoverIntent_s","apply","setTimeout","handleHover","e","this","type","on","delay","mouseenter.hoverIntent","mouseleave.hoverIntent","jQuery"],"mappings":"CAQA,SAAUA,GAAGA,EAAEC,GAAGC,YAAY,SAASC,EAAUC,EAAWC,GAAU,IAAgSC,EAAGC,EAAGC,EAAGC,EAArSC,GAAKC,SAAS,IAAIC,YAAY,EAAEC,QAAQ,GAAmCH,EAAV,iBAAZP,EAA0BH,EAAEc,OAAOJ,EAAIP,GAAmBH,EAAEe,WAAWX,GAAiBJ,EAAEc,OAAOJ,GAAKM,KAAKb,EAAUc,IAAIb,EAAWC,SAASA,IAAoBL,EAAEc,OAAOJ,GAAKM,KAAKb,EAAUc,IAAId,EAAUE,SAASD,IAA8B,IAAIc,EAAM,SAASC,GAAIb,EAAGa,EAAGC,MAAMb,EAAGY,EAAGE,OAAWC,EAAQ,SAASH,EAAGI,GAAoD,GAAhDA,EAAGC,cAAcC,aAAaF,EAAGC,eAAkBE,KAAKC,MAAMnB,EAAGF,IAAKE,EAAGF,IAAKG,EAAGF,IAAKE,EAAGF,IAAKG,EAAIE,YAA4E,OAA/DZ,EAAEuB,GAAIK,IAAI,wBAAwBV,GAAOK,EAAGM,eAAc,EAAYnB,EAAIM,KAAKc,MAAMP,GAAIJ,IAAUX,EAAGF,EAAGG,EAAGF,EAAGgB,EAAGC,cAAcO,WAAW,WAAWT,EAAQH,EAAGI,IAAKb,EAAIC,WAAgJqB,EAAY,SAASC,GAAG,IAAId,EAAGnB,EAAEc,UAAUmB,GAAOV,EAAGW,KAAQX,EAAGC,gBAAeD,EAAGC,cAAcC,aAAaF,EAAGC,gBAA2B,eAATS,EAAEE,MAAqB3B,EAAGW,EAAGC,MAAMX,EAAGU,EAAGE,MAAMrB,EAAEuB,GAAIa,GAAG,wBAAwBlB,GAAWK,EAAGM,gBAAeN,EAAGC,cAAcO,WAAW,WAAWT,EAAQH,EAAGI,IAAKb,EAAIC,aAAgBX,EAAEuB,GAAIK,IAAI,wBAAwBV,GAAUK,EAAGM,gBAAeN,EAAGC,cAAcO,WAAW,YAA9gB,SAASZ,EAAGI,GAAIA,EAAGC,cAAcC,aAAaF,EAAGC,eAAeD,EAAGM,eAAc,EAAanB,EAAIO,IAAIa,MAAMP,GAAIJ,IAAyakB,CAAMlB,EAAGI,IAAKb,EAAIG,YAAY,OAAOqB,KAAKE,IAAIE,yBAAyBN,EAAYO,yBAAyBP,GAAatB,EAAIL,WAAn4C,CAAg5CmC","file":"jquery.hoverIntent.minified.js","sourceRoot":"/js"}

Some files were not shown because too many files have changed in this diff Show More