diff --git a/fonts/FontAwesome.otf b/fonts/FontAwesome.otf index 3461e3fc..81c9ad94 100644 Binary files a/fonts/FontAwesome.otf and b/fonts/FontAwesome.otf differ diff --git a/fonts/fontawesome-webfont.eot b/fonts/fontawesome-webfont.eot index 6cfd5660..84677bc0 100644 Binary files a/fonts/fontawesome-webfont.eot and b/fonts/fontawesome-webfont.eot differ diff --git a/fonts/fontawesome-webfont.svg b/fonts/fontawesome-webfont.svg index a9f84695..d907b25a 100644 --- a/fonts/fontawesome-webfont.svg +++ b/fonts/fontawesome-webfont.svg @@ -32,473 +32,489 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - \ No newline at end of file diff --git a/fonts/fontawesome-webfont.ttf b/fonts/fontawesome-webfont.ttf index 5cd6cff6..96a3639c 100644 Binary files a/fonts/fontawesome-webfont.ttf and b/fonts/fontawesome-webfont.ttf differ diff --git a/fonts/fontawesome-webfont.woff b/fonts/fontawesome-webfont.woff index 9eaecb37..628b6a52 100644 Binary files a/fonts/fontawesome-webfont.woff and b/fonts/fontawesome-webfont.woff differ diff --git a/img/data-tables/back_disabled.png b/img/data-tables/back_disabled.png new file mode 100644 index 00000000..881de797 Binary files /dev/null and b/img/data-tables/back_disabled.png differ diff --git a/img/data-tables/back_enabled.png b/img/data-tables/back_enabled.png new file mode 100644 index 00000000..c608682b Binary files /dev/null and b/img/data-tables/back_enabled.png differ diff --git a/img/data-tables/back_enabled_hover.png b/img/data-tables/back_enabled_hover.png new file mode 100644 index 00000000..d300f106 Binary files /dev/null and b/img/data-tables/back_enabled_hover.png differ diff --git a/img/data-tables/forward_disabled.png b/img/data-tables/forward_disabled.png new file mode 100644 index 00000000..6a6ded7d Binary files /dev/null and b/img/data-tables/forward_disabled.png differ diff --git a/img/data-tables/forward_enabled.png b/img/data-tables/forward_enabled.png new file mode 100644 index 00000000..a4e6b538 Binary files /dev/null and b/img/data-tables/forward_enabled.png differ diff --git a/img/data-tables/forward_enabled_hover.png b/img/data-tables/forward_enabled_hover.png new file mode 100644 index 00000000..fc46c5eb Binary files /dev/null and b/img/data-tables/forward_enabled_hover.png differ diff --git a/img/data-tables/sort_asc.png b/img/data-tables/sort_asc.png new file mode 100644 index 00000000..a88d7975 Binary files /dev/null and b/img/data-tables/sort_asc.png differ diff --git a/img/data-tables/sort_asc_disabled.png b/img/data-tables/sort_asc_disabled.png new file mode 100644 index 00000000..dcd7b7b8 Binary files /dev/null and b/img/data-tables/sort_asc_disabled.png differ diff --git a/img/data-tables/sort_both.png b/img/data-tables/sort_both.png new file mode 100644 index 00000000..18670406 Binary files /dev/null and b/img/data-tables/sort_both.png differ diff --git a/img/data-tables/sort_desc.png b/img/data-tables/sort_desc.png new file mode 100644 index 00000000..def071ed Binary files /dev/null and b/img/data-tables/sort_desc.png differ diff --git a/img/data-tables/sort_desc_disabled.png b/img/data-tables/sort_desc_disabled.png new file mode 100644 index 00000000..7824973c Binary files /dev/null and b/img/data-tables/sort_desc_disabled.png differ diff --git a/index.htm b/index.htm index 32f935fb..c91031bd 100644 --- a/index.htm +++ b/index.htm @@ -4,9 +4,9 @@ + Pathfinder - mapping tool - @@ -16,13 +16,13 @@ -
-
+
-
-
+
-
+
+ + diff --git a/js/app.js b/js/app.js index ee39ee82..ae60561e 100644 --- a/js/app.js +++ b/js/app.js @@ -1,32 +1,47 @@ requirejs.config({ - "baseUrl": "build_js", // user build_js files, change to "js" for un-compressed source + "baseUrl": "js", // user build_js files, change to "js" for un-compressed source "paths": { - //"lib": "lib", - // "app": "app", "layout": "layout", "jquery": "lib/jquery-1.11.1.min", //"jquery": "lib/jquery-2.1.1.min", - "jqueryUI": "lib/jquery-ui.min", - "bootstrap": "lib/bootstrap", + //"jqueryUI": "lib/jquery-ui.min", + "jqueryUI": "lib/jquery-ui-custom.min", // custom script (without tooltip -> conflict with bootstrap) + "bootstrap": "lib/bootstrap.min", "text": "lib/requirejs/text", "templates": "../templates", "jsPlumb": "lib/jsPlumb-1.6.4-min", - "customScrollbar": "lib/jquery.mCustomScrollbar.concat.min" + "customScrollbar": "lib/jquery.mCustomScrollbar.concat.min", + "datatables": "lib/jquery.dataTables.min", + "datatablesBootstrap": "lib/dataTables.bootstrap", // not used (bootstrap style) + "xEditable": "lib/bootstrap-editable.min" }, shim: { - "bootstrap": { - deps: ["jquery"] - }, "jqueryUI": { export:"$", deps: ["jquery"] }, + "bootstrap": { + deps: ["jquery", "jqueryUI"] + }, "customScrollbar": { deps: ["jquery"] + }, + "datatables": { + deps: ["jquery"] + }, + "datatablesBootstrap": { + deps: ["datatables"] + }, + "xEditable": { + deps: ["bootstrap"] } } }); +/* +requirejs(['jquery', 'xEditable'], function($, ) { +}); +*/ // Load the main app module to start the app requirejs(["app/main"]); diff --git a/js/app/main.js b/js/app/main.js index 26e7d5be..8332d717 100644 --- a/js/app/main.js +++ b/js/app/main.js @@ -1,4 +1,4 @@ -define(["jquery", "app/render", "app/ccp", "app/module_map", "customScrollbar"], function($, Render, CCP) { +define(["jquery", "app/render", "app/ccp", "app/module_map"], function($, Render, CCP) { "use strict"; @@ -7,7 +7,6 @@ define(["jquery", "app/render", "app/ccp", "app/module_map", "customScrollbar"], }; $(function() { - CCP.requestTrust(); @@ -28,6 +27,7 @@ define(["jquery", "app/render", "app/ccp", "app/module_map", "customScrollbar"], id: 2, name: 'J150020', effect: 'magnetar', + type: 'wh', security: 'C6', status: 'friendly', position: { @@ -38,6 +38,7 @@ define(["jquery", "app/render", "app/ccp", "app/module_map", "customScrollbar"], id: 3, name: 'J115844', effect: 'wolfRyet', + type: 'wh', security: 'C6', status: 'empty', position: { @@ -48,6 +49,7 @@ define(["jquery", "app/render", "app/ccp", "app/module_map", "customScrollbar"], id: 4, name: 'J155207', effect: 'wolfRyet', + type: 'wh', security: 'C6', status: '', position: { @@ -59,6 +61,7 @@ define(["jquery", "app/render", "app/ccp", "app/module_map", "customScrollbar"], name: 'J145510', effect: 'pulsar', security: 'C3', + type: 'wh', status: 'hostile', position: { x: 110, @@ -92,6 +95,7 @@ define(["jquery", "app/render", "app/ccp", "app/module_map", "customScrollbar"], name: 'J150020', effect: 'magnetar', security: 'C6', + type: 'wh', status: 'friendly', position: { x: 5, @@ -102,6 +106,7 @@ define(["jquery", "app/render", "app/ccp", "app/module_map", "customScrollbar"], name: 'J115844', effect: 'wolfRyet', security: 'C6', + type: 'wh', status: 'empty', position: { x: 60, @@ -116,21 +121,23 @@ define(["jquery", "app/render", "app/ccp", "app/module_map", "customScrollbar"], }] } }, - { - map: {}, - config: { - name: 'Exodus 4D', - id: 3, - scope: 'wormhole', - icon: 'fa-cube', - type: 'private' - }, - data: { - systems: [], - connections: [] - } - }]; + { + map: {}, + config: { + name: 'Exodus 4D', + id: 3, + scope: 'wormhole', + icon: 'fa-cube', + type: 'private' + }, + data: { + systems: [], + connections: [] + } + }]; + + // current user Data for a map var userData = [ { config: { // map config diff --git a/js/app/map/contextmenu.js b/js/app/map/contextmenu.js index a5ae7ab7..756fbcd2 100644 --- a/js/app/map/contextmenu.js +++ b/js/app/map/contextmenu.js @@ -20,12 +20,13 @@ define(["jquery"], function($) { top: getTopLocation(originalEvent) }) .off('click') - .on('click', {component: component}, function (e) { + .on('click', {component: component, position:{x: getLeftLocation(originalEvent), y: getTopLocation(originalEvent)}}, function (e) { $(this).hide(); var params = { selectedMenu: $(e.target), - component: e.data.component + component: e.data.component, + position: e.data.position }; diff --git a/js/app/map/map.js b/js/app/map/map.js index d607138f..025d3e6a 100644 --- a/js/app/map/map.js +++ b/js/app/map/map.js @@ -11,6 +11,7 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R y: 0 }, + mapTabContentClass: 'pf-map-tab-content', // Tab-Content element (parent element) mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable) mapClass: 'pf-map', // class for all maps mapIdPrefix: 'pf-map-', @@ -18,6 +19,8 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R systemClass: 'pf-system', systemActiveClass: 'pf-system-active', systemHeadClass: 'pf-system-head', + systemHeadNameClass: 'pf-system-head-name', + systemHeadExpandClass: 'pf-system-head-expand', systemBodyClass: 'pf-system-body', systemBodyItemClass: 'pf-system-body-item', systemBodyItemStatusClass: 'pf-user-status', @@ -29,11 +32,13 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R endpointTargetClass: 'pf-map-endpoint-target', // context menus + mapContextMenuId: 'pf-map-contextmenu', connectionContextMenuId: 'pf-map-connection-contextmenu', systemContextMenuId: 'pf-map-system-contextmenu', // dialogs - confirmDialogId: 'pf-delete-dialog', + confirmDeleteConnectionDialogId: 'pf-delete-dialog-connection', + confirmDeleteSystemDialogId: 'pf-delete-dialog-system', systemDialogId: 'pf-system-dialog', errorConnectDialogId: 'pf-error-dialog-loopback', @@ -98,7 +103,7 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R // jsPlumb config var globalMapConfig = { source: { - filter: '.' + config.systemHeadClass, + filter: '.' + config.systemHeadNameClass, anchor: 'Continuous', connector: [ "Bezier", { curviness: 40, cssClass: 'pf-map-connection-wh' } ], maxConnections: 5, @@ -117,7 +122,7 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R ] */ }, target: { - filter: '.' + config.systemHeadClass, + filter: '.' + config.systemHeadNameClass, anchor: 'Continuous', allowLoopback:false, cssClass: config.endpointTargetClass, @@ -300,32 +305,32 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R * @param system * @param data */ - var updateSystem = function(system, data){ + var updateSystem = function(map, system, data){ // find system body var systemBody = $( $(system).find('.' + config.systemBodyClass) ); + // find expand arrow + var systemHeadExpand = $( $(system).find('.' + config.systemHeadExpandClass) ); + + // remove tooltip $(system).removeAttr('title'); // remove all content systemBody.empty(); + var userCounter = 0; + // add user information if(data.user){ - var userCounter = 0; - $.each(data.user, function(i, userData){ userCounter++; var statusClass = getStatusClassForUser(userData.status); var userName = userData.name; - if(userName.length > 7){ - // userName = userName.substr(0,7) + '...'; - } - var item = $('
', { class: config.systemBodyItemClass @@ -347,14 +352,44 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R systemBody.append(item); }); - // show active user tooltip - $(system).attr('title', userCounter); - $(system).attr('data-placement', 'top'); - $(system).attr('data-toggle', 'tooltip'); - $(system).tooltip('show'); } + $(system).removeAttr('title'); + if(userCounter === 0){ + // hide expand arrow + systemBody.hide(); + systemHeadExpand.hide(); + }else{ + systemBody.show(); + systemHeadExpand.show(); + + $(system).attr('title', userCounter); + + // show active user tooltip + toggleSystemTooltip([system], 'show', {placement: 'top', trigger: 'manual'}); + } + + // repaint connection because of system-size change + map.repaint( system ); + + }; + + /** + * show/hide systems tooltip + * @param systems + * @param show + * @param options + */ + var toggleSystemTooltip = function(systems, show, options){ + + $.each(systems, function(i, system){ + if(options){ + $(system).tooltip(options); + } + + $(system).tooltip(show); + }); }; /** @@ -378,13 +413,23 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R }).append( // system head $('
', { - class: config.systemHeadClass, - text: data.name + class: config.systemHeadClass }).append( + // System effect color + $('', { + class: config.systemHeadNameClass, + text: data.name + }) + ).append( // System effect color $('', { class: ['fa fa-square ', config.systemEffect, effectClass].join(' ') }) + ).append( + // expand option + $('', { + class: ['fa fa-angle-down ', config.systemHeadExpandClass].join(' ') + }) ).prepend( $('', { class: [config.systemSec, secClass].join(' '), @@ -396,12 +441,7 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R // system body $('
', { class: config.systemBodyClass - }).append( - $('
', { - class: config.systemBodyInnerClass - }) - - ) + }) ).css({ "left": data.position.x + "px", 'top': data.position.y + 'px' }); system.attr('data-id', data.id); @@ -427,12 +467,17 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R mapWrapper.append(mapContainer); - // append mapWrapper to parent element - $(parentElement).append(mapWrapper); + // append mapWrapper to parent element (at the top) + $(parentElement).prepend(mapWrapper); - // set main Container for current map -> the container exists now in DOM + + // set main Container for current map -> the container exists now in DOM !! very important mapConfig.map.setContainer($('#' + config.mapIdPrefix + mapConfig.config.id)); + // set map observer + setMapObserver(mapConfig.map); + + $.each(mapConfig.data.systems, function(i, data){ // draw a system to a map drawSystem(mapConfig.map, data); @@ -493,7 +538,7 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R // get System Element by data var newSystem = getSystem(systemData); - + // add new system to map mapContainer.append(newSystem); // make new System dragable @@ -521,7 +566,28 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R drawConnection(map, connectionData); }); } + }; + /** + * delete a system with all its connections + * @param map + * @param system + */ + var deleteSystem = function(map, system){ + + // detach all connections + map.detachAllConnections(system); + + // delete all endpoints + map.removeAllEndpoints(system); + + // hide tooltip + toggleSystemTooltip(system, 'hide'); + + // remove system + system.fadeOut(300, function(){ + $(this).remove() ; + }); }; /** @@ -536,17 +602,26 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R map.draggable(systems, { containment: mapContainer,// 'parent', zIndex: 2000, - start: function(){ + start: function(e){ // drag start + + // hide tooltip + toggleSystemTooltip([e.target], 'hide'); }, stop: function(e, ui){ // drag stop // update z-index for dragged system + connections updateZIndex(map, e.target); + + // rerender tooltip + toggleSystemTooltip([e.target], 'show'); }, - drag: function(){ + drag: function(e){ // while drag + + + } }); }; @@ -630,6 +705,27 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R return connection; }; + /** + * load contextmenu template for map + */ + var initMapContextMenu = function(){ + + var moduleConfig = { + name: 'modules/contextmenu', + position: $('#' + config.dynamicElementWrapperId) + }; + + var moduleData = { + id: config.mapContextMenuId, + items: [ + {icon: 'fa-plus', action: 'add_system', text: 'add system'}, + {icon: 'fa-info-circle', action: 'info', text: 'info'} + ] + }; + + Render.showModule(moduleConfig, moduleData); + }; + /** * load contextmenu template for connections */ @@ -676,6 +772,7 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R id: config.systemContextMenuId, items: [ {icon: 'fa-plus', action: 'add_system', text: 'add system'}, + {icon: 'fa-eraser', action: 'delete_system', text: 'delete system'}, {icon: 'fa-info-circle', action: 'info', text: 'info'} ] }; @@ -690,16 +787,26 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R */ var setSystemObserver = function(map, system){ + var systemHeadExpand = $( $(system).find('.' + config.systemHeadExpandClass) ); var systemBody = $( $(system).find('.' + config.systemBodyClass) ); + var bodyItemheight = 16; + // init system body expand - $(system).hover(function(e){ + systemHeadExpand.hover(function(e){ // hover in var hoverSystem = this; + // get ship counter and calculate expand height + var shipCounter = parseInt( $(system).attr('data-original-title') ); + + var expandheight = shipCounter * bodyItemheight; + systemBody.animate( { - height: '100px' + height: expandheight + 'px', + width: '100%', + 'min-width': '150px' }, { queue:false, @@ -707,6 +814,9 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R step: function(){ // repaint connections of current system map.repaint( hoverSystem ); + }, + complete: function(){ + $(this).find('.' + config.systemBodyRightClass).show(); } } ); @@ -714,49 +824,18 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R // hover out var hoverSystem = this; systemBody.animate( - { height: '16px' }, + { + height: '16px', + width: '100%', + 'min-width': '80px' + }, { queue:false, duration: 100, step: function(){ // repaint connections of current system map.repaint( hoverSystem ); - } - } - ); - }); - - - // init system body item expand - systemBody.hover(function(){ - $(this).animate( - { - width: '150px' - }, - { - queue:false, - duration: 100, - step: function(){ - // repaint connections of current system - map.repaint( system ); - }, - complete: function(){ - $(this).find('.' + config.systemBodyRightClass).show(); - } - } - ); - - }, function(){ - $(this).animate( - { - width: '80px' - }, - { - queue:false, - duration: 100, - step: function(){ console.log(system) - // repaint connections of current system - map.repaint( system ); + $(this).find('.' + config.systemBodyRightClass).hide(); }, start: function(){ $(this).find('.' + config.systemBodyRightClass).hide(); @@ -765,6 +844,8 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R ); }); + // context menu ================================================================== + // trigger context menu $(system).on('contextmenu', function(e){ $(e.target).trigger('pf:openContextMenu', [e, this]); @@ -786,45 +867,29 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R switch(action){ case 'add_system': // add a new system + showNewSystemDialog(map, {sourceSystem: currentSystem} ); + + break; + case 'delete_system': // confirm dialog var moduleConfig = { - name: 'modules/system_dialog', + name: 'modules/dialog', position: $('#' + config.dynamicElementWrapperId), link: 'after', functions: { after: function(){ - $( "#" + config.systemDialogId).dialog({ + $( "#" + config.confirmDeleteSystemDialogId).dialog({ modal: true, resizable: false, buttons: { 'Cancel': function(){ $(this).dialog('close'); }, - 'Add system': function(){ - - // get form Values - var form = $('#' + config.systemDialogId).find('form'); - - var newSystemData = {}; - - $.each(form.serializeArray(), function(i, field) { - newSystemData[field.name] = field.value; - }); - - // add new position - var currentX = currentSystem.css('left'); - var currentY = currentSystem.css('top'); - - newSystemData.position = { - x: parseInt( currentX.substring(0, currentX.length - 2) ) + config.newSystemOffset.x, - y: parseInt( currentY.substring(0, currentY.length - 2) ) + config.newSystemOffset.y - } - - - // draw new system to map - drawSystem(map, newSystemData, currentSystem); + 'Yes': function(){ + // map.detach(params.component); + deleteSystem(map, currentSystem); $(this).dialog('close'); } } @@ -833,17 +898,10 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R } }; - // format system status for form select - var systemStatus = []; - $.each(config.systemStatus, function(status, statusData){ - statusData.status = status; - systemStatus.push(statusData); - }); - var moduleData = { - id: config.systemDialogId, - titel: 'Add new system', - status: systemStatus + id: config.confirmDeleteSystemDialogId, + titel: 'Delete System', + content: 'Delete system with all its connections?' }; Render.showModule(moduleConfig, moduleData); @@ -855,6 +913,65 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R } }); + // load system data ================================================================================= + + $(system).on('click', function(e){ + + // get current map + var currentSystem = $(e.target).parents('.' + config.systemClass); + + // get parent Tab Content and fire update event + var tabContentElement = currentSystem.parents('.' + config.mapTabContentClass); + + markSystemActive(map, currentSystem); + + $(tabContentElement).trigger('pf:updateSystemData', [{system: currentSystem}]); + }); + + + }; + + var setMapObserver = function(map){ + + // get map container + var container = map.getContainer(); + + $(container).on('contextmenu', function(e){ + $(e.target).trigger('pf:openContextMenu', [e, this]); + e.preventDefault(); + return false; + }); + + $(container).contextMenu({ + menuSelector: "#" + config.mapContextMenuId, + menuSelected: function (params) { + + // click action + var action = params.selectedMenu.attr('data-action'); + + // current map + var currentMapElement = $(params.component); + + var currentMapId = parseInt( currentMapElement.attr('data-mapid') ); + + // get map instance + var currentMap = getMapInstance(currentMapId); + + // click position + var position = params.position; + + switch(action){ + case 'add_system': + // add new system dialog + showNewSystemDialog(currentMap, {position: position}); + break; + + } + + } + + }); + }; @@ -896,7 +1013,7 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R link: 'after', functions: { after: function(){ - $( "#" + config.confirmDialogId).dialog({ + $( "#" + config.confirmDeleteConnectionDialogId).dialog({ modal: true, resizable: false, buttons: { @@ -914,7 +1031,7 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R }; var moduleData = { - id: config.confirmDialogId, + id: config.confirmDeleteConnectionDialogId, titel: 'Delete Connection', content: 'Is this connection really gone?' }; @@ -957,7 +1074,123 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R } }); + }; + /** + * mark a system as active + * @param map + * @param system + */ + var markSystemActive = function(map, system){ + + // deactivate all systems in map + var mapContainer = $( map.getContainer() ); + + mapContainer.find('.' + config.systemClass).removeClass(config.systemActiveClass); + + // set current system active + system.addClass(config.systemActiveClass); + }; + + /** + * open "new system" dialog and add the system to map + * optional the new system is connected to "currentSystem" (if available) + * + * @param map + * @param options + */ + var showNewSystemDialog = function(map, options){ + + var moduleConfig = { + name: 'modules/system_dialog', + position: $('#' + config.dynamicElementWrapperId), + link: 'after', + functions: { + after: function(){ + $( "#" + config.systemDialogId).dialog({ + modal: true, + resizable: false, + buttons: { + 'Cancel': function(){ + $(this).dialog('close'); + }, + 'Add system': function(e){ + + // get form Values + var form = $('#' + config.systemDialogId).find('form'); + + var newSystemData = {}; + + $.each(form.serializeArray(), function(i, field) { + newSystemData[field.name] = field.value; + }); + + var currentX = 0; + var currentY = 0; + + var newPositon = { + x: 0, + y: 0 + }; + + var sourceSystem = null; + + // add new position + if(options.sourceSystem !== undefined){ + + sourceSystem = options.sourceSystem; + + // related system is available + currentX = sourceSystem.css('left'); + currentY = sourceSystem.css('top'); + + // remove "px" + currentX = parseInt( currentX.substring(0, currentX.length - 2) ); + currentY = parseInt( currentY.substring(0, currentY.length - 2) ); + + newPositon = { + x: currentX + config.newSystemOffset.x, + y: currentY + config.newSystemOffset.y + }; + }else{ + // check mouse cursor position (add system to map) + newPositon = { + x: options.position.x, + y: options.position.y + }; + + console.log(e) + } + + + newSystemData.position = newPositon; + + + // draw new system to map + drawSystem(map, newSystemData, sourceSystem); + + $(this).dialog('close'); + } + } + }); + } + } + }; + + // format system status for form select + var systemStatus = []; + $.each(config.systemStatus, function(status, statusData){ + statusData.status = status; + systemStatus.push(statusData); + }); + + var moduleData = { + id: config.systemDialogId, + titel: 'Add new system', + status: systemStatus + }; + + Render.showModule(moduleConfig, moduleData); }; @@ -982,8 +1215,6 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R console.log('new jsPlumbInstance: ' + mapId); } - - return activeInstances[mapId]; }; @@ -996,20 +1227,26 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R // get all systems var systems = $(this).find('.' + config.systemClass); - $.each(systems, function(i, system){ - // get user Data for System - var systemId = parseInt( $(system).attr('data-id') ); + // get new map instance or load existing + var map = getMapInstance(userData.config.id); + + // container must exist! otherwise systems cant be updated + if(map.getContainer() !== undefined){ + $.each(systems, function(i, system){ + // get user Data for System + var systemId = parseInt( $(system).attr('data-id') ); + + var data = {}; + $.each(userData.data.systems, function(j, systemData){ + if(systemId === systemData.id){ + data = systemData; + } + }); + + updateSystem(map, system, data); - var data = {}; - $.each(userData.data.systems, function(j, systemData){ - if(systemId === systemData.id){ - data = systemData; - } }); - - updateSystem(system, data); - - }); + } }; @@ -1023,6 +1260,7 @@ define(["jquery", "app/render", "jsPlumb", "app/map/contextmenu"], function($, R var parentElement = $(this); // add context menus to dom + initMapContextMenu(); initConnectionContextMenu(); initSystemContextMenu(); diff --git a/js/app/module_map.js b/js/app/module_map.js index 9496788e..dcc72e84 100644 --- a/js/app/module_map.js +++ b/js/app/module_map.js @@ -1,15 +1,29 @@ -define(["jquery", "app/render", "app/map/map", "customScrollbar"], function($, Render) { +define(['jquery', 'app/render', 'datatables', 'xEditable', 'app/map/map', 'customScrollbar'], function($, Render) { "use strict"; var config = { - dynamicElementWrapperId: 'pf-dialog-wrapper', // parent Element for dynamic content (dialoges,..) + dynamicElementWrapperId: 'pf-dialog-wrapper', // parent Element for dynamic content (dialoges,..) mapTabBarId: 'pf-map-tabs', mapTabIdPrefix: 'pf-map-tab-', - mapWrapperClass: 'pf-map-wrapper', // scrollable - mapClass: 'pf-map', // class for each map + mapTabClass: 'pf-map-tab', + mapTabContentClass: 'pf-map-tab-content', + mapTabContentSystemInfoClass: 'pf-map-tab-content-system', + mapWrapperClass: 'pf-map-wrapper', // scrollable + mapClass: 'pf-map', // class for each map newMapDialogId: 'pf-map-new-dialog', + // TabContentStructure + mapTabContentRow: 'pf-map-content-row', // main row for Tab content (grid) + mapTabContentCellFirst: 'pf-map-content-col-first', // first column + mapTabContentCellSecond: 'pf-map-content-col-second', // second column + + // sig table + sigTableClass: 'pf-sig-table', // Table class for all Signature Tables + sigTableEditText: 'pf-sig-table-edit-text', // class for editable fields (text) + sigTableEditSigTypeSelect: 'pf-sig-table-edit-sig-type-select', // class for editable fields (select) + sigTableEditSigNameSelect: 'pf-sig-table-edit-sig-name-select', // class for editable fields (select) + // map types mapTypes: [ {type: 'default', label: 'default', class: 'pf-map-type-default'}, @@ -30,7 +44,108 @@ define(["jquery", "app/render", "app/map/map", "customScrollbar"], function($, R {class: 'fa-warning', label: 'warning'}, {class: 'fa-plane', label: 'plane'}, {class: 'fa-rocket', label: 'rocket'} - ] + ], + + // Signature Type + signatureTypes: { + wh: { // system type + 1: { // C1 (area id) + 1: { // Combat + 1: 'Perimeter Ambush Point', + 2: 'Perimeter Camp', + 3: 'Phase Catalyst Node', + 4: 'The Line' + }, + 2: { // Relict + 1: 'Forgotten Perimeter Coronation Platform' + }, + 3: { // Data + 1: 'Unsecured Perimeter Amplifier ', + 2: 'Unsecured Perimeter Information Center ' + } + }, + 2: { // C2 + 1: { // Combat + 1: 'Perimeter Checkpoint', + 2: 'Perimeter Hangar', + 3: 'The Ruins of Enclave Cohort 27', + 4: 'Sleeper Data Sanctuary' + }, + 2: { // Relict + 1: 'Forgotten Perimeter Gateway', + 2: 'Forgotten Perimeter Habitation Coils' + }, + 3: { // Data + 1: 'Unsecured Perimeter Comms Relay', + 2: 'Unsecured Perimeter Transponder Farm ' + } + }, + 3: { // C3 + 1: { // Combat + 1: 'Fortification Frontier Stronghold', + 2: 'Outpost Frontier Stronghold', + 3: 'Solar Cell', + 4: 'The Oruze Construct' + }, + 2: { // Relict + 1: 'Forgotten Frontier Quarantine Outpost', + 2: 'Forgotten Frontier Recursive Depot' + }, + 3: { // Data + 1: 'Unsecured Frontier Database', + 2: 'Unsecured Frontier Receiver' + } + }, + 4: { // C4 + 1: { // Combat + 1: 'Frontier Barracks', + 2: 'Frontier Command Post', + 3: 'Integrated Terminus', + 4: 'Sleeper Information Sanctum' + }, + 2: { // Relict + 1: 'Forgotten Frontier Conversion Module', + 2: 'Forgotten Frontier Evacuation Center' + }, + 3: { // Data + 1: 'Unsecured Frontier Digital Nexus', + 2: 'Unsecured Frontier Trinary Hub' + } + }, + 5: { // C5 + 1: { // Combat + 1: 'Core Garrison', + 2: 'Core Stronghold', + 3: 'Oruze Osobnyk', + 4: 'Quarantine Area' + }, + 2: { // Relict + 1: 'Forgotten Core Data Field', + 2: 'Forgotten Core Information Pen' + }, + 3: { // Data + 1: 'Unsecured Frontier Enclave Relay', + 2: 'Unsecured Frontier Server Bank' + } + }, + 6: { // C6 + 1: { // Combat + 1: 'Core Citadel', + 2: 'Core Bastion', + 3: 'Strange Energy Readings', + 4: 'The Mirror' + }, + 2: { // Relict + 1: 'Forgotten Core Assembly Hall', + 2: 'Forgotten Core Circuitry Disassembler' + }, + 3: { // Data + 1: 'Unsecured Core Backup Array', + 2: 'Unsecured Core Emergence ' + } + } + } + } }; @@ -111,7 +226,7 @@ define(["jquery", "app/render", "app/map/map", "customScrollbar"], function($, R }; /** - * get all maps for a module + * get all maps for a maps module * @param mapModule * @returns {*} */ @@ -122,6 +237,427 @@ define(["jquery", "app/render", "app/map/map", "customScrollbar"], function($, R return maps; }; + /** + * get all Tabs for a maps module + * @param mapModule + * @returns {*} + */ + var getTabContentElements = function(mapContentModule){ + + var tabs = $(mapContentModule).find('.' + config.mapTabContentClass ); + + return tabs; + }; + + /** + * set Tab Observer, events are triggered within map.js + * @param mapContentModule + */ + $.fn.setTabContenteObserver = function(){ + + return this.each(function(){ + $(this).on('pf:updateSystemData', function(e, data){ + // update Tab Content with system data information + updateSystemInfo($( e.target )); + }); + }); + }; + + var updateSystemInfo = function(tabContentElement){ + + // get Table cell for system Info + var systemCell = $(tabContentElement).find('.' + config.mapTabContentCellFirst); + + // clear systemCell + systemCell.empty(); + + // TODO replace with backend ajax request + var systemData = tempFunctionGetSystemData(); + + var signatureData = formatSignatureData(systemData); + + // check if signatures exist + if(signatureData.length > 0){ + var table = $('', { + class: ['display', 'compact', config.sigTableClass].join(' '), + id: 'test_table' + }); + + systemCell.append(table); + + + table.dataTable( { + "data": signatureData, + "pageLength": 100, + "lengthMenu": [ 5, 10, 25, 50, 75, 100 ], + "columnDefs": [ + { + "targets": 0, + //"orderData": 0, + "orderable": true, + "title": "sig", + "width": '20px' + },{ + "targets": 1, + "orderable": true, + "title": "type", + "width": '50px' + },{ + "targets": 2, + "title": "name/description" + },{ + "targets": 3, + "title": "created", + "width": '70px' + },{ + "targets": 4, + "title": "updated", + "width": '70px' + } + ] + } ); + + systemCell.show(); + + // make Table editable + table.makeEditable(); + + + }else{ + systemCell.hide(); + } + + }; + + /** + * make a table editable (in-line-editor) + */ + $.fn.makeEditable = function(){ + // set editor mode + // $.fn.editable.defaults.mode = 'inline'; + + // cach sige types + var sigTypeCache = {}; + + // Select sig type (master) + $(this).find('.' + config.sigTableEditSigTypeSelect).editable({ + mode: 'popup', + source: function(){ + + var systemType = $(this).attr('data-systemtype'); + var areaId = $(this).attr('data-areaid'); + + var cacheKey = [systemType, areaId].join('_'); + + // check for cached signature names + if(sigTypeCache.hasOwnProperty( cacheKey )){ + return sigTypeCache[cacheKey]; + } + + var availableTypes = {}; + + // get all available Signature Types + if( + config.signatureTypes[systemType] && + config.signatureTypes[systemType][areaId] + ){ + // json object -> "translate" keys to names + var tempTypes = config.signatureTypes[systemType][areaId]; + + + for (var prop in tempTypes) { + if(tempTypes.hasOwnProperty(prop)){ + prop = parseInt(prop); + + switch(prop){ + case 1: + availableTypes[prop] = 'Combat'; + break; + case 2: + availableTypes[prop] = 'Relict'; + break; + case 3: + availableTypes[prop] = 'Data'; + break; + case 4: + availableTypes[prop] = 'Gas'; + break; + } + } + } + + + availableTypes = sigTypeCache[cacheKey] = availableTypes; + } + + return availableTypes; + } + }); + + // cache sig names + var sigNameCache = {}; + + // Select sig name (slave: depends on sig type) + $(this).find('.' + config.sigTableEditSigNameSelect).editable({ + mode: 'inline', + source: function(){ + + var systemType = $(this).attr('data-systemtype'); + var areaId = $(this).attr('data-areaid'); + var sigType = $(this).attr('data-sigtypeid'); + + var cacheKey = [systemType, areaId, sigType].join('_'); + + // check for cached signature names + if(sigNameCache.hasOwnProperty( cacheKey )){ + return sigNameCache[cacheKey]; + } + + var availableSigs = {}; + + // get all available Signature Names + if( + config.signatureTypes[systemType] && + config.signatureTypes[systemType][areaId] && + config.signatureTypes[systemType][areaId][sigType] + ){ + availableSigs = sigNameCache[cacheKey] = config.signatureTypes[systemType][areaId][sigType]; + } + + return availableSigs; + } + }); + + // Textfields + $('.' + config.sigTableEditText).editable({ + anim: "1000" + }); + }; + + /** + * get Area ID by security string + * k-space not implemented jet + * @param security + * @returns {*} + */ + var getAreaIdBySecurity = function(security){ + + var areaId = null; + + switch(security){ + case 'C1': + areaId = 1; + break; + case 'C2': + areaId = 2; + break; + case 'C3': + areaId = 3; + break; + case 'C4': + areaId = 4; + break; + case 'C5': + areaId = 5; + break; + case 'C6': + areaId = 6; + break; + } + + return areaId; + }; + + /** + * formats all signature data for table + * @param systemData + * @returns {Array} + */ + var formatSignatureData = function(systemData){ + + var formattedData = []; + + if( + systemData && + systemData.config && + systemData.config.id && + systemData.config.type === 'wh' + ){ + // system data "should" be valid :) + var systemSecurity = systemData.config.security; + var systemType = systemData.config.type; + + + var areaId = getAreaIdBySecurity(systemSecurity); + + // areaId is required as a key for signature names + if(areaId){ + + $.each(systemData.signatures, function(i, data){ + + var tempData = []; + + // set signature + tempData.push(data.sig); + + var sigType = '', { + class: ['row', config.mapTabContentRow].join(' ') + }).append( + $('
', { + class: ['col-xs-12', 'col-sm-8', config.mapTabContentCellFirst].join(' ') + }) + ).append( + $('
', { + class: ['col-xs-6', 'col-sm-4', config.mapTabContentCellSecond].join(' ') + }) + ); + + + // append grid structure + $(this).append(contentStructure); + }); }; @@ -165,10 +725,21 @@ define(["jquery", "app/render", "app/map/map", "customScrollbar"], function($, R link: 'prepend', functions: { after: function(){ - // load first map i in first tab content container - var firstTabContentElement = $("div[data-map-tabs='" + config.mapTabBarId + "'] div:first-child"); - loadMap(firstTabContentElement, mapData[0]); + // this new created module + var mapContentModule = $("div[data-map-tabs='" + config.mapTabBarId + "']"); + + // load first map i in first tab content container + var tabContentElements = getTabContentElements(mapContentModule); + + // set observer for manually triggered map events + tabContentElements.setTabContenteObserver(); + + // load all the structure elements for ALL Tab Content Body + tabContentElements.initContentStructure(); + + // load first map i in first tab content container + $( tabContentElements[0] ).initMap(mapData[0]); // check for "new map" action before tap-change $('#' + config.mapTabBarId).find('a[data-toggle="tab"]').on('show.bs.tab', function (e) { @@ -193,7 +764,7 @@ define(["jquery", "app/render", "app/map/map", "customScrollbar"], function($, R var mapId = mapData[mapIndex].config.id; var currentTabContentElement = $('#' + config.mapTabIdPrefix + mapId); - loadMap(currentTabContentElement, mapData[mapIndex]); + $( currentTabContentElement).initMap( mapData[mapIndex]); } }); @@ -222,7 +793,8 @@ define(["jquery", "app/render", "app/map/map", "customScrollbar"], function($, R index: i, name: data.config.name, icon: data.config.icon, - tabClass: getMapTypeClassForType(data.config.type), + tabClass: [config.mapTabClass, getMapTypeClassForType( data.config.type) ].join(' '), + contentClass: config.mapTabContentClass, active: active }); }); @@ -233,7 +805,8 @@ define(["jquery", "app/render", "app/map/map", "customScrollbar"], function($, R index: -1, name: 'add', icon: 'fa-plus', - tabClass: getMapTypeClassForType('default'), + tabClass: [config.mapTabClass, getMapTypeClassForType('default')].join(' '), + contentClass: config.mapTabContentClass, pullRight: true }); @@ -241,18 +814,19 @@ define(["jquery", "app/render", "app/map/map", "customScrollbar"], function($, R }; /** - * load mapData into a container and init custom scrollbar + * init map, load into a container and init custom scrollbar * @param container * @param mapData */ - var loadMap = function(container, mapData){ + $.fn.initMap = function(mapData){ - $(container).loadMap(mapData); - - // init custom scrollbars - var scrollableElement = $(container).find('.' + config.mapWrapperClass); - initCutomScrollbar( scrollableElement ); + return this.each(function(){ + $(this).loadMap(mapData); + // init custom scrollbars + var scrollableElement = $(this).find('.' + config.mapWrapperClass); + initCutomScrollbar( scrollableElement ); + }); }; /** diff --git a/js/lib/bootstrap-editable.min.js b/js/lib/bootstrap-editable.min.js new file mode 100644 index 00000000..e2703aee --- /dev/null +++ b/js/lib/bootstrap-editable.min.js @@ -0,0 +1,7 @@ +/*! X-editable - v1.5.1 +* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery +* http://github.com/vitalets/x-editable +* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ +!function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.editableform.defaults,c),this.$div=a(b),this.options.scope||(this.options.scope=this)};b.prototype={constructor:b,initInput:function(){this.input=this.options.input,this.value=this.input.str2value(this.options.value),this.input.prerender()},initTemplate:function(){this.$form=a(a.fn.editableform.template)},initButtons:function(){var b=this.$form.find(".editable-buttons");b.append(a.fn.editableform.buttons),"bottom"===this.options.showbuttons&&b.addClass("editable-buttons-bottom")},render:function(){this.$loading=a(a.fn.editableform.loading),this.$div.empty().append(this.$loading),this.initTemplate(),this.options.showbuttons?this.initButtons():this.$form.find(".editable-buttons").remove(),this.showLoading(),this.isSaving=!1,this.$div.triggerHandler("rendering"),this.initInput(),this.$form.find("div.editable-input").append(this.input.$tpl),this.$div.append(this.$form),a.when(this.input.render()).then(a.proxy(function(){if(this.options.showbuttons||this.input.autosubmit(),this.$form.find(".editable-cancel").click(a.proxy(this.cancel,this)),this.input.error)this.error(this.input.error),this.$form.find(".editable-submit").attr("disabled",!0),this.input.$input.attr("disabled",!0),this.$form.submit(function(a){a.preventDefault()});else{this.error(!1),this.input.$input.removeAttr("disabled"),this.$form.find(".editable-submit").removeAttr("disabled");var b=null===this.value||void 0===this.value||""===this.value?this.options.defaultValue:this.value;this.input.value2input(b),this.$form.submit(a.proxy(this.submit,this))}this.$div.triggerHandler("rendered"),this.showForm(),this.input.postrender&&this.input.postrender()},this))},cancel:function(){this.$div.triggerHandler("cancel")},showLoading:function(){var a,b;this.$form?(a=this.$form.outerWidth(),b=this.$form.outerHeight(),a&&this.$loading.width(a),b&&this.$loading.height(b),this.$form.hide()):(a=this.$loading.parent().width(),a&&this.$loading.width(a)),this.$loading.show()},showForm:function(a){this.$loading.hide(),this.$form.show(),a!==!1&&this.input.activate(),this.$div.triggerHandler("show")},error:function(b){var c,d=this.$form.find(".control-group"),e=this.$form.find(".editable-error-block");if(b===!1)d.removeClass(a.fn.editableform.errorGroupClass),e.removeClass(a.fn.editableform.errorBlockClass).empty().hide();else{if(b){c=(""+b).split("\n");for(var f=0;f").text(c[f]).html();b=c.join("
")}d.addClass(a.fn.editableform.errorGroupClass),e.addClass(a.fn.editableform.errorBlockClass).html(b).show()}},submit:function(b){b.stopPropagation(),b.preventDefault();var c=this.input.input2value(),d=this.validate(c);if("object"===a.type(d)&&void 0!==d.newValue){if(c=d.newValue,this.input.value2input(c),"string"==typeof d.msg)return this.error(d.msg),this.showForm(),void 0}else if(d)return this.error(d),this.showForm(),void 0;if(!this.options.savenochange&&this.input.value2str(c)==this.input.value2str(this.value))return this.$div.triggerHandler("nochange"),void 0;var e=this.input.value2submit(c);this.isSaving=!0,a.when(this.save(e)).done(a.proxy(function(a){this.isSaving=!1;var b="function"==typeof this.options.success?this.options.success.call(this.options.scope,a,c):null;return b===!1?(this.error(!1),this.showForm(!1),void 0):"string"==typeof b?(this.error(b),this.showForm(),void 0):(b&&"object"==typeof b&&b.hasOwnProperty("newValue")&&(c=b.newValue),this.error(!1),this.value=c,this.$div.triggerHandler("save",{newValue:c,submitValue:e,response:a}),void 0)},this)).fail(a.proxy(function(a){this.isSaving=!1;var b;b="function"==typeof this.options.error?this.options.error.call(this.options.scope,a,c):"string"==typeof a?a:a.responseText||a.statusText||"Unknown error!",this.error(b),this.showForm()},this))},save:function(b){this.options.pk=a.fn.editableutils.tryParseJson(this.options.pk,!0);var c,d="function"==typeof this.options.pk?this.options.pk.call(this.options.scope):this.options.pk,e=!!("function"==typeof this.options.url||this.options.url&&("always"===this.options.send||"auto"===this.options.send&&null!==d&&void 0!==d));return e?(this.showLoading(),c={name:this.options.name||"",value:b,pk:d},"function"==typeof this.options.params?c=this.options.params.call(this.options.scope,c):(this.options.params=a.fn.editableutils.tryParseJson(this.options.params,!0),a.extend(c,this.options.params)),"function"==typeof this.options.url?this.options.url.call(this.options.scope,c):a.ajax(a.extend({url:this.options.url,data:c,type:"POST"},this.options.ajaxOptions))):void 0},validate:function(a){return void 0===a&&(a=this.value),"function"==typeof this.options.validate?this.options.validate.call(this.options.scope,a):void 0},option:function(a,b){a in this.options&&(this.options[a]=b),"value"===a&&this.setValue(b)},setValue:function(a,b){this.value=b?this.input.str2value(a):a,this.$form&&this.$form.is(":visible")&&this.input.value2input(this.value)}},a.fn.editableform=function(c){var d=arguments;return this.each(function(){var e=a(this),f=e.data("editableform"),g="object"==typeof c&&c;f||e.data("editableform",f=new b(this,g)),"string"==typeof c&&f[c].apply(f,Array.prototype.slice.call(d,1))})},a.fn.editableform.Constructor=b,a.fn.editableform.defaults={type:"text",url:null,params:null,name:null,pk:null,value:null,defaultValue:null,send:"auto",validate:null,success:null,error:null,ajaxOptions:null,showbuttons:!0,scope:null,savenochange:!1},a.fn.editableform.template='
',a.fn.editableform.loading='
',a.fn.editableform.buttons='',a.fn.editableform.errorGroupClass=null,a.fn.editableform.errorBlockClass="editable-error",a.fn.editableform.engine="jquery"}(window.jQuery),function(a){"use strict";a.fn.editableutils={inherit:function(a,b){var c=function(){};c.prototype=b.prototype,a.prototype=new c,a.prototype.constructor=a,a.superclass=b.prototype},setCursorPosition:function(a,b){if(a.setSelectionRange)a.setSelectionRange(b,b);else if(a.createTextRange){var c=a.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",b),c.select()}},tryParseJson:function(a,b){if("string"==typeof a&&a.length&&a.match(/^[\{\[].*[\}\]]$/))if(b)try{a=new Function("return "+a)()}catch(c){}finally{return a}else a=new Function("return "+a)();return a},sliceObj:function(b,c,d){var e,f,g={};if(!a.isArray(c)||!c.length)return g;for(var h=0;h").text(b).html()},itemsByValue:function(b,c,d){if(!c||null===b)return[];if("function"!=typeof d){var e=d||"value";d=function(a){return a[e]}}var f=a.isArray(b),g=[],h=this;return a.each(c,function(c,e){if(e.children)g=g.concat(h.itemsByValue(b,e.children,d));else if(f)a.grep(b,function(a){return a==(e&&"object"==typeof e?d(e):e)}).length&&g.push(e);else{var i=e&&"object"==typeof e?d(e):e;b==i&&g.push(e)}}),g},createInput:function(b){var c,d,e,f=b.type;return"date"===f&&("inline"===b.mode?a.fn.editabletypes.datefield?f="datefield":a.fn.editabletypes.dateuifield&&(f="dateuifield"):a.fn.editabletypes.date?f="date":a.fn.editabletypes.dateui&&(f="dateui"),"date"!==f||a.fn.editabletypes.date||(f="combodate")),"datetime"===f&&"inline"===b.mode&&(f="datetimefield"),"wysihtml5"!==f||a.fn.editabletypes[f]||(f="textarea"),"function"==typeof a.fn.editabletypes[f]?(c=a.fn.editabletypes[f],d=this.sliceObj(b,this.objectKeys(c.defaults)),e=new c(d)):(a.error("Unknown type: "+f),!1)},supportsTransitions:function(){var a=document.body||document.documentElement,b=a.style,c="transition",d=["Moz","Webkit","Khtml","O","ms"];if("string"==typeof b[c])return!0;c=c.charAt(0).toUpperCase()+c.substr(1);for(var e=0;e"),this.tip().is(this.innerCss)?this.tip().append(this.$form):this.tip().find(this.innerCss).append(this.$form),this.renderForm()},hide:function(a){if(this.tip()&&this.tip().is(":visible")&&this.$element.hasClass("editable-open")){if(this.$form.data("editableform").isSaving)return this.delayedHide={reason:a},void 0;this.delayedHide=!1,this.$element.removeClass("editable-open"),this.innerHide(),this.$element.triggerHandler("hidden",a||"manual")}},innerShow:function(){},innerHide:function(){},toggle:function(a){this.container()&&this.tip()&&this.tip().is(":visible")?this.hide():this.show(a)},setPosition:function(){},save:function(a,b){this.$element.triggerHandler("save",b),this.hide("save")},option:function(a,b){this.options[a]=b,a in this.containerOptions?(this.containerOptions[a]=b,this.setContainerOption(a,b)):(this.formOptions[a]=b,this.$form&&this.$form.editableform("option",a,b))},setContainerOption:function(a,b){this.call("option",a,b)},destroy:function(){this.hide(),this.innerDestroy(),this.$element.off("destroyed"),this.$element.removeData("editableContainer")},innerDestroy:function(){},closeOthers:function(b){a(".editable-open").each(function(c,d){if(d!==b&&!a(d).find(b).length){var e=a(d),f=e.data("editableContainer");f&&("cancel"===f.options.onblur?e.data("editableContainer").hide("onblur"):"submit"===f.options.onblur&&e.data("editableContainer").tip().find("form").submit())}})},activate:function(){this.tip&&this.tip().is(":visible")&&this.$form&&this.$form.data("editableform").input.activate()}},a.fn.editableContainer=function(d){var e=arguments;return this.each(function(){var f=a(this),g="editableContainer",h=f.data(g),i="object"==typeof d&&d,j="inline"===i.mode?c:b;h||f.data(g,h=new j(this,i)),"string"==typeof d&&h[d].apply(h,Array.prototype.slice.call(e,1))})},a.fn.editableContainer.Popup=b,a.fn.editableContainer.Inline=c,a.fn.editableContainer.defaults={value:null,placement:"top",autohide:!0,onblur:"cancel",anim:!1,mode:"popup"},jQuery.event.special.destroyed={remove:function(a){a.handler&&a.handler()}}}(window.jQuery),function(a){"use strict";a.extend(a.fn.editableContainer.Inline.prototype,a.fn.editableContainer.Popup.prototype,{containerName:"editableform",innerCss:".editable-inline",containerClass:"editable-container editable-inline",initContainer:function(){this.$tip=a(""),this.options.anim||(this.options.anim=0)},splitOptions:function(){this.containerOptions={},this.formOptions=this.options},tip:function(){return this.$tip},innerShow:function(){this.$element.hide(),this.tip().insertAfter(this.$element).show()},innerHide:function(){this.$tip.hide(this.options.anim,a.proxy(function(){this.$element.show(),this.innerDestroy()},this))},innerDestroy:function(){this.tip()&&this.tip().empty().remove()}})}(window.jQuery),function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.editable.defaults,c,a.fn.editableutils.getConfigData(this.$element)),this.options.selector?this.initLive():this.init(),this.options.highlight&&!a.fn.editableutils.supportsTransitions()&&(this.options.highlight=!1)};b.prototype={constructor:b,init:function(){var b,c=!1;if(this.options.name=this.options.name||this.$element.attr("id"),this.options.scope=this.$element[0],this.input=a.fn.editableutils.createInput(this.options),this.input){switch(void 0===this.options.value||null===this.options.value?(this.value=this.input.html2value(a.trim(this.$element.html())),c=!0):(this.options.value=a.fn.editableutils.tryParseJson(this.options.value,!0),this.value="string"==typeof this.options.value?this.input.str2value(this.options.value):this.options.value),this.$element.addClass("editable"),"textarea"===this.input.type&&this.$element.addClass("editable-pre-wrapped"),"manual"!==this.options.toggle?(this.$element.addClass("editable-click"),this.$element.on(this.options.toggle+".editable",a.proxy(function(a){if(this.options.disabled||a.preventDefault(),"mouseenter"===this.options.toggle)this.show();else{var b="click"!==this.options.toggle;this.toggle(b)}},this))):this.$element.attr("tabindex",-1),"function"==typeof this.options.display&&(this.options.autotext="always"),this.options.autotext){case"always":b=!0;break;case"auto":b=!a.trim(this.$element.text()).length&&null!==this.value&&void 0!==this.value&&!c;break;default:b=!1}a.when(b?this.render():!0).then(a.proxy(function(){this.options.disabled?this.disable():this.enable(),this.$element.triggerHandler("init",this)},this))}},initLive:function(){var b=this.options.selector;this.options.selector=!1,this.options.autotext="never",this.$element.on(this.options.toggle+".editable",b,a.proxy(function(b){var c=a(b.target);c.data("editable")||(c.hasClass(this.options.emptyclass)&&c.empty(),c.editable(this.options).trigger(b))},this))},render:function(a){return this.options.display!==!1?this.input.value2htmlFinal?this.input.value2html(this.value,this.$element[0],this.options.display,a):"function"==typeof this.options.display?this.options.display.call(this.$element[0],this.value,a):this.input.value2html(this.value,this.$element[0]):void 0},enable:function(){this.options.disabled=!1,this.$element.removeClass("editable-disabled"),this.handleEmpty(this.isEmpty),"manual"!==this.options.toggle&&"-1"===this.$element.attr("tabindex")&&this.$element.removeAttr("tabindex")},disable:function(){this.options.disabled=!0,this.hide(),this.$element.addClass("editable-disabled"),this.handleEmpty(this.isEmpty),this.$element.attr("tabindex",-1)},toggleDisabled:function(){this.options.disabled?this.enable():this.disable()},option:function(b,c){return b&&"object"==typeof b?(a.each(b,a.proxy(function(b,c){this.option(a.trim(b),c)},this)),void 0):(this.options[b]=c,"disabled"===b?c?this.disable():this.enable():("value"===b&&this.setValue(c),this.container&&this.container.option(b,c),this.input.option&&this.input.option(b,c),void 0))},handleEmpty:function(b){this.options.display!==!1&&(this.isEmpty=void 0!==b?b:"function"==typeof this.input.isEmpty?this.input.isEmpty(this.$element):""===a.trim(this.$element.html()),this.options.disabled?this.isEmpty&&(this.$element.empty(),this.options.emptyclass&&this.$element.removeClass(this.options.emptyclass)):this.isEmpty?(this.$element.html(this.options.emptytext),this.options.emptyclass&&this.$element.addClass(this.options.emptyclass)):this.options.emptyclass&&this.$element.removeClass(this.options.emptyclass))},show:function(b){if(!this.options.disabled){if(this.container){if(this.container.tip().is(":visible"))return}else{var c=a.extend({},this.options,{value:this.value,input:this.input});this.$element.editableContainer(c),this.$element.on("save.internal",a.proxy(this.save,this)),this.container=this.$element.data("editableContainer")}this.container.show(b)}},hide:function(){this.container&&this.container.hide()},toggle:function(a){this.container&&this.container.tip().is(":visible")?this.hide():this.show(a)},save:function(a,b){if(this.options.unsavedclass){var c=!1;c=c||"function"==typeof this.options.url,c=c||this.options.display===!1,c=c||void 0!==b.response,c=c||this.options.savenochange&&this.input.value2str(this.value)!==this.input.value2str(b.newValue),c?this.$element.removeClass(this.options.unsavedclass):this.$element.addClass(this.options.unsavedclass)}if(this.options.highlight){var d=this.$element,e=d.css("background-color");d.css("background-color",this.options.highlight),setTimeout(function(){"transparent"===e&&(e=""),d.css("background-color",e),d.addClass("editable-bg-transition"),setTimeout(function(){d.removeClass("editable-bg-transition")},1700)},10)}this.setValue(b.newValue,!1,b.response)},validate:function(){return"function"==typeof this.options.validate?this.options.validate.call(this,this.value):void 0},setValue:function(b,c,d){this.value=c?this.input.str2value(b):b,this.container&&this.container.option("value",this.value),a.when(this.render(d)).then(a.proxy(function(){this.handleEmpty()},this))},activate:function(){this.container&&this.container.activate()},destroy:function(){this.disable(),this.container&&this.container.destroy(),this.input.destroy(),"manual"!==this.options.toggle&&(this.$element.removeClass("editable-click"),this.$element.off(this.options.toggle+".editable")),this.$element.off("save.internal"),this.$element.removeClass("editable editable-open editable-disabled"),this.$element.removeData("editable")}},a.fn.editable=function(c){var d={},e=arguments,f="editable";switch(c){case"validate":return this.each(function(){var b,c=a(this),e=c.data(f);e&&(b=e.validate())&&(d[e.options.name]=b)}),d;case"getValue":return 2===arguments.length&&arguments[1]===!0?d=this.eq(0).data(f).value:this.each(function(){var b=a(this),c=b.data(f);c&&void 0!==c.value&&null!==c.value&&(d[c.options.name]=c.input.value2submit(c.value))}),d;case"submit":var g=arguments[1]||{},h=this,i=this.editable("validate");if(a.isEmptyObject(i)){var j={};if(1===h.length){var k=h.data("editable"),l={name:k.options.name||"",value:k.input.value2submit(k.value),pk:"function"==typeof k.options.pk?k.options.pk.call(k.options.scope):k.options.pk};"function"==typeof k.options.params?l=k.options.params.call(k.options.scope,l):(k.options.params=a.fn.editableutils.tryParseJson(k.options.params,!0),a.extend(l,k.options.params)),j={url:k.options.url,data:l,type:"POST"},g.success=g.success||k.options.success,g.error=g.error||k.options.error}else{var m=this.editable("getValue");j={url:g.url,data:m,type:"POST"}}j.success="function"==typeof g.success?function(a){g.success.call(h,a,g)}:a.noop,j.error="function"==typeof g.error?function(){g.error.apply(h,arguments)}:a.noop,g.ajaxOptions&&a.extend(j,g.ajaxOptions),g.data&&a.extend(j.data,g.data),a.ajax(j)}else"function"==typeof g.error&&g.error.call(h,i);return this}return this.each(function(){var d=a(this),g=d.data(f),h="object"==typeof c&&c;return h&&h.selector?(g=new b(this,h),void 0):(g||d.data(f,g=new b(this,h)),"string"==typeof c&&g[c].apply(g,Array.prototype.slice.call(e,1)),void 0)})},a.fn.editable.defaults={type:"text",disabled:!1,toggle:"click",emptytext:"Empty",autotext:"auto",value:null,display:null,emptyclass:"editable-empty",unsavedclass:"editable-unsaved",selector:null,highlight:"#FFFF80"}}(window.jQuery),function(a){"use strict";a.fn.editabletypes={};var b=function(){};b.prototype={init:function(b,c,d){this.type=b,this.options=a.extend({},d,c)},prerender:function(){this.$tpl=a(this.options.tpl),this.$input=this.$tpl,this.$clear=null,this.error=null},render:function(){},value2html:function(b,c){a(c)[this.options.escape?"text":"html"](a.trim(b))},html2value:function(b){return a("
").html(b).text()},value2str:function(a){return a},str2value:function(a){return a},value2submit:function(a){return a},value2input:function(a){this.$input.val(a)},input2value:function(){return this.$input.val()},activate:function(){this.$input.is(":visible")&&this.$input.focus()},clear:function(){this.$input.val(null)},escape:function(b){return a("
").text(b).html()},autosubmit:function(){},destroy:function(){},setClass:function(){this.options.inputclass&&this.$input.addClass(this.options.inputclass)},setAttr:function(a){void 0!==this.options[a]&&null!==this.options[a]&&this.$input.attr(a,this.options[a])},option:function(a,b){this.options[a]=b}},b.defaults={tpl:"",inputclass:null,escape:!0,scope:null,showbuttons:!0},a.extend(a.fn.editabletypes,{abstractinput:b})}(window.jQuery),function(a){"use strict";var b=function(){};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{render:function(){var b=a.Deferred();return this.error=null,this.onSourceReady(function(){this.renderList(),b.resolve()},function(){this.error=this.options.sourceError,b.resolve()}),b.promise()},html2value:function(){return null},value2html:function(b,c,d,e){var f=a.Deferred(),g=function(){"function"==typeof d?d.call(c,b,this.sourceData,e):this.value2htmlFinal(b,c),f.resolve()};return null===b?g.call(this):this.onSourceReady(g,function(){f.resolve()}),f.promise()},onSourceReady:function(b,c){var d;if(a.isFunction(this.options.source)?(d=this.options.source.call(this.options.scope),this.sourceData=null):d=this.options.source,this.options.sourceCache&&a.isArray(this.sourceData))return b.call(this),void 0;try{d=a.fn.editableutils.tryParseJson(d,!1)}catch(e){return c.call(this),void 0}if("string"==typeof d){if(this.options.sourceCache){var f,g=d;if(a(document).data(g)||a(document).data(g,{}),f=a(document).data(g),f.loading===!1&&f.sourceData)return this.sourceData=f.sourceData,this.doPrepend(),b.call(this),void 0;if(f.loading===!0)return f.callbacks.push(a.proxy(function(){this.sourceData=f.sourceData,this.doPrepend(),b.call(this)},this)),f.err_callbacks.push(a.proxy(c,this)),void 0;f.loading=!0,f.callbacks=[],f.err_callbacks=[]}var h=a.extend({url:d,type:"get",cache:!1,dataType:"json",success:a.proxy(function(d){f&&(f.loading=!1),this.sourceData=this.makeArray(d),a.isArray(this.sourceData)?(f&&(f.sourceData=this.sourceData,a.each(f.callbacks,function(){this.call()})),this.doPrepend(),b.call(this)):(c.call(this),f&&a.each(f.err_callbacks,function(){this.call()}))},this),error:a.proxy(function(){c.call(this),f&&(f.loading=!1,a.each(f.err_callbacks,function(){this.call()}))},this)},this.options.sourceOptions);a.ajax(h)}else this.sourceData=this.makeArray(d),a.isArray(this.sourceData)?(this.doPrepend(),b.call(this)):c.call(this)},doPrepend:function(){null!==this.options.prepend&&void 0!==this.options.prepend&&(a.isArray(this.prependData)||(a.isFunction(this.options.prepend)&&(this.options.prepend=this.options.prepend.call(this.options.scope)),this.options.prepend=a.fn.editableutils.tryParseJson(this.options.prepend,!0),"string"==typeof this.options.prepend&&(this.options.prepend={"":this.options.prepend}),this.prependData=this.makeArray(this.options.prepend)),a.isArray(this.prependData)&&a.isArray(this.sourceData)&&(this.sourceData=this.prependData.concat(this.sourceData)))},renderList:function(){},value2htmlFinal:function(){},makeArray:function(b){var c,d,e,f,g=[];if(!b||"string"==typeof b)return null;if(a.isArray(b)){f=function(a,b){return d={value:a,text:b},c++>=2?!1:void 0};for(var h=0;h1&&(e.children&&(e.children=this.makeArray(e.children)),g.push(e))):g.push({value:e,text:e})}else a.each(b,function(a,b){g.push({value:a,text:b})});return g},option:function(a,b){this.options[a]=b,"source"===a&&(this.sourceData=null),"prepend"===a&&(this.prependData=null)}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{source:null,prepend:!1,sourceError:"Error when loading list",sourceCache:!0,sourceOptions:null}),a.fn.editabletypes.list=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("text",a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{render:function(){this.renderClear(),this.setClass(),this.setAttr("placeholder")},activate:function(){this.$input.is(":visible")&&(this.$input.focus(),a.fn.editableutils.setCursorPosition(this.$input.get(0),this.$input.val().length),this.toggleClear&&this.toggleClear())},renderClear:function(){this.options.clear&&(this.$clear=a(''),this.$input.after(this.$clear).css("padding-right",24).keyup(a.proxy(function(b){if(!~a.inArray(b.keyCode,[40,38,9,13,27])){clearTimeout(this.t);var c=this;this.t=setTimeout(function(){c.toggleClear(b)},100)}},this)).parent().css("position","relative"),this.$clear.click(a.proxy(this.clear,this)))},postrender:function(){},toggleClear:function(){if(this.$clear){var a=this.$input.val().length,b=this.$clear.is(":visible");a&&!b&&this.$clear.show(),!a&&b&&this.$clear.hide()}},clear:function(){this.$clear.hide(),this.$input.val("").focus()}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{tpl:'',placeholder:null,clear:!0}),a.fn.editabletypes.text=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("textarea",a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{render:function(){this.setClass(),this.setAttr("placeholder"),this.setAttr("rows"),this.$input.keydown(function(b){b.ctrlKey&&13===b.which&&a(this).closest("form").submit()})},activate:function(){a.fn.editabletypes.text.prototype.activate.call(this)}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{tpl:"",inputclass:"input-large",placeholder:null,rows:7}),a.fn.editabletypes.textarea=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("select",a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.list),a.extend(b.prototype,{renderList:function(){this.$input.empty();var b=function(c,d){var e;if(a.isArray(d))for(var f=0;f",e),d[f].children))):(e.value=d[f].value,d[f].disabled&&(e.disabled=!0),c.append(a("
";if(this.o.calendarWeeks){var c='';b+=c,this.picker.find(".datepicker-days thead tr:first-child").prepend(c)}for(;a'+k[this.o.language].daysMin[a++%7]+"";b+="",this.picker.find(".datepicker-days thead").append(b)},fillMonths:function(){for(var a="",b=0;12>b;)a+=''+k[this.o.language].monthsShort[b++]+"";this.picker.find(".datepicker-months td").html(a)},setRange:function(b){b&&b.length?this.range=a.map(b,function(a){return a.valueOf()}):delete this.range,this.fill()},getClassNames:function(b){var c=[],d=this.viewDate.getUTCFullYear(),e=this.viewDate.getUTCMonth(),f=this.date.valueOf(),g=new Date;return b.getUTCFullYear()d||b.getUTCFullYear()==d&&b.getUTCMonth()>e)&&c.push("new"),this.o.todayHighlight&&b.getUTCFullYear()==g.getFullYear()&&b.getUTCMonth()==g.getMonth()&&b.getUTCDate()==g.getDate()&&c.push("today"),f&&b.valueOf()==f&&c.push("active"),(b.valueOf()this.o.endDate||-1!==a.inArray(b.getUTCDay(),this.o.daysOfWeekDisabled))&&c.push("disabled"),this.range&&(b>this.range[0]&&b"),this.o.calendarWeeks)){var r=new Date(+m+864e5*((this.o.weekStart-m.getUTCDay()-7)%7)),s=new Date(+r+864e5*((11-r.getUTCDay())%7)),t=new Date(+(t=b(s.getUTCFullYear(),0,1))+864e5*((11-t.getUTCDay())%7)),u=(s-t)/864e5/7+1;q.push('")}p=this.getClassNames(m),p.push("day");var v=this.o.beforeShowDay(m);void 0===v?v={}:"boolean"==typeof v?v={enabled:v}:"string"==typeof v&&(v={classes:v}),v.enabled===!1&&p.push("disabled"),v.classes&&(p=p.concat(v.classes.split(/\s+/))),v.tooltip&&(c=v.tooltip),p=a.unique(p),q.push('"),m.getUTCDay()==this.o.weekEnd&&q.push(""),m.setUTCDate(m.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").empty().append(q.join(""));var w=this.date&&this.date.getUTCFullYear(),x=this.picker.find(".datepicker-months").find("th:eq(1)").text(e).end().find("span").removeClass("active");w&&w==e&&x.eq(this.date.getUTCMonth()).addClass("active"),(g>e||e>i)&&x.addClass("disabled"),e==g&&x.slice(0,h).addClass("disabled"),e==i&&x.slice(j+1).addClass("disabled"),q="",e=10*parseInt(e/10,10);var y=this.picker.find(".datepicker-years").find("th:eq(1)").text(e+"-"+(e+9)).end().find("td");e-=1;for(var z=-1;11>z;z++)q+='e||e>i?" disabled":"")+'">'+e+"",e+=1;y.html(q)},updateNavArrows:function(){if(this._allow_update){var a=new Date(this.viewDate),b=a.getUTCFullYear(),c=a.getUTCMonth();switch(this.viewMode){case 0:this.o.startDate!==-1/0&&b<=this.o.startDate.getUTCFullYear()&&c<=this.o.startDate.getUTCMonth()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),1/0!==this.o.endDate&&b>=this.o.endDate.getUTCFullYear()&&c>=this.o.endDate.getUTCMonth()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 1:case 2:this.o.startDate!==-1/0&&b<=this.o.startDate.getUTCFullYear()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),1/0!==this.o.endDate&&b>=this.o.endDate.getUTCFullYear()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"})}}},click:function(c){c.preventDefault();var d=a(c.target).closest("span, td, th");if(1==d.length)switch(d[0].nodeName.toLowerCase()){case"th":switch(d[0].className){case"datepicker-switch":this.showMode(1);break;case"prev":case"next":var e=l.modes[this.viewMode].navStep*("prev"==d[0].className?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveMonth(this.viewDate,e);break;case 1:case 2:this.viewDate=this.moveYear(this.viewDate,e)}this.fill();break;case"today":var f=new Date;f=b(f.getFullYear(),f.getMonth(),f.getDate(),0,0,0),this.showMode(-2);var g="linked"==this.o.todayBtn?null:"view";this._setDate(f,g);break;case"clear":var h;this.isInput?h=this.element:this.component&&(h=this.element.find("input")),h&&h.val("").change(),this._trigger("changeDate"),this.update(),this.o.autoclose&&this.hide()}break;case"span":if(!d.is(".disabled")){if(this.viewDate.setUTCDate(1),d.is(".month")){var i=1,j=d.parent().find("span").index(d),k=this.viewDate.getUTCFullYear();this.viewDate.setUTCMonth(j),this._trigger("changeMonth",this.viewDate),1===this.o.minViewMode&&this._setDate(b(k,j,i,0,0,0,0))}else{var k=parseInt(d.text(),10)||0,i=1,j=0;this.viewDate.setUTCFullYear(k),this._trigger("changeYear",this.viewDate),2===this.o.minViewMode&&this._setDate(b(k,j,i,0,0,0,0))}this.showMode(-1),this.fill()}break;case"td":if(d.is(".day")&&!d.is(".disabled")){var i=parseInt(d.text(),10)||1,k=this.viewDate.getUTCFullYear(),j=this.viewDate.getUTCMonth();d.is(".old")?0===j?(j=11,k-=1):j-=1:d.is(".new")&&(11==j?(j=0,k+=1):j+=1),this._setDate(b(k,j,i,0,0,0,0))}}},_setDate:function(a,b){b&&"date"!=b||(this.date=new Date(a)),b&&"view"!=b||(this.viewDate=new Date(a)),this.fill(),this.setValue(),this._trigger("changeDate");var c;this.isInput?c=this.element:this.component&&(c=this.element.find("input")),c&&(c.change(),!this.o.autoclose||b&&"date"!=b||this.hide())},moveMonth:function(a,b){if(!b)return a;var c,d,e=new Date(a.valueOf()),f=e.getUTCDate(),g=e.getUTCMonth(),h=Math.abs(b);if(b=b>0?1:-1,1==h)d=-1==b?function(){return e.getUTCMonth()==g}:function(){return e.getUTCMonth()!=c},c=g+b,e.setUTCMonth(c),(0>c||c>11)&&(c=(c+12)%12);else{for(var i=0;h>i;i++)e=this.moveMonth(e,b);c=e.getUTCMonth(),e.setUTCDate(f),d=function(){return c!=e.getUTCMonth()}}for(;d();)e.setUTCDate(--f),e.setUTCMonth(c);return e},moveYear:function(a,b){return this.moveMonth(a,12*b)},dateWithinRange:function(a){return a>=this.o.startDate&&a<=this.o.endDate},keydown:function(a){if(this.picker.is(":not(:visible)"))return 27==a.keyCode&&this.show(),void 0;var b,c,d,e=!1;switch(a.keyCode){case 27:this.hide(),a.preventDefault();break;case 37:case 39:if(!this.o.keyboardNavigation)break;b=37==a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.date,b),d=this.moveYear(this.viewDate,b)):a.shiftKey?(c=this.moveMonth(this.date,b),d=this.moveMonth(this.viewDate,b)):(c=new Date(this.date),c.setUTCDate(this.date.getUTCDate()+b),d=new Date(this.viewDate),d.setUTCDate(this.viewDate.getUTCDate()+b)),this.dateWithinRange(c)&&(this.date=c,this.viewDate=d,this.setValue(),this.update(),a.preventDefault(),e=!0);break;case 38:case 40:if(!this.o.keyboardNavigation)break;b=38==a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.date,b),d=this.moveYear(this.viewDate,b)):a.shiftKey?(c=this.moveMonth(this.date,b),d=this.moveMonth(this.viewDate,b)):(c=new Date(this.date),c.setUTCDate(this.date.getUTCDate()+7*b),d=new Date(this.viewDate),d.setUTCDate(this.viewDate.getUTCDate()+7*b)),this.dateWithinRange(c)&&(this.date=c,this.viewDate=d,this.setValue(),this.update(),a.preventDefault(),e=!0);break;case 13:this.hide(),a.preventDefault();break;case 9:this.hide()}if(e){this._trigger("changeDate");var f;this.isInput?f=this.element:this.component&&(f=this.element.find("input")),f&&f.change()}},showMode:function(a){a&&(this.viewMode=Math.max(this.o.minViewMode,Math.min(2,this.viewMode+a))),this.picker.find(">div").hide().filter(".datepicker-"+l.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()}};var f=function(b,c){this.element=a(b),this.inputs=a.map(c.inputs,function(a){return a.jquery?a[0]:a}),delete c.inputs,a(this.inputs).datepicker(c).bind("changeDate",a.proxy(this.dateUpdated,this)),this.pickers=a.map(this.inputs,function(b){return a(b).data("datepicker")}),this.updateDates()};f.prototype={updateDates:function(){this.dates=a.map(this.pickers,function(a){return a.date}),this.updateRanges()},updateRanges:function(){var b=a.map(this.dates,function(a){return a.valueOf()});a.each(this.pickers,function(a,c){c.setRange(b)})},dateUpdated:function(b){var c=a(b.target).data("datepicker"),d=c.getUTCDate(),e=a.inArray(b.target,this.inputs),f=this.inputs.length;if(-1!=e){if(d=0&&dthis.dates[e])for(;f>e&&d>this.dates[e];)this.pickers[e++].setUTCDate(d);this.updateDates()}},remove:function(){a.map(this.pickers,function(a){a.remove()}),delete this.element.data().datepicker}};var g=a.fn.datepicker,h=a.fn.datepicker=function(b){var g=Array.apply(null,arguments);g.shift();var h;return this.each(function(){var j=a(this),k=j.data("datepicker"),l="object"==typeof b&&b;if(!k){var m=c(this,"date"),n=a.extend({},i,m,l),o=d(n.language),p=a.extend({},i,o,m,l);if(j.is(".input-daterange")||p.inputs){var q={inputs:p.inputs||j.find("input").toArray()};j.data("datepicker",k=new f(this,a.extend(p,q)))}else j.data("datepicker",k=new e(this,p))}return"string"==typeof b&&"function"==typeof k[b]&&(h=k[b].apply(k,g),void 0!==h)?!1:void 0}),void 0!==h?h:this},i=a.fn.datepicker.defaults={autoclose:!1,beforeShowDay:a.noop,calendarWeeks:!1,clearBtn:!1,daysOfWeekDisabled:[],endDate:1/0,forceParse:!0,format:"mm/dd/yyyy",keyboardNavigation:!0,language:"en",minViewMode:0,rtl:!1,startDate:-1/0,startView:0,todayBtn:!1,todayHighlight:!1,weekStart:0},j=a.fn.datepicker.locale_opts=["format","rtl","weekStart"];a.fn.datepicker.Constructor=e;var k=a.fn.datepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",clear:"Clear"}},l={modes:[{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(a){return 0===a%4&&0!==a%100||0===a%400 +},getDaysInMonth:function(a,b){return[31,l.isLeapYear(a)?29:28,31,30,31,30,31,31,30,31,30,31][b]},validParts:/dd?|DD?|mm?|MM?|yy(?:yy)?/g,nonpunctuation:/[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,parseFormat:function(a){var b=a.replace(this.validParts,"\0").split("\0"),c=a.match(this.validParts);if(!b||!b.length||!c||0===c.length)throw new Error("Invalid date format.");return{separators:b,parts:c}},parseDate:function(c,d,f){if(c instanceof Date)return c;if("string"==typeof d&&(d=l.parseFormat(d)),/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(c)){var g,h,i=/([\-+]\d+)([dmwy])/,j=c.match(/([\-+]\d+)([dmwy])/g);c=new Date;for(var m=0;mb;)b+=12;for(b%=12,a.setUTCMonth(b);a.getUTCMonth()!=b;)a.setUTCDate(a.getUTCDate()-1);return a},d:function(a,b){return a.setUTCDate(b)}};r.M=r.MM=r.mm=r.m,r.dd=r.d,c=b(c.getFullYear(),c.getMonth(),c.getDate(),0,0,0);var s=d.parts.slice();if(j.length!=s.length&&(s=a(s).filter(function(b,c){return-1!==a.inArray(c,q)}).toArray()),j.length==s.length){for(var m=0,t=s.length;t>m;m++){if(n=parseInt(j[m],10),g=s[m],isNaN(n))switch(g){case"MM":o=a(k[f].months).filter(function(){var a=this.slice(0,j[m].length),b=j[m].slice(0,a.length);return a==b}),n=a.inArray(o[0],k[f].months)+1;break;case"M":o=a(k[f].monthsShort).filter(function(){var a=this.slice(0,j[m].length),b=j[m].slice(0,a.length);return a==b}),n=a.inArray(o[0],k[f].monthsShort)+1}p[g]=n}for(var u,m=0;m=g;g++)f.length&&b.push(f.shift()),b.push(e[c.parts[g]]);return b.join("")},headTemplate:'',contTemplate:'',footTemplate:''};l.template='
 
'+u+""+m.getUTCDate()+"
'+l.headTemplate+""+l.footTemplate+"
"+"
"+'
'+''+l.headTemplate+l.contTemplate+l.footTemplate+"
"+"
"+'
'+''+l.headTemplate+l.contTemplate+l.footTemplate+"
"+"
"+"
",a.fn.datepicker.DPGlobal=l,a.fn.datepicker.noConflict=function(){return a.fn.datepicker=g,this},a(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(b){var c=a(this);c.data("datepicker")||(b.preventDefault(),h.call(c,"show"))}),a(function(){h.call(a('[data-provide="datepicker-inline"]'))})}(window.jQuery),function(a){"use strict";a.fn.bdatepicker=a.fn.datepicker.noConflict(),a.fn.datepicker||(a.fn.datepicker=a.fn.bdatepicker);var b=function(a){this.init("date",a,b.defaults),this.initPicker(a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{initPicker:function(b,c){this.options.viewformat||(this.options.viewformat=this.options.format),b.datepicker=a.fn.editableutils.tryParseJson(b.datepicker,!0),this.options.datepicker=a.extend({},c.datepicker,b.datepicker,{format:this.options.viewformat}),this.options.datepicker.language=this.options.datepicker.language||"en",this.dpg=a.fn.bdatepicker.DPGlobal,this.parsedFormat=this.dpg.parseFormat(this.options.format),this.parsedViewFormat=this.dpg.parseFormat(this.options.viewformat)},render:function(){this.$input.bdatepicker(this.options.datepicker),this.options.clear&&(this.$clear=a('').html(this.options.clear).click(a.proxy(function(a){a.preventDefault(),a.stopPropagation(),this.clear()},this)),this.$tpl.parent().append(a('
').append(this.$clear)))},value2html:function(a,c){var d=a?this.dpg.formatDate(a,this.parsedViewFormat,this.options.datepicker.language):"";b.superclass.value2html.call(this,d,c)},html2value:function(a){return this.parseDate(a,this.parsedViewFormat)},value2str:function(a){return a?this.dpg.formatDate(a,this.parsedFormat,this.options.datepicker.language):""},str2value:function(a){return this.parseDate(a,this.parsedFormat)},value2submit:function(a){return this.value2str(a)},value2input:function(a){this.$input.bdatepicker("update",a)},input2value:function(){return this.$input.data("datepicker").date},activate:function(){},clear:function(){this.$input.data("datepicker").date=null,this.$input.find(".active").removeClass("active"),this.options.showbuttons||this.$input.closest("form").submit()},autosubmit:function(){this.$input.on("mouseup",".day",function(b){if(!a(b.currentTarget).is(".old")&&!a(b.currentTarget).is(".new")){var c=a(this).closest("form");setTimeout(function(){c.submit()},200)}})},parseDate:function(a,b){var c,d=null;return a&&(d=this.dpg.parseDate(a,b,this.options.datepicker.language),"string"==typeof a&&(c=this.dpg.formatDate(d,b,this.options.datepicker.language),a!==c&&(d=null))),d}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{tpl:'
',inputclass:null,format:"yyyy-mm-dd",viewformat:null,datepicker:{weekStart:0,startView:0,minViewMode:0,autoclose:!1},clear:"× clear"}),a.fn.editabletypes.date=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("datefield",a,b.defaults),this.initPicker(a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.date),a.extend(b.prototype,{render:function(){this.$input=this.$tpl.find("input"),this.setClass(),this.setAttr("placeholder"),this.$tpl.bdatepicker(this.options.datepicker),this.$input.off("focus keydown"),this.$input.keyup(a.proxy(function(){this.$tpl.removeData("date"),this.$tpl.bdatepicker("update")},this))},value2input:function(a){this.$input.val(a?this.dpg.formatDate(a,this.parsedViewFormat,this.options.datepicker.language):""),this.$tpl.bdatepicker("update")},input2value:function(){return this.html2value(this.$input.val())},activate:function(){a.fn.editabletypes.text.prototype.activate.call(this)},autosubmit:function(){}}),b.defaults=a.extend({},a.fn.editabletypes.date.defaults,{tpl:'
',inputclass:"input-small",datepicker:{weekStart:0,startView:0,minViewMode:0,autoclose:!0}}),a.fn.editabletypes.datefield=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("datetime",a,b.defaults),this.initPicker(a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{initPicker:function(b,c){this.options.viewformat||(this.options.viewformat=this.options.format),b.datetimepicker=a.fn.editableutils.tryParseJson(b.datetimepicker,!0),this.options.datetimepicker=a.extend({},c.datetimepicker,b.datetimepicker,{format:this.options.viewformat}),this.options.datetimepicker.language=this.options.datetimepicker.language||"en",this.dpg=a.fn.datetimepicker.DPGlobal,this.parsedFormat=this.dpg.parseFormat(this.options.format,this.options.formatType),this.parsedViewFormat=this.dpg.parseFormat(this.options.viewformat,this.options.formatType)},render:function(){this.$input.datetimepicker(this.options.datetimepicker),this.$input.on("changeMode",function(){var b=a(this).closest("form").parent();setTimeout(function(){b.triggerHandler("resize")},0)}),this.options.clear&&(this.$clear=a('').html(this.options.clear).click(a.proxy(function(a){a.preventDefault(),a.stopPropagation(),this.clear()},this)),this.$tpl.parent().append(a('
').append(this.$clear)))},value2html:function(a,c){var d=a?this.dpg.formatDate(this.toUTC(a),this.parsedViewFormat,this.options.datetimepicker.language,this.options.formatType):"";return c?(b.superclass.value2html.call(this,d,c),void 0):d},html2value:function(a){var b=this.parseDate(a,this.parsedViewFormat);return b?this.fromUTC(b):null},value2str:function(a){return a?this.dpg.formatDate(this.toUTC(a),this.parsedFormat,this.options.datetimepicker.language,this.options.formatType):""},str2value:function(a){var b=this.parseDate(a,this.parsedFormat);return b?this.fromUTC(b):null},value2submit:function(a){return this.value2str(a)},value2input:function(a){a&&this.$input.data("datetimepicker").setDate(a)},input2value:function(){var a=this.$input.data("datetimepicker");return a.date?a.getDate():null},activate:function(){},clear:function(){this.$input.data("datetimepicker").date=null,this.$input.find(".active").removeClass("active"),this.options.showbuttons||this.$input.closest("form").submit()},autosubmit:function(){this.$input.on("mouseup",".minute",function(){var b=a(this).closest("form");setTimeout(function(){b.submit()},200)})},toUTC:function(a){return a?new Date(a.valueOf()-6e4*a.getTimezoneOffset()):a},fromUTC:function(a){return a?new Date(a.valueOf()+6e4*a.getTimezoneOffset()):a},parseDate:function(a,b){var c,d=null;return a&&(d=this.dpg.parseDate(a,b,this.options.datetimepicker.language,this.options.formatType),"string"==typeof a&&(c=this.dpg.formatDate(d,b,this.options.datetimepicker.language,this.options.formatType),a!==c&&(d=null))),d}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{tpl:'
',inputclass:null,format:"yyyy-mm-dd hh:ii",formatType:"standard",viewformat:null,datetimepicker:{todayHighlight:!1,autoclose:!1},clear:"× clear"}),a.fn.editabletypes.datetime=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("datetimefield",a,b.defaults),this.initPicker(a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.datetime),a.extend(b.prototype,{render:function(){this.$input=this.$tpl.find("input"),this.setClass(),this.setAttr("placeholder"),this.$tpl.datetimepicker(this.options.datetimepicker),this.$input.off("focus keydown"),this.$input.keyup(a.proxy(function(){this.$tpl.removeData("date"),this.$tpl.datetimepicker("update")},this))},value2input:function(a){this.$input.val(this.value2html(a)),this.$tpl.datetimepicker("update")},input2value:function(){return this.html2value(this.$input.val())},activate:function(){a.fn.editabletypes.text.prototype.activate.call(this)},autosubmit:function(){}}),b.defaults=a.extend({},a.fn.editabletypes.datetime.defaults,{tpl:'
',inputclass:"input-medium",datetimepicker:{todayHighlight:!1,autoclose:!0}}),a.fn.editabletypes.datetimefield=b}(window.jQuery); \ No newline at end of file diff --git a/js/lib/bootstrap-sprockets.js b/js/lib/bootstrap-sprockets.js deleted file mode 100644 index 1abde496..00000000 --- a/js/lib/bootstrap-sprockets.js +++ /dev/null @@ -1,12 +0,0 @@ -//= require ./bootstrap/affix -//= require ./bootstrap/alert -//= require ./bootstrap/button -//= require ./bootstrap/carousel -//= require ./bootstrap/collapse -//= require ./bootstrap/dropdown -//= require ./bootstrap/tab -//= require ./bootstrap/transition -//= require ./bootstrap/scrollspy -//= require ./bootstrap/modal -//= require ./bootstrap/tooltip -//= require ./bootstrap/popover diff --git a/js/lib/bootstrap.js b/js/lib/bootstrap.js deleted file mode 100644 index 30409f48..00000000 --- a/js/lib/bootstrap.js +++ /dev/null @@ -1,2107 +0,0 @@ -/* ======================================================================== - * Bootstrap: affix.js v3.2.0 - * http://getbootstrap.com/javascript/#affix - * ======================================================================== - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // AFFIX CLASS DEFINITION - // ====================== - - var Affix = function (element, options) { - this.options = $.extend({}, Affix.DEFAULTS, options) - - this.$target = $(this.options.target) - .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) - .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) - - this.$element = $(element) - this.affixed = - this.unpin = - this.pinnedOffset = null - - this.checkPosition() - } - - Affix.VERSION = '3.2.0' - - Affix.RESET = 'affix affix-top affix-bottom' - - Affix.DEFAULTS = { - offset: 0, - target: window - } - - Affix.prototype.getPinnedOffset = function () { - if (this.pinnedOffset) return this.pinnedOffset - this.$element.removeClass(Affix.RESET).addClass('affix') - var scrollTop = this.$target.scrollTop() - var position = this.$element.offset() - return (this.pinnedOffset = position.top - scrollTop) - } - - Affix.prototype.checkPositionWithEventLoop = function () { - setTimeout($.proxy(this.checkPosition, this), 1) - } - - Affix.prototype.checkPosition = function () { - if (!this.$element.is(':visible')) return - - var scrollHeight = $(document).height() - var scrollTop = this.$target.scrollTop() - var position = this.$element.offset() - var offset = this.options.offset - var offsetTop = offset.top - var offsetBottom = offset.bottom - - if (typeof offset != 'object') offsetBottom = offsetTop = offset - if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) - if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) - - var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false : - offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' : - offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false - - if (this.affixed === affix) return - if (this.unpin != null) this.$element.css('top', '') - - var affixType = 'affix' + (affix ? '-' + affix : '') - var e = $.Event(affixType + '.bs.affix') - - this.$element.trigger(e) - - if (e.isDefaultPrevented()) return - - this.affixed = affix - this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null - - this.$element - .removeClass(Affix.RESET) - .addClass(affixType) - .trigger($.Event(affixType.replace('affix', 'affixed'))) - - if (affix == 'bottom') { - this.$element.offset({ - top: scrollHeight - this.$element.height() - offsetBottom - }) - } - } - - - // AFFIX PLUGIN DEFINITION - // ======================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.affix') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.affix', (data = new Affix(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.affix - - $.fn.affix = Plugin - $.fn.affix.Constructor = Affix - - - // AFFIX NO CONFLICT - // ================= - - $.fn.affix.noConflict = function () { - $.fn.affix = old - return this - } - - - // AFFIX DATA-API - // ============== - - $(window).on('load', function () { - $('[data-spy="affix"]').each(function () { - var $spy = $(this) - var data = $spy.data() - - data.offset = data.offset || {} - - if (data.offsetBottom) data.offset.bottom = data.offsetBottom - if (data.offsetTop) data.offset.top = data.offsetTop - - Plugin.call($spy, data) - }) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: alert.js v3.2.0 - * http://getbootstrap.com/javascript/#alerts - * ======================================================================== - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // ALERT CLASS DEFINITION - // ====================== - - var dismiss = '[data-dismiss="alert"]' - var Alert = function (el) { - $(el).on('click', dismiss, this.close) - } - - Alert.VERSION = '3.2.0' - - Alert.prototype.close = function (e) { - var $this = $(this) - var selector = $this.attr('data-target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - var $parent = $(selector) - - if (e) e.preventDefault() - - if (!$parent.length) { - $parent = $this.hasClass('alert') ? $this : $this.parent() - } - - $parent.trigger(e = $.Event('close.bs.alert')) - - if (e.isDefaultPrevented()) return - - $parent.removeClass('in') - - function removeElement() { - // detach from parent, fire event then clean up data - $parent.detach().trigger('closed.bs.alert').remove() - } - - $.support.transition && $parent.hasClass('fade') ? - $parent - .one('bsTransitionEnd', removeElement) - .emulateTransitionEnd(150) : - removeElement() - } - - - // ALERT PLUGIN DEFINITION - // ======================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.alert') - - if (!data) $this.data('bs.alert', (data = new Alert(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - var old = $.fn.alert - - $.fn.alert = Plugin - $.fn.alert.Constructor = Alert - - - // ALERT NO CONFLICT - // ================= - - $.fn.alert.noConflict = function () { - $.fn.alert = old - return this - } - - - // ALERT DATA-API - // ============== - - $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: button.js v3.2.0 - * http://getbootstrap.com/javascript/#buttons - * ======================================================================== - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // BUTTON PUBLIC CLASS DEFINITION - // ============================== - - var Button = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Button.DEFAULTS, options) - this.isLoading = false - } - - Button.VERSION = '3.2.0' - - Button.DEFAULTS = { - loadingText: 'loading...' - } - - Button.prototype.setState = function (state) { - var d = 'disabled' - var $el = this.$element - var val = $el.is('input') ? 'val' : 'html' - var data = $el.data() - - state = state + 'Text' - - if (data.resetText == null) $el.data('resetText', $el[val]()) - - $el[val](data[state] == null ? this.options[state] : data[state]) - - // push to event loop to allow forms to submit - setTimeout($.proxy(function () { - if (state == 'loadingText') { - this.isLoading = true - $el.addClass(d).attr(d, d) - } else if (this.isLoading) { - this.isLoading = false - $el.removeClass(d).removeAttr(d) - } - }, this), 0) - } - - Button.prototype.toggle = function () { - var changed = true - var $parent = this.$element.closest('[data-toggle="buttons"]') - - if ($parent.length) { - var $input = this.$element.find('input') - if ($input.prop('type') == 'radio') { - if ($input.prop('checked') && this.$element.hasClass('active')) changed = false - else $parent.find('.active').removeClass('active') - } - if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') - } - - if (changed) this.$element.toggleClass('active') - } - - - // BUTTON PLUGIN DEFINITION - // ======================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.button') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.button', (data = new Button(this, options))) - - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - - var old = $.fn.button - - $.fn.button = Plugin - $.fn.button.Constructor = Button - - - // BUTTON NO CONFLICT - // ================== - - $.fn.button.noConflict = function () { - $.fn.button = old - return this - } - - - // BUTTON DATA-API - // =============== - - $(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - Plugin.call($btn, 'toggle') - e.preventDefault() - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: carousel.js v3.2.0 - * http://getbootstrap.com/javascript/#carousel - * ======================================================================== - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // CAROUSEL CLASS DEFINITION - // ========================= - - var Carousel = function (element, options) { - this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this)) - this.$indicators = this.$element.find('.carousel-indicators') - this.options = options - this.paused = - this.sliding = - this.interval = - this.$active = - this.$items = null - - this.options.pause == 'hover' && this.$element - .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) - .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) - } - - Carousel.VERSION = '3.2.0' - - Carousel.DEFAULTS = { - interval: 5000, - pause: 'hover', - wrap: true - } - - Carousel.prototype.keydown = function (e) { - switch (e.which) { - case 37: this.prev(); break - case 39: this.next(); break - default: return - } - - e.preventDefault() - } - - Carousel.prototype.cycle = function (e) { - e || (this.paused = false) - - this.interval && clearInterval(this.interval) - - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) - - return this - } - - Carousel.prototype.getItemIndex = function (item) { - this.$items = item.parent().children('.item') - return this.$items.index(item || this.$active) - } - - Carousel.prototype.to = function (pos) { - var that = this - var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) - - if (pos > (this.$items.length - 1) || pos < 0) return - - if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" - if (activeIndex == pos) return this.pause().cycle() - - return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) - } - - Carousel.prototype.pause = function (e) { - e || (this.paused = true) - - if (this.$element.find('.next, .prev').length && $.support.transition) { - this.$element.trigger($.support.transition.end) - this.cycle(true) - } - - this.interval = clearInterval(this.interval) - - return this - } - - Carousel.prototype.next = function () { - if (this.sliding) return - return this.slide('next') - } - - Carousel.prototype.prev = function () { - if (this.sliding) return - return this.slide('prev') - } - - Carousel.prototype.slide = function (type, next) { - var $active = this.$element.find('.item.active') - var $next = next || $active[type]() - var isCycling = this.interval - var direction = type == 'next' ? 'left' : 'right' - var fallback = type == 'next' ? 'first' : 'last' - var that = this - - if (!$next.length) { - if (!this.options.wrap) return - $next = this.$element.find('.item')[fallback]() - } - - if ($next.hasClass('active')) return (this.sliding = false) - - var relatedTarget = $next[0] - var slideEvent = $.Event('slide.bs.carousel', { - relatedTarget: relatedTarget, - direction: direction - }) - this.$element.trigger(slideEvent) - if (slideEvent.isDefaultPrevented()) return - - this.sliding = true - - isCycling && this.pause() - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) - $nextIndicator && $nextIndicator.addClass('active') - } - - var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" - if ($.support.transition && this.$element.hasClass('slide')) { - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - $active - .one('bsTransitionEnd', function () { - $next.removeClass([type, direction].join(' ')).addClass('active') - $active.removeClass(['active', direction].join(' ')) - that.sliding = false - setTimeout(function () { - that.$element.trigger(slidEvent) - }, 0) - }) - .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000) - } else { - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger(slidEvent) - } - - isCycling && this.cycle() - - return this - } - - - // CAROUSEL PLUGIN DEFINITION - // ========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.carousel') - var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) - var action = typeof option == 'string' ? option : options.slide - - if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) - if (typeof option == 'number') data.to(option) - else if (action) data[action]() - else if (options.interval) data.pause().cycle() - }) - } - - var old = $.fn.carousel - - $.fn.carousel = Plugin - $.fn.carousel.Constructor = Carousel - - - // CAROUSEL NO CONFLICT - // ==================== - - $.fn.carousel.noConflict = function () { - $.fn.carousel = old - return this - } - - - // CAROUSEL DATA-API - // ================= - - $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { - var href - var $this = $(this) - var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 - if (!$target.hasClass('carousel')) return - var options = $.extend({}, $target.data(), $this.data()) - var slideIndex = $this.attr('data-slide-to') - if (slideIndex) options.interval = false - - Plugin.call($target, options) - - if (slideIndex) { - $target.data('bs.carousel').to(slideIndex) - } - - e.preventDefault() - }) - - $(window).on('load', function () { - $('[data-ride="carousel"]').each(function () { - var $carousel = $(this) - Plugin.call($carousel, $carousel.data()) - }) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: collapse.js v3.2.0 - * http://getbootstrap.com/javascript/#collapse - * ======================================================================== - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // COLLAPSE PUBLIC CLASS DEFINITION - // ================================ - - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Collapse.DEFAULTS, options) - this.transitioning = null - - if (this.options.parent) this.$parent = $(this.options.parent) - if (this.options.toggle) this.toggle() - } - - Collapse.VERSION = '3.2.0' - - Collapse.DEFAULTS = { - toggle: true - } - - Collapse.prototype.dimension = function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - Collapse.prototype.show = function () { - if (this.transitioning || this.$element.hasClass('in')) return - - var startEvent = $.Event('show.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - var actives = this.$parent && this.$parent.find('> .panel > .in') - - if (actives && actives.length) { - var hasData = actives.data('bs.collapse') - if (hasData && hasData.transitioning) return - Plugin.call(actives, 'hide') - hasData || actives.data('bs.collapse', null) - } - - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - .addClass('collapsing')[dimension](0) - - this.transitioning = 1 - - var complete = function () { - this.$element - .removeClass('collapsing') - .addClass('collapse in')[dimension]('') - this.transitioning = 0 - this.$element - .trigger('shown.bs.collapse') - } - - if (!$.support.transition) return complete.call(this) - - var scrollSize = $.camelCase(['scroll', dimension].join('-')) - - this.$element - .one('bsTransitionEnd', $.proxy(complete, this)) - .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) - } - - Collapse.prototype.hide = function () { - if (this.transitioning || !this.$element.hasClass('in')) return - - var startEvent = $.Event('hide.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - var dimension = this.dimension() - - this.$element[dimension](this.$element[dimension]())[0].offsetHeight - - this.$element - .addClass('collapsing') - .removeClass('collapse') - .removeClass('in') - - this.transitioning = 1 - - var complete = function () { - this.transitioning = 0 - this.$element - .trigger('hidden.bs.collapse') - .removeClass('collapsing') - .addClass('collapse') - } - - if (!$.support.transition) return complete.call(this) - - this.$element - [dimension](0) - .one('bsTransitionEnd', $.proxy(complete, this)) - .emulateTransitionEnd(350) - } - - Collapse.prototype.toggle = function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } - - - // COLLAPSE PLUGIN DEFINITION - // ========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.collapse') - var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) - - if (!data && options.toggle && option == 'show') option = !option - if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.collapse - - $.fn.collapse = Plugin - $.fn.collapse.Constructor = Collapse - - - // COLLAPSE NO CONFLICT - // ==================== - - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } - - - // COLLAPSE DATA-API - // ================= - - $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { - var href - var $this = $(this) - var target = $this.attr('data-target') - || e.preventDefault() - || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 - var $target = $(target) - var data = $target.data('bs.collapse') - var option = data ? 'toggle' : $this.data() - var parent = $this.attr('data-parent') - var $parent = parent && $(parent) - - if (!data || !data.transitioning) { - if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') - $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') - } - - Plugin.call($target, option) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: dropdown.js v3.2.0 - * http://getbootstrap.com/javascript/#dropdowns - * ======================================================================== - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // DROPDOWN CLASS DEFINITION - // ========================= - - var backdrop = '.dropdown-backdrop' - var toggle = '[data-toggle="dropdown"]' - var Dropdown = function (element) { - $(element).on('click.bs.dropdown', this.toggle) - } - - Dropdown.VERSION = '3.2.0' - - Dropdown.prototype.toggle = function (e) { - var $this = $(this) - - if ($this.is('.disabled, :disabled')) return - - var $parent = getParent($this) - var isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { - // if mobile we use a backdrop because click events don't delegate - $('