Commit 431e57a1 authored by Evren Kutar's avatar Evren Kutar

search directive

basic ngdocs preparation
parent d1c4af40
...@@ -352,4 +352,11 @@ module.exports = function (grunt) { ...@@ -352,4 +352,11 @@ module.exports = function (grunt) {
'uglify:branch' 'uglify:branch'
]); ]);
}); });
grunt.registerTask('dgeni', 'Generate docs via dgeni.', function() {
var Dgeni = require('dgeni');
var done = this.async();
var dgeni = new Dgeni([require('./docs/docs_conf')]);
dgeni.generate().then(done);
});
}; };
\ No newline at end of file
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
...@@ -14,7 +15,6 @@ var app = angular.module( ...@@ -14,7 +15,6 @@ var app = angular.module(
'ngRoute', 'ngRoute',
'ngSanitize', 'ngSanitize',
'ngCookies', 'ngCookies',
'general',
'formService', 'formService',
'ulakbus.dashboard', 'ulakbus.dashboard',
'ulakbus.auth', 'ulakbus.auth',
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
...@@ -7,7 +8,7 @@ ...@@ -7,7 +8,7 @@
'use strict'; 'use strict';
var auth = angular.module('ulakbus.auth', ['ngRoute', 'schemaForm', 'ngCookies', 'general']); var auth = angular.module('ulakbus.auth', ['ngRoute', 'schemaForm', 'ngCookies']);
auth.controller('LoginCtrl', function ($scope, $q, $timeout, $routeParams, Generator, LoginService) { auth.controller('LoginCtrl', function ($scope, $q, $timeout, $routeParams, Generator, LoginService) {
$scope.url = 'login'; $scope.url = 'login';
$scope.form_params = {}; $scope.form_params = {};
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
...@@ -31,10 +32,9 @@ auth.factory('LoginService', function ($http, $rootScope, $location, $log, Sessi ...@@ -31,10 +32,9 @@ auth.factory('LoginService', function ($http, $rootScope, $location, $log, Sessi
$log.info("logout"); $log.info("logout");
return $http.post(RESTURL.url + 'logout', {}).success(function (data) { return $http.post(RESTURL.url + 'logout', {}).success(function (data) {
$rootScope.loggedInUser = false; $rootScope.loggedInUser = false;
$log.info("loggedout");
$location.path("/login"); $location.path("/login");
}); });
$log.info("loggedout");
}; };
loginService.isAuthenticated = function () { loginService.isAuthenticated = function () {
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
...@@ -7,159 +8,212 @@ ...@@ -7,159 +8,212 @@
'use strict'; 'use strict';
var crud = angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']); angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
/** /**
* * @name CrudUtility
*/ * @description
crud.service('CrudUtility', function () { * Crud Utility is a service to provide functionality for Crud controllers
return { * @returns {object}
generateParam: function (scope, routeParams, cmd) { */
// define api request url path .service('CrudUtility', function ($log) {
scope.url = routeParams.wf; return {
// why do this?? /**
angular.forEach(routeParams, function (value, key) { * @name generateParam
if (key.indexOf('_id') > -1 && key !== 'param_id') { * @description
scope.param = key; * generateParam is a function to generate required params to post backend api.
scope.param_id = value; *
} * @param scope
}); * @param routeParams
scope.form_params = { * @param cmd
cmd: cmd, * @returns {*}
model: routeParams.model, */
param: scope.param || routeParams.param, generateParam: function (scope, routeParams, cmd) {
id: scope.param_id || routeParams.param_id, // define api request url path
wf: routeParams.wf, scope.url = routeParams.wf;
object_id: routeParams.key // why do this??
angular.forEach(routeParams, function (value, key) {
if (key.indexOf('_id') > -1 && key !== 'param_id') {
scope.param = key;
scope.param_id = value;
}
});
scope.form_params = {
cmd: cmd,
model: routeParams.model,
param: scope.param || routeParams.param,
id: scope.param_id || routeParams.param_id,
wf: routeParams.wf,
object_id: routeParams.key
};
scope.model = scope.form_params.model;
scope.wf = scope.form_params.wf;
scope.param = scope.form_params.param;
scope.param_id = scope.form_params.id;
return scope;
},
/**
* @name listPageItems
* @description
* listPageItems is a function to prepare objects to list in list page.
*
* @param scope
* @param pageData
*/
listPageItems: function (scope, pageData) {
angular.forEach(pageData, function (value, key) {
scope[key] = value;
});
angular.forEach(scope.objects, function (value, key) {
if (value!=='-1') {
var linkIndexes = [];
angular.forEach(value.actions, function (v, k) {
if (v.show_as === 'link') {linkIndexes= v.fields}
});
angular.forEach(value.fields, function (v, k) {
scope.objects[key].fields[k] = {type: linkIndexes.indexOf(k) > -1 ? 'link' : 'str', content: v};
});
}
});
$log.debug(scope.objects);
}
}
})
/**
*
*/
.controller('CRUDCtrl', function ($scope, $routeParams, Generator, CrudUtility) {
// get required params by calling CrudUtility.generateParam function
CrudUtility.generateParam($scope, $routeParams);
Generator.get_wf($scope);
})
/**
* @name CRUDListFormCtrl
* @description
* CRUDListFormCtrl is the main controller for crud module
* Based on the client_cmd parameter it generates its scope items.
* client_cmd can be in ['show', 'list', 'form', 'reload', 'refresh']
* There are 3 directives to manipulate controllers scope objects in crud.html
*
* @returns {object}
*/
.controller('CRUDListFormCtrl', function ($scope, $rootScope, $location, $http, $log, $modal, $timeout, Generator, $routeParams, CrudUtility) {
if ($routeParams.cmd === 'show') {
CrudUtility.generateParam($scope, $routeParams, $routeParams.cmd);
// todo: refactor createListObjects func
var createListObjects = function () {
angular.forEach($scope.object, function (value, key) {
if (typeof value == 'object') {
$scope.listobjects[key] = value;
delete $scope.object[key];
}
});
}; };
scope.model = scope.form_params.model;
scope.wf = scope.form_params.wf; $scope.listobjects = {};
scope.param = scope.form_params.param;
scope.param_id = scope.form_params.id; var pageData = Generator.getPageData();
return scope; if (pageData.pageData === true) {
}, $scope.object = pageData.object;
listPageItems: function (scope, pageData) { Generator.setPageData({pageData: false});
angular.forEach(pageData, function (value, key) { }
scope[key] = value; else {
}); // call generator's get_single_item func
Generator.get_single_item($scope).then(function (res) {
$scope.object = res.data.object;
$scope.model = $routeParams.model;
});
}
createListObjects();
} }
}
});
/** if ($routeParams.cmd === 'form' || $routeParams.cmd === 'list') {
* // function to set scope objects
*/ var setpageobjects = function (data) {
crud.controller('CRUDCtrl', function ($scope, $routeParams, Generator, CrudUtility) { CrudUtility.listPageItems($scope, data);
// get required params by calling CrudUtility.generateParam function Generator.generate($scope, data);
CrudUtility.generateParam($scope, $routeParams); Generator.setPageData({pageData: false});
Generator.get_wf($scope); };
});
/** // get pageData from service
* var pageData = Generator.getPageData();
*/
crud.controller('CRUDListFormCtrl', function ($scope, $rootScope, $location, $http, $log, $modal, $timeout, Generator, $routeParams, CrudUtility) {
if ($routeParams.cmd==='show') {
CrudUtility.generateParam($scope, $routeParams, $routeParams.cmd);
// todo: refactor createListObjects func
var createListObjects = function () {
angular.forEach($scope.object, function (value, key) {
if (typeof value == 'object') {
$scope.listobjects[key] = value;
delete $scope.object[key];
}
});
};
$scope.listobjects = {}; // if pageData exists do not call get_wf function and manipulate page with pageData
if (pageData.pageData === true) {
$log.debug('pagedata', pageData.pageData);
CrudUtility.generateParam($scope, pageData, $routeParams.cmd);
setpageobjects(pageData, pageData);
}
// if pageData didn't defined or is {pageData: false} go get data from api with get_wf function
if (pageData.pageData === undefined || pageData.pageData === false) {
CrudUtility.generateParam($scope, $routeParams, $routeParams.cmd);
Generator.get_wf($scope);
}
var pageData = Generator.getPageData(); // we use form generator for generic forms. this makes form's scope to confuse on the path to generate form
if (pageData.pageData === true) { // object by its name. to manage to locate the form to controllers scope we use a directive called form locator
$scope.object = pageData.object; // a bit dirty way to find form working on but solves our problem
Generator.setPageData({pageData: false}); $scope.$on('formLocator', function (event) {
} $scope.formgenerated = event.targetScope.formgenerated;
else {
// call generator's get_single_item func
Generator.get_single_item($scope).then(function (res) {
$scope.object = res.data.object;
$scope.model = $routeParams.model;
}); });
}
createListObjects();
}
if ($routeParams.cmd==='form' || $routeParams.cmd==='list') {
// function to set scope objects
var setpageobjects = function (data) {
CrudUtility.listPageItems($scope, data);
Generator.generate($scope, data);
Generator.setPageData({pageData: false});
};
// get pageData from service $scope.onSubmit = function (form) {
var pageData = Generator.getPageData(); $scope.$broadcast('schemaFormValidate');
if (form.$valid) {
Generator.submit($scope);
}
};
$scope.do_action = function (key, action) {
Generator.doItemAction($scope, key, action);
};
// if pageData exists do not call get_wf function and manipulate page with pageData //$scope.searchForm = ['searchbox', {type: "submit", title: "Ara"}];
if (pageData.pageData === true) { //$scope.searchSchema = {
$log.debug('pagedata', pageData.pageData); // type: "object",
CrudUtility.generateParam($scope, pageData, $routeParams.cmd); // properties: {searchbox: {type: "string", minLength: 2, title: "Ara", "x-schema-form": {placeholder: "Arama kriteri giriniz..."}}},
setpageobjects(pageData, pageData); // required: ['searchbox']
} //};
// if pageData didn't defined or is {pageData: false} go get data from api with get_wf function //$scope.searchModel = {searchbox: ''};
if (pageData.pageData === undefined || pageData.pageData === false) { //$scope.searchSubmit = function (form) {
CrudUtility.generateParam($scope, $routeParams, $routeParams.cmd); // if(form.$valid) {
Generator.get_wf($scope); // Generator.submit({url: 'search', model: $scope.searchModel, form_params: {}});
// }
//}
} }
// we use form generator for generic forms. this makes form's scope to confuse on the path to generate form })
// object by its name. to manage to locate the form to controllers scope we use a directive called form locator
// a bit dirty way to find form working on but solves our problem .directive('crudListDirective', function () {
$scope.$on('formLocator', function(event) { return {
$scope.formgenerated = event.targetScope.formgenerated; templateUrl: 'components/crud/templates/list.html',
}); restrict: 'E',
replace: true
$scope.onSubmit = function (form) { };
$scope.$broadcast('schemaFormValidate'); })
if (form.$valid) {
Generator.submit($scope); .directive('crudFormDirective', function () {
} return {
templateUrl: 'components/crud/templates/form.html',
restrict: 'E',
replace: true
}; };
})
$scope.do_action = function (key, action) { .directive('crudShowDirective', function () {
Generator.doItemAction($scope, key, action); return {
templateUrl: 'components/crud/templates/show.html',
restrict: 'E',
replace: true
}; };
} })
}); .directive('formLocator', function () {
return {
crud.directive('crudListDirective', function () { link: function (scope) {
return { scope.$emit('formLocator');
templateUrl: 'components/crud/templates/list.html', }
restrict: 'E',
replace: true
};
});
crud.directive('crudFormDirective', function () {
return {
templateUrl: 'components/crud/templates/form.html',
restrict: 'E',
replace: true
};
});
crud.directive('crudShowDirective', function () {
return {
templateUrl: 'components/crud/templates/show.html',
restrict: 'E',
replace: true
};
});
crud.directive('formLocator', function() {
return {
link: function(scope) {
scope.$emit('formLocator');
} }
} });
}); \ No newline at end of file
\ No newline at end of file
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
......
<crud-show-directive ng-if="object"></crud-show-directive> <crud-show-directive ng-if="object"></crud-show-directive>
<crud-form-directive ng-if="forms"></crud-form-directive> <crud-form-directive ng-if="forms"></crud-form-directive>
<hr> <hr class="col-md-12">
<crud-list-directive ng-if="objects"></crud-list-directive> <crud-list-directive ng-if="objects"></crud-list-directive>
\ No newline at end of file
...@@ -34,8 +34,4 @@ ...@@ -34,8 +34,4 @@
</div> </div>
<div class="buttons-on-bottom"></div> <div class="buttons-on-bottom"></div>
<!--<button id="submitbutton" type="button" class="btn btn-primary" ng-click="onSubmit(formgenerated)">Kaydet</button>-->
<!-- <button type="button" class="btn btn-warning">Düzenle</button> todo: make it conditional -->
<!-- <button type="button" class="btn btn-danger">İptal</button> todo: turn back to previous page -->
</div> </div>
\ No newline at end of file
<div class="starter-template container"> <div class="starter-template container">
<!--<h1>{{model}}--> <search-directive ng-if="meta['allow_search']===true"></search-directive>
<!--<a href="{{addLink}}">--> <div class="clearfix"></div>
<!--<button type="button" class="btn btn-primary">Ekle</button>--> <h1>{{form_params.model || form_params.wf}}</h1>
<!--</a>-->
<!--</h1>-->
<div class="row" ng-if="!objects[1]"> <div class="row" ng-if="!objects[1]">
<div class="col-md-12"> <div class="col-md-12">
<p class="no-content">Listelenecek içerik yok.</p> <p class="no-content">Listelenecek içerik yok.</p>
...@@ -19,7 +17,7 @@ ...@@ -19,7 +17,7 @@
Hepsini Seç Hepsini Seç
</label> </label>
</td> </td>
<td ng-repeat="value in objects[0]" ng-if="objects[0]!='-1'">{{ objects }}</td> <td ng-repeat="value in objects[0]" ng-if="objects[0]!='-1'">{{values }}</td>
<td ng-if="objects[0]=='-1'">{{ schema.title||model}}</td> <td ng-if="objects[0]=='-1'">{{ schema.title||model}}</td>
<td>action</td> <td>action</td>
</tr> </tr>
...@@ -32,25 +30,19 @@ ...@@ -32,25 +30,19 @@
</label> </label>
</td> </td>
<td scope="row" style="text-align:center">{{$index}}</td> <td scope="row" style="text-align:center">{{$index}}</td>
<!-- below 2 of object will not be listed there for ng repeat loops 2 less -->
<td ng-repeat="field in object.fields track by $index" ng-if="objects[0]=='-1'">
<a ng-repeat="action in object.actions" ng-href="javascript:void(0)"
ng-if="action.show_as==='link'&&action.fields.indexOf($parent.$index)>-1" ng-click="do_action(object.key, action)">{{field}}</a>
</td>
<td ng-repeat="field in object.fields track by $index" ng-if="objects[0]!='-1'"> <td ng-repeat="field in object.fields track by $index">
<a ng-repeat="action in object.actions" ng-href="javascript:void(0)" <a ng-href="javascript:void(0)"
ng-if="action.show_as==='link'&&action.fields.indexOf($index)>-1" ng-if="field.type==='link'"
ng-click="do_action(object.key, action)">{{field}}</a> ng-click="do_action(object.key, action)">{{field.content}}</a>
<span ng-if="$index!=1">{{field}}</span> <span ng-if="field.type==='str'">{{field.content}}</span>
</td> </td>
<td> <td>
<button class="btn btn-primary" style="margin-right: 5px;" ng-repeat="action in object.actions" <button class="btn btn-primary" style="margin-right: 5px;" ng-repeat="action in object.actions"
ng-if="action.show_as==='button'" ng-click="do_action(object.key, action)">{{action ng-if="action.show_as==='button'" ng-click="do_action(object.key, action)">{{action
.name}} .name}}
</button> </button>
<!--<a ng-href="javascript:void(0)" ng-repeat="action in object.actions"-->
<!--ng-if="action.show_as==='link'" ng-click="do_action(object.key, action)">{{action.name}}</a>-->
<br> <br>
</td> </td>
</tr> </tr>
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
......
...@@ -64,27 +64,27 @@ ...@@ -64,27 +64,27 @@
</div> </div>
</div> </div>
<script src="bower_components/angular/angular.js"></script> <script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/jquery/dist/jquery.js"></script> <script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script> <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script> <script src="bower_components/angular-route/angular-route.min.js"></script>
<script src="bower_components/angular-cookies/angular-cookies.js"></script> <script src="bower_components/angular-cookies/angular-cookies.min.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script> <script src="bower_components/angular-resource/angular-resource.min.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap.js"></script> <script src="bower_components/angular-bootstrap/ui-bootstrap.min.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script> <script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script> <script src="bower_components/angular-sanitize/angular-sanitize.min.js"></script>
<script src="bower_components/tv4/tv4.js"></script> <script src="bower_components/tv4/tv4.js"></script>
<script src="bower_components/objectpath/lib/ObjectPath.js"></script> <script src="bower_components/objectpath/lib/ObjectPath.js"></script>
<script src="bower_components/angular-schema-form/dist/schema-form.js"></script> <script src="bower_components/angular-schema-form/dist/schema-form.min.js"></script>
<script src="bower_components/angular-schema-form/dist/bootstrap-decorator.js"></script> <script src="bower_components/angular-schema-form/dist/bootstrap-decorator.min.js"></script>
<script src="bower_components/angular-gettext/dist/angular-gettext.js"></script> <script src="bower_components/angular-gettext/dist/angular-gettext.min.js"></script>
<!-- TODO: check all js and remove unused --> <!-- TODO: check all js and remove unused -->
<script src="bower_components/json3/lib/json3.js"></script> <!--<script src="bower_components/json3/lib/json3.js"></script>-->
<script src="bower_components/angular-loading-bar/build/loading-bar.js"></script> <script src="bower_components/angular-loading-bar/build/loading-bar.min.js"></script>
<script src="bower_components/metisMenu/dist/metisMenu.js"></script> <script src="bower_components/metisMenu/dist/metisMenu.min.js"></script>
<script src="bower_components/Chart.js/Chart.js"></script> <!--<script src="bower_components/Chart.js/Chart.js"></script>-->
<script src="shared/translations.js"></script> <script src="shared/translations.js"></script>
<script src="tmp/templates.js"></script> <script src="tmp/templates.js"></script>
<script src="app.js"></script> <script src="app.js"></script>
...@@ -92,8 +92,7 @@ ...@@ -92,8 +92,7 @@
<script src="shared/scripts/jquery-ui.min.js"></script> <script src="shared/scripts/jquery-ui.min.js"></script>
<script src="shared/directives.js"></script> <script src="shared/directives.js"></script>
<script src="zetalib/interceptors.js"></script> <script src="zetalib/interceptors.js"></script>
<script src="zetalib/general.js"></script> <script src="zetalib/form_service.js"></script>
<script src="zetalib/forms/form_service.js"></script>
<!-- components --> <!-- components -->
...@@ -103,7 +102,6 @@ ...@@ -103,7 +102,6 @@
<script src="components/crud/crud_controller.js"></script> <script src="components/crud/crud_controller.js"></script>
<script src="components/debug/debug_controller.js"></script> <script src="components/debug/debug_controller.js"></script>
<script src="components/devSettings/devSettings_controller.js"></script> <script src="components/devSettings/devSettings_controller.js"></script>
<script src="components/wf/wf_controller.js"></script>
<script src="components/uitemplates/uitemplates.js"></script> <script src="components/uitemplates/uitemplates.js"></script>
<script src="components/error_pages/error_controller.js"></script> <script src="components/error_pages/error_controller.js"></script>
<script src="components/version/interpolate-filter.js"></script> <script src="components/version/interpolate-filter.js"></script>
......
...@@ -72,27 +72,27 @@ ...@@ -72,27 +72,27 @@
</div> </div>
<!-- @if NODE_ENV == 'DEVELOPMENT' --> <!-- @if NODE_ENV == 'DEVELOPMENT' -->
<script src="bower_components/angular/angular.js"></script> <script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/jquery/dist/jquery.js"></script> <script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script> <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script> <script src="bower_components/angular-route/angular-route.min.js"></script>
<script src="bower_components/angular-cookies/angular-cookies.js"></script> <script src="bower_components/angular-cookies/angular-cookies.min.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script> <script src="bower_components/angular-resource/angular-resource.min.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap.js"></script> <script src="bower_components/angular-bootstrap/ui-bootstrap.min.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script> <script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script> <script src="bower_components/angular-sanitize/angular-sanitize.min.js"></script>
<script src="bower_components/tv4/tv4.js"></script> <script src="bower_components/tv4/tv4.js"></script>
<script src="bower_components/objectpath/lib/ObjectPath.js"></script> <script src="bower_components/objectpath/lib/ObjectPath.js"></script>
<script src="bower_components/angular-schema-form/dist/schema-form.js"></script> <script src="bower_components/angular-schema-form/dist/schema-form.min.js"></script>
<script src="bower_components/angular-schema-form/dist/bootstrap-decorator.js"></script> <script src="bower_components/angular-schema-form/dist/bootstrap-decorator.min.js"></script>
<script src="bower_components/angular-gettext/dist/angular-gettext.js"></script> <script src="bower_components/angular-gettext/dist/angular-gettext.min.js"></script>
<!-- TODO: check all js and remove unused --> <!-- TODO: check all js and remove unused -->
<script src="bower_components/json3/lib/json3.js"></script> <!--<script src="bower_components/json3/lib/json3.js"></script>-->
<script src="bower_components/angular-loading-bar/build/loading-bar.js"></script> <script src="bower_components/angular-loading-bar/build/loading-bar.min.js"></script>
<script src="bower_components/metisMenu/dist/metisMenu.js"></script> <script src="bower_components/metisMenu/dist/metisMenu.min.js"></script>
<script src="bower_components/Chart.js/Chart.js"></script> <!--<script src="bower_components/Chart.js/Chart.js"></script>-->
<script src="shared/translations.js"></script> <script src="shared/translations.js"></script>
<script src="tmp/templates.js"></script> <script src="tmp/templates.js"></script>
<script src="app.js"></script> <script src="app.js"></script>
...@@ -100,8 +100,7 @@ ...@@ -100,8 +100,7 @@
<script src="shared/scripts/jquery-ui.min.js"></script> <script src="shared/scripts/jquery-ui.min.js"></script>
<script src="shared/directives.js"></script> <script src="shared/directives.js"></script>
<script src="zetalib/interceptors.js"></script> <script src="zetalib/interceptors.js"></script>
<script src="zetalib/general.js"></script> <script src="zetalib/form_service.js"></script>
<script src="zetalib/forms/form_service.js"></script>
<!-- components --> <!-- components -->
...@@ -111,7 +110,6 @@ ...@@ -111,7 +110,6 @@
<script src="components/crud/crud_controller.js"></script> <script src="components/crud/crud_controller.js"></script>
<script src="components/debug/debug_controller.js"></script> <script src="components/debug/debug_controller.js"></script>
<script src="components/devSettings/devSettings_controller.js"></script> <script src="components/devSettings/devSettings_controller.js"></script>
<script src="components/wf/wf_controller.js"></script>
<script src="components/uitemplates/uitemplates.js"></script> <script src="components/uitemplates/uitemplates.js"></script>
<script src="components/error_pages/error_controller.js"></script> <script src="components/error_pages/error_controller.js"></script>
<script src="components/version/interpolate-filter.js"></script> <script src="components/version/interpolate-filter.js"></script>
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
...@@ -14,7 +15,6 @@ var app = angular.module( ...@@ -14,7 +15,6 @@ var app = angular.module(
'ngRoute', 'ngRoute',
'ngSanitize', 'ngSanitize',
'ngCookies', 'ngCookies',
'general',
'formService', 'formService',
'ulakbus.dashboard', 'ulakbus.dashboard',
'ulakbus.auth', 'ulakbus.auth',
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
...@@ -10,366 +11,414 @@ ...@@ -10,366 +11,414 @@
*/ */
app.directive('logout', function ($http, $location, RESTURL) { app.directive('logout', function ($http, $location, RESTURL) {
return { return {
link: function ($scope, $element, $rootScope) { link: function ($scope, $element, $rootScope) {
$element.on('click', function () { $element.on('click', function () {
$http.post(RESTURL.url + 'logout', {}).then(function () { $http.post(RESTURL.url + 'logout', {}).then(function () {
$rootScope.loggedInUser = false; $rootScope.loggedInUser = false;
$location.path("/login"); $location.path("/login");
}); });
});
}
};
});
/**
* headerNotification directive for header
*/
app.directive('headerNotification', function ($http, $rootScope, $cookies, $interval, RESTURL) {
return {
templateUrl: 'shared/templates/directives/header-notification.html',
restrict: 'E',
replace: true,
link: function ($scope) {
$scope.groupNotifications = function (notifications) {
// notification categories:
// 1: tasks, 2: messages, 3: announcements, 4: recents
$scope.notifications = {1: [], 2: [], 3: [], 4: []};
angular.forEach(notifications, function (value, key) {
$scope.notifications[value.type].push(value);
});
};
$scope.getNotifications = function () {
// ignore loading bar here
$http.get(RESTURL.url + "notify", {ignoreLoadingBar: true}).success(function (data) {
$scope.groupNotifications(data.notifications);
$rootScope.$broadcast("notifications", $scope.notifications);
}); });
}; }
};
$scope.getNotifications(); })
// check notifications every 5 seconds /**
$interval(function () { * headerNotification directive for header
if ($cookies.get("notificate") == "on") { */
$scope.getNotifications();
} .directive('headerNotification', function ($http, $rootScope, $cookies, $interval, RESTURL) {
}, 5000); return {
templateUrl: 'shared/templates/directives/header-notification.html',
// when clicked mark as read notification restrict: 'E',
// it can be list of notifications replace: true,
$scope.markAsRead = function (items) { link: function ($scope) {
$http.post(RESTURL.url + "notify", {ignoreLoadingBar: true, read: [items]}) $scope.groupNotifications = function (notifications) {
.success(function (data) { // notification categories:
// 1: tasks, 2: messages, 3: announcements, 4: recents
$scope.notifications = {1: [], 2: [], 3: [], 4: []};
angular.forEach(notifications, function (value, key) {
$scope.notifications[value.type].push(value);
});
};
$scope.getNotifications = function () {
// ignore loading bar here
$http.get(RESTURL.url + "notify", {ignoreLoadingBar: true}).success(function (data) {
$scope.groupNotifications(data.notifications); $scope.groupNotifications(data.notifications);
$rootScope.$broadcast("notifications", $scope.notifications); $rootScope.$broadcast("notifications", $scope.notifications);
}); });
}; };
// if markasread triggered outside the directive
$scope.$on("markasread", function (event, data) {
$scope.markAsRead(data);
});
}
};
});
/** $scope.getNotifications();
* collapseMenu directive
* toggle collapses sidebar menu when clicked menu button
*/
app.directive('collapseMenu', function ($timeout, $window) {
return {
templateUrl: 'shared/templates/directives/menuCollapse.html',
restrict: 'E',
replace: true,
scope: {},
controller: function ($scope, $rootScope) {
$rootScope.collapsed = false;
$rootScope.sidebarPinned = false;
$scope.collapseToggle = function () {
if ($window.innerWidth > '768') {
if ($rootScope.collapsed === false) {
jQuery(".sidebar").css("width", "62px");
jQuery(".manager-view").css("width", "calc(100% - 62px)");
$rootScope.collapsed = true;
$rootScope.sidebarPinned = false;
} else {
jQuery("span.menu-text, span.arrow, .sidebar footer").fadeIn(400); // check notifications every 5 seconds
jQuery(".sidebar").css("width", "250px"); $interval(function () {
jQuery(".manager-view").css("width", "calc(100% - 250px)"); if ($cookies.get("notificate") == "on") {
$rootScope.collapsed = false; $scope.getNotifications();
$rootScope.sidebarPinned = true; }
}, 5000);
// when clicked mark as read notification
// it can be list of notifications
$scope.markAsRead = function (items) {
$http.post(RESTURL.url + "notify", {ignoreLoadingBar: true, read: [items]})
.success(function (data) {
$scope.groupNotifications(data.notifications);
$rootScope.$broadcast("notifications", $scope.notifications);
});
};
// if markasread triggered outside the directive
$scope.$on("markasread", function (event, data) {
$scope.markAsRead(data);
});
}
};
})
/**
*
*/
.directive('searchDirective', function (Generator, $log) {
return {
templateUrl: 'shared/templates/directives/search.html',
restrict: 'E',
replace: true,
link: function ($scope) {
$scope.searchForm = [{key: 'searchbox', htmlClass: "pull-left"}, {type: "submit", title: "Ara", htmlClass: "pull-left"}];
$scope.searchSchema = {
type: "object",
properties: {
searchbox: {
type: "string",
minLength: 2,
title: "Ara",
"x-schema-form": {placeholder: "Arama kriteri giriniz..."}
}
},
required: ['searchbox']
};
$scope.searchModel = {searchbox: ''};
$scope.searchSubmit = function (form) {
$scope.$broadcast('schemaFormValidate');
if (form.$valid) {
var searchparams = {
url: $scope.wf,
token: $scope.$parent.token,
object_id: $scope.$parent.object_id,
form_params: {
model: $scope.$parent.form_params.model,
cmd: $scope.$parent.reload_cmd,
flow: $scope.$parent.form_params.flow,
param: 'query',
id: $scope.searchModel.searchbox
}
};
Generator.submit(searchparams);
} }
} }
}; }
};
$timeout(function () { })
$scope.collapseToggle();
});
} /**
}; * collapseMenu directive
}); * toggle collapses sidebar menu when clicked menu button
*/
.directive('collapseMenu', function ($timeout, $window) {
return {
templateUrl: 'shared/templates/directives/menuCollapse.html',
restrict: 'E',
replace: true,
scope: {},
controller: function ($scope, $rootScope) {
$rootScope.collapsed = false;
$rootScope.sidebarPinned = false;
$scope.collapseToggle = function () {
if ($window.innerWidth > '768') {
if ($rootScope.collapsed === false) {
jQuery(".sidebar").css("width", "62px");
jQuery(".manager-view").css("width", "calc(100% - 62px)");
$rootScope.collapsed = true;
$rootScope.sidebarPinned = false;
} else {
jQuery("span.menu-text, span.arrow, .sidebar footer").fadeIn(400);
jQuery(".sidebar").css("width", "250px");
jQuery(".manager-view").css("width", "calc(100% - 250px)");
$rootScope.collapsed = false;
$rootScope.sidebarPinned = true;
}
}
};
/** $timeout(function () {
* headerSubmenu directive $scope.collapseToggle();
*/ });
}
};
})
/**
* headerSubmenu directive
*/
.directive('headerSubMenu', function ($location) {
return {
templateUrl: 'shared/templates/directives/header-sub-menu.html',
restrict: 'E',
//controller: "CRUDAddEditCtrl",
replace: true,
link: function ($scope) {
$scope.$on('$routeChangeStart', function () {
$scope.style = $location.path() === '/dashboard' ? 'width:calc(100% - 300px);' : 'width:%100 !important;';
});
}
};
})
/**
* breadcrumb directive
* produces breadcrumb with related links
*/
.directive('headerBreadcrumb', function () {
return {
templateUrl: 'shared/templates/directives/header-breadcrumb.html',
restrict: 'E',
replace: true
};
})
/**
* selected user directive
*/
.directive('selectedUser', function () {
return {
templateUrl: 'shared/templates/directives/selected-user.html',
restrict: 'E',
replace: false,
link: function ($scope, $rootScope) {
$scope.selectedUser = $rootScope.selectedUser;
}
};
})
/**
* sidebar directive
* changes breadcrumb when an item selected
* consists of menu items of related user or transaction
* controller communicates with dashboard controller to shape menu items and authz
*/
.directive('sidebar', ['$location', function () {
return {
templateUrl: 'shared/templates/directives/sidebar.html',
restrict: 'E',
replace: true,
scope: {},
controller: function ($scope, $rootScope, $cookies, $route, $http, RESTURL, $location, $window, $timeout) {
$scope.prepareMenu = function (menuItems) {
var newMenuItems = {};
angular.forEach(menuItems, function (value, key) {
angular.forEach(value, function (v, k) {
newMenuItems[k] = v;
});
});
return newMenuItems;
};
app.directive('headerSubMenu', function ($location) { var sidebarmenu = $('#side-menu');
return { sidebarmenu.metisMenu();
templateUrl: 'shared/templates/directives/header-sub-menu.html', $http.get(RESTURL.url + 'menu/')
restrict: 'E', .success(function (data) {
//controller: "CRUDAddEditCtrl", $scope.allMenuItems = angular.copy(data);
replace: true,
link: function ($scope) { // regroup menu items based on their category
$scope.$on('$routeChangeStart', function () { function reGroupMenuItems(items, baseCategory) {
$scope.style = $location.path() === '/dashboard' ? 'width:calc(100% - 300px);' : 'width:%100 !important;'; var newItems = {};
}); angular.forEach(items, function (value, key) {
} newItems[value.kategori] = newItems[value.kategori] || [];
}; value['baseCategory'] = baseCategory;
}); // todo: generate urls here
//value['url'] = '#/wf' + value.wf;
//if (value.model) {
// value['url'] += '/model/' + value.model;
//}
value['wf'] = value.url.split('/')[0];
value['model'] = value.url.split('/')[1];
newItems[value.kategori].push(value);
});
return newItems;
}
angular.forEach($scope.allMenuItems, function (value, key) {
$scope.allMenuItems[key] = reGroupMenuItems(value, key);
});
/** // broadcast for authorized menu items, consume in dashboard to show search inputs and/or
* breadcrumb directive // related items
* produces breadcrumb with related links $rootScope.$broadcast("authz", data);
*/
app.directive('headerBreadcrumb', function () { $scope.menuItems = $scope.prepareMenu({other: $scope.allMenuItems.other});
return {
templateUrl: 'shared/templates/directives/header-breadcrumb.html',
restrict: 'E',
replace: true
};
});
/** // if selecteduser on cookie then add related part to the menu
* selected user directive
*/
app.directive('selectedUser', function () { //if ($cookies.get("selectedUserType")) {
return { // $scope.menuItems[$cookies.get("selectedUserType")] = $scope.allMenuItems[$cookies.get("selectedUserType")];
templateUrl: 'shared/templates/directives/selected-user.html', //}
restrict: 'E',
replace: false,
link: function ($scope, $rootScope) {
$scope.selectedUser = $rootScope.selectedUser;
}
};
});
/** $timeout(function () {
* sidebar directive sidebarmenu.metisMenu()
* changes breadcrumb when an item selected
* consists of menu items of related user or transaction
* controller communicates with dashboard controller to shape menu items and authz
*/
app.directive('sidebar', ['$location', function () {
return {
templateUrl: 'shared/templates/directives/sidebar.html',
restrict: 'E',
replace: true,
scope: {},
controller: function ($scope, $rootScope, $cookies, $route, $http, RESTURL, $location, $window, $timeout) {
$scope.prepareMenu = function (menuItems) {
var newMenuItems = {};
angular.forEach(menuItems, function (value, key) {
angular.forEach(value, function (v, k) {
newMenuItems[k] = v;
});
});
return newMenuItems;
};
var sidebarmenu = $('#side-menu');
sidebarmenu.metisMenu();
$http.get(RESTURL.url + 'menu/')
.success(function (data) {
$scope.allMenuItems = angular.copy(data);
// regroup menu items based on their category
function reGroupMenuItems(items, baseCategory) {
var newItems = {};
angular.forEach(items, function (value, key) {
newItems[value.kategori] = newItems[value.kategori] || [];
value['baseCategory'] = baseCategory;
// todo: generate urls here
//value['url'] = '#/wf' + value.wf;
//if (value.model) {
// value['url'] += '/model/' + value.model;
//}
value['wf'] = value.url.split('/')[0];
value['model'] = value.url.split('/')[1];
newItems[value.kategori].push(value);
}); });
return newItems;
}
angular.forEach($scope.allMenuItems, function (value, key) {
$scope.allMenuItems[key] = reGroupMenuItems(value, key);
}); });
// broadcast for authorized menu items, consume in dashboard to show search inputs and/or // changing menu items by listening for broadcast
// related items
$rootScope.$broadcast("authz", data);
$scope.menuItems = $scope.prepareMenu({other: $scope.allMenuItems.other});
// if selecteduser on cookie then add related part to the menu
//if ($cookies.get("selectedUserType")) {
// $scope.menuItems[$cookies.get("selectedUserType")] = $scope.allMenuItems[$cookies.get("selectedUserType")];
//}
$scope.$on("menuitems", function (event, data) {
var menu = {other: $scope.allMenuItems.other};
menu[data] = $scope.allMenuItems[data];
$scope.menuItems = $scope.prepareMenu(menu);
$timeout(function () { $timeout(function () {
sidebarmenu.metisMenu() sidebarmenu.metisMenu()
}); });
}); });
// changing menu items by listening for broadcast $scope.openSidebar = function () {
if ($window.innerWidth > '768') {
$scope.$on("menuitems", function (event, data) { if ($rootScope.sidebarPinned === false) {
var menu = {other: $scope.allMenuItems.other}; jQuery("span.menu-text, span.arrow, .sidebar footer, #side-menu").fadeIn(400);
menu[data] = $scope.allMenuItems[data]; jQuery(".sidebar").css("width", "250px");
$scope.menuItems = $scope.prepareMenu(menu); jQuery(".manager-view").css("width", "calc(100% - 250px)");
$timeout(function () { $rootScope.collapsed = false;
sidebarmenu.metisMenu() }
});
});
$scope.openSidebar = function () {
if ($window.innerWidth > '768') {
if ($rootScope.sidebarPinned === false) {
jQuery("span.menu-text, span.arrow, .sidebar footer, #side-menu").fadeIn(400);
jQuery(".sidebar").css("width", "250px");
jQuery(".manager-view").css("width", "calc(100% - 250px)");
$rootScope.collapsed = false;
} }
} };
};
$scope.closeSidebar = function () {
$scope.closeSidebar = function () { if ($window.innerWidth > '768') {
if ($window.innerWidth > '768') { if ($rootScope.sidebarPinned === false) {
if ($rootScope.sidebarPinned === false) { jQuery(".sidebar").css("width", "62px");
jQuery(".sidebar").css("width", "62px"); jQuery(".manager-view").css("width", "calc(100% - 62px)");
jQuery(".manager-view").css("width", "calc(100% - 62px)"); $rootScope.collapsed = true;
$rootScope.collapsed = true; }
}
}
};
$rootScope.$watch(function ($rootScope) {
return $rootScope.section;
},
function (newindex, oldindex) {
if (newindex > -1) {
$scope.menuItems = [$scope.allMenuItems[newindex]];
$scope.collapseVar = 1;
} }
}); };
$scope.selectedMenu = $location.path(); $rootScope.$watch(function ($rootScope) {
$scope.collapseVar = 0; return $rootScope.section;
$scope.multiCollapseVar = 0; },
function (newindex, oldindex) {
if (newindex > -1) {
$scope.menuItems = [$scope.allMenuItems[newindex]];
$scope.collapseVar = 1;
}
});
$scope.check = function (x) { $scope.selectedMenu = $location.path();
$scope.collapseVar = 0;
$scope.multiCollapseVar = 0;
if (x === $scope.collapseVar) { $scope.check = function (x) {
$scope.collapseVar = 0;
} else {
$scope.collapseVar = x;
}
};
// breadcrumb function changes breadcrumb items and itemlist must be list
$scope.breadcrumb = function (itemlist, $event) {
//if ($event.target.href==location.href) {
// $route.reload();
//}
$rootScope.breadcrumblinks = itemlist;
// showSaveButton is used for to show or not to show save button on top of the page
// todo: remove button
$rootScope.showSaveButton = false;
};
$scope.multiCheck = function (y) {
if (y === $scope.multiCollapseVar) {
$scope.multiCollapseVar = 0;
} else {
$scope.multiCollapseVar = y;
}
};
}
};
}]);
app.directive('stats', function () {
return {
templateUrl: 'shared/templates/directives/stats.html',
restrict: 'E',
replace: true,
scope: {
'model': '=',
'comments': '@',
'number': '@',
'name': '@',
'colour': '@',
'details': '@',
'type': '@',
'goto': '@'
}
};
});
/** if (x === $scope.collapseVar) {
* header menu notifications directive $scope.collapseVar = 0;
*/ } else {
$scope.collapseVar = x;
app.directive('notifications', function () { }
return {
templateUrl: 'shared/templates/directives/notifications.html',
restrict: 'E',
replace: true
};
});
/** };
* msgbox directive
*/
app.directive('msgbox', function () { // breadcrumb function changes breadcrumb items and itemlist must be list
return { $scope.breadcrumb = function (itemlist, $event) {
templateUrl: 'shared/templates/directives/msgbox.html', //if ($event.target.href==location.href) {
restrict: 'E', // $route.reload();
replace: false //}
}; $rootScope.breadcrumblinks = itemlist;
}); // showSaveButton is used for to show or not to show save button on top of the page
// todo: remove button
$rootScope.showSaveButton = false;
};
/** $scope.multiCheck = function (y) {
* search directive in sidebar
*/
app.directive('sidebarSearch', function () { if (y === $scope.multiCollapseVar) {
return { $scope.multiCollapseVar = 0;
templateUrl: 'shared/templates/directives/sidebar-search.html', } else {
restrict: 'E', $scope.multiCollapseVar = y;
replace: true, }
scope: {}, };
controller: function ($scope) { }
$scope.selectedMenu = 'home'; };
} }])
};
}); .directive('stats', function () {
return {
templateUrl: 'shared/templates/directives/stats.html',
restrict: 'E',
replace: true,
scope: {
'model': '=',
'comments': '@',
'number': '@',
'name': '@',
'colour': '@',
'details': '@',
'type': '@',
'goto': '@'
}
};
})
/**
* header menu notifications directive
*/
.directive('notifications', function () {
return {
templateUrl: 'shared/templates/directives/notifications.html',
restrict: 'E',
replace: true
};
})
/**
* msgbox directive
*/
.directive('msgbox', function () {
return {
templateUrl: 'shared/templates/directives/msgbox.html',
restrict: 'E',
replace: false
};
})
/**
* search directive in sidebar
*/
.directive('sidebarSearch', function () {
return {
templateUrl: 'shared/templates/directives/sidebar-search.html',
restrict: 'E',
replace: true,
scope: {},
controller: function ($scope) {
$scope.selectedMenu = 'home';
}
};
});
//app.directive('timeline', function () { //app.directive('timeline', function () {
// return { // return {
......
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
......
<form class="form-inline col-md-8" id="search" name="search" sf-schema="searchSchema" sf-form="searchForm"
sf-model="searchModel"
ng-submit="searchSubmit(search)"></form>
\ No newline at end of file
/**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc.
*
* This file is licensed under the GNU General Public License v3
* (GPLv3). See LICENSE.txt for details.
*/
/**
* @name formService
* @description
*
* The `formService` module provides generic services for auto generated forms.
*
*/
angular.module('formService', [])
/**
* @name Generator
* @description
* form service's Generator factory service handles all generic form operations
*/
.factory('Generator', function ($http, $q, $timeout, $location, $route, $compile, $log, RESTURL, $rootScope) {
var generator = {};
/**
* @name makeUrl
* @description
* this function generates url combining backend url and the related object properties for http requests
* @param scope
* @returns {string}
*/
generator.makeUrl = function (scope) {
var getparams = scope.form_params.param ? "?" + scope.form_params.param + "=" + scope.form_params.id : "";
return RESTURL.url + scope.url + '/' + (scope.form_params.model || '') + getparams;
};
/**
* @name generate
* @param scope
* @param data
* @description
* # generate function is inclusive for form generation
* defines given scope's client_cmd, model, schema, form, token, object_id objects
*
* @returns {string}
*/
generator.generate = function (scope, data) {
// if no form in response (in case of list and single item request) return scope
if (!data.forms) {
return scope;
}
// prepare scope form, schema and model from response object
angular.forEach(data.forms, function (value, key) {
scope[key] = data.forms[key];
});
scope.client_cmd = data.client_cmd;
scope.token = data.token;
// initialModel will be used in formDiff when submiting the form to submit only
scope.initialModel = angular.copy(scope.model);
// if fieldset in form, make it collapsable with template
//scope.listnodeform = {};
//scope.isCollapsed = true;
generator.prepareFormItems(scope);
scope.object_id = scope.form_params.object_id;
// showSaveButton is used for to show or not to show save button on top of the page
// here change to true because the view retrieves form from api
$rootScope.showSaveButton = true;
$log.debug('scope at after generate', scope);
return scope;
};
/**
* @name group
* @param formObject
* @description
* group function to group form layout by form meta data for layout
* @returns {object}
*/
generator.group = function (formObject) {
return formObject;
};
/**
* prepareFormItems looks up fields of schema objects and changes their types to proper type for schemaform
* for listnode, node and model types it uses templates to generate modal
* @param scope
* @returns {*}
*/
generator.prepareFormItems = function (scope) {
/**
* prepareforms checks input types and convert if necessary
*/
// todo: remove after backend fix
angular.forEach(scope.form, function (value, key) {
if (value.type === 'select') {
scope.schema.properties[value.key].type = 'select';
scope.schema.properties[value.key].titleMap = value.titleMap;
scope.form[key] = value.key;
}
});
angular.forEach(scope.schema.properties, function (v, k) {
// generically change _id fields model value
if ('form_params' in scope) {
if (k == scope.form_params.param) {
scope.model[k] = scope.form_params.id;
scope.form.splice(scope.form.indexOf(k), 1);
return;
}
}
if (v.type === 'select') {
scope.form[scope.form.indexOf(k)] = {
type: "template",
title: v.title,
templateUrl: "shared/templates/select.html",
name: k,
key: k,
titleMap: v.titleMap
};
}
if (v.type === 'submit' || v.type === 'button') {
scope.form[scope.form.indexOf(k)] = {
type: v.type,
title: v.title,
style: "btn-primary movetobottom hide",
onClick: function () {
delete scope.form_params.cmd;
delete scope.form_params.flow;
if (v.cmd) {
scope.form_params["cmd"] = v.cmd;
}
if (v.flow) {
scope.form_params["flow"] = v.flow;
}
scope.model[k] = 1;
// todo: test it
scope.$broadcast('schemaFormValidate');
if (scope.formgenerated.$valid) {
generator.submit(scope);
}
}
};
$timeout(function () {
var buttons = angular.element(document.querySelector('.movetobottom'));
angular.element(document.querySelector('.buttons-on-bottom')).append(buttons);
buttons.removeClass('hide');
});
}
// check if type is date and if type date found change it to string
if (v.type === 'date') {
v.type = 'string';
scope.model[k] = generator.dateformatter(scope.model[k]);
$timeout(function () {
jQuery('#' + k).datepicker({
changeMonth: true,
changeYear: true,
dateFormat: "dd.mm.yy",
onSelect: function (date, inst) {
scope.model[k] = date;
scope.$broadcast('schemaForm.error.' + k, 'tv4-302', true);
}
});
});
}
if (v.type === 'int' || v.type === 'float') {
v.type = 'number';
scope.model[k] = parseInt(scope.model[k]);
}
if (v.type === 'text_general') {
v.type = 'string';
v["x-schema-form"] = {
"type": "textarea",
//"placeholder": ""
}
}
// if type is model use foreignKey.html template to show them
if (v.type === 'model') {
var formitem = scope.form[scope.form.indexOf(k)];
var modelscope = {"url": scope.url, "form_params": {model: v.model_name}};
formitem = {
type: "template",
templateUrl: "shared/templates/foreignKey.html",
title: v.title,
name: v.model_name,
model_name: v.model_name,
titleMap: generator.get_list(modelscope).then(function (res) {
formitem.titleMap = [];
angular.forEach(res.data.objects, function (item) {
if (item !== res.data.objects[0]) {
formitem.titleMap.push({
"value": item[0],
"name": item[1] + ' ' + (item[2] ? item[2] : '') + '...'
});
}
});
}),
onSelect: function (item) {
scope.model[k] = item.value;
},
onDropdownSelect: function (item, inputname) {
scope.model[k] = item.value;
jQuery('input[name=' + inputname + ']').val(item.name);
}
};
// get model objects from db and add to select list
scope.form[scope.form.indexOf(k)] = formitem;
}
if (v.type === 'ListNode' || v.type === 'Node') {
scope[v.type] = scope[v.type] || {};
scope[v.type][k] = {
title: v.title,
form: [],
schema: {
properties: {},
required: [],
title: v.title,
type: "object",
formType: v.type,
model_name: k
},
url: scope.url
};
if (scope.model[k] === null) {
scope[v.type][k].model = v.type === 'Node' ? {} : [];
} else {
scope[v.type][k].model = scope.model[k];
}
angular.forEach(v.schema, function (item) {
scope[v.type][k].schema.properties[item.name] = item;
// prepare required fields
if (item.required === true && item.name !== 'idx') {
scope[v.type][k].schema.required.push(item.name);
}
// idx field must be hidden
if (item.name === 'idx') {
scope[v.type][k].form.push({type: 'string', key: item.name, htmlClass: 'hidden'});
} else {
scope[v.type][k].form.push(item.name);
}
});
// lengthModels is length of the listnode models. if greater than 0 show records on template
scope[v.type][k]['lengthModels'] = scope.model[k] ? 1 : 0;
}
});
$log.debug('scope at after prepareformitems', scope);
return scope;
};
/**
* dateformatter handles all date fields and returns humanized and jquery datepicker format dates
* @param formObject
* @returns {*}
*/
generator.dateformatter = function (formObject) {
var ndate = new Date(formObject);
if (ndate == 'Invalid Date') {
return '';
} else {
var newdatearray = [ndate.getDate(), ndate.getMonth() + 1, ndate.getFullYear()];
return newdatearray.join('.');
}
};
generator.doItemAction = function ($scope, key, action) {
$scope.form_params.cmd = action.cmd;
$scope.form_params.object_id = key;
$scope.form_params.param = $scope.param;
$scope.form_params.id = $scope.param_id;
generator.get_wf($scope);
};
generator.get_form = function (scope) {
return $http
.post(generator.makeUrl(scope), scope.form_params)
.then(function (res) {
return generator.generate(scope, res.data);
});
};
/**
* gets list of related wf/model
* @param scope
* @returns {*}
*/
generator.get_list = function (scope) {
return $http
.get(generator.makeUrl(scope))
.then(function (res) {
return res;
});
};
/**
* get_wf is the main function for client_cmd based api calls
* based on response content it redirects to related path/controller with pathDecider function
* @param scope
* @returns {*}
*/
generator.get_wf = function (scope) {
return $http
.post(generator.makeUrl(scope), scope.form_params)
.then(function (res) {
return generator.pathDecider(res.data.client_cmd, scope, res.data);
});
};
generator.isValidEmail = function (email) {
var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(email);
};
generator.isValidTCNo = function (tcno) {
var re = /^([1-9]{1}[0-9]{9}[0,2,4,6,8]{1})$/i;
return re.test(tcno);
};
generator.asyncValidators = {
emailNotValid: function (value) {
var deferred = $q.defer();
$timeout(function () {
if (generator.isValidEmail(value)) {
deferred.resolve();
} else {
deferred.reject();
}
}, 500);
return deferred.promise;
},
tcNoNotValid: function (value) {
var deferred = $q.defer();
$timeout(function () {
if (generator.isValidTCNo(value)) {
deferred.resolve();
} else {
deferred.reject();
}
}, 500);
return deferred.promise;
}
};
/**
* pageData object is moving object from response to controller
* with this object controller will not need to call the api for response object to work on to
* @type {{}}
*/
generator.pageData = {};
generator.getPageData = function () {
return generator.pageData;
};
generator.setPageData = function (value) {
generator.pageData = value;
};
/**
* pathDecider is used to redirect related path by looking up the data in response
* @param $scope
* @param data
*/
generator.pathDecider = function (client_cmd, $scope, data) {
/**
* @name redirectTo
* @description
* redirectTo function redirects to related controller and path with given data
* before redirect setPageData must be called and pageData need to be defined
* otherwise redirected path will call api for its data
* @param scope, page
*/
function redirectTo(scope, page) {
var pathUrl = '/' + scope.form_params.wf;
if (scope.form_params.model) {
pathUrl += '/' + scope.form_params.model + '/do/' + page;
} else {
pathUrl += '/do/' + page;
}
// todo add object url to path
// pathUrl += '/'+scope.form_params.object_id || '';
// if generated path url and the current path is equal route has to be reload
if ($location.path() === pathUrl) {
return $route.reload();
}
else {
$location.path(pathUrl);
}
$log.debug('pathDecider scope', scope);
}
// client_cmd can be in ['list', 'form', 'show', 'reload', 'reset']
function dispatchClientCmd() {
data[$scope.form_params.param] = $scope.form_params.id;
data['model'] = $scope.form_params.model;
data['wf'] = $scope.form_params.wf;
data['param'] = $scope.form_params.param;
data['param_id'] = $scope.form_params.id;
data['pageData'] = true;
generator.setPageData(data);
redirectTo($scope, client_cmd[0]);
}
dispatchClientCmd();
};
generator.get_diff = function (obj1, obj2) {
var result = {};
for (key in obj1) {
if (obj2[key] != obj1[key]) result[key] = obj1[key];
if (typeof obj2[key] == 'array' && typeof obj1[key] == 'array')
result[key] = arguments.callee(obj1[key], obj2[key]);
if (typeof obj2[key] == 'object' && typeof obj1[key] == 'object')
result[key] = arguments.callee(obj1[key], obj2[key]);
}
return result;
};
/**
* submit function is general function for submiting forms
* @param $scope
* @returns {*}
*/
generator.submit = function ($scope) {
// todo: diff for all submits to recognize form change. if no change returns to view with no submit
angular.forEach($scope.ListNode, function (value, key) {
$scope.model[key] = value.model;
});
angular.forEach($scope.Node, function (value, key) {
$scope.model[key] = value.model;
});
var data = {
"form": $scope.model,
"token": $scope.token,
"model": $scope.form_params.model,
"cmd": $scope.form_params.cmd,
"flow": $scope.form_params.flow,
"object_id": $scope.object_id
};
return $http.post(generator.makeUrl($scope), data)
.success(function (data) {
if (data.client_cmd) {
generator.pathDecider(data.client_cmd, $scope, data);
}
if (data.msgbox) {
$scope.msgbox = data.msgbox;
var newElement = $compile("<msgbox></msgbox>")($scope);
// this is the default action, which is removing page items and reload page with msgbox
angular.element(document.querySelector('.main.ng-scope')).children().remove();
angular.element(document.querySelector('.main.ng-scope')).append(newElement);
}
});
};
return generator;
})
/**
* @name ModalCtrl
* @description
* controller for listnode, node and linkedmodel modal and save data of it
* @param items
* @requires $scope, $modalInstance, $route
* @returns returns value for modal
*/
.controller('ModalCtrl', function ($scope, $modalInstance, Generator, items) {
angular.forEach(items, function (value, key) {
$scope[key] = items[key];
});
Generator.prepareFormItems($scope);
$scope.onSubmit = function (form) {
$scope.$broadcast('schemaFormValidate');
if (form.$valid) {
// send form to modalinstance result function
$modalInstance.close($scope);
}
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
})
/**
* @name modalForNodes
* @description
* add modal directive for nodes
* @param $modal
* @returns openmodal directive
*/
.directive('modalForNodes', function ($modal) {
return {
link: function (scope, element, attributes) {
element.on('click', function () {
var modalInstance = $modal.open({
animation: false,
templateUrl: 'shared/templates/listnodeModalContent.html',
controller: 'ModalCtrl',
size: 'lg',
resolve: {
items: function () {
var attribs = attributes.modalForNodes.split(',');
// get node from parent scope catch with attribute
var node = angular.copy(scope.$parent[attribs[1]][attribs[0]]);
if (attribs[2] === 'add') {
node.model = {};
}
if (attribs[3]) {
// if listnode catch edit object with index
node.model = node.model[attribs[3]];
}
// tell result.then function which item to edit
node.edit = attribs[3];
return node;
}
}
});
modalInstance.result.then(function (childmodel, key) {
if (childmodel.schema.formType === 'Node') {
scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].model = childmodel.model;
}
if (childmodel.schema.formType === 'ListNode') {
if (childmodel.edit) {
scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].model[childmodel.edit] = childmodel.model;
} else {
scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].model.push(childmodel.model);
}
}
scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].lengthModels += 1;
});
});
}
};
})
/**
* @name addModalForLinkedModel
* @description
* add modal directive for linked models
* @param $modal, Generator
* @returns openmodal directive
*/
.directive('addModalForLinkedModel', function ($modal, $route, Generator) {
return {
link: function (scope, element) {
element.on('click', function () {
var modalInstance = $modal.open({
animation: false,
templateUrl: 'shared/templates/linkedModelModalContent.html',
controller: 'ModalCtrl',
size: 'lg',
resolve: {
items: function () {
return Generator.get_form({
url: 'crud',
form_params: {'model': scope.form.model_name, "cmd": "form"}
});
}
}
});
modalInstance.result.then(function (childmodel, key) {
Generator.submit(childmodel);
$route.reload();
});
});
}
};
})
/**
* @name editModalForLinkedModel
* @description
* edit modal directive for linked models
* @param $modal, Generator
* @returns openmodal directive
*/
// todo: useless modal check if any use cases?? and delete if useless
.directive('editModalForLinkedModel', function ($modal, Generator) {
return {
link: function (scope, element) {
element.on('click', function () {
var modalInstance = $modal.open({
animation: false,
templateUrl: 'shared/templates/linkedModelModalContent.html',
controller: 'ModalCtrl',
size: 'lg',
resolve: {
items: function () {
return Generator.get_form({
url: 'crud',
form_params: {'model': scope.form.title, "cmd": "form"}
});
}
}
});
modalInstance.result.then(function (childmodel, key) {
Generator.submit(childmodel);
});
});
}
};
});
\ No newline at end of file
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
...@@ -323,6 +324,50 @@ describe('form service module', function () { ...@@ -323,6 +324,50 @@ describe('form service module', function () {
}) })
); );
it('should return diff object',
inject( function (Generator) {
expect(Generator.get_diff).not.toBe(null);
// test cases - testing for success
var same_json = [
{email: 'test@test.com', id: 2, name: 'travolta'},
{email: 'test@test.com', id: 2, name: 'travolta'}
];
// test cases - testing for failure
var different_jsons = [
[
{email: 'test@test.com', id: 2, name: 'travolta'},
{email: 'test1@test.com', id: 2, name: 'john'}
],
[
{id: 2, name: 'travolta'},
{email: 'test1@test.com', id: 2, name: 'john'}
]
];
var different_json = [
{},
{email: 'test1@test.com', id: 2, name: 'john'}
]
var diff = {email: 'test1@test.com', name: 'john'};
var diff2 = {email: 'test1@test.com', id: 2, name: 'john'};
var nodiff = {};
var same = Generator.get_diff(same_json[0], same_json[1]);
expect(same).toEqual(nodiff);
for (var json_obj in different_jsons) {
var different = Generator.get_diff(different_jsons[json_obj][1], different_jsons[json_obj][0]);
expect(different).toEqual(diff);
}
var different2 = Generator.get_diff(different_json[1], different_json[0]);
expect(different2).toEqual(diff2);
})
);
}); });
describe('form service', function () { describe('form service', function () {
......
/**
* Copyright (C) 2015 ZetaOps Inc.
*
* This file is licensed under the GNU General Public License v3
* (GPLv3). See LICENSE.txt for details.
*/
var form_generator = angular.module('formService', ['general']);
/**
* form service's Generator factory service handles all generic form operations
*/
form_generator.factory('Generator', function ($http, $q, $timeout, $location, $route, $compile, $log, RESTURL, FormDiff, $rootScope) {
var generator = {};
generator.makeUrl = function (scope) {
var getparams = scope.form_params.param ? "?" + scope.form_params.param + "=" + scope.form_params.id : "";
return RESTURL.url + scope.url + '/' + (scope.form_params.model || '') + getparams;
};
/**
* generate function is inclusive for form generation
* defines given scope's client_cmd, model, schema, form, token, object_id objects
* @param scope
* @param data
* @returns {*}
*/
generator.generate = function (scope, data) {
// if no form in response (in case of list and single item request) return scope
if (!data.forms) {
return scope;
}
// prepare scope form, schema and model from response object
angular.forEach(data.forms, function (value, key) {
scope[key] = data.forms[key];
});
scope.client_cmd = data.client_cmd;
scope.token = data.token;
// initialModel will be used in formDiff when submiting the form to submit only
scope.initialModel = angular.copy(scope.model);
// if fieldset in form, make it collapsable with template
//scope.listnodeform = {};
//scope.isCollapsed = true;
generator.prepareFormItems(scope);
scope.object_id = scope.form_params.object_id;
// showSaveButton is used for to show or not to show save button on top of the page
// here change to true because the view retrieves form from api
$rootScope.showSaveButton = true;
$log.debug('scope at after generate', scope);
return scope;
};
/**
* group function to group form layout by form meta data for layout
* @param formObject
* @returns {*}
*/
generator.group = function (formObject) {
return formObject;
};
/**
* prepareFormItems looks up fields of schema objects and changes their types to proper type for schemaform
* for listnode, node and model types it uses templates to generate modal
* @param scope
* @returns {*}
*/
generator.prepareFormItems = function (scope) {
/**
* prepareforms checks input types and convert if necessary
*/
// todo: remove after backend fix
angular.forEach(scope.form, function (value, key) {
if (value.type === 'select') {
scope.schema.properties[value.key].type = 'select';
scope.schema.properties[value.key].titleMap = value.titleMap;
scope.form[key] = value.key;
}
});
angular.forEach(scope.schema.properties, function (v, k) {
// generically change _id fields model value
if ('form_params' in scope) {
if (k == scope.form_params.param) {
scope.model[k] = scope.form_params.id;
scope.form.splice(scope.form.indexOf(k), 1);
return;
}
}
if (v.type === 'select') {
scope.form[scope.form.indexOf(k)] = {
type: "template",
title: v.title,
templateUrl: "shared/templates/select.html",
name: k,
key: k,
titleMap: v.titleMap
};
}
if (v.type === 'submit' || v.type === 'button') {
scope.form[scope.form.indexOf(k)] = {
type: v.type,
title: v.title,
style: "btn-primary movetobottom hide",
onClick: function () {
delete scope.form_params.cmd;
delete scope.form_params.flow;
if (v.cmd) {
scope.form_params["cmd"] = v.cmd;
}
if (v.flow) {
scope.form_params["flow"] = v.flow;
}
scope.model[k] = 1;
// todo: test it
scope.$broadcast('schemaFormValidate');
if (scope.formgenerated.$valid) {
generator.submit(scope);
}
}
};
$timeout(function () {
var buttons = angular.element(document.querySelector('.movetobottom'));
angular.element(document.querySelector('.buttons-on-bottom')).append(buttons);
buttons.removeClass('hide');
});
}
// check if type is date and if type date found change it to string
if (v.type === 'date') {
v.type = 'string';
scope.model[k] = generator.dateformatter(scope.model[k]);
$timeout(function () {
jQuery('#' + k).datepicker({
changeMonth: true,
changeYear: true,
dateFormat: "dd.mm.yy",
onSelect: function (date, inst) {
scope.model[k] = date;
scope.$broadcast('schemaForm.error.' + k, 'tv4-302', true);
}
});
});
}
if (v.type === 'int' || v.type === 'float') {
v.type = 'number';
scope.model[k] = parseInt(scope.model[k]);
}
if (v.type === 'text_general') {
v.type = 'string';
v["x-schema-form"] = {
"type": "textarea",
//"placeholder": ""
}
}
// if type is model use foreignKey.html template to show them
if (v.type === 'model') {
var formitem = scope.form[scope.form.indexOf(k)];
var modelscope = {"url": scope.url, "form_params": {model: v.model_name}};
formitem = {
type: "template",
templateUrl: "shared/templates/foreignKey.html",
title: v.title,
name: v.model_name,
model_name: v.model_name,
titleMap: generator.get_list(modelscope).then(function (res) {
formitem.titleMap = [];
angular.forEach(res.data.objects, function (item) {
if (item !== res.data.objects[0]) {
formitem.titleMap.push({
"value": item[0],
"name": item[1] + ' ' + (item[2] ? item[2] : '') + '...'
});
}
});
}),
onSelect: function (item) {
scope.model[k] = item.value;
},
onDropdownSelect: function (item, inputname) {
scope.model[k] = item.value;
jQuery('input[name=' + inputname + ']').val(item.name);
}
};
// get model objects from db and add to select list
scope.form[scope.form.indexOf(k)] = formitem;
}
if (v.type === 'ListNode' || v.type === 'Node') {
scope[v.type] = scope[v.type] || {};
scope[v.type][k] = {
title: v.title,
form: [],
schema: {
properties: {},
required: [],
title: v.title,
type: "object",
formType: v.type,
model_name: k
},
url: scope.url
};
if (scope.model[k] === null) {
scope[v.type][k].model = v.type === 'Node' ? {} : [];
} else {
scope[v.type][k].model = scope.model[k];
}
angular.forEach(v.schema, function (item) {
scope[v.type][k].schema.properties[item.name] = item;
// prepare required fields
if (item.required === true && item.name !== 'idx') {
scope[v.type][k].schema.required.push(item.name);
}
// idx field must be hidden
if (item.name === 'idx') {
scope[v.type][k].form.push({type: 'string', key: item.name, htmlClass: 'hidden'});
} else {
scope[v.type][k].form.push(item.name);
}
});
// lengthModels is length of the listnode models. if greater than 0 show records on template
scope[v.type][k]['lengthModels'] = scope.model[k] ? 1 : 0;
}
});
$log.debug('scope at after prepareformitems', scope);
return scope;
};
/**
* dateformatter handles all date fields and returns humanized and jquery datepicker format dates
* @param formObject
* @returns {*}
*/
generator.dateformatter = function (formObject) {
var ndate = new Date(formObject);
if (ndate == 'Invalid Date') {
return '';
} else {
var newdatearray = [ndate.getDate(), ndate.getMonth()+1, ndate.getFullYear()];
return newdatearray.join('.');
}
};
generator.doItemAction = function ($scope, key, action) {
$scope.form_params.cmd = action.cmd;
$scope.form_params.object_id = key;
$scope.form_params.param = $scope.param;
$scope.form_params.id = $scope.param_id;
generator.get_wf($scope);
};
generator.get_form = function (scope) {
return $http
.post(generator.makeUrl(scope), scope.form_params)
.then(function (res) {
return generator.generate(scope, res.data);
});
};
/**
* gets list of related wf/model
* @param scope
* @returns {*}
*/
generator.get_list = function (scope) {
return $http
.get(generator.makeUrl(scope))
.then(function (res) {
return res;
});
};
/**
* get_wf is the main function for client_cmd based api calls
* based on response content it redirects to related path/controller with pathDecider function
* @param scope
* @returns {*}
*/
generator.get_wf = function (scope) {
return $http
.post(generator.makeUrl(scope), scope.form_params)
.then(function (res) {
return generator.pathDecider(res.data.client_cmd, scope, res.data);
});
};
generator.isValidEmail = function (email) {
var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(email);
};
generator.isValidTCNo = function (tcno) {
var re = /^([1-9]{1}[0-9]{9}[0,2,4,6,8]{1})$/i;
return re.test(tcno);
};
generator.asyncValidators = {
emailNotValid: function (value) {
var deferred = $q.defer();
$timeout(function () {
if (generator.isValidEmail(value)) {
deferred.resolve();
} else {
deferred.reject();
}
}, 500);
return deferred.promise;
},
tcNoNotValid: function (value) {
var deferred = $q.defer();
$timeout(function () {
if (generator.isValidTCNo(value)) {
deferred.resolve();
} else {
deferred.reject();
}
}, 500);
return deferred.promise;
}
};
/**
* pageData object is moving object from response to controller
* with this object controller will not need to call the api for response object to work on to
* @type {{}}
*/
generator.pageData = {};
generator.getPageData = function () {
return generator.pageData;
};
generator.setPageData = function (value) {
generator.pageData = value;
};
/**
* pathDecider is used to redirect related path by looking up the data in response
* @param $scope
* @param data
*/
generator.pathDecider = function (client_cmd, $scope, data) {
/**
* redirectTo function redirects to related controller and path with given data
* before redirect setPageData must be called and pageData need to be defined
* otherwise redirected path will call api for its data
* @param scope
* @param page
*/
function redirectTo(scope, page){
var pathUrl = '/'+scope.form_params.wf;
if (scope.form_params.model) {
pathUrl += '/' + scope.form_params.model + '/do/' + page;
} else {
pathUrl += '/do/' + page;
}
// todo add object url to path
// pathUrl += '/'+scope.form_params.object_id || '';
// if generated path url and the current path is equal route has to be reload
if ($location.path() === pathUrl) {return $route.reload();}
else {$location.path(pathUrl);}
$log.debug('pathDecider scope', scope);
}
// client_cmd can be in ['list', 'form', 'show', 'reload', 'reset']
function dispatchClientCmd() {
data[$scope.form_params.param] = $scope.form_params.id;
data['model'] = $scope.form_params.model;
data['wf'] = $scope.form_params.wf;
data['param'] = $scope.form_params.param;
data['param_id'] = $scope.form_params.id;
data['pageData'] = true;
generator.setPageData(data);
redirectTo($scope, client_cmd[0]);
}
dispatchClientCmd();
};
/**
* submit function is general function for submiting forms
* @param $scope
* @returns {*}
*/
generator.submit = function ($scope) {
// todo: diff for all submits to recognize form change. if no change returns to view with no submit
angular.forEach($scope.ListNode, function (value, key) {
$scope.model[key] = value.model;
});
angular.forEach($scope.Node, function (value, key) {
$scope.model[key] = value.model;
});
var data = {
"form": $scope.model,
"token": $scope.token,
"model": $scope.form_params.model,
"cmd": $scope.form_params.cmd,
"flow": $scope.form_params.flow,
"object_id": $scope.object_id
};
return $http.post(generator.makeUrl($scope), data)
.success(function (data) {
if (data.client_cmd) {
generator.pathDecider(data.client_cmd, $scope, data);
}
if (data.msgbox) {
$scope.msgbox = data.msgbox;
var newElement = $compile("<msgbox></msgbox>")($scope);
// this is the default action, which is removing page items and reload page with msgbox
angular.element(document.querySelector('.main.ng-scope')).children().remove();
angular.element(document.querySelector('.main.ng-scope')).append(newElement);
}
});
};
return generator;
});
/**
* ModalCtrl
* controller for listnode, node and linkedmodel modal and save data of it
* @params: $scope, $modalInstance, $route, items
* @returns: returns value for modal
*/
form_generator.controller('ModalCtrl', function ($scope, $modalInstance, Generator, items) {
angular.forEach(items, function (value, key) {
$scope[key] = items[key];
});
Generator.prepareFormItems($scope);
$scope.onSubmit = function (form) {
$scope.$broadcast('schemaFormValidate');
if (form.$valid) {
// send form to modalinstance result function
$modalInstance.close($scope);
}
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
/**
* add modal directive for nodes
* @params: $modal
* @return: openmodal directive
*/
form_generator.directive('modalForNodes', function ($modal) {
return {
link: function (scope, element, attributes) {
element.on('click', function () {
var modalInstance = $modal.open({
animation: false,
templateUrl: 'shared/templates/listnodeModalContent.html',
controller: 'ModalCtrl',
size: 'lg',
resolve: {
items: function () {
var attribs = attributes.modalForNodes.split(',');
// get node from parent scope catch with attribute
var node = angular.copy(scope.$parent[attribs[1]][attribs[0]]);
if (attribs[2] === 'add') {
node.model = {};
}
if (attribs[3]) {
// if listnode catch edit object with index
node.model = node.model[attribs[3]];
}
// tell result.then function which item to edit
node.edit = attribs[3];
return node;
}
}
});
modalInstance.result.then(function (childmodel, key) {
if (childmodel.schema.formType === 'Node') {
scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].model = childmodel.model;
}
if (childmodel.schema.formType === 'ListNode') {
if (childmodel.edit) {
scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].model[childmodel.edit] = childmodel.model;
} else {
scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].model.push(childmodel.model);
}
}
scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].lengthModels += 1;
});
});
}
};
});
/**
* add modal directive for linked models
* @params: $modal, Generator
* @return: openmodal directive
*/
form_generator.directive('addModalForLinkedModel', function ($modal, $route, Generator) {
return {
link: function (scope, element) {
element.on('click', function () {
var modalInstance = $modal.open({
animation: false,
templateUrl: 'shared/templates/linkedModelModalContent.html',
controller: 'ModalCtrl',
size: 'lg',
resolve: {
items: function () {
return Generator.get_form({
url: 'crud',
form_params: {'model': scope.form.model_name, "cmd": "form"}
});
}
}
});
modalInstance.result.then(function (childmodel, key) {
Generator.submit(childmodel);
$route.reload();
});
});
}
};
});
/**
* edit modal directive for linked models
* @params: $modal, Generator
* @return: openmodal directive
*/
// todo: useless modal check if any use cases?? and delete if useless
form_generator.directive('editModalForLinkedModel', function ($modal, Generator) {
return {
link: function (scope, element) {
element.on('click', function () {
var modalInstance = $modal.open({
animation: false,
templateUrl: 'shared/templates/linkedModelModalContent.html',
controller: 'ModalCtrl',
size: 'lg',
resolve: {
items: function () {
return Generator.get_form({
url: 'crud',
form_params: {'model': scope.form.title, "cmd": "form"}
});
}
}
});
modalInstance.result.then(function (childmodel, key) {
Generator.submit(childmodel);
});
});
}
};
});
\ No newline at end of file
<div ng-app="FormGenerator">
<div ng-controller="FormController">
<form name="formgenerated" sf-schema="schema" sf-form="form" sf-model="model" ng-submit="onSubmit(formgenerated)"></form>
</div>
</div>
\ No newline at end of file
/**
* Copyright (C) 2015 ZetaOps Inc.
*
* This file is licensed under the GNU General Public License v3
* (GPLv3). See LICENSE.txt for details.
*/
// todo: move to form
//angular.module('FormDiff', [])
/**
* this file contains general functions of app.
*/
var general = angular.module('general', []);
general.factory('FormDiff', function () {
/**
* function to return diff of models of submitted form
* @type {{}}
* @params obj1, obj2
* @attention: obj1 must be initialModel, obj2 must be model after inputs
* filled
*/
var formDiff = {};
formDiff.get_diff = function (obj1, obj2) {
var result = {};
for (key in obj1) {
if (obj2[key] != obj1[key]) result[key] = obj1[key];
if (typeof obj2[key] == 'array' && typeof obj1[key] == 'array')
result[key] = arguments.callee(obj1[key], obj2[key]);
if (typeof obj2[key] == 'object' && typeof obj1[key] == 'object')
result[key] = arguments.callee(obj1[key], obj2[key]);
}
return result;
};
return formDiff;
});
\ No newline at end of file
/**
* Copyright (C) 2015 ZetaOps Inc.
*
* This file is licensed under the GNU General Public License v3
* (GPLv3). See LICENSE.txt for details.
*/
'use strict';
describe('general module', function () {
beforeEach(module('general'));
describe('form diff factory', function () {
it('should return diff object', inject(['FormDiff',
function (FormDiff) {
expect(FormDiff.get_diff).not.toBe(null);
// test cases - testing for success
var same_json = [
{email: 'test@test.com', id: 2, name: 'travolta'},
{email: 'test@test.com', id: 2, name: 'travolta'}
];
// test cases - testing for failure
var different_jsons = [
[
{email: 'test@test.com', id: 2, name: 'travolta'},
{email: 'test1@test.com', id: 2, name: 'john'}
],
[
{id: 2, name: 'travolta'},
{email: 'test1@test.com', id: 2, name: 'john'}
]
];
var different_json = [
{},
{email: 'test1@test.com', id: 2, name: 'john'}
]
var diff = {email: 'test1@test.com', name: 'john'};
var diff2 = {email: 'test1@test.com', id: 2, name: 'john'};
var nodiff = {};
var same = FormDiff.get_diff(same_json[0], same_json[1]);
expect(same).toEqual(nodiff);
for (var json_obj in different_jsons) {
var different = FormDiff.get_diff(different_jsons[json_obj][1], different_jsons[json_obj][0]);
expect(different).toEqual(diff);
}
var different2 = FormDiff.get_diff(different_json[1], different_json[0]);
expect(different2).toEqual(diff2);
}])
);
});
});
\ No newline at end of file
/** /**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc. * Copyright (C) 2015 ZetaOps Inc.
* *
* This file is licensed under the GNU General Public License v3 * This file is licensed under the GNU General Public License v3
......
/*! ulakbus-ui 2015-11-20 */ /*! ulakbus-ui 2015-11-23 */
"use strict";var app=angular.module("ulakbus",["ui.bootstrap","angular-loading-bar","ngRoute","ngSanitize","ngCookies","general","formService","ulakbus.dashboard","ulakbus.auth","ulakbus.error_pages","ulakbus.crud","ulakbus.debug","ulakbus.devSettings","ulakbus.version","gettext","templates-prod"]).constant("RESTURL",function(){var backendurl=location.href.indexOf("nightly")?"//nightly.api.ulakbus.net/":"//api.ulakbus.net/";if(document.cookie.indexOf("backendurl")>-1){var cookiearray=document.cookie.split(";");angular.forEach(cookiearray,function(item){item.indexOf("backendurl")>-1&&(backendurl=item.split("=")[1])})}if(location.href.indexOf("backendurl")>-1){var urlfromqstr=location.href.split("?")[1].split("=")[1];backendurl=decodeURIComponent(urlfromqstr.replace(/\+/g," ")),document.cookie="backendurl="+backendurl,window.location.href=window.location.href.split("?")[0]}return{url:backendurl}}()).constant("USER_ROLES",{all:"*",admin:"admin",student:"student",staff:"staff",dean:"dean"}).constant("AUTH_EVENTS",{loginSuccess:"auth-login-success",loginFailed:"auth-login-failed",logoutSuccess:"auth-logout-success",sessionTimeout:"auth-session-timeout",notAuthenticated:"auth-not-authenticated",notAuthorized:"auth-not-authorized"});app.config(["$routeProvider",function($routeProvider,$route){$routeProvider.when("/login",{templateUrl:"components/auth/login.html",controller:"LoginCtrl"}).when("/dashboard",{templateUrl:"components/dashboard/dashboard.html",controller:"DashCtrl"}).when("/dev/settings",{templateUrl:"components/devSettings/devSettings.html",controller:"DevSettingsCtrl"}).when("/debug/list",{templateUrl:"components/debug/debug.html",controller:"DebugCtrl"}).when("/:wf/",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDCtrl"}).when("/:wf/do/:cmd",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/do/:cmd/:key",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/:model",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDCtrl"}).when("/:wf/:model/do/:cmd",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/:model/do/:cmd/:key",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).otherwise({redirectTo:"/dashboard"})}]).run(function($rootScope){$rootScope.loggedInUser=!0,$rootScope.$on("$routeChangeStart",function(event,next,current){})}).config(["$httpProvider",function($httpProvider){$httpProvider.defaults.withCredentials=!0}]).run(function(gettextCatalog){gettextCatalog.setCurrentLanguage("tr"),gettextCatalog.debug=!0}).config(["cfpLoadingBarProvider",function(cfpLoadingBarProvider){cfpLoadingBarProvider.includeBar=!1,cfpLoadingBarProvider.parentSelector="loaderdiv",cfpLoadingBarProvider.spinnerTemplate='<div class="loader">Loading...</div>'}]),app.config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(function($q,$rootScope,$location,$timeout){return{request:function(config){return"POST"===config.method&&(config.headers["Content-Type"]="text/plain"),config},response:function(response){return response.data._debug_queries&&response.data._debug_queries.length>0&&($rootScope.debug_queries=$rootScope.debug_queries||[],$rootScope.debug_queries.push({url:response.config.url,queries:response.data._debug_queries})),response.data.is_login===!1&&($rootScope.loggedInUser=response.data.is_login,$location.path("/login")),response.data.is_login===!0&&($rootScope.loggedInUser=!0,"/login"===$location.path()&&$location.path("/dashboard")),response},responseError:function(rejection){var errorModal=function(){var codefield="";rejection.data.error&&(codefield="<p><pre>"+rejection.data.error+"</pre></p>"),$('<div class="modal"><div class="modal-dialog" style="width:1024px;" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button><h4 class="modal-title" id="exampleModalLabel">'+rejection.status+rejection.data.title+'</h4></div><div class="modal-body"><div class="alert alert-danger"><strong>'+rejection.data.description+"</strong>"+codefield+'</div></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div></div></div></div>').modal()};return-1===rejection.status&&(rejection.data={title:"error",description:"connection failed"},errorModal()),400===rejection.status&&$location.reload(),401===rejection.status&&($location.path("/login"),"/login"===$location.path()&&console.log("show errors on login form")),403===rejection.status&&(rejection.data.is_login===!0&&($rootScope.loggedInUser=!0,"/login"===$location.path()&&$location.path("/dashboard")),errorModal()),$rootScope.$broadcast("show_notifications",rejection.data),404===rejection.status&&errorModal(),500===rejection.status&&errorModal(),$q.reject(rejection)}}})}]);var general=angular.module("general",[]);general.factory("FormDiff",function(){var formDiff={};return formDiff.get_diff=function(obj1,obj2){var result={};for(key in obj1)obj2[key]!=obj1[key]&&(result[key]=obj1[key]),"array"==typeof obj2[key]&&"array"==typeof obj1[key]&&(result[key]=arguments.callee(obj1[key],obj2[key])),"object"==typeof obj2[key]&&"object"==typeof obj1[key]&&(result[key]=arguments.callee(obj1[key],obj2[key]));return result},formDiff});var form_generator=angular.module("formService",["general"]);form_generator.factory("Generator",function($http,$q,$timeout,$location,$route,$compile,$log,RESTURL,FormDiff,$rootScope){var generator={};return generator.makeUrl=function(scope){var getparams=scope.form_params.param?"?"+scope.form_params.param+"="+scope.form_params.id:"";return RESTURL.url+scope.url+"/"+(scope.form_params.model||"")+getparams},generator.generate=function(scope,data){return data.forms?(angular.forEach(data.forms,function(value,key){scope[key]=data.forms[key]}),scope.client_cmd=data.client_cmd,scope.token=data.token,scope.initialModel=angular.copy(scope.model),generator.prepareFormItems(scope),scope.object_id=scope.form_params.object_id,$rootScope.showSaveButton=!0,$log.debug("scope at after generate",scope),scope):scope},generator.group=function(formObject){return formObject},generator.prepareFormItems=function(scope){return angular.forEach(scope.form,function(value,key){"select"===value.type&&(scope.schema.properties[value.key].type="select",scope.schema.properties[value.key].titleMap=value.titleMap,scope.form[key]=value.key)}),angular.forEach(scope.schema.properties,function(v,k){if("form_params"in scope&&k==scope.form_params.param)return scope.model[k]=scope.form_params.id,void scope.form.splice(scope.form.indexOf(k),1);if("select"===v.type&&(scope.form[scope.form.indexOf(k)]={type:"template",title:v.title,templateUrl:"shared/templates/select.html",name:k,key:k,titleMap:v.titleMap}),("submit"===v.type||"button"===v.type)&&(scope.form[scope.form.indexOf(k)]={type:v.type,title:v.title,style:"btn-primary movetobottom hide",onClick:function(){delete scope.form_params.cmd,delete scope.form_params.flow,v.cmd&&(scope.form_params.cmd=v.cmd),v.flow&&(scope.form_params.flow=v.flow),scope.model[k]=1,scope.$broadcast("schemaFormValidate"),scope.formgenerated.$valid&&generator.submit(scope)}},$timeout(function(){var buttons=angular.element(document.querySelector(".movetobottom"));angular.element(document.querySelector(".buttons-on-bottom")).append(buttons),buttons.removeClass("hide")})),"date"===v.type&&(v.type="string",scope.model[k]=generator.dateformatter(scope.model[k]),$timeout(function(){jQuery("#"+k).datepicker({changeMonth:!0,changeYear:!0,dateFormat:"dd.mm.yy",onSelect:function(date,inst){scope.model[k]=date,scope.$broadcast("schemaForm.error."+k,"tv4-302",!0)}})})),("int"===v.type||"float"===v.type)&&(v.type="number",scope.model[k]=parseInt(scope.model[k])),"text_general"===v.type&&(v.type="string",v["x-schema-form"]={type:"textarea"}),"model"===v.type){var formitem=scope.form[scope.form.indexOf(k)],modelscope={url:scope.url,form_params:{model:v.model_name}};formitem={type:"template",templateUrl:"shared/templates/foreignKey.html",title:v.title,name:v.model_name,model_name:v.model_name,titleMap:generator.get_list(modelscope).then(function(res){formitem.titleMap=[],angular.forEach(res.data.objects,function(item){item!==res.data.objects[0]&&formitem.titleMap.push({value:item[0],name:item[1]+" "+(item[2]?item[2]:"")+"..."})})}),onSelect:function(item){scope.model[k]=item.value},onDropdownSelect:function(item,inputname){scope.model[k]=item.value,jQuery("input[name="+inputname+"]").val(item.name)}},scope.form[scope.form.indexOf(k)]=formitem}("ListNode"===v.type||"Node"===v.type)&&(scope[v.type]=scope[v.type]||{},scope[v.type][k]={title:v.title,form:[],schema:{properties:{},required:[],title:v.title,type:"object",formType:v.type,model_name:k},url:scope.url},null===scope.model[k]?scope[v.type][k].model="Node"===v.type?{}:[]:scope[v.type][k].model=scope.model[k],angular.forEach(v.schema,function(item){scope[v.type][k].schema.properties[item.name]=item,item.required===!0&&"idx"!==item.name&&scope[v.type][k].schema.required.push(item.name),"idx"===item.name?scope[v.type][k].form.push({type:"string",key:item.name,htmlClass:"hidden"}):scope[v.type][k].form.push(item.name)}),scope[v.type][k].lengthModels=scope.model[k]?1:0)}),$log.debug("scope at after prepareformitems",scope),scope},generator.dateformatter=function(formObject){var ndate=new Date(formObject);if("Invalid Date"==ndate)return"";var newdatearray=[ndate.getDate(),ndate.getMonth()+1,ndate.getFullYear()];return newdatearray.join(".")},generator.doItemAction=function($scope,key,action){$scope.form_params.cmd=action.cmd,$scope.form_params.object_id=key,$scope.form_params.param=$scope.param,$scope.form_params.id=$scope.param_id,generator.get_wf($scope)},generator.get_form=function(scope){return $http.post(generator.makeUrl(scope),scope.form_params).then(function(res){return generator.generate(scope,res.data)})},generator.get_list=function(scope){return $http.get(generator.makeUrl(scope)).then(function(res){return res})},generator.get_wf=function(scope){return $http.post(generator.makeUrl(scope),scope.form_params).then(function(res){return generator.pathDecider(res.data.client_cmd,scope,res.data)})},generator.isValidEmail=function(email){var re=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;return re.test(email)},generator.isValidTCNo=function(tcno){var re=/^([1-9]{1}[0-9]{9}[0,2,4,6,8]{1})$/i;return re.test(tcno)},generator.asyncValidators={emailNotValid:function(value){var deferred=$q.defer();return $timeout(function(){generator.isValidEmail(value)?deferred.resolve():deferred.reject()},500),deferred.promise},tcNoNotValid:function(value){var deferred=$q.defer();return $timeout(function(){generator.isValidTCNo(value)?deferred.resolve():deferred.reject()},500),deferred.promise}},generator.pageData={},generator.getPageData=function(){return generator.pageData},generator.setPageData=function(value){generator.pageData=value},generator.pathDecider=function(client_cmd,$scope,data){function redirectTo(scope,page){var pathUrl="/"+scope.form_params.wf;return pathUrl+=scope.form_params.model?"/"+scope.form_params.model+"/do/"+page:"/do/"+page,$location.path()===pathUrl?$route.reload():($location.path(pathUrl),void $log.debug("pathDecider scope",scope))}function dispatchClientCmd(){data[$scope.form_params.param]=$scope.form_params.id,data.model=$scope.form_params.model,data.wf=$scope.form_params.wf,data.param=$scope.form_params.param,data.param_id=$scope.form_params.id,data.pageData=!0,generator.setPageData(data),redirectTo($scope,client_cmd[0])}dispatchClientCmd()},generator.submit=function($scope){angular.forEach($scope.ListNode,function(value,key){$scope.model[key]=value.model}),angular.forEach($scope.Node,function(value,key){$scope.model[key]=value.model});var data={form:$scope.model,token:$scope.token,model:$scope.form_params.model,cmd:$scope.form_params.cmd,flow:$scope.form_params.flow,object_id:$scope.object_id};return $http.post(generator.makeUrl($scope),data).success(function(data){if(data.client_cmd&&generator.pathDecider(data.client_cmd,$scope,data),data.msgbox){$scope.msgbox=data.msgbox;var newElement=$compile("<msgbox></msgbox>")($scope);angular.element(document.querySelector(".main.ng-scope")).children().remove(),angular.element(document.querySelector(".main.ng-scope")).append(newElement)}})},generator}),form_generator.controller("ModalCtrl",function($scope,$modalInstance,Generator,items){angular.forEach(items,function(value,key){$scope[key]=items[key]}),Generator.prepareFormItems($scope),$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid&&$modalInstance.close($scope)},$scope.cancel=function(){$modalInstance.dismiss("cancel")}}),form_generator.directive("modalForNodes",function($modal){return{link:function(scope,element,attributes){element.on("click",function(){var modalInstance=$modal.open({animation:!1,templateUrl:"shared/templates/listnodeModalContent.html",controller:"ModalCtrl",size:"lg",resolve:{items:function(){var attribs=attributes.modalForNodes.split(","),node=angular.copy(scope.$parent[attribs[1]][attribs[0]]);return"add"===attribs[2]&&(node.model={}),attribs[3]&&(node.model=node.model[attribs[3]]),node.edit=attribs[3],node}}});modalInstance.result.then(function(childmodel,key){"Node"===childmodel.schema.formType&&(scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].model=childmodel.model),"ListNode"===childmodel.schema.formType&&(childmodel.edit?scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].model[childmodel.edit]=childmodel.model:scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].model.push(childmodel.model)),scope.$parent[childmodel.schema.formType][childmodel.schema.model_name].lengthModels+=1})})}}}),form_generator.directive("addModalForLinkedModel",function($modal,$route,Generator){return{link:function(scope,element){element.on("click",function(){var modalInstance=$modal.open({animation:!1,templateUrl:"shared/templates/linkedModelModalContent.html",controller:"ModalCtrl",size:"lg",resolve:{items:function(){return Generator.get_form({url:"crud",form_params:{model:scope.form.model_name,cmd:"form"}})}}});modalInstance.result.then(function(childmodel,key){Generator.submit(childmodel),$route.reload()})})}}}),form_generator.directive("editModalForLinkedModel",function($modal,Generator){return{link:function(scope,element){element.on("click",function(){var modalInstance=$modal.open({animation:!1,templateUrl:"shared/templates/linkedModelModalContent.html",controller:"ModalCtrl",size:"lg",resolve:{items:function(){return Generator.get_form({url:"crud",form_params:{model:scope.form.title,cmd:"form"}})}}});modalInstance.result.then(function(childmodel,key){Generator.submit(childmodel)})})}}}),app.directive("logout",function($http,$location,RESTURL){return{link:function($scope,$element,$rootScope){$element.on("click",function(){$http.post(RESTURL.url+"logout",{}).then(function(){$rootScope.loggedInUser=!1,$location.path("/login")})})}}}),app.directive("headerNotification",function($http,$rootScope,$cookies,$interval,RESTURL){return{templateUrl:"shared/templates/directives/header-notification.html",restrict:"E",replace:!0,link:function($scope){$scope.groupNotifications=function(notifications){$scope.notifications={1:[],2:[],3:[],4:[]},angular.forEach(notifications,function(value,key){$scope.notifications[value.type].push(value)})},$scope.getNotifications=function(){$http.get(RESTURL.url+"notify",{ignoreLoadingBar:!0}).success(function(data){$scope.groupNotifications(data.notifications),$rootScope.$broadcast("notifications",$scope.notifications)})},$scope.getNotifications(),$interval(function(){"on"==$cookies.get("notificate")&&$scope.getNotifications()},5e3),$scope.markAsRead=function(items){$http.post(RESTURL.url+"notify",{ignoreLoadingBar:!0,read:[items]}).success(function(data){$scope.groupNotifications(data.notifications),$rootScope.$broadcast("notifications",$scope.notifications)})},$scope.$on("markasread",function(event,data){$scope.markAsRead(data)})}}}),app.directive("collapseMenu",function($timeout,$window){return{templateUrl:"shared/templates/directives/menuCollapse.html",restrict:"E",replace:!0,scope:{},controller:function($scope,$rootScope){$rootScope.collapsed=!1,$rootScope.sidebarPinned=!1,$scope.collapseToggle=function(){$window.innerWidth>"768"&&($rootScope.collapsed===!1?(jQuery(".sidebar").css("width","62px"),jQuery(".manager-view").css("width","calc(100% - 62px)"),$rootScope.collapsed=!0,$rootScope.sidebarPinned=!1):(jQuery("span.menu-text, span.arrow, .sidebar footer").fadeIn(400),jQuery(".sidebar").css("width","250px"),jQuery(".manager-view").css("width","calc(100% - 250px)"),$rootScope.collapsed=!1,$rootScope.sidebarPinned=!0))},$timeout(function(){$scope.collapseToggle()})}}}),app.directive("headerSubMenu",function($location){return{templateUrl:"shared/templates/directives/header-sub-menu.html",restrict:"E",replace:!0,link:function($scope){$scope.$on("$routeChangeStart",function(){$scope.style="/dashboard"===$location.path()?"width:calc(100% - 300px);":"width:%100 !important;"})}}}),app.directive("headerBreadcrumb",function(){return{templateUrl:"shared/templates/directives/header-breadcrumb.html",restrict:"E",replace:!0}}),app.directive("selectedUser",function(){return{templateUrl:"shared/templates/directives/selected-user.html",restrict:"E",replace:!1,link:function($scope,$rootScope){$scope.selectedUser=$rootScope.selectedUser}}}),app.directive("sidebar",["$location",function(){return{templateUrl:"shared/templates/directives/sidebar.html",restrict:"E",replace:!0,scope:{},controller:function($scope,$rootScope,$cookies,$route,$http,RESTURL,$location,$window,$timeout){$scope.prepareMenu=function(menuItems){var newMenuItems={};return angular.forEach(menuItems,function(value,key){angular.forEach(value,function(v,k){newMenuItems[k]=v})}),newMenuItems};var sidebarmenu=$("#side-menu");sidebarmenu.metisMenu(),$http.get(RESTURL.url+"menu/").success(function(data){function reGroupMenuItems(items,baseCategory){var newItems={};return angular.forEach(items,function(value,key){newItems[value.kategori]=newItems[value.kategori]||[],value.baseCategory=baseCategory,value.wf=value.url.split("/")[0],value.model=value.url.split("/")[1],newItems[value.kategori].push(value)}),newItems}$scope.allMenuItems=angular.copy(data),angular.forEach($scope.allMenuItems,function(value,key){$scope.allMenuItems[key]=reGroupMenuItems(value,key)}),$rootScope.$broadcast("authz",data),$scope.menuItems=$scope.prepareMenu({other:$scope.allMenuItems.other}),$timeout(function(){sidebarmenu.metisMenu()})}),$scope.$on("menuitems",function(event,data){var menu={other:$scope.allMenuItems.other};menu[data]=$scope.allMenuItems[data],$scope.menuItems=$scope.prepareMenu(menu),$timeout(function(){sidebarmenu.metisMenu()})}),$scope.openSidebar=function(){$window.innerWidth>"768"&&$rootScope.sidebarPinned===!1&&(jQuery("span.menu-text, span.arrow, .sidebar footer, #side-menu").fadeIn(400),jQuery(".sidebar").css("width","250px"),jQuery(".manager-view").css("width","calc(100% - 250px)"),$rootScope.collapsed=!1)},$scope.closeSidebar=function(){$window.innerWidth>"768"&&$rootScope.sidebarPinned===!1&&(jQuery(".sidebar").css("width","62px"),jQuery(".manager-view").css("width","calc(100% - 62px)"),$rootScope.collapsed=!0)},$rootScope.$watch(function($rootScope){return $rootScope.section},function(newindex,oldindex){newindex>-1&&($scope.menuItems=[$scope.allMenuItems[newindex]],$scope.collapseVar=1)}),$scope.selectedMenu=$location.path(),$scope.collapseVar=0,$scope.multiCollapseVar=0,$scope.check=function(x){x===$scope.collapseVar?$scope.collapseVar=0:$scope.collapseVar=x},$scope.breadcrumb=function(itemlist,$event){$rootScope.breadcrumblinks=itemlist,$rootScope.showSaveButton=!1},$scope.multiCheck=function(y){y===$scope.multiCollapseVar?$scope.multiCollapseVar=0:$scope.multiCollapseVar=y}}}}]),app.directive("stats",function(){return{templateUrl:"shared/templates/directives/stats.html",restrict:"E",replace:!0,scope:{model:"=",comments:"@",number:"@",name:"@",colour:"@",details:"@",type:"@","goto":"@"}}}),app.directive("notifications",function(){return{templateUrl:"shared/templates/directives/notifications.html",restrict:"E",replace:!0}}),app.directive("msgbox",function(){return{templateUrl:"shared/templates/directives/msgbox.html",restrict:"E",replace:!1}}),app.directive("sidebarSearch",function(){return{templateUrl:"shared/templates/directives/sidebar-search.html",restrict:"E",replace:!0,scope:{},controller:function($scope){$scope.selectedMenu="home"}}});var auth=angular.module("ulakbus.auth",["ngRoute","schemaForm","ngCookies","general"]);auth.controller("LoginCtrl",function($scope,$q,$timeout,$routeParams,Generator,LoginService){$scope.url="login",$scope.form_params={},$scope.form_params.clear_wf=1,Generator.get_form($scope).then(function(data){$scope.form=[{key:"username",type:"string",title:"Kullanıcı Adı"},{key:"password",type:"password",title:"Şifre"},{type:"submit",title:"Giriş Yap"}]}),$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid?LoginService.login($scope.url,$scope.model).error(function(data){$scope.message=data.title}):console.log("not valid")}}),auth.factory("LoginService",function($http,$rootScope,$location,$log,Session,RESTURL){var loginService={};return loginService.login=function(url,credentials){return credentials.cmd="do",$http.post(RESTURL.url+url,credentials).success(function(data,status,headers,config){$rootScope.loggedInUser=!0}).error(function(data,status,headers,config){return data})},loginService.logout=function(){return $log.info("logout"),$http.post(RESTURL.url+"logout",{}).success(function(data){$rootScope.loggedInUser=!1,$location.path("/login")})},loginService.isAuthenticated=function(){return!!Session.userId},loginService.isAuthorized=function(authorizedRoles){return angular.isArray(authorizedRoles)||(authorizedRoles=[authorizedRoles]),loginService.isAuthenticated()&&-1!==loginService.indexOf(Session.userRole)},loginService.isValidEmail=function(email){var re=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;return re.test(email)},loginService}),auth.service("Session",function(){this.create=function(sessionId,userId,userRole){this.id=sessionId,this.userId=userId,this.userRole=userRole},this.destroy=function(){this.id=null,this.userId=null,this.userRole=null}}),angular.module("ulakbus.dashboard",["ngRoute"]).controller("DashCtrl",function($scope,$rootScope,$timeout,$http,$cookies,RESTURL){$scope.section=function(section_index){$rootScope.section=section_index},$scope.$on("authz",function(event,data){$scope.menuitems=data}),$scope.student_kw="",$scope.staff_kw="",$scope.students=[],$scope.staffs=[],$scope.search=function(where){$timeout(function(){"personel"===where&&$scope.staff_kw.length>2&&$scope.getItems(where,$scope.staff_kw).success(function(data){$scope.staffs=data.results}),"ogrenci"===where&&$scope.student_kw.length>2&&$scope.getItems(where,$scope.student_kw).success(function(data){$scope.students=data.results})})},$scope.getItems=function(where,what){return $http.get(RESTURL.url+"ara/"+where+"/"+what)},$scope.select=function(who,type){$rootScope.selectedUser={name:who[0],tcno:who[1],key:who[2]},$rootScope.$broadcast("menuitems",type)},$scope.$on("notifications",function(event,data){$scope.notifications=data}),$scope.markAsRead=function(items){$rootScope.$broadcast("markasread",items)}}).directive("sidebarNotifications",function(){return{templateUrl:"shared/templates/directives/sidebar-notification.html",restrict:"E",replace:!0,link:function($scope){}}});var crud=angular.module("ulakbus.crud",["ui.bootstrap","schemaForm","formService"]);crud.service("CrudUtility",function(){return{generateParam:function(scope,routeParams,cmd){return scope.url=routeParams.wf,angular.forEach(routeParams,function(value,key){key.indexOf("_id")>-1&&"param_id"!==key&&(scope.param=key,scope.param_id=value)}),scope.form_params={cmd:cmd,model:routeParams.model,param:scope.param||routeParams.param,id:scope.param_id||routeParams.param_id,wf:routeParams.wf,object_id:routeParams.key},scope.model=scope.form_params.model,scope.wf=scope.form_params.wf,scope.param=scope.form_params.param,scope.param_id=scope.form_params.id,scope},listPageItems:function(scope,pageData){angular.forEach(pageData,function(value,key){scope[key]=value})}}}),crud.controller("CRUDCtrl",function($scope,$routeParams,Generator,CrudUtility){CrudUtility.generateParam($scope,$routeParams),Generator.get_wf($scope)}),crud.controller("CRUDListFormCtrl",function($scope,$rootScope,$location,$http,$log,$modal,$timeout,Generator,$routeParams,CrudUtility){if("show"===$routeParams.cmd){CrudUtility.generateParam($scope,$routeParams,$routeParams.cmd);var createListObjects=function(){angular.forEach($scope.object,function(value,key){"object"==typeof value&&($scope.listobjects[key]=value,delete $scope.object[key])})};$scope.listobjects={};var pageData=Generator.getPageData();pageData.pageData===!0?($scope.object=pageData.object,Generator.setPageData({pageData:!1})):Generator.get_single_item($scope).then(function(res){$scope.object=res.data.object,$scope.model=$routeParams.model}),createListObjects()}if("form"===$routeParams.cmd||"list"===$routeParams.cmd){var setpageobjects=function(data){CrudUtility.listPageItems($scope,data),Generator.generate($scope,data),Generator.setPageData({pageData:!1})},pageData=Generator.getPageData();pageData.pageData===!0&&($log.debug("pagedata",pageData.pageData),CrudUtility.generateParam($scope,pageData,$routeParams.cmd),setpageobjects(pageData,pageData)),(void 0===pageData.pageData||pageData.pageData===!1)&&(CrudUtility.generateParam($scope,$routeParams,$routeParams.cmd),Generator.get_wf($scope)),$scope.$on("formLocator",function(event){$scope.formgenerated=event.targetScope.formgenerated}),$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid&&Generator.submit($scope)},$scope.do_action=function(key,action){Generator.doItemAction($scope,key,action)}}}),crud.directive("crudListDirective",function(){return{templateUrl:"components/crud/templates/list.html",restrict:"E",replace:!0}}),crud.directive("crudFormDirective",function(){return{templateUrl:"components/crud/templates/form.html",restrict:"E",replace:!0}}),crud.directive("crudShowDirective",function(){return{templateUrl:"components/crud/templates/show.html",restrict:"E",replace:!0}}),crud.directive("formLocator",function(){return{link:function(scope){scope.$emit("formLocator")}}}),angular.module("ulakbus.debug",["ngRoute"]).controller("DebugCtrl",function($scope,$rootScope,$location){$scope.debug_queries=$rootScope.debug_queries}),angular.module("ulakbus.devSettings",["ngRoute"]).controller("DevSettingsCtrl",function($scope,$cookies,$rootScope,RESTURL){$scope.backendurl=$cookies.get("backendurl"),$scope.notificate=$cookies.get("notificate")||"on",$scope.changeSettings=function(what,set){document.cookie=what+"="+set,$scope[what]=set,$rootScope.$broadcast(what,set)},$scope.switchOnOff=function(pinn){return"on"==pinn?"off":"on"},$scope.setbackendurl=function(){$scope.changeSettings("backendurl",$scope.backendurl),RESTURL.url=$scope.backendurl},$scope.setnotification=function(){$scope.changeSettings("notificate",$scope.switchOnOff($scope.notificate))}}),app.config(["$routeProvider",function($routeProvider){$routeProvider.when("/error/500",{templateUrl:"components/error_pages/500.html",controller:"500Ctrl"}).when("/error/404",{templateUrl:"components/error_pages/404.html",controller:"404Ctrl"})}]),angular.module("ulakbus.error_pages",["ngRoute"]).controller("500Ctrl",function($scope,$rootScope,$location){}).controller("404Ctrl",function($scope,$rootScope,$location){}),angular.module("ulakbus.version",["ulakbus.version.interpolate-filter","ulakbus.version.version-directive"]).value("version","0.4.1"),angular.module("ulakbus.version.interpolate-filter",[]).filter("interpolate",["version",function(version){return function(text){return String(text).replace(/\%VERSION\%/gm,version)}}]),angular.module("ulakbus.version.version-directive",[]).directive("appVersion",["version",function(version){return function(scope,elm,attrs){elm.text(version)}}]); "use strict";var app=angular.module("ulakbus",["ui.bootstrap","angular-loading-bar","ngRoute","ngSanitize","ngCookies","formService","ulakbus.dashboard","ulakbus.auth","ulakbus.error_pages","ulakbus.crud","ulakbus.debug","ulakbus.devSettings","ulakbus.version","gettext","templates-prod"]).constant("RESTURL",function(){var backendurl=location.href.indexOf("nightly")?"//nightly.api.ulakbus.net/":"//api.ulakbus.net/";if(document.cookie.indexOf("backendurl")>-1){var cookiearray=document.cookie.split(";");angular.forEach(cookiearray,function(item){item.indexOf("backendurl")>-1&&(backendurl=item.split("=")[1])})}if(location.href.indexOf("backendurl")>-1){var urlfromqstr=location.href.split("?")[1].split("=")[1];backendurl=decodeURIComponent(urlfromqstr.replace(/\+/g," ")),document.cookie="backendurl="+backendurl,window.location.href=window.location.href.split("?")[0]}return{url:backendurl}}()).constant("USER_ROLES",{all:"*",admin:"admin",student:"student",staff:"staff",dean:"dean"}).constant("AUTH_EVENTS",{loginSuccess:"auth-login-success",loginFailed:"auth-login-failed",logoutSuccess:"auth-logout-success",sessionTimeout:"auth-session-timeout",notAuthenticated:"auth-not-authenticated",notAuthorized:"auth-not-authorized"});app.config(["$routeProvider",function($routeProvider,$route){$routeProvider.when("/login",{templateUrl:"components/auth/login.html",controller:"LoginCtrl"}).when("/dashboard",{templateUrl:"components/dashboard/dashboard.html",controller:"DashCtrl"}).when("/dev/settings",{templateUrl:"components/devSettings/devSettings.html",controller:"DevSettingsCtrl"}).when("/debug/list",{templateUrl:"components/debug/debug.html",controller:"DebugCtrl"}).when("/:wf/",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDCtrl"}).when("/:wf/do/:cmd",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/do/:cmd/:key",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/:model",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDCtrl"}).when("/:wf/:model/do/:cmd",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/:model/do/:cmd/:key",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).otherwise({redirectTo:"/dashboard"})}]).run(function($rootScope){$rootScope.loggedInUser=!0,$rootScope.$on("$routeChangeStart",function(event,next,current){})}).config(["$httpProvider",function($httpProvider){$httpProvider.defaults.withCredentials=!0}]).run(function(gettextCatalog){gettextCatalog.setCurrentLanguage("tr"),gettextCatalog.debug=!0}).config(["cfpLoadingBarProvider",function(cfpLoadingBarProvider){cfpLoadingBarProvider.includeBar=!1,cfpLoadingBarProvider.parentSelector="loaderdiv",cfpLoadingBarProvider.spinnerTemplate='<div class="loader">Loading...</div>'}]),app.config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(function($q,$rootScope,$location,$timeout){return{request:function(config){return"POST"===config.method&&(config.headers["Content-Type"]="text/plain"),config},response:function(response){return response.data._debug_queries&&response.data._debug_queries.length>0&&($rootScope.debug_queries=$rootScope.debug_queries||[],$rootScope.debug_queries.push({url:response.config.url,queries:response.data._debug_queries})),response.data.is_login===!1&&($rootScope.loggedInUser=response.data.is_login,$location.path("/login")),response.data.is_login===!0&&($rootScope.loggedInUser=!0,"/login"===$location.path()&&$location.path("/dashboard")),response},responseError:function(rejection){var errorModal=function(){var codefield="";rejection.data.error&&(codefield="<p><pre>"+rejection.data.error+"</pre></p>"),$('<div class="modal"><div class="modal-dialog" style="width:1024px;" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button><h4 class="modal-title" id="exampleModalLabel">'+rejection.status+rejection.data.title+'</h4></div><div class="modal-body"><div class="alert alert-danger"><strong>'+rejection.data.description+"</strong>"+codefield+'</div></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div></div></div></div>').modal()};return-1===rejection.status&&(rejection.data={title:"error",description:"connection failed"},errorModal()),400===rejection.status&&$location.reload(),401===rejection.status&&($location.path("/login"),"/login"===$location.path()&&console.log("show errors on login form")),403===rejection.status&&(rejection.data.is_login===!0&&($rootScope.loggedInUser=!0,"/login"===$location.path()&&$location.path("/dashboard")),errorModal()),$rootScope.$broadcast("show_notifications",rejection.data),404===rejection.status&&errorModal(),500===rejection.status&&errorModal(),$q.reject(rejection)}}})}]),app.directive("logout",function($http,$location,RESTURL){return{link:function($scope,$element,$rootScope){$element.on("click",function(){$http.post(RESTURL.url+"logout",{}).then(function(){$rootScope.loggedInUser=!1,$location.path("/login")})})}}}).directive("headerNotification",function($http,$rootScope,$cookies,$interval,RESTURL){return{templateUrl:"shared/templates/directives/header-notification.html",restrict:"E",replace:!0,link:function($scope){$scope.groupNotifications=function(notifications){$scope.notifications={1:[],2:[],3:[],4:[]},angular.forEach(notifications,function(value,key){$scope.notifications[value.type].push(value)})},$scope.getNotifications=function(){$http.get(RESTURL.url+"notify",{ignoreLoadingBar:!0}).success(function(data){$scope.groupNotifications(data.notifications),$rootScope.$broadcast("notifications",$scope.notifications)})},$scope.getNotifications(),$interval(function(){"on"==$cookies.get("notificate")&&$scope.getNotifications()},5e3),$scope.markAsRead=function(items){$http.post(RESTURL.url+"notify",{ignoreLoadingBar:!0,read:[items]}).success(function(data){$scope.groupNotifications(data.notifications),$rootScope.$broadcast("notifications",$scope.notifications)})},$scope.$on("markasread",function(event,data){$scope.markAsRead(data)})}}}).directive("searchDirective",function(Generator,$log){return{templateUrl:"shared/templates/directives/search.html",restrict:"E",replace:!0,link:function($scope){$scope.searchForm=[{key:"searchbox",htmlClass:"pull-left"},{type:"submit",title:"Ara",htmlClass:"pull-left"}],$scope.searchSchema={type:"object",properties:{searchbox:{type:"string",minLength:2,title:"Ara","x-schema-form":{placeholder:"Arama kriteri giriniz..."}}},required:["searchbox"]},$scope.searchModel={searchbox:""},$scope.searchSubmit=function(form){if($scope.$broadcast("schemaFormValidate"),form.$valid){var searchparams={url:$scope.wf,token:$scope.$parent.token,object_id:$scope.$parent.object_id,form_params:{model:$scope.$parent.form_params.model,cmd:$scope.$parent.reload_cmd,flow:$scope.$parent.form_params.flow,param:"query",id:$scope.searchModel.searchbox}};Generator.submit(searchparams)}}}}}).directive("collapseMenu",function($timeout,$window){return{templateUrl:"shared/templates/directives/menuCollapse.html",restrict:"E",replace:!0,scope:{},controller:function($scope,$rootScope){$rootScope.collapsed=!1,$rootScope.sidebarPinned=!1,$scope.collapseToggle=function(){$window.innerWidth>"768"&&($rootScope.collapsed===!1?(jQuery(".sidebar").css("width","62px"),jQuery(".manager-view").css("width","calc(100% - 62px)"),$rootScope.collapsed=!0,$rootScope.sidebarPinned=!1):(jQuery("span.menu-text, span.arrow, .sidebar footer").fadeIn(400),jQuery(".sidebar").css("width","250px"),jQuery(".manager-view").css("width","calc(100% - 250px)"),$rootScope.collapsed=!1,$rootScope.sidebarPinned=!0))},$timeout(function(){$scope.collapseToggle()})}}}).directive("headerSubMenu",function($location){return{templateUrl:"shared/templates/directives/header-sub-menu.html",restrict:"E",replace:!0,link:function($scope){$scope.$on("$routeChangeStart",function(){$scope.style="/dashboard"===$location.path()?"width:calc(100% - 300px);":"width:%100 !important;"})}}}).directive("headerBreadcrumb",function(){return{templateUrl:"shared/templates/directives/header-breadcrumb.html",restrict:"E",replace:!0}}).directive("selectedUser",function(){return{templateUrl:"shared/templates/directives/selected-user.html",restrict:"E",replace:!1,link:function($scope,$rootScope){$scope.selectedUser=$rootScope.selectedUser}}}).directive("sidebar",["$location",function(){return{templateUrl:"shared/templates/directives/sidebar.html",restrict:"E",replace:!0,scope:{},controller:function($scope,$rootScope,$cookies,$route,$http,RESTURL,$location,$window,$timeout){$scope.prepareMenu=function(menuItems){var newMenuItems={};return angular.forEach(menuItems,function(value,key){angular.forEach(value,function(v,k){newMenuItems[k]=v})}),newMenuItems};var sidebarmenu=$("#side-menu");sidebarmenu.metisMenu(),$http.get(RESTURL.url+"menu/").success(function(data){function reGroupMenuItems(items,baseCategory){var newItems={};return angular.forEach(items,function(value,key){newItems[value.kategori]=newItems[value.kategori]||[],value.baseCategory=baseCategory,value.wf=value.url.split("/")[0],value.model=value.url.split("/")[1],newItems[value.kategori].push(value)}),newItems}$scope.allMenuItems=angular.copy(data),angular.forEach($scope.allMenuItems,function(value,key){$scope.allMenuItems[key]=reGroupMenuItems(value,key)}),$rootScope.$broadcast("authz",data),$scope.menuItems=$scope.prepareMenu({other:$scope.allMenuItems.other}),$timeout(function(){sidebarmenu.metisMenu()})}),$scope.$on("menuitems",function(event,data){var menu={other:$scope.allMenuItems.other};menu[data]=$scope.allMenuItems[data],$scope.menuItems=$scope.prepareMenu(menu),$timeout(function(){sidebarmenu.metisMenu()})}),$scope.openSidebar=function(){$window.innerWidth>"768"&&$rootScope.sidebarPinned===!1&&(jQuery("span.menu-text, span.arrow, .sidebar footer, #side-menu").fadeIn(400),jQuery(".sidebar").css("width","250px"),jQuery(".manager-view").css("width","calc(100% - 250px)"),$rootScope.collapsed=!1)},$scope.closeSidebar=function(){$window.innerWidth>"768"&&$rootScope.sidebarPinned===!1&&(jQuery(".sidebar").css("width","62px"),jQuery(".manager-view").css("width","calc(100% - 62px)"),$rootScope.collapsed=!0)},$rootScope.$watch(function($rootScope){return $rootScope.section},function(newindex,oldindex){newindex>-1&&($scope.menuItems=[$scope.allMenuItems[newindex]],$scope.collapseVar=1)}),$scope.selectedMenu=$location.path(),$scope.collapseVar=0,$scope.multiCollapseVar=0,$scope.check=function(x){x===$scope.collapseVar?$scope.collapseVar=0:$scope.collapseVar=x},$scope.breadcrumb=function(itemlist,$event){$rootScope.breadcrumblinks=itemlist,$rootScope.showSaveButton=!1},$scope.multiCheck=function(y){y===$scope.multiCollapseVar?$scope.multiCollapseVar=0:$scope.multiCollapseVar=y}}}}]).directive("stats",function(){return{templateUrl:"shared/templates/directives/stats.html",restrict:"E",replace:!0,scope:{model:"=",comments:"@",number:"@",name:"@",colour:"@",details:"@",type:"@","goto":"@"}}}).directive("notifications",function(){return{templateUrl:"shared/templates/directives/notifications.html",restrict:"E",replace:!0}}).directive("msgbox",function(){return{templateUrl:"shared/templates/directives/msgbox.html",restrict:"E",replace:!1}}).directive("sidebarSearch",function(){return{templateUrl:"shared/templates/directives/sidebar-search.html",restrict:"E",replace:!0,scope:{},controller:function($scope){$scope.selectedMenu="home"}}});var auth=angular.module("ulakbus.auth",["ngRoute","schemaForm","ngCookies"]);auth.controller("LoginCtrl",function($scope,$q,$timeout,$routeParams,Generator,LoginService){$scope.url="login",$scope.form_params={},$scope.form_params.clear_wf=1,Generator.get_form($scope).then(function(data){$scope.form=[{key:"username",type:"string",title:"Kullanıcı Adı"},{key:"password",type:"password",title:"Şifre"},{type:"submit",title:"Giriş Yap"}]}),$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid?LoginService.login($scope.url,$scope.model).error(function(data){$scope.message=data.title}):console.log("not valid")}}),auth.factory("LoginService",function($http,$rootScope,$location,$log,Session,RESTURL){var loginService={};return loginService.login=function(url,credentials){return credentials.cmd="do",$http.post(RESTURL.url+url,credentials).success(function(data,status,headers,config){$rootScope.loggedInUser=!0}).error(function(data,status,headers,config){return data})},loginService.logout=function(){return $log.info("logout"),$http.post(RESTURL.url+"logout",{}).success(function(data){$rootScope.loggedInUser=!1,$log.info("loggedout"),$location.path("/login")})},loginService.isAuthenticated=function(){return!!Session.userId},loginService.isAuthorized=function(authorizedRoles){return angular.isArray(authorizedRoles)||(authorizedRoles=[authorizedRoles]),loginService.isAuthenticated()&&-1!==loginService.indexOf(Session.userRole)},loginService.isValidEmail=function(email){var re=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;return re.test(email)},loginService}),auth.service("Session",function(){this.create=function(sessionId,userId,userRole){this.id=sessionId,this.userId=userId,this.userRole=userRole},this.destroy=function(){this.id=null,this.userId=null,this.userRole=null}}),angular.module("ulakbus.dashboard",["ngRoute"]).controller("DashCtrl",function($scope,$rootScope,$timeout,$http,$cookies,RESTURL){$scope.section=function(section_index){$rootScope.section=section_index},$scope.$on("authz",function(event,data){$scope.menuitems=data}),$scope.student_kw="",$scope.staff_kw="",$scope.students=[],$scope.staffs=[],$scope.search=function(where){$timeout(function(){"personel"===where&&$scope.staff_kw.length>2&&$scope.getItems(where,$scope.staff_kw).success(function(data){$scope.staffs=data.results}),"ogrenci"===where&&$scope.student_kw.length>2&&$scope.getItems(where,$scope.student_kw).success(function(data){$scope.students=data.results})})},$scope.getItems=function(where,what){return $http.get(RESTURL.url+"ara/"+where+"/"+what)},$scope.select=function(who,type){$rootScope.selectedUser={name:who[0],tcno:who[1],key:who[2]},$rootScope.$broadcast("menuitems",type)},$scope.$on("notifications",function(event,data){$scope.notifications=data}),$scope.markAsRead=function(items){$rootScope.$broadcast("markasread",items)}}).directive("sidebarNotifications",function(){return{templateUrl:"shared/templates/directives/sidebar-notification.html",restrict:"E",replace:!0,link:function($scope){}}}),angular.module("ulakbus.crud",["ui.bootstrap","schemaForm","formService"]).service("CrudUtility",function($log){return{generateParam:function(scope,routeParams,cmd){return scope.url=routeParams.wf,angular.forEach(routeParams,function(value,key){key.indexOf("_id")>-1&&"param_id"!==key&&(scope.param=key,scope.param_id=value)}),scope.form_params={cmd:cmd,model:routeParams.model,param:scope.param||routeParams.param,id:scope.param_id||routeParams.param_id,wf:routeParams.wf,object_id:routeParams.key},scope.model=scope.form_params.model,scope.wf=scope.form_params.wf,scope.param=scope.form_params.param,scope.param_id=scope.form_params.id,scope},listPageItems:function(scope,pageData){angular.forEach(pageData,function(value,key){scope[key]=value}),angular.forEach(scope.objects,function(value,key){if("-1"!==value){var linkIndexes=[];angular.forEach(value.actions,function(v,k){"link"===v.show_as&&(linkIndexes=v.fields)}),angular.forEach(value.fields,function(v,k){scope.objects[key].fields[k]={type:linkIndexes.indexOf(k)>-1?"link":"str",content:v}})}}),$log.debug(scope.objects)}}}).controller("CRUDCtrl",function($scope,$routeParams,Generator,CrudUtility){CrudUtility.generateParam($scope,$routeParams),Generator.get_wf($scope)}).controller("CRUDListFormCtrl",function($scope,$rootScope,$location,$http,$log,$modal,$timeout,Generator,$routeParams,CrudUtility){if("show"===$routeParams.cmd){CrudUtility.generateParam($scope,$routeParams,$routeParams.cmd);var createListObjects=function(){angular.forEach($scope.object,function(value,key){"object"==typeof value&&($scope.listobjects[key]=value,delete $scope.object[key])})};$scope.listobjects={};var pageData=Generator.getPageData();pageData.pageData===!0?($scope.object=pageData.object,Generator.setPageData({pageData:!1})):Generator.get_single_item($scope).then(function(res){$scope.object=res.data.object,$scope.model=$routeParams.model}),createListObjects()}if("form"===$routeParams.cmd||"list"===$routeParams.cmd){var setpageobjects=function(data){CrudUtility.listPageItems($scope,data),Generator.generate($scope,data),Generator.setPageData({pageData:!1})},pageData=Generator.getPageData();pageData.pageData===!0&&($log.debug("pagedata",pageData.pageData),CrudUtility.generateParam($scope,pageData,$routeParams.cmd),setpageobjects(pageData,pageData)),(void 0===pageData.pageData||pageData.pageData===!1)&&(CrudUtility.generateParam($scope,$routeParams,$routeParams.cmd),Generator.get_wf($scope)),$scope.$on("formLocator",function(event){$scope.formgenerated=event.targetScope.formgenerated}),$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid&&Generator.submit($scope)},$scope.do_action=function(key,action){Generator.doItemAction($scope,key,action)}}}).directive("crudListDirective",function(){return{templateUrl:"components/crud/templates/list.html",restrict:"E",replace:!0}}).directive("crudFormDirective",function(){return{templateUrl:"components/crud/templates/form.html",restrict:"E",replace:!0}}).directive("crudShowDirective",function(){return{templateUrl:"components/crud/templates/show.html",restrict:"E",replace:!0}}).directive("formLocator",function(){return{link:function(scope){scope.$emit("formLocator")}}}),angular.module("ulakbus.debug",["ngRoute"]).controller("DebugCtrl",function($scope,$rootScope,$location){$scope.debug_queries=$rootScope.debug_queries}),angular.module("ulakbus.devSettings",["ngRoute"]).controller("DevSettingsCtrl",function($scope,$cookies,$rootScope,RESTURL){$scope.backendurl=$cookies.get("backendurl"),$scope.notificate=$cookies.get("notificate")||"on",$scope.changeSettings=function(what,set){document.cookie=what+"="+set,$scope[what]=set,$rootScope.$broadcast(what,set)},$scope.switchOnOff=function(pinn){return"on"==pinn?"off":"on"},$scope.setbackendurl=function(){$scope.changeSettings("backendurl",$scope.backendurl),RESTURL.url=$scope.backendurl},$scope.setnotification=function(){$scope.changeSettings("notificate",$scope.switchOnOff($scope.notificate))}}),app.config(["$routeProvider",function($routeProvider){$routeProvider.when("/error/500",{templateUrl:"components/error_pages/500.html",controller:"500Ctrl"}).when("/error/404",{templateUrl:"components/error_pages/404.html",controller:"404Ctrl"})}]),angular.module("ulakbus.error_pages",["ngRoute"]).controller("500Ctrl",function($scope,$rootScope,$location){}).controller("404Ctrl",function($scope,$rootScope,$location){}),angular.module("ulakbus.version",["ulakbus.version.interpolate-filter","ulakbus.version.version-directive"]).value("version","0.4.1"),angular.module("ulakbus.version.interpolate-filter",[]).filter("interpolate",["version",function(version){return function(text){return String(text).replace(/\%VERSION\%/gm,version)}}]),angular.module("ulakbus.version.version-directive",[]).directive("appVersion",["version",function(version){return function(scope,elm,attrs){elm.text(version)}}]);
\ No newline at end of file \ No newline at end of file
/*! ulakbus-ui 2015-11-20 */ /*! ulakbus-ui 2015-11-23 */
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function($){"use strict";var version=$.fn.jquery.split(" ")[0].split(".");if(version[0]<2&&version[1]<9||1==version[0]&&9==version[1]&&version[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function($){"use strict";function transitionEnd(){var el=document.createElement("bootstrap"),transEndEventNames={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var name in transEndEventNames)if(void 0!==el.style[name])return{end:transEndEventNames[name]};return!1}$.fn.emulateTransitionEnd=function(duration){var called=!1,$el=this;$(this).one("bsTransitionEnd",function(){called=!0});var callback=function(){called||$($el).trigger($.support.transition.end)};return setTimeout(callback,duration),this},$(function(){$.support.transition=transitionEnd(),$.support.transition&&($.event.special.bsTransitionEnd={bindType:$.support.transition.end,delegateType:$.support.transition.end,handle:function(e){return $(e.target).is(this)?e.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.alert");data||$this.data("bs.alert",data=new Alert(this)),"string"==typeof option&&data[option].call($this)})}var dismiss='[data-dismiss="alert"]',Alert=function(el){$(el).on("click",dismiss,this.close)};Alert.VERSION="3.3.5",Alert.TRANSITION_DURATION=150,Alert.prototype.close=function(e){function removeElement(){$parent.detach().trigger("closed.bs.alert").remove()}var $this=$(this),selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,""));var $parent=$(selector);e&&e.preventDefault(),$parent.length||($parent=$this.closest(".alert")),$parent.trigger(e=$.Event("close.bs.alert")),e.isDefaultPrevented()||($parent.removeClass("in"),$.support.transition&&$parent.hasClass("fade")?$parent.one("bsTransitionEnd",removeElement).emulateTransitionEnd(Alert.TRANSITION_DURATION):removeElement())};var old=$.fn.alert;$.fn.alert=Plugin,$.fn.alert.Constructor=Alert,$.fn.alert.noConflict=function(){return $.fn.alert=old,this},$(document).on("click.bs.alert.data-api",dismiss,Alert.prototype.close)}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.button"),options="object"==typeof option&&option;data||$this.data("bs.button",data=new Button(this,options)),"toggle"==option?data.toggle():option&&data.setState(option)})}var Button=function(element,options){this.$element=$(element),this.options=$.extend({},Button.DEFAULTS,options),this.isLoading=!1};Button.VERSION="3.3.5",Button.DEFAULTS={loadingText:"loading..."},Button.prototype.setState=function(state){var d="disabled",$el=this.$element,val=$el.is("input")?"val":"html",data=$el.data();state+="Text",null==data.resetText&&$el.data("resetText",$el[val]()),setTimeout($.proxy(function(){$el[val](null==data[state]?this.options[state]:data[state]),"loadingText"==state?(this.isLoading=!0,$el.addClass(d).attr(d,d)):this.isLoading&&(this.isLoading=!1,$el.removeClass(d).removeAttr(d))},this),0)},Button.prototype.toggle=function(){var changed=!0,$parent=this.$element.closest('[data-toggle="buttons"]');if($parent.length){var $input=this.$element.find("input");"radio"==$input.prop("type")?($input.prop("checked")&&(changed=!1),$parent.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==$input.prop("type")&&($input.prop("checked")!==this.$element.hasClass("active")&&(changed=!1),this.$element.toggleClass("active")),$input.prop("checked",this.$element.hasClass("active")),changed&&$input.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var old=$.fn.button;$.fn.button=Plugin,$.fn.button.Constructor=Button,$.fn.button.noConflict=function(){return $.fn.button=old,this},$(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(e){var $btn=$(e.target);$btn.hasClass("btn")||($btn=$btn.closest(".btn")),Plugin.call($btn,"toggle"),$(e.target).is('input[type="radio"]')||$(e.target).is('input[type="checkbox"]')||e.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(e){$(e.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(e.type))})}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.carousel"),options=$.extend({},Carousel.DEFAULTS,$this.data(),"object"==typeof option&&option),action="string"==typeof option?option:options.slide;data||$this.data("bs.carousel",data=new Carousel(this,options)),"number"==typeof option?data.to(option):action?data[action]():options.interval&&data.pause().cycle()})}var Carousel=function(element,options){this.$element=$(element),this.$indicators=this.$element.find(".carousel-indicators"),this.options=options,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",$.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",$.proxy(this.pause,this)).on("mouseleave.bs.carousel",$.proxy(this.cycle,this))};Carousel.VERSION="3.3.5",Carousel.TRANSITION_DURATION=600,Carousel.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},Carousel.prototype.keydown=function(e){if(!/input|textarea/i.test(e.target.tagName)){switch(e.which){case 37:this.prev();break;case 39:this.next();break;default:return}e.preventDefault()}},Carousel.prototype.cycle=function(e){return e||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval($.proxy(this.next,this),this.options.interval)),this},Carousel.prototype.getItemIndex=function(item){return this.$items=item.parent().children(".item"),this.$items.index(item||this.$active)},Carousel.prototype.getItemForDirection=function(direction,active){var activeIndex=this.getItemIndex(active),willWrap="prev"==direction&&0===activeIndex||"next"==direction&&activeIndex==this.$items.length-1;if(willWrap&&!this.options.wrap)return active;var delta="prev"==direction?-1:1,itemIndex=(activeIndex+delta)%this.$items.length;return this.$items.eq(itemIndex)},Carousel.prototype.to=function(pos){var that=this,activeIndex=this.getItemIndex(this.$active=this.$element.find(".item.active"));return pos>this.$items.length-1||0>pos?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){that.to(pos)}):activeIndex==pos?this.pause().cycle():this.slide(pos>activeIndex?"next":"prev",this.$items.eq(pos))},Carousel.prototype.pause=function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&$.support.transition&&(this.$element.trigger($.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},Carousel.prototype.next=function(){return this.sliding?void 0:this.slide("next")},Carousel.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},Carousel.prototype.slide=function(type,next){var $active=this.$element.find(".item.active"),$next=next||this.getItemForDirection(type,$active),isCycling=this.interval,direction="next"==type?"left":"right",that=this;if($next.hasClass("active"))return this.sliding=!1;var relatedTarget=$next[0],slideEvent=$.Event("slide.bs.carousel",{relatedTarget:relatedTarget,direction:direction});if(this.$element.trigger(slideEvent),!slideEvent.isDefaultPrevented()){if(this.sliding=!0,isCycling&&this.pause(),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});return $.support.transition&&this.$element.hasClass("slide")?($next.addClass(type),$next[0].offsetWidth,$active.addClass(direction),$next.addClass(direction),$active.one("bsTransitionEnd",function(){$next.removeClass([type,direction].join(" ")).addClass("active"),$active.removeClass(["active",direction].join(" ")),that.sliding=!1,setTimeout(function(){that.$element.trigger(slidEvent)},0)}).emulateTransitionEnd(Carousel.TRANSITION_DURATION)):($active.removeClass("active"),$next.addClass("active"),this.sliding=!1,this.$element.trigger(slidEvent)),isCycling&&this.cycle(),this}};var old=$.fn.carousel;$.fn.carousel=Plugin,$.fn.carousel.Constructor=Carousel,$.fn.carousel.noConflict=function(){return $.fn.carousel=old,this};var clickHandler=function(e){var href,$this=$(this),$target=$($this.attr("data-target")||(href=$this.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,""));if($target.hasClass("carousel")){var options=$.extend({},$target.data(),$this.data()),slideIndex=$this.attr("data-slide-to");slideIndex&&(options.interval=!1),Plugin.call($target,options),slideIndex&&$target.data("bs.carousel").to(slideIndex),e.preventDefault()}};$(document).on("click.bs.carousel.data-api","[data-slide]",clickHandler).on("click.bs.carousel.data-api","[data-slide-to]",clickHandler),$(window).on("load",function(){$('[data-ride="carousel"]').each(function(){var $carousel=$(this);Plugin.call($carousel,$carousel.data())})})}(jQuery),+function($){"use strict";function getTargetFromTrigger($trigger){var href,target=$trigger.attr("data-target")||(href=$trigger.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,"");return $(target)}function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.collapse"),options=$.extend({},Collapse.DEFAULTS,$this.data(),"object"==typeof option&&option);!data&&options.toggle&&/show|hide/.test(option)&&(options.toggle=!1),data||$this.data("bs.collapse",data=new Collapse(this,options)),"string"==typeof option&&data[option]()})}var Collapse=function(element,options){this.$element=$(element),this.options=$.extend({},Collapse.DEFAULTS,options),this.$trigger=$('[data-toggle="collapse"][href="#'+element.id+'"],[data-toggle="collapse"][data-target="#'+element.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};Collapse.VERSION="3.3.5",Collapse.TRANSITION_DURATION=350,Collapse.DEFAULTS={toggle:!0},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")){var activesData,actives=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(actives&&actives.length&&(activesData=actives.data("bs.collapse"),activesData&&activesData.transitioning))){var startEvent=$.Event("show.bs.collapse");if(this.$element.trigger(startEvent),!startEvent.isDefaultPrevented()){actives&&actives.length&&(Plugin.call(actives,"hide"),activesData||actives.data("bs.collapse",null));var dimension=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[dimension](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!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(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])}}}},Collapse.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var startEvent=$.Event("hide.bs.collapse");if(this.$element.trigger(startEvent),!startEvent.isDefaultPrevented()){var dimension=this.dimension();this.$element[dimension](this.$element[dimension]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var complete=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return $.support.transition?void this.$element[dimension](0).one("bsTransitionEnd",$.proxy(complete,this)).emulateTransitionEnd(Collapse.TRANSITION_DURATION):complete.call(this)}}},Collapse.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},Collapse.prototype.getParent=function(){return $(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each($.proxy(function(i,element){var $element=$(element);this.addAriaAndCollapsedClass(getTargetFromTrigger($element),$element)},this)).end()},Collapse.prototype.addAriaAndCollapsedClass=function($element,$trigger){var isOpen=$element.hasClass("in");$element.attr("aria-expanded",isOpen),$trigger.toggleClass("collapsed",!isOpen).attr("aria-expanded",isOpen)};var old=$.fn.collapse;$.fn.collapse=Plugin,$.fn.collapse.Constructor=Collapse,$.fn.collapse.noConflict=function(){return $.fn.collapse=old,this},$(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(e){var $this=$(this);$this.attr("data-target")||e.preventDefault();var $target=getTargetFromTrigger($this),data=$target.data("bs.collapse"),option=data?"toggle":$this.data();Plugin.call($target,option)})}(jQuery),+function($){"use strict";function getParent($this){var selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&/#[A-Za-z]/.test(selector)&&selector.replace(/.*(?=#[^\s]*$)/,""));var $parent=selector&&$(selector);return $parent&&$parent.length?$parent:$this.parent()}function clearMenus(e){e&&3===e.which||($(backdrop).remove(),$(toggle).each(function(){var $this=$(this),$parent=getParent($this),relatedTarget={relatedTarget:this};$parent.hasClass("open")&&(e&&"click"==e.type&&/input|textarea/i.test(e.target.tagName)&&$.contains($parent[0],e.target)||($parent.trigger(e=$.Event("hide.bs.dropdown",relatedTarget)),e.isDefaultPrevented()||($this.attr("aria-expanded","false"),$parent.removeClass("open").trigger("hidden.bs.dropdown",relatedTarget))))}))}function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.dropdown");data||$this.data("bs.dropdown",data=new Dropdown(this)),"string"==typeof option&&data[option].call($this)})}var backdrop=".dropdown-backdrop",toggle='[data-toggle="dropdown"]',Dropdown=function(element){$(element).on("click.bs.dropdown",this.toggle)};Dropdown.VERSION="3.3.5",Dropdown.prototype.toggle=function(e){var $this=$(this);if(!$this.is(".disabled, :disabled")){var $parent=getParent($this),isActive=$parent.hasClass("open");if(clearMenus(),!isActive){"ontouchstart"in document.documentElement&&!$parent.closest(".navbar-nav").length&&$(document.createElement("div")).addClass("dropdown-backdrop").insertAfter($(this)).on("click",clearMenus);var relatedTarget={relatedTarget:this};if($parent.trigger(e=$.Event("show.bs.dropdown",relatedTarget)),e.isDefaultPrevented())return;$this.trigger("focus").attr("aria-expanded","true"),$parent.toggleClass("open").trigger("shown.bs.dropdown",relatedTarget)}return!1}},Dropdown.prototype.keydown=function(e){if(/(38|40|27|32)/.test(e.which)&&!/input|textarea/i.test(e.target.tagName)){var $this=$(this);if(e.preventDefault(),e.stopPropagation(),!$this.is(".disabled, :disabled")){var $parent=getParent($this),isActive=$parent.hasClass("open");if(!isActive&&27!=e.which||isActive&&27==e.which)return 27==e.which&&$parent.find(toggle).trigger("focus"),$this.trigger("click");var desc=" li:not(.disabled):visible a",$items=$parent.find(".dropdown-menu"+desc);if($items.length){var index=$items.index(e.target);38==e.which&&index>0&&index--,40==e.which&&index<$items.length-1&&index++,~index||(index=0),$items.eq(index).trigger("focus")}}}};var old=$.fn.dropdown;$.fn.dropdown=Plugin,$.fn.dropdown.Constructor=Dropdown,$.fn.dropdown.noConflict=function(){return $.fn.dropdown=old,this},$(document).on("click.bs.dropdown.data-api",clearMenus).on("click.bs.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("click.bs.dropdown.data-api",toggle,Dropdown.prototype.toggle).on("keydown.bs.dropdown.data-api",toggle,Dropdown.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",Dropdown.prototype.keydown)}(jQuery),+function($){"use strict";function Plugin(option,_relatedTarget){return this.each(function(){var $this=$(this),data=$this.data("bs.modal"),options=$.extend({},Modal.DEFAULTS,$this.data(),"object"==typeof option&&option);data||$this.data("bs.modal",data=new Modal(this,options)),"string"==typeof option?data[option](_relatedTarget):options.show&&data.show(_relatedTarget)})}var Modal=function(element,options){this.options=options,this.$body=$(document.body),this.$element=$(element),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,$.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};Modal.VERSION="3.3.5",Modal.TRANSITION_DURATION=300,Modal.BACKDROP_TRANSITION_DURATION=150,Modal.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},Modal.prototype.toggle=function(_relatedTarget){return this.isShown?this.hide():this.show(_relatedTarget)},Modal.prototype.show=function(_relatedTarget){var that=this,e=$.Event("show.bs.modal",{relatedTarget:_relatedTarget});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',$.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){that.$element.one("mouseup.dismiss.bs.modal",function(e){$(e.target).is(that.$element)&&(that.ignoreBackdropClick=!0)})}),this.backdrop(function(){var transition=$.support.transition&&that.$element.hasClass("fade");that.$element.parent().length||that.$element.appendTo(that.$body),that.$element.show().scrollTop(0),that.adjustDialog(),transition&&that.$element[0].offsetWidth,that.$element.addClass("in"),that.enforceFocus();var e=$.Event("shown.bs.modal",{relatedTarget:_relatedTarget});transition?that.$dialog.one("bsTransitionEnd",function(){that.$element.trigger("focus").trigger(e)}).emulateTransitionEnd(Modal.TRANSITION_DURATION):that.$element.trigger("focus").trigger(e)}))},Modal.prototype.hide=function(e){e&&e.preventDefault(),e=$.Event("hide.bs.modal"),this.$element.trigger(e),this.isShown&&!e.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),$(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),$.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",$.proxy(this.hideModal,this)).emulateTransitionEnd(Modal.TRANSITION_DURATION):this.hideModal())},Modal.prototype.enforceFocus=function(){$(document).off("focusin.bs.modal").on("focusin.bs.modal",$.proxy(function(e){this.$element[0]===e.target||this.$element.has(e.target).length||this.$element.trigger("focus")},this))},Modal.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",$.proxy(function(e){27==e.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},Modal.prototype.resize=function(){this.isShown?$(window).on("resize.bs.modal",$.proxy(this.handleUpdate,this)):$(window).off("resize.bs.modal")},Modal.prototype.hideModal=function(){var that=this;this.$element.hide(),this.backdrop(function(){that.$body.removeClass("modal-open"),that.resetAdjustments(),that.resetScrollbar(),that.$element.trigger("hidden.bs.modal")})},Modal.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},Modal.prototype.backdrop=function(callback){var that=this,animate=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var doAnimate=$.support.transition&&animate;if(this.$backdrop=$(document.createElement("div")).addClass("modal-backdrop "+animate).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",$.proxy(function(e){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(e.target===e.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),doAnimate&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!callback)return;doAnimate?this.$backdrop.one("bsTransitionEnd",callback).emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION):callback()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var callbackRemove=function(){that.removeBackdrop(),callback&&callback()};$.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",callbackRemove).emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION):callbackRemove()}else callback&&callback()},Modal.prototype.handleUpdate=function(){this.adjustDialog()},Modal.prototype.adjustDialog=function(){var modalIsOverflowing=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&modalIsOverflowing?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!modalIsOverflowing?this.scrollbarWidth:""})},Modal.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},Modal.prototype.checkScrollbar=function(){var fullWindowWidth=window.innerWidth;if(!fullWindowWidth){var documentElementRect=document.documentElement.getBoundingClientRect();fullWindowWidth=documentElementRect.right-Math.abs(documentElementRect.left)}this.bodyIsOverflowing=document.body.clientWidth<fullWindowWidth,this.scrollbarWidth=this.measureScrollbar()},Modal.prototype.setScrollbar=function(){var bodyPad=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",bodyPad+this.scrollbarWidth)},Modal.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},Modal.prototype.measureScrollbar=function(){var scrollDiv=document.createElement("div");scrollDiv.className="modal-scrollbar-measure",this.$body.append(scrollDiv);var scrollbarWidth=scrollDiv.offsetWidth-scrollDiv.clientWidth;return this.$body[0].removeChild(scrollDiv),scrollbarWidth};var old=$.fn.modal;$.fn.modal=Plugin,$.fn.modal.Constructor=Modal,$.fn.modal.noConflict=function(){return $.fn.modal=old,this},$(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(e){var $this=$(this),href=$this.attr("href"),$target=$($this.attr("data-target")||href&&href.replace(/.*(?=#[^\s]+$)/,"")),option=$target.data("bs.modal")?"toggle":$.extend({remote:!/#/.test(href)&&href},$target.data(),$this.data());$this.is("a")&&e.preventDefault(),$target.one("show.bs.modal",function(showEvent){showEvent.isDefaultPrevented()||$target.one("hidden.bs.modal",function(){$this.is(":visible")&&$this.trigger("focus")})}),Plugin.call($target,option,this)})}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.tooltip"),options="object"==typeof option&&option;(data||!/destroy|hide/.test(option))&&(data||$this.data("bs.tooltip",data=new Tooltip(this,options)),"string"==typeof option&&data[option]())})}var Tooltip=function(element,options){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",element,options)};Tooltip.VERSION="3.3.5",Tooltip.TRANSITION_DURATION=150,Tooltip.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},Tooltip.prototype.init=function(type,element,options){if(this.enabled=!0,this.type=type,this.$element=$(element),this.options=this.getOptions(options),this.$viewport=this.options.viewport&&$($.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var triggers=this.options.trigger.split(" "),i=triggers.length;i--;){var trigger=triggers[i];if("click"==trigger)this.$element.on("click."+this.type,this.options.selector,$.proxy(this.toggle,this));else if("manual"!=trigger){var eventIn="hover"==trigger?"mouseenter":"focusin",eventOut="hover"==trigger?"mouseleave":"focusout";this.$element.on(eventIn+"."+this.type,this.options.selector,$.proxy(this.enter,this)),this.$element.on(eventOut+"."+this.type,this.options.selector,$.proxy(this.leave,this))}}this.options.selector?this._options=$.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},Tooltip.prototype.getDefaults=function(){return Tooltip.DEFAULTS},Tooltip.prototype.getOptions=function(options){return options=$.extend({},this.getDefaults(),this.$element.data(),options),options.delay&&"number"==typeof options.delay&&(options.delay={show:options.delay,hide:options.delay}),options},Tooltip.prototype.getDelegateOptions=function(){var options={},defaults=this.getDefaults();return this._options&&$.each(this._options,function(key,value){defaults[key]!=value&&(options[key]=value)}),options},Tooltip.prototype.enter=function(obj){var self=obj instanceof this.constructor?obj:$(obj.currentTarget).data("bs."+this.type);return self||(self=new this.constructor(obj.currentTarget,this.getDelegateOptions()),$(obj.currentTarget).data("bs."+this.type,self)),obj instanceof $.Event&&(self.inState["focusin"==obj.type?"focus":"hover"]=!0),self.tip().hasClass("in")||"in"==self.hoverState?void(self.hoverState="in"):(clearTimeout(self.timeout),self.hoverState="in",self.options.delay&&self.options.delay.show?void(self.timeout=setTimeout(function(){"in"==self.hoverState&&self.show()},self.options.delay.show)):self.show())},Tooltip.prototype.isInStateTrue=function(){for(var key in this.inState)if(this.inState[key])return!0;return!1},Tooltip.prototype.leave=function(obj){var self=obj instanceof this.constructor?obj:$(obj.currentTarget).data("bs."+this.type);return self||(self=new this.constructor(obj.currentTarget,this.getDelegateOptions()),$(obj.currentTarget).data("bs."+this.type,self)),obj instanceof $.Event&&(self.inState["focusout"==obj.type?"focus":"hover"]=!1),self.isInStateTrue()?void 0:(clearTimeout(self.timeout),self.hoverState="out",self.options.delay&&self.options.delay.hide?void(self.timeout=setTimeout(function(){"out"==self.hoverState&&self.hide()},self.options.delay.hide)):self.hide())},Tooltip.prototype.show=function(){var e=$.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var inDom=$.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!inDom)return;var that=this,$tip=this.tip(),tipId=this.getUID(this.type);this.setContent(),$tip.attr("id",tipId),this.$element.attr("aria-describedby",tipId),this.options.animation&&$tip.addClass("fade");var placement="function"==typeof this.options.placement?this.options.placement.call(this,$tip[0],this.$element[0]):this.options.placement,autoToken=/\s?auto?\s?/i,autoPlace=autoToken.test(placement);autoPlace&&(placement=placement.replace(autoToken,"")||"top"),$tip.detach().css({top:0,left:0,display:"block"}).addClass(placement).data("bs."+this.type,this),this.options.container?$tip.appendTo(this.options.container):$tip.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var pos=this.getPosition(),actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight;if(autoPlace){var orgPlacement=placement,viewportDim=this.getPosition(this.$viewport);placement="bottom"==placement&&pos.bottom+actualHeight>viewportDim.bottom?"top":"top"==placement&&pos.top-actualHeight<viewportDim.top?"bottom":"right"==placement&&pos.right+actualWidth>viewportDim.width?"left":"left"==placement&&pos.left-actualWidth<viewportDim.left?"right":placement,$tip.removeClass(orgPlacement).addClass(placement)}var calculatedOffset=this.getCalculatedOffset(placement,pos,actualWidth,actualHeight);this.applyPlacement(calculatedOffset,placement);var complete=function(){var prevHoverState=that.hoverState;that.$element.trigger("shown.bs."+that.type),that.hoverState=null,"out"==prevHoverState&&that.leave(that)};$.support.transition&&this.$tip.hasClass("fade")?$tip.one("bsTransitionEnd",complete).emulateTransitionEnd(Tooltip.TRANSITION_DURATION):complete()}},Tooltip.prototype.applyPlacement=function(offset,placement){var $tip=this.tip(),width=$tip[0].offsetWidth,height=$tip[0].offsetHeight,marginTop=parseInt($tip.css("margin-top"),10),marginLeft=parseInt($tip.css("margin-left"),10);isNaN(marginTop)&&(marginTop=0),isNaN(marginLeft)&&(marginLeft=0),offset.top+=marginTop,offset.left+=marginLeft,$.offset.setOffset($tip[0],$.extend({using:function(props){$tip.css({top:Math.round(props.top),left:Math.round(props.left)})}},offset),0),$tip.addClass("in");var actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight;"top"==placement&&actualHeight!=height&&(offset.top=offset.top+height-actualHeight);var delta=this.getViewportAdjustedDelta(placement,offset,actualWidth,actualHeight);delta.left?offset.left+=delta.left:offset.top+=delta.top;var isVertical=/top|bottom/.test(placement),arrowDelta=isVertical?2*delta.left-width+actualWidth:2*delta.top-height+actualHeight,arrowOffsetPosition=isVertical?"offsetWidth":"offsetHeight";$tip.offset(offset),this.replaceArrow(arrowDelta,$tip[0][arrowOffsetPosition],isVertical)},Tooltip.prototype.replaceArrow=function(delta,dimension,isVertical){this.arrow().css(isVertical?"left":"top",50*(1-delta/dimension)+"%").css(isVertical?"top":"left","")},Tooltip.prototype.setContent=function(){var $tip=this.tip(),title=this.getTitle();$tip.find(".tooltip-inner")[this.options.html?"html":"text"](title),$tip.removeClass("fade in top bottom left right")},Tooltip.prototype.hide=function(callback){function complete(){"in"!=that.hoverState&&$tip.detach(),that.$element.removeAttr("aria-describedby").trigger("hidden.bs."+that.type),callback&&callback()}var that=this,$tip=$(this.$tip),e=$.Event("hide.bs."+this.type);return this.$element.trigger(e),e.isDefaultPrevented()?void 0:($tip.removeClass("in"),$.support.transition&&$tip.hasClass("fade")?$tip.one("bsTransitionEnd",complete).emulateTransitionEnd(Tooltip.TRANSITION_DURATION):complete(),this.hoverState=null,this)},Tooltip.prototype.fixTitle=function(){var $e=this.$element;($e.attr("title")||"string"!=typeof $e.attr("data-original-title"))&&$e.attr("data-original-title",$e.attr("title")||"").attr("title","")},Tooltip.prototype.hasContent=function(){return this.getTitle()},Tooltip.prototype.getPosition=function($element){$element=$element||this.$element;var el=$element[0],isBody="BODY"==el.tagName,elRect=el.getBoundingClientRect();null==elRect.width&&(elRect=$.extend({},elRect,{width:elRect.right-elRect.left,height:elRect.bottom-elRect.top}));var elOffset=isBody?{top:0,left:0}:$element.offset(),scroll={scroll:isBody?document.documentElement.scrollTop||document.body.scrollTop:$element.scrollTop() if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function($){"use strict";var version=$.fn.jquery.split(" ")[0].split(".");if(version[0]<2&&version[1]<9||1==version[0]&&9==version[1]&&version[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function($){"use strict";function transitionEnd(){var el=document.createElement("bootstrap"),transEndEventNames={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var name in transEndEventNames)if(void 0!==el.style[name])return{end:transEndEventNames[name]};return!1}$.fn.emulateTransitionEnd=function(duration){var called=!1,$el=this;$(this).one("bsTransitionEnd",function(){called=!0});var callback=function(){called||$($el).trigger($.support.transition.end)};return setTimeout(callback,duration),this},$(function(){$.support.transition=transitionEnd(),$.support.transition&&($.event.special.bsTransitionEnd={bindType:$.support.transition.end,delegateType:$.support.transition.end,handle:function(e){return $(e.target).is(this)?e.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.alert");data||$this.data("bs.alert",data=new Alert(this)),"string"==typeof option&&data[option].call($this)})}var dismiss='[data-dismiss="alert"]',Alert=function(el){$(el).on("click",dismiss,this.close)};Alert.VERSION="3.3.5",Alert.TRANSITION_DURATION=150,Alert.prototype.close=function(e){function removeElement(){$parent.detach().trigger("closed.bs.alert").remove()}var $this=$(this),selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,""));var $parent=$(selector);e&&e.preventDefault(),$parent.length||($parent=$this.closest(".alert")),$parent.trigger(e=$.Event("close.bs.alert")),e.isDefaultPrevented()||($parent.removeClass("in"),$.support.transition&&$parent.hasClass("fade")?$parent.one("bsTransitionEnd",removeElement).emulateTransitionEnd(Alert.TRANSITION_DURATION):removeElement())};var old=$.fn.alert;$.fn.alert=Plugin,$.fn.alert.Constructor=Alert,$.fn.alert.noConflict=function(){return $.fn.alert=old,this},$(document).on("click.bs.alert.data-api",dismiss,Alert.prototype.close)}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.button"),options="object"==typeof option&&option;data||$this.data("bs.button",data=new Button(this,options)),"toggle"==option?data.toggle():option&&data.setState(option)})}var Button=function(element,options){this.$element=$(element),this.options=$.extend({},Button.DEFAULTS,options),this.isLoading=!1};Button.VERSION="3.3.5",Button.DEFAULTS={loadingText:"loading..."},Button.prototype.setState=function(state){var d="disabled",$el=this.$element,val=$el.is("input")?"val":"html",data=$el.data();state+="Text",null==data.resetText&&$el.data("resetText",$el[val]()),setTimeout($.proxy(function(){$el[val](null==data[state]?this.options[state]:data[state]),"loadingText"==state?(this.isLoading=!0,$el.addClass(d).attr(d,d)):this.isLoading&&(this.isLoading=!1,$el.removeClass(d).removeAttr(d))},this),0)},Button.prototype.toggle=function(){var changed=!0,$parent=this.$element.closest('[data-toggle="buttons"]');if($parent.length){var $input=this.$element.find("input");"radio"==$input.prop("type")?($input.prop("checked")&&(changed=!1),$parent.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==$input.prop("type")&&($input.prop("checked")!==this.$element.hasClass("active")&&(changed=!1),this.$element.toggleClass("active")),$input.prop("checked",this.$element.hasClass("active")),changed&&$input.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var old=$.fn.button;$.fn.button=Plugin,$.fn.button.Constructor=Button,$.fn.button.noConflict=function(){return $.fn.button=old,this},$(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(e){var $btn=$(e.target);$btn.hasClass("btn")||($btn=$btn.closest(".btn")),Plugin.call($btn,"toggle"),$(e.target).is('input[type="radio"]')||$(e.target).is('input[type="checkbox"]')||e.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(e){$(e.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(e.type))})}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.carousel"),options=$.extend({},Carousel.DEFAULTS,$this.data(),"object"==typeof option&&option),action="string"==typeof option?option:options.slide;data||$this.data("bs.carousel",data=new Carousel(this,options)),"number"==typeof option?data.to(option):action?data[action]():options.interval&&data.pause().cycle()})}var Carousel=function(element,options){this.$element=$(element),this.$indicators=this.$element.find(".carousel-indicators"),this.options=options,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",$.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",$.proxy(this.pause,this)).on("mouseleave.bs.carousel",$.proxy(this.cycle,this))};Carousel.VERSION="3.3.5",Carousel.TRANSITION_DURATION=600,Carousel.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},Carousel.prototype.keydown=function(e){if(!/input|textarea/i.test(e.target.tagName)){switch(e.which){case 37:this.prev();break;case 39:this.next();break;default:return}e.preventDefault()}},Carousel.prototype.cycle=function(e){return e||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval($.proxy(this.next,this),this.options.interval)),this},Carousel.prototype.getItemIndex=function(item){return this.$items=item.parent().children(".item"),this.$items.index(item||this.$active)},Carousel.prototype.getItemForDirection=function(direction,active){var activeIndex=this.getItemIndex(active),willWrap="prev"==direction&&0===activeIndex||"next"==direction&&activeIndex==this.$items.length-1;if(willWrap&&!this.options.wrap)return active;var delta="prev"==direction?-1:1,itemIndex=(activeIndex+delta)%this.$items.length;return this.$items.eq(itemIndex)},Carousel.prototype.to=function(pos){var that=this,activeIndex=this.getItemIndex(this.$active=this.$element.find(".item.active"));return pos>this.$items.length-1||0>pos?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){that.to(pos)}):activeIndex==pos?this.pause().cycle():this.slide(pos>activeIndex?"next":"prev",this.$items.eq(pos))},Carousel.prototype.pause=function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&$.support.transition&&(this.$element.trigger($.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},Carousel.prototype.next=function(){return this.sliding?void 0:this.slide("next")},Carousel.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},Carousel.prototype.slide=function(type,next){var $active=this.$element.find(".item.active"),$next=next||this.getItemForDirection(type,$active),isCycling=this.interval,direction="next"==type?"left":"right",that=this;if($next.hasClass("active"))return this.sliding=!1;var relatedTarget=$next[0],slideEvent=$.Event("slide.bs.carousel",{relatedTarget:relatedTarget,direction:direction});if(this.$element.trigger(slideEvent),!slideEvent.isDefaultPrevented()){if(this.sliding=!0,isCycling&&this.pause(),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});return $.support.transition&&this.$element.hasClass("slide")?($next.addClass(type),$next[0].offsetWidth,$active.addClass(direction),$next.addClass(direction),$active.one("bsTransitionEnd",function(){$next.removeClass([type,direction].join(" ")).addClass("active"),$active.removeClass(["active",direction].join(" ")),that.sliding=!1,setTimeout(function(){that.$element.trigger(slidEvent)},0)}).emulateTransitionEnd(Carousel.TRANSITION_DURATION)):($active.removeClass("active"),$next.addClass("active"),this.sliding=!1,this.$element.trigger(slidEvent)),isCycling&&this.cycle(),this}};var old=$.fn.carousel;$.fn.carousel=Plugin,$.fn.carousel.Constructor=Carousel,$.fn.carousel.noConflict=function(){return $.fn.carousel=old,this};var clickHandler=function(e){var href,$this=$(this),$target=$($this.attr("data-target")||(href=$this.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,""));if($target.hasClass("carousel")){var options=$.extend({},$target.data(),$this.data()),slideIndex=$this.attr("data-slide-to");slideIndex&&(options.interval=!1),Plugin.call($target,options),slideIndex&&$target.data("bs.carousel").to(slideIndex),e.preventDefault()}};$(document).on("click.bs.carousel.data-api","[data-slide]",clickHandler).on("click.bs.carousel.data-api","[data-slide-to]",clickHandler),$(window).on("load",function(){$('[data-ride="carousel"]').each(function(){var $carousel=$(this);Plugin.call($carousel,$carousel.data())})})}(jQuery),+function($){"use strict";function getTargetFromTrigger($trigger){var href,target=$trigger.attr("data-target")||(href=$trigger.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,"");return $(target)}function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.collapse"),options=$.extend({},Collapse.DEFAULTS,$this.data(),"object"==typeof option&&option);!data&&options.toggle&&/show|hide/.test(option)&&(options.toggle=!1),data||$this.data("bs.collapse",data=new Collapse(this,options)),"string"==typeof option&&data[option]()})}var Collapse=function(element,options){this.$element=$(element),this.options=$.extend({},Collapse.DEFAULTS,options),this.$trigger=$('[data-toggle="collapse"][href="#'+element.id+'"],[data-toggle="collapse"][data-target="#'+element.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};Collapse.VERSION="3.3.5",Collapse.TRANSITION_DURATION=350,Collapse.DEFAULTS={toggle:!0},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")){var activesData,actives=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(actives&&actives.length&&(activesData=actives.data("bs.collapse"),activesData&&activesData.transitioning))){var startEvent=$.Event("show.bs.collapse");if(this.$element.trigger(startEvent),!startEvent.isDefaultPrevented()){actives&&actives.length&&(Plugin.call(actives,"hide"),activesData||actives.data("bs.collapse",null));var dimension=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[dimension](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!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(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])}}}},Collapse.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var startEvent=$.Event("hide.bs.collapse");if(this.$element.trigger(startEvent),!startEvent.isDefaultPrevented()){var dimension=this.dimension();this.$element[dimension](this.$element[dimension]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var complete=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return $.support.transition?void this.$element[dimension](0).one("bsTransitionEnd",$.proxy(complete,this)).emulateTransitionEnd(Collapse.TRANSITION_DURATION):complete.call(this)}}},Collapse.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},Collapse.prototype.getParent=function(){return $(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each($.proxy(function(i,element){var $element=$(element);this.addAriaAndCollapsedClass(getTargetFromTrigger($element),$element)},this)).end()},Collapse.prototype.addAriaAndCollapsedClass=function($element,$trigger){var isOpen=$element.hasClass("in");$element.attr("aria-expanded",isOpen),$trigger.toggleClass("collapsed",!isOpen).attr("aria-expanded",isOpen)};var old=$.fn.collapse;$.fn.collapse=Plugin,$.fn.collapse.Constructor=Collapse,$.fn.collapse.noConflict=function(){return $.fn.collapse=old,this},$(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(e){var $this=$(this);$this.attr("data-target")||e.preventDefault();var $target=getTargetFromTrigger($this),data=$target.data("bs.collapse"),option=data?"toggle":$this.data();Plugin.call($target,option)})}(jQuery),+function($){"use strict";function getParent($this){var selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&/#[A-Za-z]/.test(selector)&&selector.replace(/.*(?=#[^\s]*$)/,""));var $parent=selector&&$(selector);return $parent&&$parent.length?$parent:$this.parent()}function clearMenus(e){e&&3===e.which||($(backdrop).remove(),$(toggle).each(function(){var $this=$(this),$parent=getParent($this),relatedTarget={relatedTarget:this};$parent.hasClass("open")&&(e&&"click"==e.type&&/input|textarea/i.test(e.target.tagName)&&$.contains($parent[0],e.target)||($parent.trigger(e=$.Event("hide.bs.dropdown",relatedTarget)),e.isDefaultPrevented()||($this.attr("aria-expanded","false"),$parent.removeClass("open").trigger("hidden.bs.dropdown",relatedTarget))))}))}function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.dropdown");data||$this.data("bs.dropdown",data=new Dropdown(this)),"string"==typeof option&&data[option].call($this)})}var backdrop=".dropdown-backdrop",toggle='[data-toggle="dropdown"]',Dropdown=function(element){$(element).on("click.bs.dropdown",this.toggle)};Dropdown.VERSION="3.3.5",Dropdown.prototype.toggle=function(e){var $this=$(this);if(!$this.is(".disabled, :disabled")){var $parent=getParent($this),isActive=$parent.hasClass("open");if(clearMenus(),!isActive){"ontouchstart"in document.documentElement&&!$parent.closest(".navbar-nav").length&&$(document.createElement("div")).addClass("dropdown-backdrop").insertAfter($(this)).on("click",clearMenus);var relatedTarget={relatedTarget:this};if($parent.trigger(e=$.Event("show.bs.dropdown",relatedTarget)),e.isDefaultPrevented())return;$this.trigger("focus").attr("aria-expanded","true"),$parent.toggleClass("open").trigger("shown.bs.dropdown",relatedTarget)}return!1}},Dropdown.prototype.keydown=function(e){if(/(38|40|27|32)/.test(e.which)&&!/input|textarea/i.test(e.target.tagName)){var $this=$(this);if(e.preventDefault(),e.stopPropagation(),!$this.is(".disabled, :disabled")){var $parent=getParent($this),isActive=$parent.hasClass("open");if(!isActive&&27!=e.which||isActive&&27==e.which)return 27==e.which&&$parent.find(toggle).trigger("focus"),$this.trigger("click");var desc=" li:not(.disabled):visible a",$items=$parent.find(".dropdown-menu"+desc);if($items.length){var index=$items.index(e.target);38==e.which&&index>0&&index--,40==e.which&&index<$items.length-1&&index++,~index||(index=0),$items.eq(index).trigger("focus")}}}};var old=$.fn.dropdown;$.fn.dropdown=Plugin,$.fn.dropdown.Constructor=Dropdown,$.fn.dropdown.noConflict=function(){return $.fn.dropdown=old,this},$(document).on("click.bs.dropdown.data-api",clearMenus).on("click.bs.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("click.bs.dropdown.data-api",toggle,Dropdown.prototype.toggle).on("keydown.bs.dropdown.data-api",toggle,Dropdown.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",Dropdown.prototype.keydown)}(jQuery),+function($){"use strict";function Plugin(option,_relatedTarget){return this.each(function(){var $this=$(this),data=$this.data("bs.modal"),options=$.extend({},Modal.DEFAULTS,$this.data(),"object"==typeof option&&option);data||$this.data("bs.modal",data=new Modal(this,options)),"string"==typeof option?data[option](_relatedTarget):options.show&&data.show(_relatedTarget)})}var Modal=function(element,options){this.options=options,this.$body=$(document.body),this.$element=$(element),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,$.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};Modal.VERSION="3.3.5",Modal.TRANSITION_DURATION=300,Modal.BACKDROP_TRANSITION_DURATION=150,Modal.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},Modal.prototype.toggle=function(_relatedTarget){return this.isShown?this.hide():this.show(_relatedTarget)},Modal.prototype.show=function(_relatedTarget){var that=this,e=$.Event("show.bs.modal",{relatedTarget:_relatedTarget});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',$.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){that.$element.one("mouseup.dismiss.bs.modal",function(e){$(e.target).is(that.$element)&&(that.ignoreBackdropClick=!0)})}),this.backdrop(function(){var transition=$.support.transition&&that.$element.hasClass("fade");that.$element.parent().length||that.$element.appendTo(that.$body),that.$element.show().scrollTop(0),that.adjustDialog(),transition&&that.$element[0].offsetWidth,that.$element.addClass("in"),that.enforceFocus();var e=$.Event("shown.bs.modal",{relatedTarget:_relatedTarget});transition?that.$dialog.one("bsTransitionEnd",function(){that.$element.trigger("focus").trigger(e)}).emulateTransitionEnd(Modal.TRANSITION_DURATION):that.$element.trigger("focus").trigger(e)}))},Modal.prototype.hide=function(e){e&&e.preventDefault(),e=$.Event("hide.bs.modal"),this.$element.trigger(e),this.isShown&&!e.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),$(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),$.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",$.proxy(this.hideModal,this)).emulateTransitionEnd(Modal.TRANSITION_DURATION):this.hideModal())},Modal.prototype.enforceFocus=function(){$(document).off("focusin.bs.modal").on("focusin.bs.modal",$.proxy(function(e){this.$element[0]===e.target||this.$element.has(e.target).length||this.$element.trigger("focus")},this))},Modal.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",$.proxy(function(e){27==e.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},Modal.prototype.resize=function(){this.isShown?$(window).on("resize.bs.modal",$.proxy(this.handleUpdate,this)):$(window).off("resize.bs.modal")},Modal.prototype.hideModal=function(){var that=this;this.$element.hide(),this.backdrop(function(){that.$body.removeClass("modal-open"),that.resetAdjustments(),that.resetScrollbar(),that.$element.trigger("hidden.bs.modal")})},Modal.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},Modal.prototype.backdrop=function(callback){var that=this,animate=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var doAnimate=$.support.transition&&animate;if(this.$backdrop=$(document.createElement("div")).addClass("modal-backdrop "+animate).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",$.proxy(function(e){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(e.target===e.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),doAnimate&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!callback)return;doAnimate?this.$backdrop.one("bsTransitionEnd",callback).emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION):callback()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var callbackRemove=function(){that.removeBackdrop(),callback&&callback()};$.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",callbackRemove).emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION):callbackRemove()}else callback&&callback()},Modal.prototype.handleUpdate=function(){this.adjustDialog()},Modal.prototype.adjustDialog=function(){var modalIsOverflowing=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&modalIsOverflowing?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!modalIsOverflowing?this.scrollbarWidth:""})},Modal.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},Modal.prototype.checkScrollbar=function(){var fullWindowWidth=window.innerWidth;if(!fullWindowWidth){var documentElementRect=document.documentElement.getBoundingClientRect();fullWindowWidth=documentElementRect.right-Math.abs(documentElementRect.left)}this.bodyIsOverflowing=document.body.clientWidth<fullWindowWidth,this.scrollbarWidth=this.measureScrollbar()},Modal.prototype.setScrollbar=function(){var bodyPad=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",bodyPad+this.scrollbarWidth)},Modal.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},Modal.prototype.measureScrollbar=function(){var scrollDiv=document.createElement("div");scrollDiv.className="modal-scrollbar-measure",this.$body.append(scrollDiv);var scrollbarWidth=scrollDiv.offsetWidth-scrollDiv.clientWidth;return this.$body[0].removeChild(scrollDiv),scrollbarWidth};var old=$.fn.modal;$.fn.modal=Plugin,$.fn.modal.Constructor=Modal,$.fn.modal.noConflict=function(){return $.fn.modal=old,this},$(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(e){var $this=$(this),href=$this.attr("href"),$target=$($this.attr("data-target")||href&&href.replace(/.*(?=#[^\s]+$)/,"")),option=$target.data("bs.modal")?"toggle":$.extend({remote:!/#/.test(href)&&href},$target.data(),$this.data());$this.is("a")&&e.preventDefault(),$target.one("show.bs.modal",function(showEvent){showEvent.isDefaultPrevented()||$target.one("hidden.bs.modal",function(){$this.is(":visible")&&$this.trigger("focus")})}),Plugin.call($target,option,this)})}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.tooltip"),options="object"==typeof option&&option;(data||!/destroy|hide/.test(option))&&(data||$this.data("bs.tooltip",data=new Tooltip(this,options)),"string"==typeof option&&data[option]())})}var Tooltip=function(element,options){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",element,options)};Tooltip.VERSION="3.3.5",Tooltip.TRANSITION_DURATION=150,Tooltip.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},Tooltip.prototype.init=function(type,element,options){if(this.enabled=!0,this.type=type,this.$element=$(element),this.options=this.getOptions(options),this.$viewport=this.options.viewport&&$($.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var triggers=this.options.trigger.split(" "),i=triggers.length;i--;){var trigger=triggers[i];if("click"==trigger)this.$element.on("click."+this.type,this.options.selector,$.proxy(this.toggle,this));else if("manual"!=trigger){var eventIn="hover"==trigger?"mouseenter":"focusin",eventOut="hover"==trigger?"mouseleave":"focusout";this.$element.on(eventIn+"."+this.type,this.options.selector,$.proxy(this.enter,this)),this.$element.on(eventOut+"."+this.type,this.options.selector,$.proxy(this.leave,this))}}this.options.selector?this._options=$.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},Tooltip.prototype.getDefaults=function(){return Tooltip.DEFAULTS},Tooltip.prototype.getOptions=function(options){return options=$.extend({},this.getDefaults(),this.$element.data(),options),options.delay&&"number"==typeof options.delay&&(options.delay={show:options.delay,hide:options.delay}),options},Tooltip.prototype.getDelegateOptions=function(){var options={},defaults=this.getDefaults();return this._options&&$.each(this._options,function(key,value){defaults[key]!=value&&(options[key]=value)}),options},Tooltip.prototype.enter=function(obj){var self=obj instanceof this.constructor?obj:$(obj.currentTarget).data("bs."+this.type);return self||(self=new this.constructor(obj.currentTarget,this.getDelegateOptions()),$(obj.currentTarget).data("bs."+this.type,self)),obj instanceof $.Event&&(self.inState["focusin"==obj.type?"focus":"hover"]=!0),self.tip().hasClass("in")||"in"==self.hoverState?void(self.hoverState="in"):(clearTimeout(self.timeout),self.hoverState="in",self.options.delay&&self.options.delay.show?void(self.timeout=setTimeout(function(){"in"==self.hoverState&&self.show()},self.options.delay.show)):self.show())},Tooltip.prototype.isInStateTrue=function(){for(var key in this.inState)if(this.inState[key])return!0;return!1},Tooltip.prototype.leave=function(obj){var self=obj instanceof this.constructor?obj:$(obj.currentTarget).data("bs."+this.type);return self||(self=new this.constructor(obj.currentTarget,this.getDelegateOptions()),$(obj.currentTarget).data("bs."+this.type,self)),obj instanceof $.Event&&(self.inState["focusout"==obj.type?"focus":"hover"]=!1),self.isInStateTrue()?void 0:(clearTimeout(self.timeout),self.hoverState="out",self.options.delay&&self.options.delay.hide?void(self.timeout=setTimeout(function(){"out"==self.hoverState&&self.hide()},self.options.delay.hide)):self.hide())},Tooltip.prototype.show=function(){var e=$.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var inDom=$.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!inDom)return;var that=this,$tip=this.tip(),tipId=this.getUID(this.type);this.setContent(),$tip.attr("id",tipId),this.$element.attr("aria-describedby",tipId),this.options.animation&&$tip.addClass("fade");var placement="function"==typeof this.options.placement?this.options.placement.call(this,$tip[0],this.$element[0]):this.options.placement,autoToken=/\s?auto?\s?/i,autoPlace=autoToken.test(placement);autoPlace&&(placement=placement.replace(autoToken,"")||"top"),$tip.detach().css({top:0,left:0,display:"block"}).addClass(placement).data("bs."+this.type,this),this.options.container?$tip.appendTo(this.options.container):$tip.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var pos=this.getPosition(),actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight;if(autoPlace){var orgPlacement=placement,viewportDim=this.getPosition(this.$viewport);placement="bottom"==placement&&pos.bottom+actualHeight>viewportDim.bottom?"top":"top"==placement&&pos.top-actualHeight<viewportDim.top?"bottom":"right"==placement&&pos.right+actualWidth>viewportDim.width?"left":"left"==placement&&pos.left-actualWidth<viewportDim.left?"right":placement,$tip.removeClass(orgPlacement).addClass(placement)}var calculatedOffset=this.getCalculatedOffset(placement,pos,actualWidth,actualHeight);this.applyPlacement(calculatedOffset,placement);var complete=function(){var prevHoverState=that.hoverState;that.$element.trigger("shown.bs."+that.type),that.hoverState=null,"out"==prevHoverState&&that.leave(that)};$.support.transition&&this.$tip.hasClass("fade")?$tip.one("bsTransitionEnd",complete).emulateTransitionEnd(Tooltip.TRANSITION_DURATION):complete()}},Tooltip.prototype.applyPlacement=function(offset,placement){var $tip=this.tip(),width=$tip[0].offsetWidth,height=$tip[0].offsetHeight,marginTop=parseInt($tip.css("margin-top"),10),marginLeft=parseInt($tip.css("margin-left"),10);isNaN(marginTop)&&(marginTop=0),isNaN(marginLeft)&&(marginLeft=0),offset.top+=marginTop,offset.left+=marginLeft,$.offset.setOffset($tip[0],$.extend({using:function(props){$tip.css({top:Math.round(props.top),left:Math.round(props.left)})}},offset),0),$tip.addClass("in");var actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight;"top"==placement&&actualHeight!=height&&(offset.top=offset.top+height-actualHeight);var delta=this.getViewportAdjustedDelta(placement,offset,actualWidth,actualHeight);delta.left?offset.left+=delta.left:offset.top+=delta.top;var isVertical=/top|bottom/.test(placement),arrowDelta=isVertical?2*delta.left-width+actualWidth:2*delta.top-height+actualHeight,arrowOffsetPosition=isVertical?"offsetWidth":"offsetHeight";$tip.offset(offset),this.replaceArrow(arrowDelta,$tip[0][arrowOffsetPosition],isVertical)},Tooltip.prototype.replaceArrow=function(delta,dimension,isVertical){this.arrow().css(isVertical?"left":"top",50*(1-delta/dimension)+"%").css(isVertical?"top":"left","")},Tooltip.prototype.setContent=function(){var $tip=this.tip(),title=this.getTitle();$tip.find(".tooltip-inner")[this.options.html?"html":"text"](title),$tip.removeClass("fade in top bottom left right")},Tooltip.prototype.hide=function(callback){function complete(){"in"!=that.hoverState&&$tip.detach(),that.$element.removeAttr("aria-describedby").trigger("hidden.bs."+that.type),callback&&callback()}var that=this,$tip=$(this.$tip),e=$.Event("hide.bs."+this.type);return this.$element.trigger(e),e.isDefaultPrevented()?void 0:($tip.removeClass("in"),$.support.transition&&$tip.hasClass("fade")?$tip.one("bsTransitionEnd",complete).emulateTransitionEnd(Tooltip.TRANSITION_DURATION):complete(),this.hoverState=null,this)},Tooltip.prototype.fixTitle=function(){var $e=this.$element;($e.attr("title")||"string"!=typeof $e.attr("data-original-title"))&&$e.attr("data-original-title",$e.attr("title")||"").attr("title","")},Tooltip.prototype.hasContent=function(){return this.getTitle()},Tooltip.prototype.getPosition=function($element){$element=$element||this.$element;var el=$element[0],isBody="BODY"==el.tagName,elRect=el.getBoundingClientRect();null==elRect.width&&(elRect=$.extend({},elRect,{width:elRect.right-elRect.left,height:elRect.bottom-elRect.top}));var elOffset=isBody?{top:0,left:0}:$element.offset(),scroll={scroll:isBody?document.documentElement.scrollTop||document.body.scrollTop:$element.scrollTop()
},outerDims=isBody?{width:$(window).width(),height:$(window).height()}:null;return $.extend({},elRect,scroll,outerDims,elOffset)},Tooltip.prototype.getCalculatedOffset=function(placement,pos,actualWidth,actualHeight){return"bottom"==placement?{top:pos.top+pos.height,left:pos.left+pos.width/2-actualWidth/2}:"top"==placement?{top:pos.top-actualHeight,left:pos.left+pos.width/2-actualWidth/2}:"left"==placement?{top:pos.top+pos.height/2-actualHeight/2,left:pos.left-actualWidth}:{top:pos.top+pos.height/2-actualHeight/2,left:pos.left+pos.width}},Tooltip.prototype.getViewportAdjustedDelta=function(placement,pos,actualWidth,actualHeight){var delta={top:0,left:0};if(!this.$viewport)return delta;var viewportPadding=this.options.viewport&&this.options.viewport.padding||0,viewportDimensions=this.getPosition(this.$viewport);if(/right|left/.test(placement)){var topEdgeOffset=pos.top-viewportPadding-viewportDimensions.scroll,bottomEdgeOffset=pos.top+viewportPadding-viewportDimensions.scroll+actualHeight;topEdgeOffset<viewportDimensions.top?delta.top=viewportDimensions.top-topEdgeOffset:bottomEdgeOffset>viewportDimensions.top+viewportDimensions.height&&(delta.top=viewportDimensions.top+viewportDimensions.height-bottomEdgeOffset)}else{var leftEdgeOffset=pos.left-viewportPadding,rightEdgeOffset=pos.left+viewportPadding+actualWidth;leftEdgeOffset<viewportDimensions.left?delta.left=viewportDimensions.left-leftEdgeOffset:rightEdgeOffset>viewportDimensions.right&&(delta.left=viewportDimensions.left+viewportDimensions.width-rightEdgeOffset)}return delta},Tooltip.prototype.getTitle=function(){var title,$e=this.$element,o=this.options;return title=$e.attr("data-original-title")||("function"==typeof o.title?o.title.call($e[0]):o.title)},Tooltip.prototype.getUID=function(prefix){do prefix+=~~(1e6*Math.random());while(document.getElementById(prefix));return prefix},Tooltip.prototype.tip=function(){if(!this.$tip&&(this.$tip=$(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},Tooltip.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},Tooltip.prototype.enable=function(){this.enabled=!0},Tooltip.prototype.disable=function(){this.enabled=!1},Tooltip.prototype.toggleEnabled=function(){this.enabled=!this.enabled},Tooltip.prototype.toggle=function(e){var self=this;e&&(self=$(e.currentTarget).data("bs."+this.type),self||(self=new this.constructor(e.currentTarget,this.getDelegateOptions()),$(e.currentTarget).data("bs."+this.type,self))),e?(self.inState.click=!self.inState.click,self.isInStateTrue()?self.enter(self):self.leave(self)):self.tip().hasClass("in")?self.leave(self):self.enter(self)},Tooltip.prototype.destroy=function(){var that=this;clearTimeout(this.timeout),this.hide(function(){that.$element.off("."+that.type).removeData("bs."+that.type),that.$tip&&that.$tip.detach(),that.$tip=null,that.$arrow=null,that.$viewport=null})};var old=$.fn.tooltip;$.fn.tooltip=Plugin,$.fn.tooltip.Constructor=Tooltip,$.fn.tooltip.noConflict=function(){return $.fn.tooltip=old,this}}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.popover"),options="object"==typeof option&&option;(data||!/destroy|hide/.test(option))&&(data||$this.data("bs.popover",data=new Popover(this,options)),"string"==typeof option&&data[option]())})}var Popover=function(element,options){this.init("popover",element,options)};if(!$.fn.tooltip)throw new Error("Popover requires tooltip.js");Popover.VERSION="3.3.5",Popover.DEFAULTS=$.extend({},$.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),Popover.prototype=$.extend({},$.fn.tooltip.Constructor.prototype),Popover.prototype.constructor=Popover,Popover.prototype.getDefaults=function(){return Popover.DEFAULTS},Popover.prototype.setContent=function(){var $tip=this.tip(),title=this.getTitle(),content=this.getContent();$tip.find(".popover-title")[this.options.html?"html":"text"](title),$tip.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof content?"html":"append":"text"](content),$tip.removeClass("fade top bottom left right in"),$tip.find(".popover-title").html()||$tip.find(".popover-title").hide()},Popover.prototype.hasContent=function(){return this.getTitle()||this.getContent()},Popover.prototype.getContent=function(){var $e=this.$element,o=this.options;return $e.attr("data-content")||("function"==typeof o.content?o.content.call($e[0]):o.content)},Popover.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var old=$.fn.popover;$.fn.popover=Plugin,$.fn.popover.Constructor=Popover,$.fn.popover.noConflict=function(){return $.fn.popover=old,this}}(jQuery),+function($){"use strict";function ScrollSpy(element,options){this.$body=$(document.body),this.$scrollElement=$($(element).is(document.body)?window:element),this.options=$.extend({},ScrollSpy.DEFAULTS,options),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",$.proxy(this.process,this)),this.refresh(),this.process()}function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.scrollspy"),options="object"==typeof option&&option;data||$this.data("bs.scrollspy",data=new ScrollSpy(this,options)),"string"==typeof option&&data[option]()})}ScrollSpy.VERSION="3.3.5",ScrollSpy.DEFAULTS={offset:10},ScrollSpy.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},ScrollSpy.prototype.refresh=function(){var that=this,offsetMethod="offset",offsetBase=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),$.isWindow(this.$scrollElement[0])||(offsetMethod="position",offsetBase=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var $el=$(this),href=$el.data("target")||$el.attr("href"),$href=/^#./.test(href)&&$(href);return $href&&$href.length&&$href.is(":visible")&&[[$href[offsetMethod]().top+offsetBase,href]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){that.offsets.push(this[0]),that.targets.push(this[1])})},ScrollSpy.prototype.process=function(){var i,scrollTop=this.$scrollElement.scrollTop()+this.options.offset,scrollHeight=this.getScrollHeight(),maxScroll=this.options.offset+scrollHeight-this.$scrollElement.height(),offsets=this.offsets,targets=this.targets,activeTarget=this.activeTarget;if(this.scrollHeight!=scrollHeight&&this.refresh(),scrollTop>=maxScroll)return activeTarget!=(i=targets[targets.length-1])&&this.activate(i);if(activeTarget&&scrollTop<offsets[0])return this.activeTarget=null,this.clear();for(i=offsets.length;i--;)activeTarget!=targets[i]&&scrollTop>=offsets[i]&&(void 0===offsets[i+1]||scrollTop<offsets[i+1])&&this.activate(targets[i])},ScrollSpy.prototype.activate=function(target){this.activeTarget=target,this.clear();var selector=this.selector+'[data-target="'+target+'"],'+this.selector+'[href="'+target+'"]',active=$(selector).parents("li").addClass("active");active.parent(".dropdown-menu").length&&(active=active.closest("li.dropdown").addClass("active")),active.trigger("activate.bs.scrollspy")},ScrollSpy.prototype.clear=function(){$(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var old=$.fn.scrollspy;$.fn.scrollspy=Plugin,$.fn.scrollspy.Constructor=ScrollSpy,$.fn.scrollspy.noConflict=function(){return $.fn.scrollspy=old,this},$(window).on("load.bs.scrollspy.data-api",function(){$('[data-spy="scroll"]').each(function(){var $spy=$(this);Plugin.call($spy,$spy.data())})})}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.tab");data||$this.data("bs.tab",data=new Tab(this)),"string"==typeof option&&data[option]()})}var Tab=function(element){this.element=$(element)};Tab.VERSION="3.3.5",Tab.TRANSITION_DURATION=150,Tab.prototype.show=function(){var $this=this.element,$ul=$this.closest("ul:not(.dropdown-menu)"),selector=$this.data("target");if(selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,"")),!$this.parent("li").hasClass("active")){var $previous=$ul.find(".active:last a"),hideEvent=$.Event("hide.bs.tab",{relatedTarget:$this[0]}),showEvent=$.Event("show.bs.tab",{relatedTarget:$previous[0]});if($previous.trigger(hideEvent),$this.trigger(showEvent),!showEvent.isDefaultPrevented()&&!hideEvent.isDefaultPrevented()){var $target=$(selector);this.activate($this.closest("li"),$ul),this.activate($target,$target.parent(),function(){$previous.trigger({type:"hidden.bs.tab",relatedTarget:$this[0]}),$this.trigger({type:"shown.bs.tab",relatedTarget:$previous[0]})})}}},Tab.prototype.activate=function(element,container,callback){function next(){$active.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),element.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),transition?(element[0].offsetWidth,element.addClass("in")):element.removeClass("fade"),element.parent(".dropdown-menu").length&&element.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),callback&&callback()}var $active=container.find("> .active"),transition=callback&&$.support.transition&&($active.length&&$active.hasClass("fade")||!!container.find("> .fade").length);$active.length&&transition?$active.one("bsTransitionEnd",next).emulateTransitionEnd(Tab.TRANSITION_DURATION):next(),$active.removeClass("in")};var old=$.fn.tab;$.fn.tab=Plugin,$.fn.tab.Constructor=Tab,$.fn.tab.noConflict=function(){return $.fn.tab=old,this};var clickHandler=function(e){e.preventDefault(),Plugin.call($(this),"show")};$(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',clickHandler).on("click.bs.tab.data-api",'[data-toggle="pill"]',clickHandler)}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.affix"),options="object"==typeof option&&option;data||$this.data("bs.affix",data=new Affix(this,options)),"string"==typeof option&&data[option]()})}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=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};Affix.VERSION="3.3.5",Affix.RESET="affix affix-top affix-bottom",Affix.DEFAULTS={offset:0,target:window},Affix.prototype.getState=function(scrollHeight,height,offsetTop,offsetBottom){var scrollTop=this.$target.scrollTop(),position=this.$element.offset(),targetHeight=this.$target.height();if(null!=offsetTop&&"top"==this.affixed)return offsetTop>scrollTop?"top":!1;if("bottom"==this.affixed)return null!=offsetTop?scrollTop+this.unpin<=position.top?!1:"bottom":scrollHeight-offsetBottom>=scrollTop+targetHeight?!1:"bottom";var initializing=null==this.affixed,colliderTop=initializing?scrollTop:position.top,colliderHeight=initializing?targetHeight:height;return null!=offsetTop&&offsetTop>=scrollTop?"top":null!=offsetBottom&&colliderTop+colliderHeight>=scrollHeight-offsetBottom?"bottom":!1},Affix.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(Affix.RESET).addClass("affix");var scrollTop=this.$target.scrollTop(),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")){var height=this.$element.height(),offset=this.options.offset,offsetTop=offset.top,offsetBottom=offset.bottom,scrollHeight=Math.max($(document).height(),$(document.body).height());"object"!=typeof offset&&(offsetBottom=offsetTop=offset),"function"==typeof offsetTop&&(offsetTop=offset.top(this.$element)),"function"==typeof offsetBottom&&(offsetBottom=offset.bottom(this.$element));var affix=this.getState(scrollHeight,height,offsetTop,offsetBottom);if(this.affixed!=affix){null!=this.unpin&&this.$element.css("top","");var affixType="affix"+(affix?"-"+affix:""),e=$.Event(affixType+".bs.affix");if(this.$element.trigger(e),e.isDefaultPrevented())return;this.affixed=affix,this.unpin="bottom"==affix?this.getPinnedOffset():null,this.$element.removeClass(Affix.RESET).addClass(affixType).trigger(affixType.replace("affix","affixed")+".bs.affix")}"bottom"==affix&&this.$element.offset({top:scrollHeight-height-offsetBottom})}};var old=$.fn.affix;$.fn.affix=Plugin,$.fn.affix.Constructor=Affix,$.fn.affix.noConflict=function(){return $.fn.affix=old,this},$(window).on("load",function(){$('[data-spy="affix"]').each(function(){var $spy=$(this),data=$spy.data();data.offset=data.offset||{},null!=data.offsetBottom&&(data.offset.bottom=data.offsetBottom),null!=data.offsetTop&&(data.offset.top=data.offsetTop),Plugin.call($spy,data)})})}(jQuery),function(window,angular,undefined){"use strict";function $RouteProvider(){function inherit(parent,extra){return angular.extend(Object.create(parent),extra)}function pathRegExp(path,opts){var insensitive=opts.caseInsensitiveMatch,ret={originalPath:path,regexp:path},keys=ret.keys=[];return path=path.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(_,slash,key,option){var optional="?"===option?option:null,star="*"===option?option:null;return keys.push({name:key,optional:!!optional}),slash=slash||"",""+(optional?"":slash)+"(?:"+(optional?slash:"")+(star&&"(.+?)"||"([^/]+)")+(optional||"")+")"+(optional||"")}).replace(/([\/$\*])/g,"\\$1"),ret.regexp=new RegExp("^"+path+"$",insensitive?"i":""),ret}var routes={};this.when=function(path,route){var routeCopy=angular.copy(route);if(angular.isUndefined(routeCopy.reloadOnSearch)&&(routeCopy.reloadOnSearch=!0),angular.isUndefined(routeCopy.caseInsensitiveMatch)&&(routeCopy.caseInsensitiveMatch=this.caseInsensitiveMatch),routes[path]=angular.extend(routeCopy,path&&pathRegExp(path,routeCopy)),path){var redirectPath="/"==path[path.length-1]?path.substr(0,path.length-1):path+"/";routes[redirectPath]=angular.extend({redirectTo:path},pathRegExp(redirectPath,routeCopy))}return this},this.caseInsensitiveMatch=!1,this.otherwise=function(params){return"string"==typeof params&&(params={redirectTo:params}),this.when(null,params),this},this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function($rootScope,$location,$routeParams,$q,$injector,$templateRequest,$sce){function switchRouteMatcher(on,route){var keys=route.keys,params={};if(!route.regexp)return null;var m=route.regexp.exec(on);if(!m)return null;for(var i=1,len=m.length;len>i;++i){var key=keys[i-1],val=m[i];key&&val&&(params[key.name]=val)}return params}function prepareRoute($locationEvent){var lastRoute=$route.current;preparedRoute=parseRoute(),preparedRouteIsUpdateOnly=preparedRoute&&lastRoute&&preparedRoute.$$route===lastRoute.$$route&&angular.equals(preparedRoute.pathParams,lastRoute.pathParams)&&!preparedRoute.reloadOnSearch&&!forceReload,preparedRouteIsUpdateOnly||!lastRoute&&!preparedRoute||$rootScope.$broadcast("$routeChangeStart",preparedRoute,lastRoute).defaultPrevented&&$locationEvent&&$locationEvent.preventDefault()}function commitRoute(){var lastRoute=$route.current,nextRoute=preparedRoute;preparedRouteIsUpdateOnly?(lastRoute.params=nextRoute.params,angular.copy(lastRoute.params,$routeParams),$rootScope.$broadcast("$routeUpdate",lastRoute)):(nextRoute||lastRoute)&&(forceReload=!1,$route.current=nextRoute,nextRoute&&nextRoute.redirectTo&&(angular.isString(nextRoute.redirectTo)?$location.path(interpolate(nextRoute.redirectTo,nextRoute.params)).search(nextRoute.params).replace():$location.url(nextRoute.redirectTo(nextRoute.pathParams,$location.path(),$location.search())).replace()),$q.when(nextRoute).then(function(){if(nextRoute){var template,templateUrl,locals=angular.extend({},nextRoute.resolve);return angular.forEach(locals,function(value,key){locals[key]=angular.isString(value)?$injector.get(value):$injector.invoke(value,null,null,key)}),angular.isDefined(template=nextRoute.template)?angular.isFunction(template)&&(template=template(nextRoute.params)):angular.isDefined(templateUrl=nextRoute.templateUrl)&&(angular.isFunction(templateUrl)&&(templateUrl=templateUrl(nextRoute.params)),angular.isDefined(templateUrl)&&(nextRoute.loadedTemplateUrl=$sce.valueOf(templateUrl),template=$templateRequest(templateUrl))),angular.isDefined(template)&&(locals.$template=template),$q.all(locals)}}).then(function(locals){nextRoute==$route.current&&(nextRoute&&(nextRoute.locals=locals,angular.copy(nextRoute.params,$routeParams)),$rootScope.$broadcast("$routeChangeSuccess",nextRoute,lastRoute))},function(error){nextRoute==$route.current&&$rootScope.$broadcast("$routeChangeError",nextRoute,lastRoute,error)}))}function parseRoute(){var params,match;return angular.forEach(routes,function(route,path){!match&&(params=switchRouteMatcher($location.path(),route))&&(match=inherit(route,{params:angular.extend({},$location.search(),params),pathParams:params}),match.$$route=route)}),match||routes[null]&&inherit(routes[null],{params:{},pathParams:{}})}function interpolate(string,params){var result=[];return angular.forEach((string||"").split(":"),function(segment,i){if(0===i)result.push(segment);else{var segmentMatch=segment.match(/(\w+)(?:[?*])?(.*)/),key=segmentMatch[1];result.push(params[key]),result.push(segmentMatch[2]||""),delete params[key]}}),result.join("")}var preparedRoute,preparedRouteIsUpdateOnly,forceReload=!1,$route={routes:routes,reload:function(){forceReload=!0,$rootScope.$evalAsync(function(){prepareRoute(),commitRoute()})},updateParams:function(newParams){if(!this.current||!this.current.$$route)throw $routeMinErr("norout","Tried updating route when with no current route");newParams=angular.extend({},this.current.params,newParams),$location.path(interpolate(this.current.$$route.originalPath,newParams)),$location.search(newParams)}};return $rootScope.$on("$locationChangeStart",prepareRoute),$rootScope.$on("$locationChangeSuccess",commitRoute),$route}]}function $RouteParamsProvider(){this.$get=function(){return{}}}function ngViewFactory($route,$anchorScroll,$animate){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(scope,$element,attr,ctrl,$transclude){function cleanupLastView(){previousLeaveAnimation&&($animate.cancel(previousLeaveAnimation),previousLeaveAnimation=null),currentScope&&(currentScope.$destroy(),currentScope=null),currentElement&&(previousLeaveAnimation=$animate.leave(currentElement),previousLeaveAnimation.then(function(){previousLeaveAnimation=null}),currentElement=null)}function update(){var locals=$route.current&&$route.current.locals,template=locals&&locals.$template;if(angular.isDefined(template)){var newScope=scope.$new(),current=$route.current,clone=$transclude(newScope,function(clone){$animate.enter(clone,null,currentElement||$element).then(function(){!angular.isDefined(autoScrollExp)||autoScrollExp&&!scope.$eval(autoScrollExp)||$anchorScroll()}),cleanupLastView()});currentElement=clone,currentScope=current.scope=newScope,currentScope.$emit("$viewContentLoaded"),currentScope.$eval(onloadExp)}else cleanupLastView()}var currentScope,currentElement,previousLeaveAnimation,autoScrollExp=attr.autoscroll,onloadExp=attr.onload||"";scope.$on("$routeChangeSuccess",update),update()}}}function ngViewFillContentFactory($compile,$controller,$route){return{restrict:"ECA",priority:-400,link:function(scope,$element){var current=$route.current,locals=current.locals;$element.html(locals.$template);var link=$compile($element.contents());if(current.controller){locals.$scope=scope;var controller=$controller(current.controller,locals);current.controllerAs&&(scope[current.controllerAs]=controller),$element.data("$ngControllerController",controller),$element.children().data("$ngControllerController",controller)}link(scope)}}}var ngRouteModule=angular.module("ngRoute",["ng"]).provider("$route",$RouteProvider),$routeMinErr=angular.$$minErr("ngRoute");ngRouteModule.provider("$routeParams",$RouteParamsProvider),ngRouteModule.directive("ngView",ngViewFactory),ngRouteModule.directive("ngView",ngViewFillContentFactory),ngViewFactory.$inject=["$route","$anchorScroll","$animate"],ngViewFillContentFactory.$inject=["$compile","$controller","$route"]}(window,window.angular),function(window,angular,undefined){"use strict";function $$CookieWriter($document,$log,$browser){function buildCookieString(name,value,options){var path,expires;options=options||{},expires=options.expires,path=angular.isDefined(options.path)?options.path:cookiePath,angular.isUndefined(value)&&(expires="Thu, 01 Jan 1970 00:00:00 GMT",value=""),angular.isString(expires)&&(expires=new Date(expires));var str=encodeURIComponent(name)+"="+encodeURIComponent(value);str+=path?";path="+path:"",str+=options.domain?";domain="+options.domain:"",str+=expires?";expires="+expires.toUTCString():"",str+=options.secure?";secure":"";var cookieLength=str.length+1;return cookieLength>4096&&$log.warn("Cookie '"+name+"' possibly not set or overflowed because it was too large ("+cookieLength+" > 4096 bytes)!"),str}var cookiePath=$browser.baseHref(),rawDocument=$document[0];return function(name,value,options){rawDocument.cookie=buildCookieString(name,value,options)}}angular.module("ngCookies",["ng"]).provider("$cookies",[function(){function calcOptions(options){return options?angular.extend({},defaults,options):defaults}var defaults=this.defaults={};this.$get=["$$cookieReader","$$cookieWriter",function($$cookieReader,$$cookieWriter){return{get:function(key){return $$cookieReader()[key]},getObject:function(key){var value=this.get(key);return value?angular.fromJson(value):value},getAll:function(){return $$cookieReader()},put:function(key,value,options){$$cookieWriter(key,value,calcOptions(options))},putObject:function(key,value,options){this.put(key,angular.toJson(value),options)},remove:function(key,options){$$cookieWriter(key,undefined,calcOptions(options))}}}]}]),angular.module("ngCookies").factory("$cookieStore",["$cookies",function($cookies){return{get:function(key){return $cookies.getObject(key)},put:function(key,value){$cookies.putObject(key,value)},remove:function(key){$cookies.remove(key)}}}]),$$CookieWriter.$inject=["$document","$log","$browser"],angular.module("ngCookies").provider("$$cookieWriter",function(){this.$get=$$CookieWriter})}(window,window.angular),function(window,angular,undefined){"use strict";function isValidDottedPath(path){return null!=path&&""!==path&&"hasOwnProperty"!==path&&MEMBER_NAME_REGEX.test("."+path)}function lookupDottedPath(obj,path){if(!isValidDottedPath(path))throw $resourceMinErr("badmember",'Dotted member path "@{0}" is invalid.',path);for(var keys=path.split("."),i=0,ii=keys.length;ii>i&&angular.isDefined(obj);i++){var key=keys[i];obj=null!==obj?obj[key]:undefined}return obj}function shallowClearAndCopy(src,dst){dst=dst||{},angular.forEach(dst,function(value,key){delete dst[key]});for(var key in src)!src.hasOwnProperty(key)||"$"===key.charAt(0)&&"$"===key.charAt(1)||(dst[key]=src[key]);return dst}var $resourceMinErr=angular.$$minErr("$resource"),MEMBER_NAME_REGEX=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;angular.module("ngResource",["ng"]).provider("$resource",function(){var PROTOCOL_AND_DOMAIN_REGEX=/^https?:\/\/[^\/]*/,provider=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}},this.$get=["$http","$q",function($http,$q){function encodeUriSegment(val){return encodeUriQuery(val,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function encodeUriQuery(val,pctEncodeSpaces){return encodeURIComponent(val).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,pctEncodeSpaces?"%20":"+")}function Route(template,defaults){this.template=template,this.defaults=extend({},provider.defaults,defaults),this.urlParams={}}function resourceFactory(url,paramDefaults,actions,options){function extractParams(data,actionParams){var ids={};return actionParams=extend({},paramDefaults,actionParams),forEach(actionParams,function(value,key){isFunction(value)&&(value=value()),ids[key]=value&&value.charAt&&"@"==value.charAt(0)?lookupDottedPath(data,value.substr(1)):value}),ids}function defaultResponseInterceptor(response){return response.resource}function Resource(value){shallowClearAndCopy(value||{},this)}var route=new Route(url,options);return actions=extend({},provider.defaults.actions,actions),Resource.prototype.toJSON=function(){var data=extend({},this);return delete data.$promise,delete data.$resolved,data},forEach(actions,function(action,name){var hasBody=/^(POST|PUT|PATCH)$/i.test(action.method);Resource[name]=function(a1,a2,a3,a4){var data,success,error,params={};switch(arguments.length){case 4:error=a4,success=a3;case 3:case 2:if(!isFunction(a2)){params=a1,data=a2,success=a3;break}if(isFunction(a1)){success=a1,error=a2;break}success=a2,error=a3;case 1:isFunction(a1)?success=a1:hasBody?data=a1:params=a1;break;case 0:break;default:throw $resourceMinErr("badargs","Expected up to 4 arguments [params, data, success, error], got {0} arguments",arguments.length)}var isInstanceCall=this instanceof Resource,value=isInstanceCall?data:action.isArray?[]:new Resource(data),httpConfig={},responseInterceptor=action.interceptor&&action.interceptor.response||defaultResponseInterceptor,responseErrorInterceptor=action.interceptor&&action.interceptor.responseError||undefined;forEach(action,function(value,key){"params"!=key&&"isArray"!=key&&"interceptor"!=key&&(httpConfig[key]=copy(value))}),hasBody&&(httpConfig.data=data),route.setUrlParams(httpConfig,extend({},extractParams(data,action.params||{}),params),action.url);var promise=$http(httpConfig).then(function(response){var data=response.data,promise=value.$promise;if(data){if(angular.isArray(data)!==!!action.isArray)throw $resourceMinErr("badcfg","Error in resource configuration for action `{0}`. Expected response to contain an {1} but got an {2} (Request: {3} {4})",name,action.isArray?"array":"object",angular.isArray(data)?"array":"object",httpConfig.method,httpConfig.url);action.isArray?(value.length=0,forEach(data,function(item){"object"==typeof item?value.push(new Resource(item)):value.push(item)})):(shallowClearAndCopy(data,value),value.$promise=promise)}return value.$resolved=!0,response.resource=value,response},function(response){return value.$resolved=!0,(error||noop)(response),$q.reject(response)});return promise=promise.then(function(response){var value=responseInterceptor(response);return(success||noop)(value,response.headers),value},responseErrorInterceptor),isInstanceCall?promise:(value.$promise=promise,value.$resolved=!1,value)},Resource.prototype["$"+name]=function(params,success,error){isFunction(params)&&(error=success,success=params,params={});var result=Resource[name].call(this,params,this,success,error);return result.$promise||result}}),Resource.bind=function(additionalParamDefaults){return resourceFactory(url,extend({},paramDefaults,additionalParamDefaults),actions)},Resource}var noop=angular.noop,forEach=angular.forEach,extend=angular.extend,copy=angular.copy,isFunction=angular.isFunction;return Route.prototype={setUrlParams:function(config,params,actionUrl){var val,encodedVal,self=this,url=actionUrl||self.template,protocolAndDomain="",urlParams=self.urlParams={};forEach(url.split(/\W/),function(param){if("hasOwnProperty"===param)throw $resourceMinErr("badname","hasOwnProperty is not a valid parameter name.");!new RegExp("^\\d+$").test(param)&&param&&new RegExp("(^|[^\\\\]):"+param+"(\\W|$)").test(url)&&(urlParams[param]=!0)}),url=url.replace(/\\:/g,":"),url=url.replace(PROTOCOL_AND_DOMAIN_REGEX,function(match){return protocolAndDomain=match,""}),params=params||{},forEach(self.urlParams,function(_,urlParam){val=params.hasOwnProperty(urlParam)?params[urlParam]:self.defaults[urlParam],angular.isDefined(val)&&null!==val?(encodedVal=encodeUriSegment(val),url=url.replace(new RegExp(":"+urlParam+"(\\W|$)","g"),function(match,p1){return encodedVal+p1})):url=url.replace(new RegExp("(/?):"+urlParam+"(\\W|$)","g"),function(match,leadingSlashes,tail){return"/"==tail.charAt(0)?tail:leadingSlashes+tail})}),self.defaults.stripTrailingSlashes&&(url=url.replace(/\/+$/,"")||"/"),url=url.replace(/\/\.(?=\w+($|\?))/,"."),config.url=protocolAndDomain+url.replace(/\/\\\./,"/."),forEach(params,function(value,key){self.urlParams[key]||(config.params=config.params||{},config.params[key]=value)})}},resourceFactory}]})}(window,window.angular),angular.module("ui.bootstrap",["ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdown","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.transition","ui.bootstrap.typeahead"]),angular.module("ui.bootstrap.collapse",[]).directive("collapse",["$animate",function($animate){return{link:function(scope,element,attrs){function expand(){element.removeClass("collapse").addClass("collapsing").attr("aria-expanded",!0).attr("aria-hidden",!1),$animate.addClass(element,"in",{to:{height:element[0].scrollHeight+"px"}}).then(expandDone)}function expandDone(){element.removeClass("collapsing"),element.css({height:"auto"})}function collapse(){return element.hasClass("collapse")||element.hasClass("in")?(element.css({height:element[0].scrollHeight+"px"}).removeClass("collapse").addClass("collapsing").attr("aria-expanded",!1).attr("aria-hidden",!0),void $animate.removeClass(element,"in",{to:{height:"0"}}).then(collapseDone)):collapseDone()}function collapseDone(){element.css({height:"0"}),element.removeClass("collapsing"),element.addClass("collapse")}scope.$watch(attrs.collapse,function(shouldCollapse){shouldCollapse?collapse():expand()})}}}]),angular.module("ui.bootstrap.accordion",["ui.bootstrap.collapse"]).constant("accordionConfig",{closeOthers:!0}).controller("AccordionController",["$scope","$attrs","accordionConfig",function($scope,$attrs,accordionConfig){this.groups=[],this.closeOthers=function(openGroup){var closeOthers=angular.isDefined($attrs.closeOthers)?$scope.$eval($attrs.closeOthers):accordionConfig.closeOthers;closeOthers&&angular.forEach(this.groups,function(group){group!==openGroup&&(group.isOpen=!1)})},this.addGroup=function(groupScope){var that=this;this.groups.push(groupScope),groupScope.$on("$destroy",function(event){that.removeGroup(groupScope)})},this.removeGroup=function(group){var index=this.groups.indexOf(group);-1!==index&&this.groups.splice(index,1)}}]).directive("accordion",function(){return{restrict:"EA",controller:"AccordionController",transclude:!0,replace:!1,templateUrl:"template/accordion/accordion.html"}}).directive("accordionGroup",function(){return{require:"^accordion",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/accordion/accordion-group.html",scope:{heading:"@",isOpen:"=?",isDisabled:"=?"},controller:function(){this.setHeading=function(element){this.heading=element}},link:function(scope,element,attrs,accordionCtrl){accordionCtrl.addGroup(scope), },outerDims=isBody?{width:$(window).width(),height:$(window).height()}:null;return $.extend({},elRect,scroll,outerDims,elOffset)},Tooltip.prototype.getCalculatedOffset=function(placement,pos,actualWidth,actualHeight){return"bottom"==placement?{top:pos.top+pos.height,left:pos.left+pos.width/2-actualWidth/2}:"top"==placement?{top:pos.top-actualHeight,left:pos.left+pos.width/2-actualWidth/2}:"left"==placement?{top:pos.top+pos.height/2-actualHeight/2,left:pos.left-actualWidth}:{top:pos.top+pos.height/2-actualHeight/2,left:pos.left+pos.width}},Tooltip.prototype.getViewportAdjustedDelta=function(placement,pos,actualWidth,actualHeight){var delta={top:0,left:0};if(!this.$viewport)return delta;var viewportPadding=this.options.viewport&&this.options.viewport.padding||0,viewportDimensions=this.getPosition(this.$viewport);if(/right|left/.test(placement)){var topEdgeOffset=pos.top-viewportPadding-viewportDimensions.scroll,bottomEdgeOffset=pos.top+viewportPadding-viewportDimensions.scroll+actualHeight;topEdgeOffset<viewportDimensions.top?delta.top=viewportDimensions.top-topEdgeOffset:bottomEdgeOffset>viewportDimensions.top+viewportDimensions.height&&(delta.top=viewportDimensions.top+viewportDimensions.height-bottomEdgeOffset)}else{var leftEdgeOffset=pos.left-viewportPadding,rightEdgeOffset=pos.left+viewportPadding+actualWidth;leftEdgeOffset<viewportDimensions.left?delta.left=viewportDimensions.left-leftEdgeOffset:rightEdgeOffset>viewportDimensions.right&&(delta.left=viewportDimensions.left+viewportDimensions.width-rightEdgeOffset)}return delta},Tooltip.prototype.getTitle=function(){var title,$e=this.$element,o=this.options;return title=$e.attr("data-original-title")||("function"==typeof o.title?o.title.call($e[0]):o.title)},Tooltip.prototype.getUID=function(prefix){do prefix+=~~(1e6*Math.random());while(document.getElementById(prefix));return prefix},Tooltip.prototype.tip=function(){if(!this.$tip&&(this.$tip=$(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},Tooltip.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},Tooltip.prototype.enable=function(){this.enabled=!0},Tooltip.prototype.disable=function(){this.enabled=!1},Tooltip.prototype.toggleEnabled=function(){this.enabled=!this.enabled},Tooltip.prototype.toggle=function(e){var self=this;e&&(self=$(e.currentTarget).data("bs."+this.type),self||(self=new this.constructor(e.currentTarget,this.getDelegateOptions()),$(e.currentTarget).data("bs."+this.type,self))),e?(self.inState.click=!self.inState.click,self.isInStateTrue()?self.enter(self):self.leave(self)):self.tip().hasClass("in")?self.leave(self):self.enter(self)},Tooltip.prototype.destroy=function(){var that=this;clearTimeout(this.timeout),this.hide(function(){that.$element.off("."+that.type).removeData("bs."+that.type),that.$tip&&that.$tip.detach(),that.$tip=null,that.$arrow=null,that.$viewport=null})};var old=$.fn.tooltip;$.fn.tooltip=Plugin,$.fn.tooltip.Constructor=Tooltip,$.fn.tooltip.noConflict=function(){return $.fn.tooltip=old,this}}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.popover"),options="object"==typeof option&&option;(data||!/destroy|hide/.test(option))&&(data||$this.data("bs.popover",data=new Popover(this,options)),"string"==typeof option&&data[option]())})}var Popover=function(element,options){this.init("popover",element,options)};if(!$.fn.tooltip)throw new Error("Popover requires tooltip.js");Popover.VERSION="3.3.5",Popover.DEFAULTS=$.extend({},$.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),Popover.prototype=$.extend({},$.fn.tooltip.Constructor.prototype),Popover.prototype.constructor=Popover,Popover.prototype.getDefaults=function(){return Popover.DEFAULTS},Popover.prototype.setContent=function(){var $tip=this.tip(),title=this.getTitle(),content=this.getContent();$tip.find(".popover-title")[this.options.html?"html":"text"](title),$tip.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof content?"html":"append":"text"](content),$tip.removeClass("fade top bottom left right in"),$tip.find(".popover-title").html()||$tip.find(".popover-title").hide()},Popover.prototype.hasContent=function(){return this.getTitle()||this.getContent()},Popover.prototype.getContent=function(){var $e=this.$element,o=this.options;return $e.attr("data-content")||("function"==typeof o.content?o.content.call($e[0]):o.content)},Popover.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var old=$.fn.popover;$.fn.popover=Plugin,$.fn.popover.Constructor=Popover,$.fn.popover.noConflict=function(){return $.fn.popover=old,this}}(jQuery),+function($){"use strict";function ScrollSpy(element,options){this.$body=$(document.body),this.$scrollElement=$($(element).is(document.body)?window:element),this.options=$.extend({},ScrollSpy.DEFAULTS,options),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",$.proxy(this.process,this)),this.refresh(),this.process()}function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.scrollspy"),options="object"==typeof option&&option;data||$this.data("bs.scrollspy",data=new ScrollSpy(this,options)),"string"==typeof option&&data[option]()})}ScrollSpy.VERSION="3.3.5",ScrollSpy.DEFAULTS={offset:10},ScrollSpy.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},ScrollSpy.prototype.refresh=function(){var that=this,offsetMethod="offset",offsetBase=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),$.isWindow(this.$scrollElement[0])||(offsetMethod="position",offsetBase=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var $el=$(this),href=$el.data("target")||$el.attr("href"),$href=/^#./.test(href)&&$(href);return $href&&$href.length&&$href.is(":visible")&&[[$href[offsetMethod]().top+offsetBase,href]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){that.offsets.push(this[0]),that.targets.push(this[1])})},ScrollSpy.prototype.process=function(){var i,scrollTop=this.$scrollElement.scrollTop()+this.options.offset,scrollHeight=this.getScrollHeight(),maxScroll=this.options.offset+scrollHeight-this.$scrollElement.height(),offsets=this.offsets,targets=this.targets,activeTarget=this.activeTarget;if(this.scrollHeight!=scrollHeight&&this.refresh(),scrollTop>=maxScroll)return activeTarget!=(i=targets[targets.length-1])&&this.activate(i);if(activeTarget&&scrollTop<offsets[0])return this.activeTarget=null,this.clear();for(i=offsets.length;i--;)activeTarget!=targets[i]&&scrollTop>=offsets[i]&&(void 0===offsets[i+1]||scrollTop<offsets[i+1])&&this.activate(targets[i])},ScrollSpy.prototype.activate=function(target){this.activeTarget=target,this.clear();var selector=this.selector+'[data-target="'+target+'"],'+this.selector+'[href="'+target+'"]',active=$(selector).parents("li").addClass("active");active.parent(".dropdown-menu").length&&(active=active.closest("li.dropdown").addClass("active")),active.trigger("activate.bs.scrollspy")},ScrollSpy.prototype.clear=function(){$(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var old=$.fn.scrollspy;$.fn.scrollspy=Plugin,$.fn.scrollspy.Constructor=ScrollSpy,$.fn.scrollspy.noConflict=function(){return $.fn.scrollspy=old,this},$(window).on("load.bs.scrollspy.data-api",function(){$('[data-spy="scroll"]').each(function(){var $spy=$(this);Plugin.call($spy,$spy.data())})})}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.tab");data||$this.data("bs.tab",data=new Tab(this)),"string"==typeof option&&data[option]()})}var Tab=function(element){this.element=$(element)};Tab.VERSION="3.3.5",Tab.TRANSITION_DURATION=150,Tab.prototype.show=function(){var $this=this.element,$ul=$this.closest("ul:not(.dropdown-menu)"),selector=$this.data("target");if(selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,"")),!$this.parent("li").hasClass("active")){var $previous=$ul.find(".active:last a"),hideEvent=$.Event("hide.bs.tab",{relatedTarget:$this[0]}),showEvent=$.Event("show.bs.tab",{relatedTarget:$previous[0]});if($previous.trigger(hideEvent),$this.trigger(showEvent),!showEvent.isDefaultPrevented()&&!hideEvent.isDefaultPrevented()){var $target=$(selector);this.activate($this.closest("li"),$ul),this.activate($target,$target.parent(),function(){$previous.trigger({type:"hidden.bs.tab",relatedTarget:$this[0]}),$this.trigger({type:"shown.bs.tab",relatedTarget:$previous[0]})})}}},Tab.prototype.activate=function(element,container,callback){function next(){$active.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),element.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),transition?(element[0].offsetWidth,element.addClass("in")):element.removeClass("fade"),element.parent(".dropdown-menu").length&&element.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),callback&&callback()}var $active=container.find("> .active"),transition=callback&&$.support.transition&&($active.length&&$active.hasClass("fade")||!!container.find("> .fade").length);$active.length&&transition?$active.one("bsTransitionEnd",next).emulateTransitionEnd(Tab.TRANSITION_DURATION):next(),$active.removeClass("in")};var old=$.fn.tab;$.fn.tab=Plugin,$.fn.tab.Constructor=Tab,$.fn.tab.noConflict=function(){return $.fn.tab=old,this};var clickHandler=function(e){e.preventDefault(),Plugin.call($(this),"show")};$(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',clickHandler).on("click.bs.tab.data-api",'[data-toggle="pill"]',clickHandler)}(jQuery),+function($){"use strict";function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.affix"),options="object"==typeof option&&option;data||$this.data("bs.affix",data=new Affix(this,options)),"string"==typeof option&&data[option]()})}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=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};Affix.VERSION="3.3.5",Affix.RESET="affix affix-top affix-bottom",Affix.DEFAULTS={offset:0,target:window},Affix.prototype.getState=function(scrollHeight,height,offsetTop,offsetBottom){var scrollTop=this.$target.scrollTop(),position=this.$element.offset(),targetHeight=this.$target.height();if(null!=offsetTop&&"top"==this.affixed)return offsetTop>scrollTop?"top":!1;if("bottom"==this.affixed)return null!=offsetTop?scrollTop+this.unpin<=position.top?!1:"bottom":scrollHeight-offsetBottom>=scrollTop+targetHeight?!1:"bottom";var initializing=null==this.affixed,colliderTop=initializing?scrollTop:position.top,colliderHeight=initializing?targetHeight:height;return null!=offsetTop&&offsetTop>=scrollTop?"top":null!=offsetBottom&&colliderTop+colliderHeight>=scrollHeight-offsetBottom?"bottom":!1},Affix.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(Affix.RESET).addClass("affix");var scrollTop=this.$target.scrollTop(),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")){var height=this.$element.height(),offset=this.options.offset,offsetTop=offset.top,offsetBottom=offset.bottom,scrollHeight=Math.max($(document).height(),$(document.body).height());"object"!=typeof offset&&(offsetBottom=offsetTop=offset),"function"==typeof offsetTop&&(offsetTop=offset.top(this.$element)),"function"==typeof offsetBottom&&(offsetBottom=offset.bottom(this.$element));var affix=this.getState(scrollHeight,height,offsetTop,offsetBottom);if(this.affixed!=affix){null!=this.unpin&&this.$element.css("top","");var affixType="affix"+(affix?"-"+affix:""),e=$.Event(affixType+".bs.affix");if(this.$element.trigger(e),e.isDefaultPrevented())return;this.affixed=affix,this.unpin="bottom"==affix?this.getPinnedOffset():null,this.$element.removeClass(Affix.RESET).addClass(affixType).trigger(affixType.replace("affix","affixed")+".bs.affix")}"bottom"==affix&&this.$element.offset({top:scrollHeight-height-offsetBottom})}};var old=$.fn.affix;$.fn.affix=Plugin,$.fn.affix.Constructor=Affix,$.fn.affix.noConflict=function(){return $.fn.affix=old,this},$(window).on("load",function(){$('[data-spy="affix"]').each(function(){var $spy=$(this),data=$spy.data();data.offset=data.offset||{},null!=data.offsetBottom&&(data.offset.bottom=data.offsetBottom),null!=data.offsetTop&&(data.offset.top=data.offsetTop),Plugin.call($spy,data)})})}(jQuery),function(window,angular,undefined){"use strict";function $RouteProvider(){function inherit(parent,extra){return angular.extend(Object.create(parent),extra)}function pathRegExp(path,opts){var insensitive=opts.caseInsensitiveMatch,ret={originalPath:path,regexp:path},keys=ret.keys=[];return path=path.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(_,slash,key,option){var optional="?"===option?option:null,star="*"===option?option:null;return keys.push({name:key,optional:!!optional}),slash=slash||"",""+(optional?"":slash)+"(?:"+(optional?slash:"")+(star&&"(.+?)"||"([^/]+)")+(optional||"")+")"+(optional||"")}).replace(/([\/$\*])/g,"\\$1"),ret.regexp=new RegExp("^"+path+"$",insensitive?"i":""),ret}var routes={};this.when=function(path,route){var routeCopy=angular.copy(route);if(angular.isUndefined(routeCopy.reloadOnSearch)&&(routeCopy.reloadOnSearch=!0),angular.isUndefined(routeCopy.caseInsensitiveMatch)&&(routeCopy.caseInsensitiveMatch=this.caseInsensitiveMatch),routes[path]=angular.extend(routeCopy,path&&pathRegExp(path,routeCopy)),path){var redirectPath="/"==path[path.length-1]?path.substr(0,path.length-1):path+"/";routes[redirectPath]=angular.extend({redirectTo:path},pathRegExp(redirectPath,routeCopy))}return this},this.caseInsensitiveMatch=!1,this.otherwise=function(params){return"string"==typeof params&&(params={redirectTo:params}),this.when(null,params),this},this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function($rootScope,$location,$routeParams,$q,$injector,$templateRequest,$sce){function switchRouteMatcher(on,route){var keys=route.keys,params={};if(!route.regexp)return null;var m=route.regexp.exec(on);if(!m)return null;for(var i=1,len=m.length;len>i;++i){var key=keys[i-1],val=m[i];key&&val&&(params[key.name]=val)}return params}function prepareRoute($locationEvent){var lastRoute=$route.current;preparedRoute=parseRoute(),preparedRouteIsUpdateOnly=preparedRoute&&lastRoute&&preparedRoute.$$route===lastRoute.$$route&&angular.equals(preparedRoute.pathParams,lastRoute.pathParams)&&!preparedRoute.reloadOnSearch&&!forceReload,preparedRouteIsUpdateOnly||!lastRoute&&!preparedRoute||$rootScope.$broadcast("$routeChangeStart",preparedRoute,lastRoute).defaultPrevented&&$locationEvent&&$locationEvent.preventDefault()}function commitRoute(){var lastRoute=$route.current,nextRoute=preparedRoute;preparedRouteIsUpdateOnly?(lastRoute.params=nextRoute.params,angular.copy(lastRoute.params,$routeParams),$rootScope.$broadcast("$routeUpdate",lastRoute)):(nextRoute||lastRoute)&&(forceReload=!1,$route.current=nextRoute,nextRoute&&nextRoute.redirectTo&&(angular.isString(nextRoute.redirectTo)?$location.path(interpolate(nextRoute.redirectTo,nextRoute.params)).search(nextRoute.params).replace():$location.url(nextRoute.redirectTo(nextRoute.pathParams,$location.path(),$location.search())).replace()),$q.when(nextRoute).then(function(){if(nextRoute){var template,templateUrl,locals=angular.extend({},nextRoute.resolve);return angular.forEach(locals,function(value,key){locals[key]=angular.isString(value)?$injector.get(value):$injector.invoke(value,null,null,key)}),angular.isDefined(template=nextRoute.template)?angular.isFunction(template)&&(template=template(nextRoute.params)):angular.isDefined(templateUrl=nextRoute.templateUrl)&&(angular.isFunction(templateUrl)&&(templateUrl=templateUrl(nextRoute.params)),angular.isDefined(templateUrl)&&(nextRoute.loadedTemplateUrl=$sce.valueOf(templateUrl),template=$templateRequest(templateUrl))),angular.isDefined(template)&&(locals.$template=template),$q.all(locals)}}).then(function(locals){nextRoute==$route.current&&(nextRoute&&(nextRoute.locals=locals,angular.copy(nextRoute.params,$routeParams)),$rootScope.$broadcast("$routeChangeSuccess",nextRoute,lastRoute))},function(error){nextRoute==$route.current&&$rootScope.$broadcast("$routeChangeError",nextRoute,lastRoute,error)}))}function parseRoute(){var params,match;return angular.forEach(routes,function(route,path){!match&&(params=switchRouteMatcher($location.path(),route))&&(match=inherit(route,{params:angular.extend({},$location.search(),params),pathParams:params}),match.$$route=route)}),match||routes[null]&&inherit(routes[null],{params:{},pathParams:{}})}function interpolate(string,params){var result=[];return angular.forEach((string||"").split(":"),function(segment,i){if(0===i)result.push(segment);else{var segmentMatch=segment.match(/(\w+)(?:[?*])?(.*)/),key=segmentMatch[1];result.push(params[key]),result.push(segmentMatch[2]||""),delete params[key]}}),result.join("")}var preparedRoute,preparedRouteIsUpdateOnly,forceReload=!1,$route={routes:routes,reload:function(){forceReload=!0,$rootScope.$evalAsync(function(){prepareRoute(),commitRoute()})},updateParams:function(newParams){if(!this.current||!this.current.$$route)throw $routeMinErr("norout","Tried updating route when with no current route");newParams=angular.extend({},this.current.params,newParams),$location.path(interpolate(this.current.$$route.originalPath,newParams)),$location.search(newParams)}};return $rootScope.$on("$locationChangeStart",prepareRoute),$rootScope.$on("$locationChangeSuccess",commitRoute),$route}]}function $RouteParamsProvider(){this.$get=function(){return{}}}function ngViewFactory($route,$anchorScroll,$animate){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(scope,$element,attr,ctrl,$transclude){function cleanupLastView(){previousLeaveAnimation&&($animate.cancel(previousLeaveAnimation),previousLeaveAnimation=null),currentScope&&(currentScope.$destroy(),currentScope=null),currentElement&&(previousLeaveAnimation=$animate.leave(currentElement),previousLeaveAnimation.then(function(){previousLeaveAnimation=null}),currentElement=null)}function update(){var locals=$route.current&&$route.current.locals,template=locals&&locals.$template;if(angular.isDefined(template)){var newScope=scope.$new(),current=$route.current,clone=$transclude(newScope,function(clone){$animate.enter(clone,null,currentElement||$element).then(function(){!angular.isDefined(autoScrollExp)||autoScrollExp&&!scope.$eval(autoScrollExp)||$anchorScroll()}),cleanupLastView()});currentElement=clone,currentScope=current.scope=newScope,currentScope.$emit("$viewContentLoaded"),currentScope.$eval(onloadExp)}else cleanupLastView()}var currentScope,currentElement,previousLeaveAnimation,autoScrollExp=attr.autoscroll,onloadExp=attr.onload||"";scope.$on("$routeChangeSuccess",update),update()}}}function ngViewFillContentFactory($compile,$controller,$route){return{restrict:"ECA",priority:-400,link:function(scope,$element){var current=$route.current,locals=current.locals;$element.html(locals.$template);var link=$compile($element.contents());if(current.controller){locals.$scope=scope;var controller=$controller(current.controller,locals);current.controllerAs&&(scope[current.controllerAs]=controller),$element.data("$ngControllerController",controller),$element.children().data("$ngControllerController",controller)}link(scope)}}}var ngRouteModule=angular.module("ngRoute",["ng"]).provider("$route",$RouteProvider),$routeMinErr=angular.$$minErr("ngRoute");ngRouteModule.provider("$routeParams",$RouteParamsProvider),ngRouteModule.directive("ngView",ngViewFactory),ngRouteModule.directive("ngView",ngViewFillContentFactory),ngViewFactory.$inject=["$route","$anchorScroll","$animate"],ngViewFillContentFactory.$inject=["$compile","$controller","$route"]}(window,window.angular),function(window,angular,undefined){"use strict";function $$CookieWriter($document,$log,$browser){function buildCookieString(name,value,options){var path,expires;options=options||{},expires=options.expires,path=angular.isDefined(options.path)?options.path:cookiePath,angular.isUndefined(value)&&(expires="Thu, 01 Jan 1970 00:00:00 GMT",value=""),angular.isString(expires)&&(expires=new Date(expires));var str=encodeURIComponent(name)+"="+encodeURIComponent(value);str+=path?";path="+path:"",str+=options.domain?";domain="+options.domain:"",str+=expires?";expires="+expires.toUTCString():"",str+=options.secure?";secure":"";var cookieLength=str.length+1;return cookieLength>4096&&$log.warn("Cookie '"+name+"' possibly not set or overflowed because it was too large ("+cookieLength+" > 4096 bytes)!"),str}var cookiePath=$browser.baseHref(),rawDocument=$document[0];return function(name,value,options){rawDocument.cookie=buildCookieString(name,value,options)}}angular.module("ngCookies",["ng"]).provider("$cookies",[function(){function calcOptions(options){return options?angular.extend({},defaults,options):defaults}var defaults=this.defaults={};this.$get=["$$cookieReader","$$cookieWriter",function($$cookieReader,$$cookieWriter){return{get:function(key){return $$cookieReader()[key]},getObject:function(key){var value=this.get(key);return value?angular.fromJson(value):value},getAll:function(){return $$cookieReader()},put:function(key,value,options){$$cookieWriter(key,value,calcOptions(options))},putObject:function(key,value,options){this.put(key,angular.toJson(value),options)},remove:function(key,options){$$cookieWriter(key,undefined,calcOptions(options))}}}]}]),angular.module("ngCookies").factory("$cookieStore",["$cookies",function($cookies){return{get:function(key){return $cookies.getObject(key)},put:function(key,value){$cookies.putObject(key,value)},remove:function(key){$cookies.remove(key)}}}]),$$CookieWriter.$inject=["$document","$log","$browser"],angular.module("ngCookies").provider("$$cookieWriter",function(){this.$get=$$CookieWriter})}(window,window.angular),function(window,angular,undefined){"use strict";function isValidDottedPath(path){return null!=path&&""!==path&&"hasOwnProperty"!==path&&MEMBER_NAME_REGEX.test("."+path)}function lookupDottedPath(obj,path){if(!isValidDottedPath(path))throw $resourceMinErr("badmember",'Dotted member path "@{0}" is invalid.',path);for(var keys=path.split("."),i=0,ii=keys.length;ii>i&&angular.isDefined(obj);i++){var key=keys[i];obj=null!==obj?obj[key]:undefined}return obj}function shallowClearAndCopy(src,dst){dst=dst||{},angular.forEach(dst,function(value,key){delete dst[key]});for(var key in src)!src.hasOwnProperty(key)||"$"===key.charAt(0)&&"$"===key.charAt(1)||(dst[key]=src[key]);return dst}var $resourceMinErr=angular.$$minErr("$resource"),MEMBER_NAME_REGEX=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;angular.module("ngResource",["ng"]).provider("$resource",function(){var PROTOCOL_AND_DOMAIN_REGEX=/^https?:\/\/[^\/]*/,provider=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}},this.$get=["$http","$q",function($http,$q){function encodeUriSegment(val){return encodeUriQuery(val,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function encodeUriQuery(val,pctEncodeSpaces){return encodeURIComponent(val).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,pctEncodeSpaces?"%20":"+")}function Route(template,defaults){this.template=template,this.defaults=extend({},provider.defaults,defaults),this.urlParams={}}function resourceFactory(url,paramDefaults,actions,options){function extractParams(data,actionParams){var ids={};return actionParams=extend({},paramDefaults,actionParams),forEach(actionParams,function(value,key){isFunction(value)&&(value=value()),ids[key]=value&&value.charAt&&"@"==value.charAt(0)?lookupDottedPath(data,value.substr(1)):value}),ids}function defaultResponseInterceptor(response){return response.resource}function Resource(value){shallowClearAndCopy(value||{},this)}var route=new Route(url,options);return actions=extend({},provider.defaults.actions,actions),Resource.prototype.toJSON=function(){var data=extend({},this);return delete data.$promise,delete data.$resolved,data},forEach(actions,function(action,name){var hasBody=/^(POST|PUT|PATCH)$/i.test(action.method);Resource[name]=function(a1,a2,a3,a4){var data,success,error,params={};switch(arguments.length){case 4:error=a4,success=a3;case 3:case 2:if(!isFunction(a2)){params=a1,data=a2,success=a3;break}if(isFunction(a1)){success=a1,error=a2;break}success=a2,error=a3;case 1:isFunction(a1)?success=a1:hasBody?data=a1:params=a1;break;case 0:break;default:throw $resourceMinErr("badargs","Expected up to 4 arguments [params, data, success, error], got {0} arguments",arguments.length)}var isInstanceCall=this instanceof Resource,value=isInstanceCall?data:action.isArray?[]:new Resource(data),httpConfig={},responseInterceptor=action.interceptor&&action.interceptor.response||defaultResponseInterceptor,responseErrorInterceptor=action.interceptor&&action.interceptor.responseError||undefined;forEach(action,function(value,key){"params"!=key&&"isArray"!=key&&"interceptor"!=key&&(httpConfig[key]=copy(value))}),hasBody&&(httpConfig.data=data),route.setUrlParams(httpConfig,extend({},extractParams(data,action.params||{}),params),action.url);var promise=$http(httpConfig).then(function(response){var data=response.data,promise=value.$promise;if(data){if(angular.isArray(data)!==!!action.isArray)throw $resourceMinErr("badcfg","Error in resource configuration for action `{0}`. Expected response to contain an {1} but got an {2} (Request: {3} {4})",name,action.isArray?"array":"object",angular.isArray(data)?"array":"object",httpConfig.method,httpConfig.url);action.isArray?(value.length=0,forEach(data,function(item){"object"==typeof item?value.push(new Resource(item)):value.push(item)})):(shallowClearAndCopy(data,value),value.$promise=promise)}return value.$resolved=!0,response.resource=value,response},function(response){return value.$resolved=!0,(error||noop)(response),$q.reject(response)});return promise=promise.then(function(response){var value=responseInterceptor(response);return(success||noop)(value,response.headers),value},responseErrorInterceptor),isInstanceCall?promise:(value.$promise=promise,value.$resolved=!1,value)},Resource.prototype["$"+name]=function(params,success,error){isFunction(params)&&(error=success,success=params,params={});var result=Resource[name].call(this,params,this,success,error);return result.$promise||result}}),Resource.bind=function(additionalParamDefaults){return resourceFactory(url,extend({},paramDefaults,additionalParamDefaults),actions)},Resource}var noop=angular.noop,forEach=angular.forEach,extend=angular.extend,copy=angular.copy,isFunction=angular.isFunction;return Route.prototype={setUrlParams:function(config,params,actionUrl){var val,encodedVal,self=this,url=actionUrl||self.template,protocolAndDomain="",urlParams=self.urlParams={};forEach(url.split(/\W/),function(param){if("hasOwnProperty"===param)throw $resourceMinErr("badname","hasOwnProperty is not a valid parameter name.");!new RegExp("^\\d+$").test(param)&&param&&new RegExp("(^|[^\\\\]):"+param+"(\\W|$)").test(url)&&(urlParams[param]=!0)}),url=url.replace(/\\:/g,":"),url=url.replace(PROTOCOL_AND_DOMAIN_REGEX,function(match){return protocolAndDomain=match,""}),params=params||{},forEach(self.urlParams,function(_,urlParam){val=params.hasOwnProperty(urlParam)?params[urlParam]:self.defaults[urlParam],angular.isDefined(val)&&null!==val?(encodedVal=encodeUriSegment(val),url=url.replace(new RegExp(":"+urlParam+"(\\W|$)","g"),function(match,p1){return encodedVal+p1})):url=url.replace(new RegExp("(/?):"+urlParam+"(\\W|$)","g"),function(match,leadingSlashes,tail){return"/"==tail.charAt(0)?tail:leadingSlashes+tail})}),self.defaults.stripTrailingSlashes&&(url=url.replace(/\/+$/,"")||"/"),url=url.replace(/\/\.(?=\w+($|\?))/,"."),config.url=protocolAndDomain+url.replace(/\/\\\./,"/."),forEach(params,function(value,key){self.urlParams[key]||(config.params=config.params||{},config.params[key]=value)})}},resourceFactory}]})}(window,window.angular),angular.module("ui.bootstrap",["ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdown","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.transition","ui.bootstrap.typeahead"]),angular.module("ui.bootstrap.collapse",[]).directive("collapse",["$animate",function($animate){return{link:function(scope,element,attrs){function expand(){element.removeClass("collapse").addClass("collapsing").attr("aria-expanded",!0).attr("aria-hidden",!1),$animate.addClass(element,"in",{to:{height:element[0].scrollHeight+"px"}}).then(expandDone)}function expandDone(){element.removeClass("collapsing"),element.css({height:"auto"})}function collapse(){return element.hasClass("collapse")||element.hasClass("in")?(element.css({height:element[0].scrollHeight+"px"}).removeClass("collapse").addClass("collapsing").attr("aria-expanded",!1).attr("aria-hidden",!0),void $animate.removeClass(element,"in",{to:{height:"0"}}).then(collapseDone)):collapseDone()}function collapseDone(){element.css({height:"0"}),element.removeClass("collapsing"),element.addClass("collapse")}scope.$watch(attrs.collapse,function(shouldCollapse){shouldCollapse?collapse():expand()})}}}]),angular.module("ui.bootstrap.accordion",["ui.bootstrap.collapse"]).constant("accordionConfig",{closeOthers:!0}).controller("AccordionController",["$scope","$attrs","accordionConfig",function($scope,$attrs,accordionConfig){this.groups=[],this.closeOthers=function(openGroup){var closeOthers=angular.isDefined($attrs.closeOthers)?$scope.$eval($attrs.closeOthers):accordionConfig.closeOthers;closeOthers&&angular.forEach(this.groups,function(group){group!==openGroup&&(group.isOpen=!1)})},this.addGroup=function(groupScope){var that=this;this.groups.push(groupScope),groupScope.$on("$destroy",function(event){that.removeGroup(groupScope)})},this.removeGroup=function(group){var index=this.groups.indexOf(group);-1!==index&&this.groups.splice(index,1)}}]).directive("accordion",function(){return{restrict:"EA",controller:"AccordionController",transclude:!0,replace:!1,templateUrl:"template/accordion/accordion.html"}}).directive("accordionGroup",function(){return{require:"^accordion",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/accordion/accordion-group.html",scope:{heading:"@",isOpen:"=?",isDisabled:"=?"},controller:function(){this.setHeading=function(element){this.heading=element}},link:function(scope,element,attrs,accordionCtrl){accordionCtrl.addGroup(scope),
scope.$watch("isOpen",function(value){value&&accordionCtrl.closeOthers(scope)}),scope.toggleOpen=function(){scope.isDisabled||(scope.isOpen=!scope.isOpen)}}}}).directive("accordionHeading",function(){return{restrict:"EA",transclude:!0,template:"",replace:!0,require:"^accordionGroup",link:function(scope,element,attr,accordionGroupCtrl,transclude){accordionGroupCtrl.setHeading(transclude(scope,angular.noop))}}}).directive("accordionTransclude",function(){return{require:"^accordionGroup",link:function(scope,element,attr,controller){scope.$watch(function(){return controller[attr.accordionTransclude]},function(heading){heading&&(element.html(""),element.append(heading))})}}}),angular.module("ui.bootstrap.alert",[]).controller("AlertController",["$scope","$attrs",function($scope,$attrs){$scope.closeable=!!$attrs.close,this.close=$scope.close}]).directive("alert",function(){return{restrict:"EA",controller:"AlertController",templateUrl:"template/alert/alert.html",transclude:!0,replace:!0,scope:{type:"@",close:"&"}}}).directive("dismissOnTimeout",["$timeout",function($timeout){return{require:"alert",link:function(scope,element,attrs,alertCtrl){$timeout(function(){alertCtrl.close()},parseInt(attrs.dismissOnTimeout,10))}}}]),angular.module("ui.bootstrap.bindHtml",[]).value("$bindHtmlUnsafeSuppressDeprecated",!1).directive("bindHtmlUnsafe",["$log","$bindHtmlUnsafeSuppressDeprecated",function($log,$bindHtmlUnsafeSuppressDeprecated){return function(scope,element,attr){$bindHtmlUnsafeSuppressDeprecated||$log.warn("bindHtmlUnsafe is now deprecated. Use ngBindHtml instead"),element.addClass("ng-binding").data("$binding",attr.bindHtmlUnsafe),scope.$watch(attr.bindHtmlUnsafe,function(value){element.html(value||"")})}}]),angular.module("ui.bootstrap.buttons",[]).constant("buttonConfig",{activeClass:"active",toggleEvent:"click"}).controller("ButtonsController",["buttonConfig",function(buttonConfig){this.activeClass=buttonConfig.activeClass||"active",this.toggleEvent=buttonConfig.toggleEvent||"click"}]).directive("btnRadio",function(){return{require:["btnRadio","ngModel"],controller:"ButtonsController",link:function(scope,element,attrs,ctrls){var buttonsCtrl=ctrls[0],ngModelCtrl=ctrls[1];ngModelCtrl.$render=function(){element.toggleClass(buttonsCtrl.activeClass,angular.equals(ngModelCtrl.$modelValue,scope.$eval(attrs.btnRadio)))},element.bind(buttonsCtrl.toggleEvent,function(){var isActive=element.hasClass(buttonsCtrl.activeClass);(!isActive||angular.isDefined(attrs.uncheckable))&&scope.$apply(function(){ngModelCtrl.$setViewValue(isActive?null:scope.$eval(attrs.btnRadio)),ngModelCtrl.$render()})})}}}).directive("btnCheckbox",function(){return{require:["btnCheckbox","ngModel"],controller:"ButtonsController",link:function(scope,element,attrs,ctrls){function getTrueValue(){return getCheckboxValue(attrs.btnCheckboxTrue,!0)}function getFalseValue(){return getCheckboxValue(attrs.btnCheckboxFalse,!1)}function getCheckboxValue(attributeValue,defaultValue){var val=scope.$eval(attributeValue);return angular.isDefined(val)?val:defaultValue}var buttonsCtrl=ctrls[0],ngModelCtrl=ctrls[1];ngModelCtrl.$render=function(){element.toggleClass(buttonsCtrl.activeClass,angular.equals(ngModelCtrl.$modelValue,getTrueValue()))},element.bind(buttonsCtrl.toggleEvent,function(){scope.$apply(function(){ngModelCtrl.$setViewValue(element.hasClass(buttonsCtrl.activeClass)?getFalseValue():getTrueValue()),ngModelCtrl.$render()})})}}}),angular.module("ui.bootstrap.carousel",[]).controller("CarouselController",["$scope","$element","$interval","$animate",function($scope,$element,$interval,$animate){function goNext(slide,index,direction){destroyed||(angular.extend(slide,{direction:direction,active:!0}),angular.extend(self.currentSlide||{},{direction:direction,active:!1}),$animate.enabled()&&!$scope.noTransition&&!$scope.$currentTransition&&slide.$element&&(slide.$element.data(SLIDE_DIRECTION,slide.direction),$scope.$currentTransition=!0,slide.$element.one("$animate:close",function(){$scope.$currentTransition=null})),self.currentSlide=slide,currentIndex=index,restartTimer())}function getSlideByIndex(index){if(angular.isUndefined(slides[index].index))return slides[index];var i;slides.length;for(i=0;i<slides.length;++i)if(slides[i].index==index)return slides[i]}function restartTimer(){resetTimer();var interval=+$scope.interval;!isNaN(interval)&&interval>0&&(currentInterval=$interval(timerFn,interval))}function resetTimer(){currentInterval&&($interval.cancel(currentInterval),currentInterval=null)}function timerFn(){var interval=+$scope.interval;isPlaying&&!isNaN(interval)&&interval>0&&slides.length?$scope.next():$scope.pause()}var currentInterval,isPlaying,self=this,slides=self.slides=$scope.slides=[],NO_TRANSITION="uib-noTransition",SLIDE_DIRECTION="uib-slideDirection",currentIndex=-1;self.currentSlide=null;var destroyed=!1;self.select=$scope.select=function(nextSlide,direction){var nextIndex=self.indexOfSlide(nextSlide);void 0===direction&&(direction=nextIndex>self.getCurrentIndex()?"next":"prev"),nextSlide&&nextSlide!==self.currentSlide&&!$scope.$currentTransition&&goNext(nextSlide,nextIndex,direction)},$scope.$on("$destroy",function(){destroyed=!0}),self.getCurrentIndex=function(){return self.currentSlide&&angular.isDefined(self.currentSlide.index)?+self.currentSlide.index:currentIndex},self.indexOfSlide=function(slide){return angular.isDefined(slide.index)?+slide.index:slides.indexOf(slide)},$scope.next=function(){var newIndex=(self.getCurrentIndex()+1)%slides.length;return 0===newIndex&&$scope.noWrap()?void $scope.pause():self.select(getSlideByIndex(newIndex),"next")},$scope.prev=function(){var newIndex=self.getCurrentIndex()-1<0?slides.length-1:self.getCurrentIndex()-1;return $scope.noWrap()&&newIndex===slides.length-1?void $scope.pause():self.select(getSlideByIndex(newIndex),"prev")},$scope.isActive=function(slide){return self.currentSlide===slide},$scope.$watch("interval",restartTimer),$scope.$on("$destroy",resetTimer),$scope.play=function(){isPlaying||(isPlaying=!0,restartTimer())},$scope.pause=function(){$scope.noPause||(isPlaying=!1,resetTimer())},self.addSlide=function(slide,element){slide.$element=element,slides.push(slide),1===slides.length||slide.active?(self.select(slides[slides.length-1]),1==slides.length&&$scope.play()):slide.active=!1},self.removeSlide=function(slide){angular.isDefined(slide.index)&&slides.sort(function(a,b){return+a.index>+b.index});var index=slides.indexOf(slide);slides.splice(index,1),slides.length>0&&slide.active?index>=slides.length?self.select(slides[index-1]):self.select(slides[index]):currentIndex>index&&currentIndex--},$scope.$watch("noTransition",function(noTransition){$element.data(NO_TRANSITION,noTransition)})}]).directive("carousel",[function(){return{restrict:"EA",transclude:!0,replace:!0,controller:"CarouselController",require:"carousel",templateUrl:"template/carousel/carousel.html",scope:{interval:"=",noTransition:"=",noPause:"=",noWrap:"&"}}}]).directive("slide",function(){return{require:"^carousel",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/carousel/slide.html",scope:{active:"=?",index:"=?"},link:function(scope,element,attrs,carouselCtrl){carouselCtrl.addSlide(scope,element),scope.$on("$destroy",function(){carouselCtrl.removeSlide(scope)}),scope.$watch("active",function(active){active&&carouselCtrl.select(scope)})}}}).animation(".item",["$animate",function($animate){var NO_TRANSITION="uib-noTransition",SLIDE_DIRECTION="uib-slideDirection";return{beforeAddClass:function(element,className,done){if("active"==className&&element.parent()&&!element.parent().data(NO_TRANSITION)){var stopped=!1,direction=element.data(SLIDE_DIRECTION),directionClass="next"==direction?"left":"right";return element.addClass(direction),$animate.addClass(element,directionClass).then(function(){stopped||element.removeClass(directionClass+" "+direction),done()}),function(){stopped=!0}}done()},beforeRemoveClass:function(element,className,done){if("active"==className&&element.parent()&&!element.parent().data(NO_TRANSITION)){var stopped=!1,direction=element.data(SLIDE_DIRECTION),directionClass="next"==direction?"left":"right";return $animate.addClass(element,directionClass).then(function(){stopped||element.removeClass(directionClass),done()}),function(){stopped=!0}}done()}}}]),angular.module("ui.bootstrap.dateparser",[]).service("dateParser",["$locale","orderByFilter",function($locale,orderByFilter){function createParser(format){var map=[],regex=format.split("");return angular.forEach(formatCodeToRegex,function(data,code){var index=format.indexOf(code);if(index>-1){format=format.split(""),regex[index]="("+data.regex+")",format[index]="$";for(var i=index+1,n=index+code.length;n>i;i++)regex[i]="",format[i]="$";format=format.join(""),map.push({index:index,apply:data.apply})}}),{regex:new RegExp("^"+regex.join("")+"$"),map:orderByFilter(map,"index")}}function isValid(year,month,date){return 1>date?!1:1===month&&date>28?29===date&&(year%4===0&&year%100!==0||year%400===0):3===month||5===month||8===month||10===month?31>date:!0}var SPECIAL_CHARACTERS_REGEXP=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;this.parsers={};var formatCodeToRegex={yyyy:{regex:"\\d{4}",apply:function(value){this.year=+value}},yy:{regex:"\\d{2}",apply:function(value){this.year=+value+2e3}},y:{regex:"\\d{1,4}",apply:function(value){this.year=+value}},MMMM:{regex:$locale.DATETIME_FORMATS.MONTH.join("|"),apply:function(value){this.month=$locale.DATETIME_FORMATS.MONTH.indexOf(value)}},MMM:{regex:$locale.DATETIME_FORMATS.SHORTMONTH.join("|"),apply:function(value){this.month=$locale.DATETIME_FORMATS.SHORTMONTH.indexOf(value)}},MM:{regex:"0[1-9]|1[0-2]",apply:function(value){this.month=value-1}},M:{regex:"[1-9]|1[0-2]",apply:function(value){this.month=value-1}},dd:{regex:"[0-2][0-9]{1}|3[0-1]{1}",apply:function(value){this.date=+value}},d:{regex:"[1-2]?[0-9]{1}|3[0-1]{1}",apply:function(value){this.date=+value}},EEEE:{regex:$locale.DATETIME_FORMATS.DAY.join("|")},EEE:{regex:$locale.DATETIME_FORMATS.SHORTDAY.join("|")},HH:{regex:"(?:0|1)[0-9]|2[0-3]",apply:function(value){this.hours=+value}},H:{regex:"1?[0-9]|2[0-3]",apply:function(value){this.hours=+value}},mm:{regex:"[0-5][0-9]",apply:function(value){this.minutes=+value}},m:{regex:"[0-9]|[1-5][0-9]",apply:function(value){this.minutes=+value}},sss:{regex:"[0-9][0-9][0-9]",apply:function(value){this.milliseconds=+value}},ss:{regex:"[0-5][0-9]",apply:function(value){this.seconds=+value}},s:{regex:"[0-9]|[1-5][0-9]",apply:function(value){this.seconds=+value}}};this.parse=function(input,format,baseDate){if(!angular.isString(input)||!format)return input;format=$locale.DATETIME_FORMATS[format]||format,format=format.replace(SPECIAL_CHARACTERS_REGEXP,"\\$&"),this.parsers[format]||(this.parsers[format]=createParser(format));var parser=this.parsers[format],regex=parser.regex,map=parser.map,results=input.match(regex);if(results&&results.length){var fields,dt;fields=baseDate?{year:baseDate.getFullYear(),month:baseDate.getMonth(),date:baseDate.getDate(),hours:baseDate.getHours(),minutes:baseDate.getMinutes(),seconds:baseDate.getSeconds(),milliseconds:baseDate.getMilliseconds()}:{year:1900,month:0,date:1,hours:0,minutes:0,seconds:0,milliseconds:0};for(var i=1,n=results.length;n>i;i++){var mapper=map[i-1];mapper.apply&&mapper.apply.call(fields,results[i])}return isValid(fields.year,fields.month,fields.date)&&(dt=new Date(fields.year,fields.month,fields.date,fields.hours,fields.minutes,fields.seconds,fields.milliseconds||0)),dt}}}]),angular.module("ui.bootstrap.position",[]).factory("$position",["$document","$window",function($document,$window){function getStyle(el,cssprop){return el.currentStyle?el.currentStyle[cssprop]:$window.getComputedStyle?$window.getComputedStyle(el)[cssprop]:el.style[cssprop]}function isStaticPositioned(element){return"static"===(getStyle(element,"position")||"static")}var parentOffsetEl=function(element){for(var docDomEl=$document[0],offsetParent=element.offsetParent||docDomEl;offsetParent&&offsetParent!==docDomEl&&isStaticPositioned(offsetParent);)offsetParent=offsetParent.offsetParent;return offsetParent||docDomEl};return{position:function(element){var elBCR=this.offset(element),offsetParentBCR={top:0,left:0},offsetParentEl=parentOffsetEl(element[0]);offsetParentEl!=$document[0]&&(offsetParentBCR=this.offset(angular.element(offsetParentEl)),offsetParentBCR.top+=offsetParentEl.clientTop-offsetParentEl.scrollTop,offsetParentBCR.left+=offsetParentEl.clientLeft-offsetParentEl.scrollLeft);var boundingClientRect=element[0].getBoundingClientRect();return{width:boundingClientRect.width||element.prop("offsetWidth"),height:boundingClientRect.height||element.prop("offsetHeight"),top:elBCR.top-offsetParentBCR.top,left:elBCR.left-offsetParentBCR.left}},offset:function(element){var boundingClientRect=element[0].getBoundingClientRect();return{width:boundingClientRect.width||element.prop("offsetWidth"),height:boundingClientRect.height||element.prop("offsetHeight"),top:boundingClientRect.top+($window.pageYOffset||$document[0].documentElement.scrollTop),left:boundingClientRect.left+($window.pageXOffset||$document[0].documentElement.scrollLeft)}},positionElements:function(hostEl,targetEl,positionStr,appendToBody){var hostElPos,targetElWidth,targetElHeight,targetElPos,positionStrParts=positionStr.split("-"),pos0=positionStrParts[0],pos1=positionStrParts[1]||"center";hostElPos=appendToBody?this.offset(hostEl):this.position(hostEl),targetElWidth=targetEl.prop("offsetWidth"),targetElHeight=targetEl.prop("offsetHeight");var shiftWidth={center:function(){return hostElPos.left+hostElPos.width/2-targetElWidth/2},left:function(){return hostElPos.left},right:function(){return hostElPos.left+hostElPos.width}},shiftHeight={center:function(){return hostElPos.top+hostElPos.height/2-targetElHeight/2},top:function(){return hostElPos.top},bottom:function(){return hostElPos.top+hostElPos.height}};switch(pos0){case"right":targetElPos={top:shiftHeight[pos1](),left:shiftWidth[pos0]()};break;case"left":targetElPos={top:shiftHeight[pos1](),left:hostElPos.left-targetElWidth};break;case"bottom":targetElPos={top:shiftHeight[pos0](),left:shiftWidth[pos1]()};break;default:targetElPos={top:hostElPos.top-targetElHeight,left:shiftWidth[pos1]()}}return targetElPos}}}]),angular.module("ui.bootstrap.datepicker",["ui.bootstrap.dateparser","ui.bootstrap.position"]).constant("datepickerConfig",{formatDay:"dd",formatMonth:"MMMM",formatYear:"yyyy",formatDayHeader:"EEE",formatDayTitle:"MMMM yyyy",formatMonthTitle:"yyyy",datepickerMode:"day",minMode:"day",maxMode:"year",showWeeks:!0,startingDay:0,yearRange:20,minDate:null,maxDate:null,shortcutPropagation:!1}).controller("DatepickerController",["$scope","$attrs","$parse","$interpolate","$log","dateFilter","datepickerConfig",function($scope,$attrs,$parse,$interpolate,$log,dateFilter,datepickerConfig){var self=this,ngModelCtrl={$setViewValue:angular.noop};this.modes=["day","month","year"],angular.forEach(["formatDay","formatMonth","formatYear","formatDayHeader","formatDayTitle","formatMonthTitle","minMode","maxMode","showWeeks","startingDay","yearRange","shortcutPropagation"],function(key,index){self[key]=angular.isDefined($attrs[key])?8>index?$interpolate($attrs[key])($scope.$parent):$scope.$parent.$eval($attrs[key]):datepickerConfig[key]}),angular.forEach(["minDate","maxDate"],function(key){$attrs[key]?$scope.$parent.$watch($parse($attrs[key]),function(value){self[key]=value?new Date(value):null,self.refreshView()}):self[key]=datepickerConfig[key]?new Date(datepickerConfig[key]):null}),$scope.datepickerMode=$scope.datepickerMode||datepickerConfig.datepickerMode,$scope.maxMode=self.maxMode,$scope.uniqueId="datepicker-"+$scope.$id+"-"+Math.floor(1e4*Math.random()),angular.isDefined($attrs.initDate)?(this.activeDate=$scope.$parent.$eval($attrs.initDate)||new Date,$scope.$parent.$watch($attrs.initDate,function(initDate){initDate&&(ngModelCtrl.$isEmpty(ngModelCtrl.$modelValue)||ngModelCtrl.$invalid)&&(self.activeDate=initDate,self.refreshView())})):this.activeDate=new Date,$scope.isActive=function(dateObject){return 0===self.compare(dateObject.date,self.activeDate)?($scope.activeDateId=dateObject.uid,!0):!1},this.init=function(ngModelCtrl_){ngModelCtrl=ngModelCtrl_,ngModelCtrl.$render=function(){self.render()}},this.render=function(){if(ngModelCtrl.$viewValue){var date=new Date(ngModelCtrl.$viewValue),isValid=!isNaN(date);isValid?this.activeDate=date:$log.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.'),ngModelCtrl.$setValidity("date",isValid)}this.refreshView()},this.refreshView=function(){if(this.element){this._refreshView();var date=ngModelCtrl.$viewValue?new Date(ngModelCtrl.$viewValue):null;ngModelCtrl.$setValidity("date-disabled",!date||this.element&&!this.isDisabled(date))}},this.createDateObject=function(date,format){var model=ngModelCtrl.$viewValue?new Date(ngModelCtrl.$viewValue):null;return{date:date,label:dateFilter(date,format),selected:model&&0===this.compare(date,model),disabled:this.isDisabled(date),current:0===this.compare(date,new Date),customClass:this.customClass(date)}},this.isDisabled=function(date){return this.minDate&&this.compare(date,this.minDate)<0||this.maxDate&&this.compare(date,this.maxDate)>0||$attrs.dateDisabled&&$scope.dateDisabled({date:date,mode:$scope.datepickerMode})},this.customClass=function(date){return $scope.customClass({date:date,mode:$scope.datepickerMode})},this.split=function(arr,size){for(var arrays=[];arr.length>0;)arrays.push(arr.splice(0,size));return arrays},this.fixTimeZone=function(date){var hours=date.getHours();date.setHours(23===hours?hours+2:0)},$scope.select=function(date){if($scope.datepickerMode===self.minMode){var dt=ngModelCtrl.$viewValue?new Date(ngModelCtrl.$viewValue):new Date(0,0,0,0,0,0,0);dt.setFullYear(date.getFullYear(),date.getMonth(),date.getDate()),ngModelCtrl.$setViewValue(dt),ngModelCtrl.$render()}else self.activeDate=date,$scope.datepickerMode=self.modes[self.modes.indexOf($scope.datepickerMode)-1]},$scope.move=function(direction){var year=self.activeDate.getFullYear()+direction*(self.step.years||0),month=self.activeDate.getMonth()+direction*(self.step.months||0);self.activeDate.setFullYear(year,month,1),self.refreshView()},$scope.toggleMode=function(direction){direction=direction||1,$scope.datepickerMode===self.maxMode&&1===direction||$scope.datepickerMode===self.minMode&&-1===direction||($scope.datepickerMode=self.modes[self.modes.indexOf($scope.datepickerMode)+direction])},$scope.keys={13:"enter",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down"};var focusElement=function(){self.element[0].focus()};$scope.$on("datepicker.focus",focusElement),$scope.keydown=function(evt){var key=$scope.keys[evt.which];if(key&&!evt.shiftKey&&!evt.altKey)if(evt.preventDefault(),self.shortcutPropagation||evt.stopPropagation(),"enter"===key||"space"===key){if(self.isDisabled(self.activeDate))return;$scope.select(self.activeDate),focusElement()}else!evt.ctrlKey||"up"!==key&&"down"!==key?(self.handleKeyDown(key,evt),self.refreshView()):($scope.toggleMode("up"===key?1:-1),focusElement())}}]).directive("datepicker",function(){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/datepicker.html",scope:{datepickerMode:"=?",dateDisabled:"&",customClass:"&",shortcutPropagation:"&?"},require:["datepicker","?^ngModel"],controller:"DatepickerController",link:function(scope,element,attrs,ctrls){var datepickerCtrl=ctrls[0],ngModelCtrl=ctrls[1];ngModelCtrl&&datepickerCtrl.init(ngModelCtrl)}}}).directive("daypicker",["dateFilter",function(dateFilter){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/day.html",require:"^datepicker",link:function(scope,element,attrs,ctrl){function getDaysInMonth(year,month){return 1!==month||year%4!==0||year%100===0&&year%400!==0?DAYS_IN_MONTH[month]:29}function getDates(startDate,n){for(var date,dates=new Array(n),current=new Date(startDate),i=0;n>i;)date=new Date(current),ctrl.fixTimeZone(date),dates[i++]=date,current.setDate(current.getDate()+1);return dates}function getISO8601WeekNumber(date){var checkDate=new Date(date);checkDate.setDate(checkDate.getDate()+4-(checkDate.getDay()||7));var time=checkDate.getTime();return checkDate.setMonth(0),checkDate.setDate(1),Math.floor(Math.round((time-checkDate)/864e5)/7)+1}scope.showWeeks=ctrl.showWeeks,ctrl.step={months:1},ctrl.element=element;var DAYS_IN_MONTH=[31,28,31,30,31,30,31,31,30,31,30,31];ctrl._refreshView=function(){var year=ctrl.activeDate.getFullYear(),month=ctrl.activeDate.getMonth(),firstDayOfMonth=new Date(year,month,1),difference=ctrl.startingDay-firstDayOfMonth.getDay(),numDisplayedFromPreviousMonth=difference>0?7-difference:-difference,firstDate=new Date(firstDayOfMonth);numDisplayedFromPreviousMonth>0&&firstDate.setDate(-numDisplayedFromPreviousMonth+1);for(var days=getDates(firstDate,42),i=0;42>i;i++)days[i]=angular.extend(ctrl.createDateObject(days[i],ctrl.formatDay),{secondary:days[i].getMonth()!==month,uid:scope.uniqueId+"-"+i});scope.labels=new Array(7);for(var j=0;7>j;j++)scope.labels[j]={abbr:dateFilter(days[j].date,ctrl.formatDayHeader),full:dateFilter(days[j].date,"EEEE")};if(scope.title=dateFilter(ctrl.activeDate,ctrl.formatDayTitle),scope.rows=ctrl.split(days,7),scope.showWeeks){scope.weekNumbers=[];for(var thursdayIndex=(11-ctrl.startingDay)%7,numWeeks=scope.rows.length,curWeek=0;numWeeks>curWeek;curWeek++)scope.weekNumbers.push(getISO8601WeekNumber(scope.rows[curWeek][thursdayIndex].date))}},ctrl.compare=function(date1,date2){return new Date(date1.getFullYear(),date1.getMonth(),date1.getDate())-new Date(date2.getFullYear(),date2.getMonth(),date2.getDate())},ctrl.handleKeyDown=function(key,evt){var date=ctrl.activeDate.getDate();if("left"===key)date-=1;else if("up"===key)date-=7;else if("right"===key)date+=1;else if("down"===key)date+=7;else if("pageup"===key||"pagedown"===key){var month=ctrl.activeDate.getMonth()+("pageup"===key?-1:1);ctrl.activeDate.setMonth(month,1),date=Math.min(getDaysInMonth(ctrl.activeDate.getFullYear(),ctrl.activeDate.getMonth()),date)}else"home"===key?date=1:"end"===key&&(date=getDaysInMonth(ctrl.activeDate.getFullYear(),ctrl.activeDate.getMonth()));ctrl.activeDate.setDate(date)},ctrl.refreshView()}}}]).directive("monthpicker",["dateFilter",function(dateFilter){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/month.html",require:"^datepicker",link:function(scope,element,attrs,ctrl){ctrl.step={years:1},ctrl.element=element,ctrl._refreshView=function(){for(var date,months=new Array(12),year=ctrl.activeDate.getFullYear(),i=0;12>i;i++)date=new Date(year,i,1),ctrl.fixTimeZone(date),months[i]=angular.extend(ctrl.createDateObject(date,ctrl.formatMonth),{uid:scope.uniqueId+"-"+i});scope.title=dateFilter(ctrl.activeDate,ctrl.formatMonthTitle),scope.rows=ctrl.split(months,3)},ctrl.compare=function(date1,date2){return new Date(date1.getFullYear(),date1.getMonth())-new Date(date2.getFullYear(),date2.getMonth())},ctrl.handleKeyDown=function(key,evt){var date=ctrl.activeDate.getMonth();if("left"===key)date-=1;else if("up"===key)date-=3;else if("right"===key)date+=1;else if("down"===key)date+=3;else if("pageup"===key||"pagedown"===key){var year=ctrl.activeDate.getFullYear()+("pageup"===key?-1:1);ctrl.activeDate.setFullYear(year)}else"home"===key?date=0:"end"===key&&(date=11);ctrl.activeDate.setMonth(date)},ctrl.refreshView()}}}]).directive("yearpicker",["dateFilter",function(dateFilter){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/year.html",require:"^datepicker",link:function(scope,element,attrs,ctrl){function getStartingYear(year){return parseInt((year-1)/range,10)*range+1}var range=ctrl.yearRange;ctrl.step={years:range},ctrl.element=element,ctrl._refreshView=function(){for(var date,years=new Array(range),i=0,start=getStartingYear(ctrl.activeDate.getFullYear());range>i;i++)date=new Date(start+i,0,1),ctrl.fixTimeZone(date),years[i]=angular.extend(ctrl.createDateObject(date,ctrl.formatYear),{uid:scope.uniqueId+"-"+i});scope.title=[years[0].label,years[range-1].label].join(" - "),scope.rows=ctrl.split(years,5)},ctrl.compare=function(date1,date2){return date1.getFullYear()-date2.getFullYear()},ctrl.handleKeyDown=function(key,evt){var date=ctrl.activeDate.getFullYear();"left"===key?date-=1:"up"===key?date-=5:"right"===key?date+=1:"down"===key?date+=5:"pageup"===key||"pagedown"===key?date+=("pageup"===key?-1:1)*ctrl.step.years:"home"===key?date=getStartingYear(ctrl.activeDate.getFullYear()):"end"===key&&(date=getStartingYear(ctrl.activeDate.getFullYear())+range-1),ctrl.activeDate.setFullYear(date)},ctrl.refreshView()}}}]).constant("datepickerPopupConfig",{datepickerPopup:"yyyy-MM-dd",html5Types:{date:"yyyy-MM-dd","datetime-local":"yyyy-MM-ddTHH:mm:ss.sss",month:"yyyy-MM"},currentText:"Today",clearText:"Clear",closeText:"Done",closeOnDateSelection:!0,appendToBody:!1,showButtonBar:!0}).directive("datepickerPopup",["$compile","$parse","$document","$position","dateFilter","dateParser","datepickerPopupConfig","$timeout",function($compile,$parse,$document,$position,dateFilter,dateParser,datepickerPopupConfig,$timeout){return{restrict:"EA",require:"ngModel",scope:{isOpen:"=?",currentText:"@",clearText:"@",closeText:"@",dateDisabled:"&",customClass:"&"},link:function(scope,element,attrs,ngModel){function cameltoDash(string){return string.replace(/([A-Z])/g,function($1){return"-"+$1.toLowerCase()})}function parseDate(viewValue){if(angular.isNumber(viewValue)&&(viewValue=new Date(viewValue)),viewValue){if(angular.isDate(viewValue)&&!isNaN(viewValue))return viewValue;if(angular.isString(viewValue)){var date=dateParser.parse(viewValue,dateFormat,scope.date)||new Date(viewValue);return isNaN(date)?void 0:date}return void 0}return null}function validator(modelValue,viewValue){var value=modelValue||viewValue;if(angular.isNumber(value)&&(value=new Date(value)),value){if(angular.isDate(value)&&!isNaN(value))return!0;if(angular.isString(value)){var date=dateParser.parse(value,dateFormat)||new Date(value);return!isNaN(date)}return!1}return!0}var dateFormat,closeOnDateSelection=angular.isDefined(attrs.closeOnDateSelection)?scope.$parent.$eval(attrs.closeOnDateSelection):datepickerPopupConfig.closeOnDateSelection,appendToBody=angular.isDefined(attrs.datepickerAppendToBody)?scope.$parent.$eval(attrs.datepickerAppendToBody):datepickerPopupConfig.appendToBody;scope.showButtonBar=angular.isDefined(attrs.showButtonBar)?scope.$parent.$eval(attrs.showButtonBar):datepickerPopupConfig.showButtonBar,scope.getText=function(key){return scope[key+"Text"]||datepickerPopupConfig[key+"Text"]};var isHtml5DateInput=!1;if(datepickerPopupConfig.html5Types[attrs.type]?(dateFormat=datepickerPopupConfig.html5Types[attrs.type],isHtml5DateInput=!0):(dateFormat=attrs.datepickerPopup||datepickerPopupConfig.datepickerPopup,attrs.$observe("datepickerPopup",function(value,oldValue){var newDateFormat=value||datepickerPopupConfig.datepickerPopup;if(newDateFormat!==dateFormat&&(dateFormat=newDateFormat,ngModel.$modelValue=null,!dateFormat))throw new Error("datepickerPopup must have a date format specified.")})),!dateFormat)throw new Error("datepickerPopup must have a date format specified.");if(isHtml5DateInput&&attrs.datepickerPopup)throw new Error("HTML5 date input types do not support custom formats.");var popupEl=angular.element("<div datepicker-popup-wrap><div datepicker></div></div>");popupEl.attr({"ng-model":"date","ng-change":"dateSelection(date)"});var datepickerEl=angular.element(popupEl.children()[0]);if(isHtml5DateInput&&"month"==attrs.type&&(datepickerEl.attr("datepicker-mode",'"month"'),datepickerEl.attr("min-mode","month")),attrs.datepickerOptions){var options=scope.$parent.$eval(attrs.datepickerOptions);options.initDate&&(scope.initDate=options.initDate,datepickerEl.attr("init-date","initDate"),delete options.initDate),angular.forEach(options,function(value,option){datepickerEl.attr(cameltoDash(option),value)})}scope.watchData={},angular.forEach(["minDate","maxDate","datepickerMode","initDate","shortcutPropagation"],function(key){if(attrs[key]){var getAttribute=$parse(attrs[key]);if(scope.$parent.$watch(getAttribute,function(value){scope.watchData[key]=value}),datepickerEl.attr(cameltoDash(key),"watchData."+key),"datepickerMode"===key){var setAttribute=getAttribute.assign;scope.$watch("watchData."+key,function(value,oldvalue){angular.isFunction(setAttribute)&&value!==oldvalue&&setAttribute(scope.$parent,value)})}}}),attrs.dateDisabled&&datepickerEl.attr("date-disabled","dateDisabled({ date: date, mode: mode })"),attrs.showWeeks&&datepickerEl.attr("show-weeks",attrs.showWeeks),attrs.customClass&&datepickerEl.attr("custom-class","customClass({ date: date, mode: mode })"),isHtml5DateInput?ngModel.$formatters.push(function(value){return scope.date=value,value}):(ngModel.$$parserName="date",ngModel.$validators.date=validator,ngModel.$parsers.unshift(parseDate),ngModel.$formatters.push(function(value){return scope.date=value,ngModel.$isEmpty(value)?value:dateFilter(value,dateFormat)})),scope.dateSelection=function(dt){angular.isDefined(dt)&&(scope.date=dt);var date=scope.date?dateFilter(scope.date,dateFormat):"";element.val(date),ngModel.$setViewValue(date),closeOnDateSelection&&(scope.isOpen=!1,element[0].focus())},ngModel.$viewChangeListeners.push(function(){scope.date=dateParser.parse(ngModel.$viewValue,dateFormat,scope.date)||new Date(ngModel.$viewValue)});var documentClickBind=function(event){scope.isOpen&&event.target!==element[0]&&scope.$apply(function(){scope.isOpen=!1})},inputKeydownBind=function(evt){27===evt.which&&scope.isOpen?(evt.preventDefault(),evt.stopPropagation(),scope.$apply(function(){scope.isOpen=!1}),element[0].focus()):40!==evt.which||scope.isOpen||(evt.preventDefault(),evt.stopPropagation(),scope.$apply(function(){scope.isOpen=!0}))};element.bind("keydown",inputKeydownBind),scope.keydown=function(evt){27===evt.which&&(scope.isOpen=!1,element[0].focus())},scope.$watch("isOpen",function(value){value?(scope.position=appendToBody?$position.offset(element):$position.position(element),scope.position.top=scope.position.top+element.prop("offsetHeight"),$document.bind("click",documentClickBind),$timeout(function(){scope.$broadcast("datepicker.focus")},0,!1)):$document.unbind("click",documentClickBind)}),scope.select=function(date){if("today"===date){var today=new Date;angular.isDate(scope.date)?(date=new Date(scope.date),date.setFullYear(today.getFullYear(),today.getMonth(),today.getDate())):date=new Date(today.setHours(0,0,0,0))}scope.dateSelection(date)},scope.close=function(){scope.isOpen=!1,element[0].focus()};var $popup=$compile(popupEl)(scope);popupEl.remove(),appendToBody?$document.find("body").append($popup):element.after($popup),scope.$on("$destroy",function(){scope.isOpen===!0&&scope.$apply(function(){scope.isOpen=!1}),$popup.remove(),element.unbind("keydown",inputKeydownBind),$document.unbind("click",documentClickBind)})}}}]).directive("datepickerPopupWrap",function(){return{restrict:"EA",replace:!0,transclude:!0,templateUrl:"template/datepicker/popup.html"}}),angular.module("ui.bootstrap.dropdown",["ui.bootstrap.position"]).constant("dropdownConfig",{openClass:"open"}).service("dropdownService",["$document","$rootScope",function($document,$rootScope){var openScope=null;this.open=function(dropdownScope){openScope||($document.bind("click",closeDropdown),$document.bind("keydown",keybindFilter)),openScope&&openScope!==dropdownScope&&(openScope.isOpen=!1),openScope=dropdownScope},this.close=function(dropdownScope){openScope===dropdownScope&&(openScope=null,$document.unbind("click",closeDropdown),$document.unbind("keydown",keybindFilter))};var closeDropdown=function(evt){if(openScope&&(!evt||"disabled"!==openScope.getAutoClose())){var toggleElement=openScope.getToggleElement();if(!(evt&&toggleElement&&toggleElement[0].contains(evt.target))){var dropdownElement=openScope.getDropdownElement(); scope.$watch("isOpen",function(value){value&&accordionCtrl.closeOthers(scope)}),scope.toggleOpen=function(){scope.isDisabled||(scope.isOpen=!scope.isOpen)}}}}).directive("accordionHeading",function(){return{restrict:"EA",transclude:!0,template:"",replace:!0,require:"^accordionGroup",link:function(scope,element,attr,accordionGroupCtrl,transclude){accordionGroupCtrl.setHeading(transclude(scope,angular.noop))}}}).directive("accordionTransclude",function(){return{require:"^accordionGroup",link:function(scope,element,attr,controller){scope.$watch(function(){return controller[attr.accordionTransclude]},function(heading){heading&&(element.html(""),element.append(heading))})}}}),angular.module("ui.bootstrap.alert",[]).controller("AlertController",["$scope","$attrs",function($scope,$attrs){$scope.closeable=!!$attrs.close,this.close=$scope.close}]).directive("alert",function(){return{restrict:"EA",controller:"AlertController",templateUrl:"template/alert/alert.html",transclude:!0,replace:!0,scope:{type:"@",close:"&"}}}).directive("dismissOnTimeout",["$timeout",function($timeout){return{require:"alert",link:function(scope,element,attrs,alertCtrl){$timeout(function(){alertCtrl.close()},parseInt(attrs.dismissOnTimeout,10))}}}]),angular.module("ui.bootstrap.bindHtml",[]).value("$bindHtmlUnsafeSuppressDeprecated",!1).directive("bindHtmlUnsafe",["$log","$bindHtmlUnsafeSuppressDeprecated",function($log,$bindHtmlUnsafeSuppressDeprecated){return function(scope,element,attr){$bindHtmlUnsafeSuppressDeprecated||$log.warn("bindHtmlUnsafe is now deprecated. Use ngBindHtml instead"),element.addClass("ng-binding").data("$binding",attr.bindHtmlUnsafe),scope.$watch(attr.bindHtmlUnsafe,function(value){element.html(value||"")})}}]),angular.module("ui.bootstrap.buttons",[]).constant("buttonConfig",{activeClass:"active",toggleEvent:"click"}).controller("ButtonsController",["buttonConfig",function(buttonConfig){this.activeClass=buttonConfig.activeClass||"active",this.toggleEvent=buttonConfig.toggleEvent||"click"}]).directive("btnRadio",function(){return{require:["btnRadio","ngModel"],controller:"ButtonsController",link:function(scope,element,attrs,ctrls){var buttonsCtrl=ctrls[0],ngModelCtrl=ctrls[1];ngModelCtrl.$render=function(){element.toggleClass(buttonsCtrl.activeClass,angular.equals(ngModelCtrl.$modelValue,scope.$eval(attrs.btnRadio)))},element.bind(buttonsCtrl.toggleEvent,function(){var isActive=element.hasClass(buttonsCtrl.activeClass);(!isActive||angular.isDefined(attrs.uncheckable))&&scope.$apply(function(){ngModelCtrl.$setViewValue(isActive?null:scope.$eval(attrs.btnRadio)),ngModelCtrl.$render()})})}}}).directive("btnCheckbox",function(){return{require:["btnCheckbox","ngModel"],controller:"ButtonsController",link:function(scope,element,attrs,ctrls){function getTrueValue(){return getCheckboxValue(attrs.btnCheckboxTrue,!0)}function getFalseValue(){return getCheckboxValue(attrs.btnCheckboxFalse,!1)}function getCheckboxValue(attributeValue,defaultValue){var val=scope.$eval(attributeValue);return angular.isDefined(val)?val:defaultValue}var buttonsCtrl=ctrls[0],ngModelCtrl=ctrls[1];ngModelCtrl.$render=function(){element.toggleClass(buttonsCtrl.activeClass,angular.equals(ngModelCtrl.$modelValue,getTrueValue()))},element.bind(buttonsCtrl.toggleEvent,function(){scope.$apply(function(){ngModelCtrl.$setViewValue(element.hasClass(buttonsCtrl.activeClass)?getFalseValue():getTrueValue()),ngModelCtrl.$render()})})}}}),angular.module("ui.bootstrap.carousel",[]).controller("CarouselController",["$scope","$element","$interval","$animate",function($scope,$element,$interval,$animate){function goNext(slide,index,direction){destroyed||(angular.extend(slide,{direction:direction,active:!0}),angular.extend(self.currentSlide||{},{direction:direction,active:!1}),$animate.enabled()&&!$scope.noTransition&&!$scope.$currentTransition&&slide.$element&&(slide.$element.data(SLIDE_DIRECTION,slide.direction),$scope.$currentTransition=!0,slide.$element.one("$animate:close",function(){$scope.$currentTransition=null})),self.currentSlide=slide,currentIndex=index,restartTimer())}function getSlideByIndex(index){if(angular.isUndefined(slides[index].index))return slides[index];var i;slides.length;for(i=0;i<slides.length;++i)if(slides[i].index==index)return slides[i]}function restartTimer(){resetTimer();var interval=+$scope.interval;!isNaN(interval)&&interval>0&&(currentInterval=$interval(timerFn,interval))}function resetTimer(){currentInterval&&($interval.cancel(currentInterval),currentInterval=null)}function timerFn(){var interval=+$scope.interval;isPlaying&&!isNaN(interval)&&interval>0&&slides.length?$scope.next():$scope.pause()}var currentInterval,isPlaying,self=this,slides=self.slides=$scope.slides=[],NO_TRANSITION="uib-noTransition",SLIDE_DIRECTION="uib-slideDirection",currentIndex=-1;self.currentSlide=null;var destroyed=!1;self.select=$scope.select=function(nextSlide,direction){var nextIndex=self.indexOfSlide(nextSlide);void 0===direction&&(direction=nextIndex>self.getCurrentIndex()?"next":"prev"),nextSlide&&nextSlide!==self.currentSlide&&!$scope.$currentTransition&&goNext(nextSlide,nextIndex,direction)},$scope.$on("$destroy",function(){destroyed=!0}),self.getCurrentIndex=function(){return self.currentSlide&&angular.isDefined(self.currentSlide.index)?+self.currentSlide.index:currentIndex},self.indexOfSlide=function(slide){return angular.isDefined(slide.index)?+slide.index:slides.indexOf(slide)},$scope.next=function(){var newIndex=(self.getCurrentIndex()+1)%slides.length;return 0===newIndex&&$scope.noWrap()?void $scope.pause():self.select(getSlideByIndex(newIndex),"next")},$scope.prev=function(){var newIndex=self.getCurrentIndex()-1<0?slides.length-1:self.getCurrentIndex()-1;return $scope.noWrap()&&newIndex===slides.length-1?void $scope.pause():self.select(getSlideByIndex(newIndex),"prev")},$scope.isActive=function(slide){return self.currentSlide===slide},$scope.$watch("interval",restartTimer),$scope.$on("$destroy",resetTimer),$scope.play=function(){isPlaying||(isPlaying=!0,restartTimer())},$scope.pause=function(){$scope.noPause||(isPlaying=!1,resetTimer())},self.addSlide=function(slide,element){slide.$element=element,slides.push(slide),1===slides.length||slide.active?(self.select(slides[slides.length-1]),1==slides.length&&$scope.play()):slide.active=!1},self.removeSlide=function(slide){angular.isDefined(slide.index)&&slides.sort(function(a,b){return+a.index>+b.index});var index=slides.indexOf(slide);slides.splice(index,1),slides.length>0&&slide.active?index>=slides.length?self.select(slides[index-1]):self.select(slides[index]):currentIndex>index&&currentIndex--},$scope.$watch("noTransition",function(noTransition){$element.data(NO_TRANSITION,noTransition)})}]).directive("carousel",[function(){return{restrict:"EA",transclude:!0,replace:!0,controller:"CarouselController",require:"carousel",templateUrl:"template/carousel/carousel.html",scope:{interval:"=",noTransition:"=",noPause:"=",noWrap:"&"}}}]).directive("slide",function(){return{require:"^carousel",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/carousel/slide.html",scope:{active:"=?",index:"=?"},link:function(scope,element,attrs,carouselCtrl){carouselCtrl.addSlide(scope,element),scope.$on("$destroy",function(){carouselCtrl.removeSlide(scope)}),scope.$watch("active",function(active){active&&carouselCtrl.select(scope)})}}}).animation(".item",["$animate",function($animate){var NO_TRANSITION="uib-noTransition",SLIDE_DIRECTION="uib-slideDirection";return{beforeAddClass:function(element,className,done){if("active"==className&&element.parent()&&!element.parent().data(NO_TRANSITION)){var stopped=!1,direction=element.data(SLIDE_DIRECTION),directionClass="next"==direction?"left":"right";return element.addClass(direction),$animate.addClass(element,directionClass).then(function(){stopped||element.removeClass(directionClass+" "+direction),done()}),function(){stopped=!0}}done()},beforeRemoveClass:function(element,className,done){if("active"==className&&element.parent()&&!element.parent().data(NO_TRANSITION)){var stopped=!1,direction=element.data(SLIDE_DIRECTION),directionClass="next"==direction?"left":"right";return $animate.addClass(element,directionClass).then(function(){stopped||element.removeClass(directionClass),done()}),function(){stopped=!0}}done()}}}]),angular.module("ui.bootstrap.dateparser",[]).service("dateParser",["$locale","orderByFilter",function($locale,orderByFilter){function createParser(format){var map=[],regex=format.split("");return angular.forEach(formatCodeToRegex,function(data,code){var index=format.indexOf(code);if(index>-1){format=format.split(""),regex[index]="("+data.regex+")",format[index]="$";for(var i=index+1,n=index+code.length;n>i;i++)regex[i]="",format[i]="$";format=format.join(""),map.push({index:index,apply:data.apply})}}),{regex:new RegExp("^"+regex.join("")+"$"),map:orderByFilter(map,"index")}}function isValid(year,month,date){return 1>date?!1:1===month&&date>28?29===date&&(year%4===0&&year%100!==0||year%400===0):3===month||5===month||8===month||10===month?31>date:!0}var SPECIAL_CHARACTERS_REGEXP=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;this.parsers={};var formatCodeToRegex={yyyy:{regex:"\\d{4}",apply:function(value){this.year=+value}},yy:{regex:"\\d{2}",apply:function(value){this.year=+value+2e3}},y:{regex:"\\d{1,4}",apply:function(value){this.year=+value}},MMMM:{regex:$locale.DATETIME_FORMATS.MONTH.join("|"),apply:function(value){this.month=$locale.DATETIME_FORMATS.MONTH.indexOf(value)}},MMM:{regex:$locale.DATETIME_FORMATS.SHORTMONTH.join("|"),apply:function(value){this.month=$locale.DATETIME_FORMATS.SHORTMONTH.indexOf(value)}},MM:{regex:"0[1-9]|1[0-2]",apply:function(value){this.month=value-1}},M:{regex:"[1-9]|1[0-2]",apply:function(value){this.month=value-1}},dd:{regex:"[0-2][0-9]{1}|3[0-1]{1}",apply:function(value){this.date=+value}},d:{regex:"[1-2]?[0-9]{1}|3[0-1]{1}",apply:function(value){this.date=+value}},EEEE:{regex:$locale.DATETIME_FORMATS.DAY.join("|")},EEE:{regex:$locale.DATETIME_FORMATS.SHORTDAY.join("|")},HH:{regex:"(?:0|1)[0-9]|2[0-3]",apply:function(value){this.hours=+value}},H:{regex:"1?[0-9]|2[0-3]",apply:function(value){this.hours=+value}},mm:{regex:"[0-5][0-9]",apply:function(value){this.minutes=+value}},m:{regex:"[0-9]|[1-5][0-9]",apply:function(value){this.minutes=+value}},sss:{regex:"[0-9][0-9][0-9]",apply:function(value){this.milliseconds=+value}},ss:{regex:"[0-5][0-9]",apply:function(value){this.seconds=+value}},s:{regex:"[0-9]|[1-5][0-9]",apply:function(value){this.seconds=+value}}};this.parse=function(input,format,baseDate){if(!angular.isString(input)||!format)return input;format=$locale.DATETIME_FORMATS[format]||format,format=format.replace(SPECIAL_CHARACTERS_REGEXP,"\\$&"),this.parsers[format]||(this.parsers[format]=createParser(format));var parser=this.parsers[format],regex=parser.regex,map=parser.map,results=input.match(regex);if(results&&results.length){var fields,dt;fields=baseDate?{year:baseDate.getFullYear(),month:baseDate.getMonth(),date:baseDate.getDate(),hours:baseDate.getHours(),minutes:baseDate.getMinutes(),seconds:baseDate.getSeconds(),milliseconds:baseDate.getMilliseconds()}:{year:1900,month:0,date:1,hours:0,minutes:0,seconds:0,milliseconds:0};for(var i=1,n=results.length;n>i;i++){var mapper=map[i-1];mapper.apply&&mapper.apply.call(fields,results[i])}return isValid(fields.year,fields.month,fields.date)&&(dt=new Date(fields.year,fields.month,fields.date,fields.hours,fields.minutes,fields.seconds,fields.milliseconds||0)),dt}}}]),angular.module("ui.bootstrap.position",[]).factory("$position",["$document","$window",function($document,$window){function getStyle(el,cssprop){return el.currentStyle?el.currentStyle[cssprop]:$window.getComputedStyle?$window.getComputedStyle(el)[cssprop]:el.style[cssprop]}function isStaticPositioned(element){return"static"===(getStyle(element,"position")||"static")}var parentOffsetEl=function(element){for(var docDomEl=$document[0],offsetParent=element.offsetParent||docDomEl;offsetParent&&offsetParent!==docDomEl&&isStaticPositioned(offsetParent);)offsetParent=offsetParent.offsetParent;return offsetParent||docDomEl};return{position:function(element){var elBCR=this.offset(element),offsetParentBCR={top:0,left:0},offsetParentEl=parentOffsetEl(element[0]);offsetParentEl!=$document[0]&&(offsetParentBCR=this.offset(angular.element(offsetParentEl)),offsetParentBCR.top+=offsetParentEl.clientTop-offsetParentEl.scrollTop,offsetParentBCR.left+=offsetParentEl.clientLeft-offsetParentEl.scrollLeft);var boundingClientRect=element[0].getBoundingClientRect();return{width:boundingClientRect.width||element.prop("offsetWidth"),height:boundingClientRect.height||element.prop("offsetHeight"),top:elBCR.top-offsetParentBCR.top,left:elBCR.left-offsetParentBCR.left}},offset:function(element){var boundingClientRect=element[0].getBoundingClientRect();return{width:boundingClientRect.width||element.prop("offsetWidth"),height:boundingClientRect.height||element.prop("offsetHeight"),top:boundingClientRect.top+($window.pageYOffset||$document[0].documentElement.scrollTop),left:boundingClientRect.left+($window.pageXOffset||$document[0].documentElement.scrollLeft)}},positionElements:function(hostEl,targetEl,positionStr,appendToBody){var hostElPos,targetElWidth,targetElHeight,targetElPos,positionStrParts=positionStr.split("-"),pos0=positionStrParts[0],pos1=positionStrParts[1]||"center";hostElPos=appendToBody?this.offset(hostEl):this.position(hostEl),targetElWidth=targetEl.prop("offsetWidth"),targetElHeight=targetEl.prop("offsetHeight");var shiftWidth={center:function(){return hostElPos.left+hostElPos.width/2-targetElWidth/2},left:function(){return hostElPos.left},right:function(){return hostElPos.left+hostElPos.width}},shiftHeight={center:function(){return hostElPos.top+hostElPos.height/2-targetElHeight/2},top:function(){return hostElPos.top},bottom:function(){return hostElPos.top+hostElPos.height}};switch(pos0){case"right":targetElPos={top:shiftHeight[pos1](),left:shiftWidth[pos0]()};break;case"left":targetElPos={top:shiftHeight[pos1](),left:hostElPos.left-targetElWidth};break;case"bottom":targetElPos={top:shiftHeight[pos0](),left:shiftWidth[pos1]()};break;default:targetElPos={top:hostElPos.top-targetElHeight,left:shiftWidth[pos1]()}}return targetElPos}}}]),angular.module("ui.bootstrap.datepicker",["ui.bootstrap.dateparser","ui.bootstrap.position"]).constant("datepickerConfig",{formatDay:"dd",formatMonth:"MMMM",formatYear:"yyyy",formatDayHeader:"EEE",formatDayTitle:"MMMM yyyy",formatMonthTitle:"yyyy",datepickerMode:"day",minMode:"day",maxMode:"year",showWeeks:!0,startingDay:0,yearRange:20,minDate:null,maxDate:null,shortcutPropagation:!1}).controller("DatepickerController",["$scope","$attrs","$parse","$interpolate","$log","dateFilter","datepickerConfig",function($scope,$attrs,$parse,$interpolate,$log,dateFilter,datepickerConfig){var self=this,ngModelCtrl={$setViewValue:angular.noop};this.modes=["day","month","year"],angular.forEach(["formatDay","formatMonth","formatYear","formatDayHeader","formatDayTitle","formatMonthTitle","minMode","maxMode","showWeeks","startingDay","yearRange","shortcutPropagation"],function(key,index){self[key]=angular.isDefined($attrs[key])?8>index?$interpolate($attrs[key])($scope.$parent):$scope.$parent.$eval($attrs[key]):datepickerConfig[key]}),angular.forEach(["minDate","maxDate"],function(key){$attrs[key]?$scope.$parent.$watch($parse($attrs[key]),function(value){self[key]=value?new Date(value):null,self.refreshView()}):self[key]=datepickerConfig[key]?new Date(datepickerConfig[key]):null}),$scope.datepickerMode=$scope.datepickerMode||datepickerConfig.datepickerMode,$scope.maxMode=self.maxMode,$scope.uniqueId="datepicker-"+$scope.$id+"-"+Math.floor(1e4*Math.random()),angular.isDefined($attrs.initDate)?(this.activeDate=$scope.$parent.$eval($attrs.initDate)||new Date,$scope.$parent.$watch($attrs.initDate,function(initDate){initDate&&(ngModelCtrl.$isEmpty(ngModelCtrl.$modelValue)||ngModelCtrl.$invalid)&&(self.activeDate=initDate,self.refreshView())})):this.activeDate=new Date,$scope.isActive=function(dateObject){return 0===self.compare(dateObject.date,self.activeDate)?($scope.activeDateId=dateObject.uid,!0):!1},this.init=function(ngModelCtrl_){ngModelCtrl=ngModelCtrl_,ngModelCtrl.$render=function(){self.render()}},this.render=function(){if(ngModelCtrl.$viewValue){var date=new Date(ngModelCtrl.$viewValue),isValid=!isNaN(date);isValid?this.activeDate=date:$log.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.'),ngModelCtrl.$setValidity("date",isValid)}this.refreshView()},this.refreshView=function(){if(this.element){this._refreshView();var date=ngModelCtrl.$viewValue?new Date(ngModelCtrl.$viewValue):null;ngModelCtrl.$setValidity("date-disabled",!date||this.element&&!this.isDisabled(date))}},this.createDateObject=function(date,format){var model=ngModelCtrl.$viewValue?new Date(ngModelCtrl.$viewValue):null;return{date:date,label:dateFilter(date,format),selected:model&&0===this.compare(date,model),disabled:this.isDisabled(date),current:0===this.compare(date,new Date),customClass:this.customClass(date)}},this.isDisabled=function(date){return this.minDate&&this.compare(date,this.minDate)<0||this.maxDate&&this.compare(date,this.maxDate)>0||$attrs.dateDisabled&&$scope.dateDisabled({date:date,mode:$scope.datepickerMode})},this.customClass=function(date){return $scope.customClass({date:date,mode:$scope.datepickerMode})},this.split=function(arr,size){for(var arrays=[];arr.length>0;)arrays.push(arr.splice(0,size));return arrays},this.fixTimeZone=function(date){var hours=date.getHours();date.setHours(23===hours?hours+2:0)},$scope.select=function(date){if($scope.datepickerMode===self.minMode){var dt=ngModelCtrl.$viewValue?new Date(ngModelCtrl.$viewValue):new Date(0,0,0,0,0,0,0);dt.setFullYear(date.getFullYear(),date.getMonth(),date.getDate()),ngModelCtrl.$setViewValue(dt),ngModelCtrl.$render()}else self.activeDate=date,$scope.datepickerMode=self.modes[self.modes.indexOf($scope.datepickerMode)-1]},$scope.move=function(direction){var year=self.activeDate.getFullYear()+direction*(self.step.years||0),month=self.activeDate.getMonth()+direction*(self.step.months||0);self.activeDate.setFullYear(year,month,1),self.refreshView()},$scope.toggleMode=function(direction){direction=direction||1,$scope.datepickerMode===self.maxMode&&1===direction||$scope.datepickerMode===self.minMode&&-1===direction||($scope.datepickerMode=self.modes[self.modes.indexOf($scope.datepickerMode)+direction])},$scope.keys={13:"enter",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down"};var focusElement=function(){self.element[0].focus()};$scope.$on("datepicker.focus",focusElement),$scope.keydown=function(evt){var key=$scope.keys[evt.which];if(key&&!evt.shiftKey&&!evt.altKey)if(evt.preventDefault(),self.shortcutPropagation||evt.stopPropagation(),"enter"===key||"space"===key){if(self.isDisabled(self.activeDate))return;$scope.select(self.activeDate),focusElement()}else!evt.ctrlKey||"up"!==key&&"down"!==key?(self.handleKeyDown(key,evt),self.refreshView()):($scope.toggleMode("up"===key?1:-1),focusElement())}}]).directive("datepicker",function(){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/datepicker.html",scope:{datepickerMode:"=?",dateDisabled:"&",customClass:"&",shortcutPropagation:"&?"},require:["datepicker","?^ngModel"],controller:"DatepickerController",link:function(scope,element,attrs,ctrls){var datepickerCtrl=ctrls[0],ngModelCtrl=ctrls[1];ngModelCtrl&&datepickerCtrl.init(ngModelCtrl)}}}).directive("daypicker",["dateFilter",function(dateFilter){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/day.html",require:"^datepicker",link:function(scope,element,attrs,ctrl){function getDaysInMonth(year,month){return 1!==month||year%4!==0||year%100===0&&year%400!==0?DAYS_IN_MONTH[month]:29}function getDates(startDate,n){for(var date,dates=new Array(n),current=new Date(startDate),i=0;n>i;)date=new Date(current),ctrl.fixTimeZone(date),dates[i++]=date,current.setDate(current.getDate()+1);return dates}function getISO8601WeekNumber(date){var checkDate=new Date(date);checkDate.setDate(checkDate.getDate()+4-(checkDate.getDay()||7));var time=checkDate.getTime();return checkDate.setMonth(0),checkDate.setDate(1),Math.floor(Math.round((time-checkDate)/864e5)/7)+1}scope.showWeeks=ctrl.showWeeks,ctrl.step={months:1},ctrl.element=element;var DAYS_IN_MONTH=[31,28,31,30,31,30,31,31,30,31,30,31];ctrl._refreshView=function(){var year=ctrl.activeDate.getFullYear(),month=ctrl.activeDate.getMonth(),firstDayOfMonth=new Date(year,month,1),difference=ctrl.startingDay-firstDayOfMonth.getDay(),numDisplayedFromPreviousMonth=difference>0?7-difference:-difference,firstDate=new Date(firstDayOfMonth);numDisplayedFromPreviousMonth>0&&firstDate.setDate(-numDisplayedFromPreviousMonth+1);for(var days=getDates(firstDate,42),i=0;42>i;i++)days[i]=angular.extend(ctrl.createDateObject(days[i],ctrl.formatDay),{secondary:days[i].getMonth()!==month,uid:scope.uniqueId+"-"+i});scope.labels=new Array(7);for(var j=0;7>j;j++)scope.labels[j]={abbr:dateFilter(days[j].date,ctrl.formatDayHeader),full:dateFilter(days[j].date,"EEEE")};if(scope.title=dateFilter(ctrl.activeDate,ctrl.formatDayTitle),scope.rows=ctrl.split(days,7),scope.showWeeks){scope.weekNumbers=[];for(var thursdayIndex=(11-ctrl.startingDay)%7,numWeeks=scope.rows.length,curWeek=0;numWeeks>curWeek;curWeek++)scope.weekNumbers.push(getISO8601WeekNumber(scope.rows[curWeek][thursdayIndex].date))}},ctrl.compare=function(date1,date2){return new Date(date1.getFullYear(),date1.getMonth(),date1.getDate())-new Date(date2.getFullYear(),date2.getMonth(),date2.getDate())},ctrl.handleKeyDown=function(key,evt){var date=ctrl.activeDate.getDate();if("left"===key)date-=1;else if("up"===key)date-=7;else if("right"===key)date+=1;else if("down"===key)date+=7;else if("pageup"===key||"pagedown"===key){var month=ctrl.activeDate.getMonth()+("pageup"===key?-1:1);ctrl.activeDate.setMonth(month,1),date=Math.min(getDaysInMonth(ctrl.activeDate.getFullYear(),ctrl.activeDate.getMonth()),date)}else"home"===key?date=1:"end"===key&&(date=getDaysInMonth(ctrl.activeDate.getFullYear(),ctrl.activeDate.getMonth()));ctrl.activeDate.setDate(date)},ctrl.refreshView()}}}]).directive("monthpicker",["dateFilter",function(dateFilter){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/month.html",require:"^datepicker",link:function(scope,element,attrs,ctrl){ctrl.step={years:1},ctrl.element=element,ctrl._refreshView=function(){for(var date,months=new Array(12),year=ctrl.activeDate.getFullYear(),i=0;12>i;i++)date=new Date(year,i,1),ctrl.fixTimeZone(date),months[i]=angular.extend(ctrl.createDateObject(date,ctrl.formatMonth),{uid:scope.uniqueId+"-"+i});scope.title=dateFilter(ctrl.activeDate,ctrl.formatMonthTitle),scope.rows=ctrl.split(months,3)},ctrl.compare=function(date1,date2){return new Date(date1.getFullYear(),date1.getMonth())-new Date(date2.getFullYear(),date2.getMonth())},ctrl.handleKeyDown=function(key,evt){var date=ctrl.activeDate.getMonth();if("left"===key)date-=1;else if("up"===key)date-=3;else if("right"===key)date+=1;else if("down"===key)date+=3;else if("pageup"===key||"pagedown"===key){var year=ctrl.activeDate.getFullYear()+("pageup"===key?-1:1);ctrl.activeDate.setFullYear(year)}else"home"===key?date=0:"end"===key&&(date=11);ctrl.activeDate.setMonth(date)},ctrl.refreshView()}}}]).directive("yearpicker",["dateFilter",function(dateFilter){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/year.html",require:"^datepicker",link:function(scope,element,attrs,ctrl){function getStartingYear(year){return parseInt((year-1)/range,10)*range+1}var range=ctrl.yearRange;ctrl.step={years:range},ctrl.element=element,ctrl._refreshView=function(){for(var date,years=new Array(range),i=0,start=getStartingYear(ctrl.activeDate.getFullYear());range>i;i++)date=new Date(start+i,0,1),ctrl.fixTimeZone(date),years[i]=angular.extend(ctrl.createDateObject(date,ctrl.formatYear),{uid:scope.uniqueId+"-"+i});scope.title=[years[0].label,years[range-1].label].join(" - "),scope.rows=ctrl.split(years,5)},ctrl.compare=function(date1,date2){return date1.getFullYear()-date2.getFullYear()},ctrl.handleKeyDown=function(key,evt){var date=ctrl.activeDate.getFullYear();"left"===key?date-=1:"up"===key?date-=5:"right"===key?date+=1:"down"===key?date+=5:"pageup"===key||"pagedown"===key?date+=("pageup"===key?-1:1)*ctrl.step.years:"home"===key?date=getStartingYear(ctrl.activeDate.getFullYear()):"end"===key&&(date=getStartingYear(ctrl.activeDate.getFullYear())+range-1),ctrl.activeDate.setFullYear(date)},ctrl.refreshView()}}}]).constant("datepickerPopupConfig",{datepickerPopup:"yyyy-MM-dd",html5Types:{date:"yyyy-MM-dd","datetime-local":"yyyy-MM-ddTHH:mm:ss.sss",month:"yyyy-MM"},currentText:"Today",clearText:"Clear",closeText:"Done",closeOnDateSelection:!0,appendToBody:!1,showButtonBar:!0}).directive("datepickerPopup",["$compile","$parse","$document","$position","dateFilter","dateParser","datepickerPopupConfig","$timeout",function($compile,$parse,$document,$position,dateFilter,dateParser,datepickerPopupConfig,$timeout){return{restrict:"EA",require:"ngModel",scope:{isOpen:"=?",currentText:"@",clearText:"@",closeText:"@",dateDisabled:"&",customClass:"&"},link:function(scope,element,attrs,ngModel){function cameltoDash(string){return string.replace(/([A-Z])/g,function($1){return"-"+$1.toLowerCase()})}function parseDate(viewValue){if(angular.isNumber(viewValue)&&(viewValue=new Date(viewValue)),viewValue){if(angular.isDate(viewValue)&&!isNaN(viewValue))return viewValue;if(angular.isString(viewValue)){var date=dateParser.parse(viewValue,dateFormat,scope.date)||new Date(viewValue);return isNaN(date)?void 0:date}return void 0}return null}function validator(modelValue,viewValue){var value=modelValue||viewValue;if(angular.isNumber(value)&&(value=new Date(value)),value){if(angular.isDate(value)&&!isNaN(value))return!0;if(angular.isString(value)){var date=dateParser.parse(value,dateFormat)||new Date(value);return!isNaN(date)}return!1}return!0}var dateFormat,closeOnDateSelection=angular.isDefined(attrs.closeOnDateSelection)?scope.$parent.$eval(attrs.closeOnDateSelection):datepickerPopupConfig.closeOnDateSelection,appendToBody=angular.isDefined(attrs.datepickerAppendToBody)?scope.$parent.$eval(attrs.datepickerAppendToBody):datepickerPopupConfig.appendToBody;scope.showButtonBar=angular.isDefined(attrs.showButtonBar)?scope.$parent.$eval(attrs.showButtonBar):datepickerPopupConfig.showButtonBar,scope.getText=function(key){return scope[key+"Text"]||datepickerPopupConfig[key+"Text"]};var isHtml5DateInput=!1;if(datepickerPopupConfig.html5Types[attrs.type]?(dateFormat=datepickerPopupConfig.html5Types[attrs.type],isHtml5DateInput=!0):(dateFormat=attrs.datepickerPopup||datepickerPopupConfig.datepickerPopup,attrs.$observe("datepickerPopup",function(value,oldValue){var newDateFormat=value||datepickerPopupConfig.datepickerPopup;if(newDateFormat!==dateFormat&&(dateFormat=newDateFormat,ngModel.$modelValue=null,!dateFormat))throw new Error("datepickerPopup must have a date format specified.")})),!dateFormat)throw new Error("datepickerPopup must have a date format specified.");if(isHtml5DateInput&&attrs.datepickerPopup)throw new Error("HTML5 date input types do not support custom formats.");var popupEl=angular.element("<div datepicker-popup-wrap><div datepicker></div></div>");popupEl.attr({"ng-model":"date","ng-change":"dateSelection(date)"});var datepickerEl=angular.element(popupEl.children()[0]);if(isHtml5DateInput&&"month"==attrs.type&&(datepickerEl.attr("datepicker-mode",'"month"'),datepickerEl.attr("min-mode","month")),attrs.datepickerOptions){var options=scope.$parent.$eval(attrs.datepickerOptions);options.initDate&&(scope.initDate=options.initDate,datepickerEl.attr("init-date","initDate"),delete options.initDate),angular.forEach(options,function(value,option){datepickerEl.attr(cameltoDash(option),value)})}scope.watchData={},angular.forEach(["minDate","maxDate","datepickerMode","initDate","shortcutPropagation"],function(key){if(attrs[key]){var getAttribute=$parse(attrs[key]);if(scope.$parent.$watch(getAttribute,function(value){scope.watchData[key]=value}),datepickerEl.attr(cameltoDash(key),"watchData."+key),"datepickerMode"===key){var setAttribute=getAttribute.assign;scope.$watch("watchData."+key,function(value,oldvalue){angular.isFunction(setAttribute)&&value!==oldvalue&&setAttribute(scope.$parent,value)})}}}),attrs.dateDisabled&&datepickerEl.attr("date-disabled","dateDisabled({ date: date, mode: mode })"),attrs.showWeeks&&datepickerEl.attr("show-weeks",attrs.showWeeks),attrs.customClass&&datepickerEl.attr("custom-class","customClass({ date: date, mode: mode })"),isHtml5DateInput?ngModel.$formatters.push(function(value){return scope.date=value,value}):(ngModel.$$parserName="date",ngModel.$validators.date=validator,ngModel.$parsers.unshift(parseDate),ngModel.$formatters.push(function(value){return scope.date=value,ngModel.$isEmpty(value)?value:dateFilter(value,dateFormat)})),scope.dateSelection=function(dt){angular.isDefined(dt)&&(scope.date=dt);var date=scope.date?dateFilter(scope.date,dateFormat):"";element.val(date),ngModel.$setViewValue(date),closeOnDateSelection&&(scope.isOpen=!1,element[0].focus())},ngModel.$viewChangeListeners.push(function(){scope.date=dateParser.parse(ngModel.$viewValue,dateFormat,scope.date)||new Date(ngModel.$viewValue)});var documentClickBind=function(event){scope.isOpen&&event.target!==element[0]&&scope.$apply(function(){scope.isOpen=!1})},inputKeydownBind=function(evt){27===evt.which&&scope.isOpen?(evt.preventDefault(),evt.stopPropagation(),scope.$apply(function(){scope.isOpen=!1}),element[0].focus()):40!==evt.which||scope.isOpen||(evt.preventDefault(),evt.stopPropagation(),scope.$apply(function(){scope.isOpen=!0}))};element.bind("keydown",inputKeydownBind),scope.keydown=function(evt){27===evt.which&&(scope.isOpen=!1,element[0].focus())},scope.$watch("isOpen",function(value){value?(scope.position=appendToBody?$position.offset(element):$position.position(element),scope.position.top=scope.position.top+element.prop("offsetHeight"),$document.bind("click",documentClickBind),$timeout(function(){scope.$broadcast("datepicker.focus")},0,!1)):$document.unbind("click",documentClickBind)}),scope.select=function(date){if("today"===date){var today=new Date;angular.isDate(scope.date)?(date=new Date(scope.date),date.setFullYear(today.getFullYear(),today.getMonth(),today.getDate())):date=new Date(today.setHours(0,0,0,0))}scope.dateSelection(date)},scope.close=function(){scope.isOpen=!1,element[0].focus()};var $popup=$compile(popupEl)(scope);popupEl.remove(),appendToBody?$document.find("body").append($popup):element.after($popup),scope.$on("$destroy",function(){scope.isOpen===!0&&scope.$apply(function(){scope.isOpen=!1}),$popup.remove(),element.unbind("keydown",inputKeydownBind),$document.unbind("click",documentClickBind)})}}}]).directive("datepickerPopupWrap",function(){return{restrict:"EA",replace:!0,transclude:!0,templateUrl:"template/datepicker/popup.html"}}),angular.module("ui.bootstrap.dropdown",["ui.bootstrap.position"]).constant("dropdownConfig",{openClass:"open"}).service("dropdownService",["$document","$rootScope",function($document,$rootScope){var openScope=null;this.open=function(dropdownScope){openScope||($document.bind("click",closeDropdown),$document.bind("keydown",keybindFilter)),openScope&&openScope!==dropdownScope&&(openScope.isOpen=!1),openScope=dropdownScope},this.close=function(dropdownScope){openScope===dropdownScope&&(openScope=null,$document.unbind("click",closeDropdown),$document.unbind("keydown",keybindFilter))};var closeDropdown=function(evt){if(openScope&&(!evt||"disabled"!==openScope.getAutoClose())){var toggleElement=openScope.getToggleElement();if(!(evt&&toggleElement&&toggleElement[0].contains(evt.target))){var dropdownElement=openScope.getDropdownElement();
......
angular.module('templates-prod', ['components/auth/login.html', 'components/crud/templates/crud.html', 'components/crud/templates/form.html', 'components/crud/templates/list.html', 'components/crud/templates/show.html', 'components/dashboard/dashboard.html', 'components/debug/debug.html', 'components/devSettings/devSettings.html', 'components/error_pages/404.html', 'components/error_pages/500.html', 'components/uitemplates/404.html', 'components/uitemplates/500.html', 'shared/templates/add.html', 'shared/templates/datefield.html', 'shared/templates/directives/chat.html', 'shared/templates/directives/header-breadcrumb.html', 'shared/templates/directives/header-notification.html', 'shared/templates/directives/header-sub-menu.html', 'shared/templates/directives/menuCollapse.html', 'shared/templates/directives/msgbox.html', 'shared/templates/directives/notifications.html', 'shared/templates/directives/selected-user.html', 'shared/templates/directives/sidebar-notification.html', 'shared/templates/directives/sidebar-search.html', 'shared/templates/directives/sidebar.html', 'shared/templates/directives/stats.html', 'shared/templates/directives/timeline.html', 'shared/templates/fieldset.html', 'shared/templates/foreignKey.html', 'shared/templates/linkedModelModalContent.html', 'shared/templates/listnodeModalContent.html', 'shared/templates/modalContent.html', 'shared/templates/nodeTable.html', 'shared/templates/select.html']); angular.module('templates-prod', ['components/auth/login.html', 'components/crud/templates/crud.html', 'components/crud/templates/form.html', 'components/crud/templates/list.html', 'components/crud/templates/show.html', 'components/dashboard/dashboard.html', 'components/debug/debug.html', 'components/devSettings/devSettings.html', 'components/error_pages/404.html', 'components/error_pages/500.html', 'components/uitemplates/404.html', 'components/uitemplates/500.html', 'shared/templates/add.html', 'shared/templates/datefield.html', 'shared/templates/directives/chat.html', 'shared/templates/directives/header-breadcrumb.html', 'shared/templates/directives/header-notification.html', 'shared/templates/directives/header-sub-menu.html', 'shared/templates/directives/menuCollapse.html', 'shared/templates/directives/msgbox.html', 'shared/templates/directives/notifications.html', 'shared/templates/directives/search.html', 'shared/templates/directives/selected-user.html', 'shared/templates/directives/sidebar-notification.html', 'shared/templates/directives/sidebar-search.html', 'shared/templates/directives/sidebar.html', 'shared/templates/directives/stats.html', 'shared/templates/directives/timeline.html', 'shared/templates/fieldset.html', 'shared/templates/foreignKey.html', 'shared/templates/linkedModelModalContent.html', 'shared/templates/listnodeModalContent.html', 'shared/templates/modalContent.html', 'shared/templates/nodeTable.html', 'shared/templates/select.html']);
angular.module("components/auth/login.html", []).run(["$templateCache", function($templateCache) { angular.module("components/auth/login.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("components/auth/login.html", $templateCache.put("components/auth/login.html",
...@@ -24,7 +24,7 @@ angular.module("components/crud/templates/crud.html", []).run(["$templateCache", ...@@ -24,7 +24,7 @@ angular.module("components/crud/templates/crud.html", []).run(["$templateCache",
$templateCache.put("components/crud/templates/crud.html", $templateCache.put("components/crud/templates/crud.html",
"<crud-show-directive ng-if=\"object\"></crud-show-directive>\n" + "<crud-show-directive ng-if=\"object\"></crud-show-directive>\n" +
"<crud-form-directive ng-if=\"forms\"></crud-form-directive>\n" + "<crud-form-directive ng-if=\"forms\"></crud-form-directive>\n" +
"<hr>\n" + "<hr class=\"col-md-12\">\n" +
"<crud-list-directive ng-if=\"objects\"></crud-list-directive>"); "<crud-list-directive ng-if=\"objects\"></crud-list-directive>");
}]); }]);
...@@ -66,21 +66,15 @@ angular.module("components/crud/templates/form.html", []).run(["$templateCache", ...@@ -66,21 +66,15 @@ angular.module("components/crud/templates/form.html", []).run(["$templateCache",
" </div>\n" + " </div>\n" +
"\n" + "\n" +
" <div class=\"buttons-on-bottom\"></div>\n" + " <div class=\"buttons-on-bottom\"></div>\n" +
"\n" +
" <!--<button id=\"submitbutton\" type=\"button\" class=\"btn btn-primary\" ng-click=\"onSubmit(formgenerated)\">Kaydet</button>-->\n" +
" <!-- <button type=\"button\" class=\"btn btn-warning\">Düzenle</button> todo: make it conditional -->\n" +
" <!-- <button type=\"button\" class=\"btn btn-danger\">İptal</button> todo: turn back to previous page -->\n" +
"</div>"); "</div>");
}]); }]);
angular.module("components/crud/templates/list.html", []).run(["$templateCache", function($templateCache) { angular.module("components/crud/templates/list.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("components/crud/templates/list.html", $templateCache.put("components/crud/templates/list.html",
"<div class=\"starter-template container\">\n" + "<div class=\"starter-template container\">\n" +
" <!--<h1>{{model}}-->\n" + " <search-directive ng-if=\"meta['allow_search']===true\"></search-directive>\n" +
" <!--<a href=\"{{addLink}}\">-->\n" + " <div class=\"clearfix\"></div>\n" +
" <!--<button type=\"button\" class=\"btn btn-primary\">Ekle</button>-->\n" + " <h1>{{form_params.model || form_params.wf}}</h1>\n" +
" <!--</a>-->\n" +
" <!--</h1>-->\n" +
" <div class=\"row\" ng-if=\"!objects[1]\">\n" + " <div class=\"row\" ng-if=\"!objects[1]\">\n" +
" <div class=\"col-md-12\">\n" + " <div class=\"col-md-12\">\n" +
" <p class=\"no-content\">Listelenecek içerik yok.</p>\n" + " <p class=\"no-content\">Listelenecek içerik yok.</p>\n" +
...@@ -96,7 +90,7 @@ angular.module("components/crud/templates/list.html", []).run(["$templateCache", ...@@ -96,7 +90,7 @@ angular.module("components/crud/templates/list.html", []).run(["$templateCache",
" Hepsini Seç\n" + " Hepsini Seç\n" +
" </label>\n" + " </label>\n" +
" </td>\n" + " </td>\n" +
" <td ng-repeat=\"value in objects[0]\" ng-if=\"objects[0]!='-1'\">{{ objects }}</td>\n" + " <td ng-repeat=\"value in objects[0]\" ng-if=\"objects[0]!='-1'\">{{values }}</td>\n" +
" <td ng-if=\"objects[0]=='-1'\">{{ schema.title||model}}</td>\n" + " <td ng-if=\"objects[0]=='-1'\">{{ schema.title||model}}</td>\n" +
" <td>action</td>\n" + " <td>action</td>\n" +
" </tr>\n" + " </tr>\n" +
...@@ -109,25 +103,19 @@ angular.module("components/crud/templates/list.html", []).run(["$templateCache", ...@@ -109,25 +103,19 @@ angular.module("components/crud/templates/list.html", []).run(["$templateCache",
" </label>\n" + " </label>\n" +
" </td>\n" + " </td>\n" +
" <td scope=\"row\" style=\"text-align:center\">{{$index}}</td>\n" + " <td scope=\"row\" style=\"text-align:center\">{{$index}}</td>\n" +
" <!-- below 2 of object will not be listed there for ng repeat loops 2 less -->\n" +
" <td ng-repeat=\"field in object.fields track by $index\" ng-if=\"objects[0]=='-1'\">\n" +
" <a ng-repeat=\"action in object.actions\" ng-href=\"javascript:void(0)\"\n" +
" ng-if=\"action.show_as==='link'&&action.fields.indexOf($parent.$index)>-1\" ng-click=\"do_action(object.key, action)\">{{field}}</a>\n" +
" </td>\n" +
"\n" + "\n" +
" <td ng-repeat=\"field in object.fields track by $index\" ng-if=\"objects[0]!='-1'\">\n" + " <td ng-repeat=\"field in object.fields track by $index\">\n" +
" <a ng-repeat=\"action in object.actions\" ng-href=\"javascript:void(0)\"\n" + " <a ng-href=\"javascript:void(0)\"\n" +
" ng-if=\"action.show_as==='link'&&action.fields.indexOf($index)>-1\"\n" + " ng-if=\"field.type==='link'\"\n" +
" ng-click=\"do_action(object.key, action)\">{{field}}</a>\n" + " ng-click=\"do_action(object.key, action)\">{{field.content}}</a>\n" +
" <span ng-if=\"$index!=1\">{{field}}</span>\n" + " <span ng-if=\"field.type==='str'\">{{field.content}}</span>\n" +
" </td>\n" + " </td>\n" +
"\n" +
" <td>\n" + " <td>\n" +
" <button class=\"btn btn-primary\" style=\"margin-right: 5px;\" ng-repeat=\"action in object.actions\"\n" + " <button class=\"btn btn-primary\" style=\"margin-right: 5px;\" ng-repeat=\"action in object.actions\"\n" +
" ng-if=\"action.show_as==='button'\" ng-click=\"do_action(object.key, action)\">{{action\n" + " ng-if=\"action.show_as==='button'\" ng-click=\"do_action(object.key, action)\">{{action\n" +
" .name}}\n" + " .name}}\n" +
" </button>\n" + " </button>\n" +
" <!--<a ng-href=\"javascript:void(0)\" ng-repeat=\"action in object.actions\"-->\n" +
" <!--ng-if=\"action.show_as==='link'\" ng-click=\"do_action(object.key, action)\">{{action.name}}</a>-->\n" +
" <br>\n" + " <br>\n" +
" </td>\n" + " </td>\n" +
" </tr>\n" + " </tr>\n" +
...@@ -1049,6 +1037,13 @@ angular.module("shared/templates/directives/notifications.html", []).run(["$temp ...@@ -1049,6 +1037,13 @@ angular.module("shared/templates/directives/notifications.html", []).run(["$temp
"</div>"); "</div>");
}]); }]);
angular.module("shared/templates/directives/search.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("shared/templates/directives/search.html",
"<form class=\"form-inline col-md-8\" id=\"search\" name=\"search\" sf-schema=\"searchSchema\" sf-form=\"searchForm\"\n" +
" sf-model=\"searchModel\"\n" +
" ng-submit=\"searchSubmit(search)\"></form>");
}]);
angular.module("shared/templates/directives/selected-user.html", []).run(["$templateCache", function($templateCache) { angular.module("shared/templates/directives/selected-user.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("shared/templates/directives/selected-user.html", $templateCache.put("shared/templates/directives/selected-user.html",
"<a href=\"#\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"Tooltip on left\">İşlem: {{$root.selectedUser.name}}</a>\n" + "<a href=\"#\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"Tooltip on left\">İşlem: {{$root.selectedUser.name}}</a>\n" +
......
/* Space out content a bit */
body {
font-family:'robotoregular';
background-color: #f5f5f5;
overflow:hidden;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
}
::-webkit-scrollbar-track {
background-color:#ccc;
}
::-webkit-scrollbar-thumb {
background-color:#999;
}
.badge {
border-radius: 100%;
width: 22px;
height: 22px;
padding: 0;
position: absolute;
z-index: 1;
line-height: 19px;
top: 4px;
left: 2px;
background-color: rgba(220, 112, 0, 1);
border: 2px solid #a61229;
font-family: 'robotomedium';
font-weight: normal;
}
.form-control {
box-shadow:none;
border-radius:0;
border-color:#ececec;
}
.btn {
border:none;
}
.btn:focus,
.btn:active:focus,
.btn.active:focus,
.btn.focus,
.btn:active.focus,
.btn.active.focus {
outline: none;
}
a {
color:#a61229;
-webkit-transition: all .1s;
-moz-transition: all .1s;
-ms-transition: all .1s;
-o-transition: all .1s;
transition: all .1s;
}
a:hover {
color:#941A1A;
}
.breadcrumb {
background-color:transparent;
padding:0;
font-size:18px;
float:left;
margin-bottom: 0;
}
/** BRAND **/
.brand-bg {
background-color:#A61229;
}
button.brand-bg {
background-color:#A61229;
color:#fff;
}
button.brand-bg:hover {
background-color:#941A1A;
color:#fff;
}
.brand {
height:98px;
border-bottom:1px solid #ccc;
}
.logo {
}
.logo img {
width: 80%;
margin-left: 8%;
margin-top: 22px;
margin-bottom: 22px;
}
/** END OF BRAND **/
/** LOADER **/
.loader {
font-size: 2px;
position: relative;
text-indent: -9999em;
border-top: 1.1em solid rgba(166, 12, 41, 0.2);
border-right: 1.1em solid rgba(166, 12, 41, 0.2);
border-bottom: 1.1em solid rgba(166, 12, 41, 0.2);
border-left: 1.1em solid #A61229;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
-webkit-animation: load8 1.1s infinite linear;
animation: load8 1.1s infinite linear;
float: left;
margin-left: 10px;
margin-top: 3px;
}
.loader,
.loader:after {
border-radius: 50%;
width: 10em;
height: 10em;
}
@-webkit-keyframes load8 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes load8 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
/** END OF LOADER **/
/* Everything but the jumbotron gets side spacing for mobile first views */
.header,
.marketing,
.footer {
padding-left: 15px;
padding-right: 15px;
}
/* Custom page header */
.header {
border-bottom: 1px solid #e5e5e5;
}
/* Make the masthead heading the same height as the navigation */
.header h3 {
margin-top: 0;
margin-bottom: 0;
line-height: 40px;
padding-bottom: 19px;
}
/* Custom page footer */
.footer {
padding-top: 19px;
color: #777;
border-top: 1px solid #e5e5e5;
}
nav.navbar {
background-color: #A61229;
border-color: #941A1A;
min-height:30px;
}
a.navbar-brand img {
height:45px;
margin-top:-6px;
}
.navbar-default .navbar-toggle .icon-bar {
background-color:#fff;
}
.navbar-default .navbar-toggle:hover {
background-color:#9a1026;
}
.navbar-default .navbar-toggle:focus {
background-color:#A61229;
}
.container-narrow > hr {
margin: 30px 0;
}
/* Main marketing message and sign up button */
.jumbotron {
text-align: center;
border-bottom: 1px solid #e5e5e5;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}
/* Supporting marketing content */
.marketing {
margin: 40px 0;
}
.marketing p + h4 {
margin-top: 28px;
}
ul.header-menu {
float:left;
padding-left:23px;
}
ul.header-menu li {
list-style:none;
float:left;
margin-right:15px;
margin-top:10px;
}
ul.header-menu li a{
color:#fff;
text-decoration:none;
opacity:0.9;
}
ul.header-menu li a:hover{
opacity:1;
}
.nav>li>a {
color: #696969;
border-left:3px solid transparent;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
}
.sidebar .nav>li ul {
border-left: 3px solid #A61229;
}
.sidebar .nav>li ul>li a {
font-family:'robotoregular';
background-color:#fdfdfd;
}
.nav>li>a:visited {
}
.nav>li.active>a {
text-decoration: none;
background-color: #fdfdfd;
color: #565656;
border-color:#A61229;
}
.nav>li.active>a:hover,
.sidebar .nav>li ul>li a:hover,
.nav>li>a:hover {
background-color:#f9f9f9;
}
/*!
* Start Bootstrap - SB Admin 2 Bootstrap Admin Theme (http://startbootstrap.com)
* Code licensed under the Apache License v2.0.
* For details, see http://www.apache.org/licenses/LICENSE-2.0.
*/
select {
padding: 5px 10px;
border-color: #dcdcdc;
outline: none;
}
#wrapper {
width: 100%;
}
.manager-view {
height:100%;
width: calc(100% - 250px);
-webkit-width: calc(100% - 250px);
position: absolute;
right: 0;
background-color:#f5f5f5;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
}
.manager-view-inner {
height:calc(100% - 41px);
-webkit-height:calc(100% - 41px);
width:100%;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
}
.manager-view-header {
/*width:100%;*/
/*width: calc(100% - 300px);*/
padding:10px;
background-color:#fff;
border-bottom:1px solid #ccc;
-webkit-flex-shrink: 0;
flex-shrink: 0;
position:relative;
z-index:1;
height: 43px;
}
.manager-view-content {
padding:35px 40px;
overflow:auto;
-webkit-flex-grow: 1;
flex-grow: 1;
}
.navbar-top-links {
margin-right: 0;
}
.navbar-top-links li {
display: inline-block;
}
.navbar-top-links li:last-child {
margin-right: 15px;
}
.navbar-top-links li a {
color:#fff;
cursor:pointer;
}
.navbar-top-links li>a:hover,
.navbar-top-links .open>a,
.navbar-top-links .open>a:hover,
.navbar-top-links .open>a:active,
.navbar-top-links .open>a:focus {
background-color:#9A1026;
}
.navbar-top-links .dropdown-menu li.divider {
margin:0;
}
.navbar-top-links .dropdown-menu li a:hover {
background-color:#fcfcfc;
}
.navbar-top-links .open>a,
.navbar-top-links .open>a:hover {
border-color:#9A1026;
}
.navbar-top-links .dropdown-menu li {
display: block;
}
.navbar-top-links .dropdown-menu li:last-child {
margin-right: 0;
}
.navbar-top-links .dropdown-menu li a {
padding: 10px 20px;
min-height: 0;
color:#444;
}
.navbar-top-links .dropdown-menu li a div {
white-space: normal;
}
.navbar-top-links .dropdown-messages,
.navbar-top-links .dropdown-tasks,
.navbar-top-links .dropdown-alerts {
width: 310px;
min-width: 0;
}
.navbar-top-links .dropdown-messages {
margin-left: 5px;
}
.navbar-top-links .dropdown-tasks {
margin-left: -59px;
}
.navbar-top-links .dropdown-alerts {
margin-left: -123px;
}
.navbar-top-links .dropdown-user {
right: 0;
left: auto;
}
.sidebar {
background-color:#fff;
border-right: 1px solid #ccc;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
}
.sidebar .fa {
font-size:18px;
margin-right:10px;
}
.sidebar span.menu-text {
display:inline-block;
}
.sidebar .sidebar-nav.navbar-collapse {
padding-right: 0;
padding-left: 0;
}
.sidebar .sidebar-search {
padding: 15px;
}
.sidebar ul li {
font-family: 'robotomedium';
letter-spacing: 0.2px;
border-bottom: 1px solid #DCDCDC;
}
.sidebar ul li a {
height:40px;
overflow:hidden;
}
.sidebar ul li a.active {
background-color: #eee;
}
.sidebar .arrow {
float: right;
}
.sidebar .fa.arrow:before {
content: "\f104";
}
.sidebar .active>a>.fa.arrow:before {
content: "\f107";
}
.sidebar .nav-second-level li,
.sidebar .nav-third-level li {
border-bottom: 0!important;
}
.sidebar .nav-second-level li a {
padding-left: 37px;
}
.sidebar .nav-third-level li a {
padding-left: 52px;
font-size: 12px;
}
.sidebar-person-info {
overflow-x: visible;
overflow-y: auto;
position: absolute;
width: 100%;
max-height: calc(85% - 139px);
background: #fff;
/*display:none;*/ /** angular template will hndle this */
}
.sidebar-person-info .identity {
color:#555;
padding:15px;
padding-bottom: 0px;
}
.sidebar-person-info .identity-header {
border-bottom: 1px solid #ECECEC;
}
.sidebar-person-info .identity-info {
margin-top:10px;
color: #6D6D6D;
border-bottom: 1px solid #ECECEC;
}
.sidebar-person-info .identity-info div {
margin-bottom:4px;
}
.sidebar-person-info .identity-info div div {
float:left;
width:80%;
}
.sidebar-person-info .identity-info span {
float:left;
width:27px;
margin-top: 3px;
}
.sidebar-person-info .identity img {
width:50px;
height:50px;
border-radius:100%;
margin:10px auto;
float:left;
margin-right:10px;
}
.sidebar-person-info .identity p.identity-name {
font-family:'robotomedium';
font-size:16px;
margin-bottom: 0;
margin-top:13px;
}
.sidebar-person-info .identity p.identity-surname {
font-family:'robotomedium';
font-size:16px;
margin-bottom: 0;
text-transform:uppercase;
}
.sidebar-person-info .identity p.identity-email {
float:left;
}
.sidebar-person-info .identity ul {
margin:0;
padding:0;
}
.sidebar-person-info .identity ul li {
list-style:none;
border:none;
}
.sidebar-person-info .person-actions {
}
.sidebar-person-info .person-actions ul {
margin:0;
padding:0;
}
.sidebar-person-info .person-actions ul li {
list-style:none;
border:none;
}
.sidebar-person-info .person-actions ul li a {
text-decoration:none;
color:#555;
display:block;
padding:10px 15px;
font-family: 'robotobold';
}
.sidebar-person-info .person-actions ul li a:hover {
background-color:#f5f5f5;
}
.sidebar-person-info .person-actions ul li a span {
margin-right:13px;
}
.sidebar-person-info .close-sidebar-person-info {
width: 45%;
margin-left: auto;
margin-right: auto;
margin-top: 11px;
border-radius: 5px;
padding: 8px 10px;
text-align: center;
cursor: pointer;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
background-color: #B93939;
color: #fff;
display:block;
}
.sidebar-person-info .close-sidebar-person-info:hover {
background-color:#9A1026;
}
.sidebar-person-info .close-sidebar-person-info span {
font-size: 12px;
color: #555;
margin-right: 6px;
position: relative;
top: -1px;
}
.btn-outline {
color: inherit;
background-color: transparent;
transition: all .5s;
}
.btn-primary.btn-outline {
color: #428bca;
}
.btn-success.btn-outline {
color: #5cb85c;
}
.btn-info.btn-outline {
color: #5bc0de;
}
.btn-warning.btn-outline {
color: #f0ad4e;
}
.btn-danger.btn-outline {
color: #d9534f;
}
.btn-primary.btn-outline:hover,
.btn-success.btn-outline:hover,
.btn-info.btn-outline:hover,
.btn-warning.btn-outline:hover,
.btn-danger.btn-outline:hover {
color: #fff;
}
.chat {
margin: 0;
padding: 0;
list-style: none;
}
.chat li {
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px dotted #999;
}
.chat li.left .chat-body {
margin-left: 60px;
}
.chat li.right .chat-body {
margin-right: 60px;
}
.chat li .chat-body p {
margin: 0;
}
.panel .slidedown .glyphicon,
.chat .glyphicon {
margin-right: 5px;
}
.chat-panel .panel-body {
height: 350px;
overflow-y: scroll;
}
.login-panel {
margin-top: 25%;
}
.flot-chart {
display: block;
height: 400px;
}
.flot-chart-content {
width: 100%;
height: 100%;
}
.dataTables_wrapper {
position: relative;
clear: both;
}
table.dataTable thead .sorting,
table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc,
table.dataTable thead .sorting_asc_disabled,
table.dataTable thead .sorting_desc_disabled {
background: 0 0;
}
table.dataTable thead .sorting_asc:after {
content: "\f0de";
float: right;
font-family: fontawesome;
}
table.dataTable thead .sorting_desc:after {
content: "\f0dd";
float: right;
font-family: fontawesome;
}
table.dataTable thead .sorting:after {
content: "\f0dc";
float: right;
font-family: fontawesome;
color: rgba(50,50,50,.5);
}
.btn-circle {
width: 30px;
height: 30px;
padding: 6px 0;
border-radius: 15px;
text-align: center;
font-size: 12px;
line-height: 1.428571429;
}
.btn-circle.btn-lg {
width: 50px;
height: 50px;
padding: 10px 16px;
border-radius: 25px;
font-size: 18px;
line-height: 1.33;
}
.btn-circle.btn-xl {
width: 70px;
height: 70px;
padding: 10px 16px;
border-radius: 35px;
font-size: 24px;
line-height: 1.33;
}
.show-grid [class^=col-] {
padding-top: 10px;
padding-bottom: 10px;
border: 1px solid #ddd;
background-color: #eee!important;
}
.show-grid {
margin: 15px 0;
}
.huge {
font-size: 40px;
}
.panel-green {
border-color: #5cb85c;
}
.panel-green .panel-heading {
border-color: #5cb85c;
color: #fff;
background-color: #5cb85c;
}
.panel-green a {
color: #5cb85c;
}
.panel-green a:hover {
color: #3d8b3d;
}
.panel-red {
border-color: #d9534f;
}
.panel-red .panel-heading {
border-color: #d9534f;
color: #fff;
background-color: #d9534f;
}
.panel-red a {
color: #d9534f;
}
.panel-red a:hover {
color: #b52b27;
}
.panel-yellow {
border-color: #f0ad4e;
}
.panel-yellow .panel-heading {
border-color: #f0ad4e;
color: #fff;
background-color: #f0ad4e;
}
.panel-yellow a {
color: #f0ad4e;
}
.panel-yellow a:hover {
color: #df8a13;
}
.timeline {
position: relative;
padding: 20px 0 20px;
list-style: none;
}
.timeline:before {
content: " ";
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 3px;
margin-left: -1.5px;
background-color: #eeeeee;
}
.timeline > li {
position: relative;
margin-bottom: 20px;
}
.timeline > li:before,
.timeline > li:after {
content: " ";
display: table;
}
.timeline > li:after {
clear: both;
}
.timeline > li:before,
.timeline > li:after {
content: " ";
display: table;
}
.timeline > li:after {
clear: both;
}
.timeline > li > .timeline-panel {
float: left;
position: relative;
width: 46%;
padding: 20px;
border: 1px solid #d4d4d4;
border-radius: 2px;
-webkit-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175);
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175);
}
.timeline > li > .timeline-panel:before {
content: " ";
display: inline-block;
position: absolute;
top: 26px;
right: -15px;
border-top: 15px solid transparent;
border-right: 0 solid #ccc;
border-bottom: 15px solid transparent;
border-left: 15px solid #ccc;
}
.timeline > li > .timeline-panel:after {
content: " ";
display: inline-block;
position: absolute;
top: 27px;
right: -14px;
border-top: 14px solid transparent;
border-right: 0 solid #fff;
border-bottom: 14px solid transparent;
border-left: 14px solid #fff;
}
.timeline > li > .timeline-badge {
z-index: 100;
position: absolute;
top: 16px;
left: 50%;
width: 50px;
height: 50px;
margin-left: -25px;
border-radius: 50% 50% 50% 50%;
text-align: center;
font-size: 1.4em;
line-height: 50px;
color: #fff;
background-color: #999999;
}
.timeline > li.timeline-inverted > .timeline-panel {
float: right;
}
.timeline > li.timeline-inverted > .timeline-panel:before {
right: auto;
left: -15px;
border-right-width: 15px;
border-left-width: 0;
}
.timeline > li.timeline-inverted > .timeline-panel:after {
right: auto;
left: -14px;
border-right-width: 14px;
border-left-width: 0;
}
.timeline-badge.primary {
background-color: #2e6da4 !important;
}
.timeline-badge.success {
background-color: #3f903f !important;
}
.timeline-badge.warning {
background-color: #f0ad4e !important;
}
.timeline-badge.danger {
background-color: #d9534f !important;
}
.timeline-badge.info {
background-color: #5bc0de !important;
}
.timeline-title {
margin-top: 0;
color: inherit;
}
.timeline-body > p,
.timeline-body > ul {
margin-bottom: 0;
}
.timeline-body > p + p {
margin-top: 5px;
}
/* DASHBOARD */
.dashboard .row {
margin-bottom:30px;
}
.dashboard .major-buttons {
margin-bottom:20px;
}
.dashboard .major-buttons i {
margin-right:10px;
}
.dashboard .major-buttons a button {
width:100%;
height:100px;
font-size: 19px;
font-family: 'robotolight';
}
.dashboard .major-buttons a button:focus {
color:#fff;
}
.dashboard-main-search {
width: calc(100% - 300px);
}
.dashboard-main-search .dashboard-student-search h3,
.dashboard-main-search .dashboard-personnel-search h3 {
font-family: 'robotoblack';
color: #5A5A5A;
letter-spacing: 1px;
}
.dashboard-main-search input {
width: 70%;
border-radius: 3px;
border: 1px solid #e0e0e0;
padding: 7px;
outline: none;
border-right: none;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
.dashboard-main-search .fa {
padding: 10px 15px;
border: 1px solid #e0e0e0;
border-bottom-right-radius: 3px;
border-top-right-radius: 3px;
background-color: #FBF9F9;
cursor:pointer;
color:#5A5A5A;
}
.dashboard-student-search {
float: left;
width: 50%;
border-right: 1px solid #e8e8e8;
}
.dashboard-personnel-search {
float: left;
width: 50%;
}
.dashboard-search-results {
width: 80%;
margin-left: auto;
margin-right: auto;
margin-top: 25px;
}
.dashboard-search-results ul {
max-height: 600px;
overflow-y: auto;
padding:0;
webkit-box-shadow: 0 0 4px rgba(0,0,0,0.15);
-moz-box-shadow: 0 0 4px rgba(0,0,0,0.15);
box-shadow: 0 0 4px rgba(0,0,0,0.15);
background-color: #fff;
border-radius: 3px;
}
.dashboard-search-results ul li {
list-style:none;
border-bottom: 1px solid #F3F3F3;
}
.dashboard-search-results ul li:last-child {
border:none;
}
.dashboard-search-results ul li a {
color:#666;
padding: 10px 25px;
display:block;
text-decoration:none;
}
.dashboard-search-results ul li a:hover {
background-color:#f5f5f5;
}
.dashboard-search-results ul li:first-child a:hover {
border-top-left-radius:3px;
border-top-right-radius:3px;
}
.dashboard-search-results ul li:last-child a:hover {
border-bottom-left-radius:3px;
border-bottom-right-radius:3px;
}
.right-sidebar {
width: 300px;
background-color: #FFFFFF;
border-left: 1px solid #ccc;
/*height: calc(100% - 140px);*/
height: calc(100% - 40px);
position: absolute;
top: 0px;
right: 0px;
overflow-y: auto;
}
.right-sidebar-box {
border-bottom: 1px solid #D0D0D0;
}
.right-sidebar-title {
border-bottom: 1px solid #D0D0D0;
padding: 10px;
background-color: #F3F3F3;
}
.right-sidebar-title h3 {
float: left;
margin: 0;
font-size: 16px;
color: #666;
font-weight: bold;
font-family: 'robotobold';
text-transform: uppercase;
line-height:normal;
}
.right-sidebar-title span a {
float: right;
color: #A61229;
text-decoration:none;
}
.right-sidebar-message-block {
border-bottom: 1px solid #F3F3F3;
}
.right-sidebar-message-block:last-child {
border-bottom:none;
}
.right-sidebar-message-block a {
padding: 10px 15px;
display: block;
color: #555;
}
.right-sidebar-message-block a:hover{
background-color:#f5f5f5;
}
.right-sidebar-message-block a img {
width: 30px;
height: 30px;
border-radius: 100%;
float: left;
}
.right-sidebar-message-content {
float: left;
margin-left: 15px;
position:relative;
width: calc(100% - 50px);
}
.right-sidebar-message-content div:nth-child(1) {
width: 180px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
font-family: 'robotomedium';
font-size: 15px;
margin-top: -5px;
}
.right-sidebar-message-content div:nth-child(2) {
width: 180px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
margin-top: -5px;
}
.right-sidebar-message-content div:nth-child(3) {
color: #8C8C8C;
position: absolute;
right: 0;
top: 5px;
}
.right-sidebar-task-block a {
padding: 10px 25px;
display: block;
color: #555;
text-decoration:none;
}
.right-sidebar-task-block a:hover {
background-color:#f5f5f5;
}
.right-sidebar-task-block .task-type {
padding: 5px 10px;
font-size: 15px;
font-family: 'robotomedium';
color: #666;
}
.right-sidebar-task-block .progress {
margin-top: 5px;
margin-bottom: 0;
}
.right-sidebar-task-block .progress .progress-bar {
background-color: #A61229;
}
.right-sidebar-announcement-block a,
.right-sidebar-last-action-block a {
width: 100%;
display: block;
padding: 7px 15px;
color:#555;
text-decoration:none;
border-bottom: 1px solid #f3f3f3;
}
.right-sidebar-announcement-block a:hover,
.right-sidebar-last-action-block a:hover {
background-color:#f5f5f5;
}
/* END OF DASHBOARD */
/* PERSONNEL INFO */
.generic-profile-picture img {
width:220px;
height:220px;
}
.personnel-info-container {
width:1000px;
height:530px;
margin-left:auto;
margin-right:auto;
margin-bottom:50px;
background-color:#fff;
-webkit-box-shadow: 0 0 3px rgba(0,0,0,0.1);
-moz-box-shadow: 0 0 3px rgba(0,0,0,0.1);
box-shadow: 0 0 3px rgba(0,0,0,0.1);
position:relative;
}
.personnel-info-left {
width:250px;
height:100%;
background-color:#fcfcfc;
padding:15px;
position:absolute;
left:0;
overflow-y: auto;
overflow-x: hidden;
border-right: 1px solid #F7F7F7;
}
.personnel-info-left ul {
padding:0;
margin-top:20px;
}
.personnel-info-left ul li {
list-style:none;
margin-bottom:15px;
position:relative;
padding-left:30px;
color:#555;
}
.personnel-info-left ul li:nth-child(1) {
padding:0;
font-family:'robotobold';
font-size:18px;
color:#333;
}
.personnel-info-left ul li:nth-child(2) {
padding:0;
font-family:'robotomedium';
font-size:17px;
color:#666;
}
.personnel-info-left ul li i.fa {
width:18px;
margin-right:15px;
font-size:18px;
position:absolute;
left:0;
text-align:center;
}
.personnel-info-right {
width:750px;
height:100%;
background-color:#fff;
padding:40px;
padding-top:15px;
position:absolute;
right:0;
overflow-y:auto;
}
.personnel-info-right h2 {
margin-top:0;
margin-bottom:20px;
font-family:'robotolight';
font-size:23px;
}
.info-block {
margin-bottom:70px;
}
.info-block:last-child {
margin-bottom:0px;
}
.info-block-body dt {
text-align:left;
font-family:'robotomedium';
font-weight:normal;
}
.info-block-body dl {
margin-bottom:10px;
color:#444;
}
.personnel-info-edit .personnel-info-left ul li {
padding-left:0;
}
/* END OF PERSONNEL INFO */
/* SIDEBAR COLLAPSE */
.sidebar-collapse-button {
width: 62px;
height: 41px;
float: left;
padding: 8px 16px;
cursor:pointer;
}
.sidebar-collapse-button:hover {
background-color:#9A1026;
}
.sidebar-collapse-button div {
width: 30px;
height: 2px;
background-color: #fff;
margin-top:5px;
border-radius:5px;
}
/* END OF SIDEBAR COLLAPSE */
/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
/* Remove the padding we set earlier */
.header,
.marketing,
.footer {
padding-left: 0;
padding-right: 0;
}
/* Space out the masthead */
.header {
margin-bottom: 30px;
}
/* Remove the bottom border on the jumbotron for visual effect */
.jumbotron {
border-bottom: 0;
}
.sidebar {
z-index: 1;
position: absolute;
width: 250px;
height: 100%;
-webkit-box-shadow: 0 0 25px rgba(0,0,0,0.1);
-moz-box-shadow: 0 0 25px rgba(0,0,0,0.1);
box-shadow: 0 0 25px rgba(0,0,0,0.1);
}
.navbar-top-links .dropdown-messages,
.navbar-top-links .dropdown-tasks,
.navbar-top-links .dropdown-alerts {
margin-left: auto;
}
.container {
max-width: 730px;
}
.manager-view {
height:100%;
}
.sidebar .sidebar-nav.navbar-collapse {
overflow-x: visible;
overflow-y: auto;
position: absolute;
width: 100%;
max-height: calc(85% - 139px);
}
footer {
position: absolute;
bottom: 35px;
padding: 15px;
width:100%;
text-align:center;
}
footer span {
font-family:'robotobold';
color:#777;
}
}
@media (max-width: 767px) {
.manager-view {
width:100%;
}
ul.timeline:before {
left: 40px;
}
ul.timeline > li > .timeline-panel {
width: calc(100% - 90px);
width: -moz-calc(100% - 90px);
width: -webkit-calc(100% - 90px);
}
ul.timeline > li > .timeline-badge {
top: 16px;
left: 15px;
margin-left: 0;
}
ul.timeline > li > .timeline-panel {
float: right;
}
ul.timeline > li > .timeline-panel:before {
right: auto;
left: -15px;
border-right-width: 15px;
border-left-width: 0;
}
ul.timeline > li > .timeline-panel:after {
right: auto;
left: -14px;
border-right-width: 14px;
border-left-width: 0;
}
.sidebar {
width:100% !important;
}
.brand,
footer {
display:none;
}
.logo img {
width:200px;
margin-left:0;
}
.manager-view-content {
overflow:inherit;
}
body {
overflow:auto;
}
.sidebar-collapse-button {
display:none;
}
.right-sidebar {
display: none;
}
}
@media (max-width: 1350px) {
.personnel-info-container {
width:700px;
}
.personnel-info-right {
width:450px;
}
}
@media (max-width: 1000px) {
.personnel-info-container {
width:500px;
height:auto;
}
.personnel-info-left {
width:100%;
position:relative;
height:auto;
border:none;
}
.personnel-info-right {
width:100%;
position:relative;
height:auto;
}
.generic-profile-picture,
.personnel-info-left ul li:nth-child(1),
.personnel-info-left ul li:nth-child(2) {
text-align:center;
}
.generic-profile-picture img {
border-radius:100%;
}
}
@media (max-width: 560px) {
.personnel-info-container {
width: 350px;
}
}
@media (max-width: 991px) {
.dashboard .major-buttons a button {
margin-bottom:20px;
}
}
.tablescroll{
width: 100%;
overflow-x:scroll;
overflow-y:visible;
padding-bottom:1px;
}
.tablescrollfixleft {
position:absolute;
left:0;
top:auto;
}
.tablescrollfixleft {
position:absolute;
right:0;
top:auto;
}
/* loading bar */
.loadingbarfullsize{
z-index:10001;
position:fixed;
width:100%;
height:100%;
top: 0;
left: 0;
background: url('/img/loading_spinner.gif') rgba(0, 0, 3, 0.2) no-repeat center center;
background-size: 100px 100px;
}
/* page transitions */
.slide {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.slide.ng-enter,
.slide.ng-leave {
-webkit-transition: all 1s ease;
transition: all 1s ease;
}
.slide.ng-enter {
left: 100%;
}
.slide.ng-enter-active {
left: 0;
}
.slide.ng-leave {
left: 0;
}
.slide.ng-leave-active {
left: -100%;
}
/* end page transitions */
.movetobottom {
margin-right: 10px !important;
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment