├── .gitignore
├── README.md
├── client
├── css
│ └── style.css
├── js
│ ├── app.js
│ ├── app.service.js
│ ├── auth.controller.js
│ ├── home.controller.js
│ └── ui-bootstrap-2.5.0.min.js
└── views
│ ├── index.html
│ └── pages
│ ├── auth.html
│ └── home.html
├── package-lock.json
├── package.json
├── server.js
└── utils
├── config.js
├── db.js
├── helper.js
├── routes.js
└── socket.js
/.gitignore:
--------------------------------------------------------------------------------
1 | <<<<<<< HEAD
2 | # See http://help.github.com/ignore-files/ for more about ignoring files.
3 |
4 | # dependencies
5 | /node_modules
6 |
7 | # IDEs and editors
8 | /.idea
9 | .project
10 | .classpath
11 | .c9/
12 | *.launch
13 | .settings/
14 | *.sublime-workspace
15 |
16 | # IDE - VSCode
17 | .vscode/*
18 | !.vscode/settings.json
19 | !.vscode/tasks.json
20 | !.vscode/launch.json
21 | !.vscode/extensions.json
22 | =======
23 | # Logs
24 | logs
25 | *.log
26 | npm-debug.log*
27 | yarn-debug.log*
28 | yarn-error.log*
29 |
30 | # Runtime data
31 | pids
32 | *.pid
33 | *.seed
34 | *.pid.lock
35 |
36 | # Directory for instrumented libs generated by jscoverage/JSCover
37 | lib-cov
38 |
39 | # Coverage directory used by tools like istanbul
40 | coverage
41 |
42 | # nyc test coverage
43 | .nyc_output
44 |
45 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
46 | .grunt
47 |
48 | # Bower dependency directory (https://bower.io/)
49 | bower_components
50 |
51 | # node-waf configuration
52 | .lock-wscript
53 |
54 | # Compiled binary addons (http://nodejs.org/api/addons.html)
55 | build/Release
56 |
57 | # Dependency directories
58 | node_modules/
59 | jspm_packages/
60 |
61 | # Typescript v1 declaration files
62 | typings/
63 |
64 | # Optional npm cache directory
65 | .npm
66 |
67 | # Optional eslint cache
68 | .eslintcache
69 |
70 | # Optional REPL history
71 | .node_repl_history
72 |
73 | # Output of 'npm pack'
74 | *.tgz
75 |
76 | # Yarn Integrity file
77 | .yarn-integrity
78 |
79 | # dotenv environment variables file
80 | .env
81 |
82 | >>>>>>> 2f57339a7bda8575156e0ca997a5615a7519029f
83 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Realtime-Private-Chat-using-Angular-Nodejs-and-Mysql
2 | As the title suggests, this app is private chat application, In which front-end is built-in AngularJs(version 1.6.5). This is SPA application, which uses UI-bootstrap.
3 | Server-side is written in Nodejs (version 8.9.3) and Mysql (version 5.7.21-log).
4 |
5 |
6 | ## Installation
7 | 1. `Run install`
8 | 2. `node server.js`
9 |
10 | ## Explanation and Blog Post
11 | I have written a complete article on this application in three parts, for more details and Code explanation.
12 |
13 | 1. [Blog Post Part 1](http://www.codershood.info/2015/12/10/real-time-chatting-app-using-nodejs-mysql-angularjs-and-socket-io-part-1/) => Explains Login and Registration process.
14 | 2. [Blog Post Part 2](http://www.codershood.info/2015/12/10/real-time-chatting-app-using-nodejs-mysql-angularjs-and-socket-io-part-2/) => Explains the chat list implementation and modification.
15 | 3. [Blog Post Part 3](http://www.codershood.info/2015/12/10/real-time-chatting-app-using-nodejs-mysql-angularjs-and-socket-io-part-3/) => In this part, the user can actually send messages to each other.
16 |
17 | # Looking for Angular 2 and above
18 | I have written this application in Angular as well, [Read this popular Blog post](http://www.codershood.info/2017/02/09/real-time-private-chatting-app-using-angular-2-nodejs-mongodb-socket-io-part-1/).
19 | Alternatively, you can download an **[Ebook](http://www.codershood.info)** for the same application, along with Ebook you will get the source code of the application. In the ebook, you will get some of the must-have features such as notifications and online/offline chat list.
--------------------------------------------------------------------------------
/client/css/style.css:
--------------------------------------------------------------------------------
1 | body{
2 | overflow-x: hidden;
3 | }
4 |
5 | /* Auth page CSS starts */
6 | .auth-page{
7 | background: #ffffff;
8 | height: 100%;
9 | }
10 |
11 | .auth-container {
12 | padding-top: 5%;
13 | width: 50%;
14 | margin: auto;
15 | }
16 | .auth{
17 | width: 400px;
18 | margin: auto;
19 | padding: 5%;
20 | border-radius: 5px;
21 | border: solid 1px #0000003d;
22 | }
23 |
24 | .auth-header-btn{
25 | width: 49%;
26 | }
27 |
28 | .login,
29 | .register {
30 | padding: 1.5%;
31 | }
32 | /* Auth page CSS ends */
33 |
34 | /* Home page CSS starts */
35 | .home-header {
36 | width: 100%;
37 | padding: 1% 1% 1% 1%;
38 | background: #007bff;
39 | margin-bottom: 20px;
40 | color: #ffffff;
41 | }
42 |
43 | .home-body {
44 | width: 100%;
45 | height:85%;
46 | }
47 |
48 | .logout-user{
49 | float: right;
50 | margin-top: -2%;
51 | cursor: pointer;
52 | }
53 |
54 | .message-container{
55 | padding: 20px 0px 20px 20px;
56 | background-color: rgba(255, 255, 255, 0.80);
57 | margin: 10px 0px 10px 10px;
58 | border-radius: 5px;
59 | }
60 |
61 | .message-thread {
62 | overflow-y: scroll;
63 | list-style-type: none;
64 | height: 400px;
65 | width: 100%;
66 | border: solid 1px #BDBDBD;
67 | margin: 0px !important;
68 | padding: 5px !important;
69 | }
70 |
71 | .message-thread li {
72 | max-width: 300px;
73 | border-color: solid 0.5px rgba(0, 0, 0, 0.32);
74 | clear: both;
75 | text-decoration: none;
76 | list-style-type: none;
77 | margin: 20px 10px 0px 20px;
78 | float: left;
79 | margin-right: 20px;
80 | padding: 25px 34px;
81 | min-width: 160px;
82 | min-height: 10px;
83 | max-width: 350px;
84 | border-radius: 5px;
85 | border:solid 1px #0000001f;
86 | background-color: rgba(255, 255, 255, 0.80);
87 | line-height: 1.4;
88 | word-wrap: break-word;
89 | color: #444444;
90 | text-align: left;
91 | }
92 |
93 | .align-left {
94 | float: left !important;;
95 | }
96 | .align-right {
97 | float: right !important;;
98 | }
99 |
100 | .message-text{
101 | margin-top: 1%;
102 | }
103 |
104 |
105 | .chat-list-container {
106 | padding: 20px 20px 20px 0px;
107 | }
108 |
109 | .chat-list-heading {
110 | margin: 10px 10px 10px 0px;
111 | }
112 |
113 | .chat-list{
114 | overflow-y: scroll;
115 | height: 400px;
116 | width: 100%;
117 | margin: 10px 10px 10px 0px;
118 | padding-right: 20px;
119 | }
120 |
121 | .chat-list li{
122 | cursor: pointer;
123 | }
--------------------------------------------------------------------------------
/client/js/app.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Real Time chatting app
3 | * @author Shashank Tiwari
4 | */
5 |
6 | 'use strict';
7 | const app = angular.module('app', ['ngRoute', 'ui.bootstrap']);
8 |
9 | /*
10 | * configuring our routes for the app
11 | */
12 | app.config(function ($routeProvider, $locationProvider) {
13 | $routeProvider
14 | // route for the home page
15 | .when('/', {
16 | templateUrl: '/views/pages/auth.html',
17 | controller: 'authController'
18 | })
19 | .when('/home/:userId', {
20 | templateUrl: '/views/pages/home.html',
21 | controller: 'homeController'
22 | });
23 |
24 | // use the HTML5 History API
25 | $locationProvider.html5Mode(true);
26 | });
27 |
28 | app.factory('appService', ($http) => {
29 | return new AppService($http)
30 | });
31 |
--------------------------------------------------------------------------------
/client/js/app.service.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Real Time chatting app
3 | * @author Shashank Tiwari
4 | */
5 |
6 | 'use strict';
7 |
8 | class AppService{
9 | constructor($http){
10 | this.$http = $http;
11 | this.socket = null;
12 | }
13 | httpCall(httpData){
14 | if (httpData.url === undefined || httpData.url === null || httpData.url === ''){
15 | alert(`Invalid HTTP call`);
16 | }
17 | const HTTP = this.$http;
18 | const params = httpData.params;
19 | return new Promise( (resolve, reject) => {
20 | HTTP.post(httpData.url, params).then( (response) => {
21 | resolve(response.data);
22 | }).catch( (response, status, header, config) => {
23 | reject(response.data);
24 | });
25 | });
26 | }
27 | connectSocketServer(userId){
28 | const socket = io.connect( { query: `userId=${userId}` });
29 | this.socket = socket;
30 | }
31 |
32 | socketEmit(eventName, params){
33 | this.socket.emit(eventName, params);
34 | }
35 |
36 | socketOn(eventName, callback) {
37 | this.socket.on(eventName, (response) => {
38 | if (callback) {
39 | callback(response);
40 | }
41 | });
42 | }
43 |
44 | getMessages(userId, friendId) {
45 | return new Promise((resolve, reject) => {
46 | this.httpCall({
47 | url: '/getMessages',
48 | params: {
49 | 'userId': userId,
50 | 'toUserId': friendId
51 | }
52 | }).then((response) => {
53 | resolve(response);
54 | }).catch((error) => {
55 | reject(error);
56 | });
57 | });
58 | }
59 |
60 | scrollToBottom(){
61 | const messageThread = document.querySelector('.message-thread');
62 | setTimeout(() => {
63 | messageThread.scrollTop = messageThread.scrollHeight + 500;
64 | }, 10);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/client/js/auth.controller.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Real Time chatting app
3 | * @author Shashank Tiwari
4 | */
5 |
6 | 'user strict';
7 |
8 | app.controller('authController', function ($scope, $location, $timeout, appService) {
9 |
10 | $scope.data = {
11 | regUsername : '',
12 | regPassword : '',
13 | usernameAvailable : false,
14 | loginUsername : '',
15 | loginPassword : ''
16 | };
17 |
18 | /* usernamme check variables starts*/
19 | let TypeTimer;
20 | const TypingInterval = 800;
21 | /* usernamme check variables ends*/
22 |
23 | $scope.initiateCheckUserName = () => {
24 | $scope.data.usernameAvailable = false;
25 | $timeout.cancel(TypeTimer);
26 | TypeTimer = $timeout( () => {
27 | appService.httpCall({
28 | url: '/usernameCheck',
29 | params: {
30 | 'username': $scope.data.regUsername
31 | }
32 | })
33 | .then((response) => {
34 | $scope.$apply( () =>{
35 | $scope.data.usernameAvailable = response.error ? true : false;
36 | });
37 | })
38 | .catch((error) => {
39 | $scope.$apply(() => {
40 | $scope.data.usernameAvailable = true;
41 | });
42 |
43 | });
44 | }, TypingInterval);
45 | }
46 |
47 | $scope.clearCheckUserName = () => {
48 | $timeout.cancel(TypeTimer);
49 | }
50 |
51 | $scope.registerUser = () => {
52 | appService.httpCall({
53 | url: '/registerUser',
54 | params: {
55 | 'username': $scope.data.regUsername,
56 | 'password': $scope.data.regPassword
57 | }
58 | })
59 | .then((response) => {
60 | $location.path(`/home/${response.userId}`);
61 | $scope.$apply();
62 | })
63 | .catch((error) => {
64 | alert(error.message);
65 | });
66 | }
67 |
68 | $scope.loginUser = () => {
69 | appService.httpCall({
70 | url: '/login',
71 | params: {
72 | 'username': $scope.data.loginUsername,
73 | 'password': $scope.data.loginPassword
74 | }
75 | })
76 | .then((response) => {
77 | $location.path(`/home/${response.userId}`);
78 | $scope.$apply();
79 | })
80 | .catch((error) => {
81 | alert(error.message);
82 | });
83 | }
84 | });
--------------------------------------------------------------------------------
/client/js/home.controller.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Real Time chatting app
3 | * @author Shashank Tiwari
4 | */
5 |
6 | 'user strict';
7 |
8 | app.controller('homeController', function ($scope, $routeParams, $location, appService){
9 |
10 | const UserId = $routeParams.userId;
11 |
12 | $scope.data = {
13 | username: '',
14 | chatlist: [],
15 | selectedFriendId: null,
16 | selectedFriendName: null,
17 | messages: []
18 | };
19 |
20 | appService.connectSocketServer(UserId);
21 |
22 | appService.httpCall({
23 | url: '/userSessionCheck',
24 | params: {
25 | 'userId': UserId
26 | }
27 | })
28 | .then((response) => {
29 | $scope.data.username = response.username;
30 | appService.socketEmit(`chat-list`, UserId);
31 | appService.socketOn('chat-list-response', (response) => {
32 | $scope.$apply( () =>{
33 | if (!response.error) {
34 | if (response.singleUser) {
35 | /*
36 | * Removing duplicate user from chat list array
37 | */
38 | if ($scope.data.chatlist.length > 0) {
39 | $scope.data.chatlist = $scope.data.chatlist.filter(function (obj) {
40 | return obj.id !== response.chatList.id;
41 | });
42 | }
43 | /*
44 | * Adding new online user into chat list array
45 | */
46 | $scope.data.chatlist.push(response.chatList);
47 | } else if (response.userDisconnected) {
48 | /*
49 | * Removing a user from chat list, if user goes offline
50 | */
51 | $scope.data.chatlist = $scope.data.chatlist.filter(function (obj) {
52 | return obj.socketid !== response.socketId;
53 | });
54 | } else {
55 | /*
56 | * Updating entire chatlist if user logs in
57 | */
58 | $scope.data.chatlist = response.chatList;
59 | }
60 | } else {
61 | alert(`Faild to load Chat list`);
62 | }
63 | });
64 | });
65 |
66 | /*
67 | * This eventt will display the new incmoing message
68 | */
69 | appService.socketOn('add-message-response', (response) => {
70 | $scope.$apply( () => {
71 | if (response && response.fromUserId == $scope.data.selectedFriendId) {
72 | $scope.data.messages.push(response);
73 | appService.scrollToBottom();
74 | }
75 | });
76 | });
77 | })
78 | .catch((error) => {
79 | console.log(error.message);
80 | $scope.$apply( () =>{
81 | $location.path(`/`);
82 | });
83 | });
84 |
85 |
86 | $scope.selectFriendToChat = (friendId) => {
87 | /*
88 | * Highlighting the selected user from the chat list
89 | */
90 | const friendData = $scope.data.chatlist.filter((obj) => {
91 | return obj.id === friendId;
92 | });
93 | $scope.data.selectedFriendName = friendData[0]['username'];
94 | $scope.data.selectedFriendId = friendId;
95 | /**
96 | * This HTTP call will fetch chat between two users
97 | */
98 | appService.getMessages(UserId, friendId).then( (response) => {
99 | $scope.$apply(() => {
100 | $scope.data.messages = response.messages;
101 | });
102 | }).catch( (error) => {
103 | console.log(error);
104 | alert('Unexpected Error, Contact your Site Admin.');
105 | });
106 | }
107 |
108 | $scope.sendMessage = (event) => {
109 |
110 | if (event.keyCode === 13) {
111 |
112 | let toUserId = null;
113 | let toSocketId = null;
114 |
115 | /* Fetching the selected User from the chat list starts */
116 | let selectedFriendId = $scope.data.selectedFriendId;
117 | if (selectedFriendId === null) {
118 | return null;
119 | }
120 | friendData = $scope.data.chatlist.filter((obj) => {
121 | return obj.id === selectedFriendId;
122 | });
123 | /* Fetching the selected User from the chat list ends */
124 |
125 | /* Emmiting socket event to server with Message, starts */
126 | if (friendData.length > 0) {
127 |
128 | toUserId = friendData[0]['id'];
129 | toSocketId = friendData[0]['socketid'];
130 |
131 | let messagePacket = {
132 | message: document.querySelector('#message').value,
133 | fromUserId: UserId,
134 | toUserId: toUserId,
135 | toSocketId: toSocketId
136 | };
137 | $scope.data.messages.push(messagePacket);
138 | appService.socketEmit(`add-message`, messagePacket);
139 |
140 | document.querySelector('#message').value = '';
141 | appService.scrollToBottom();
142 | }else {
143 | alert('Unexpected Error Occured,Please contact Admin');
144 | }
145 | /* Emmiting socket event to server with Message, ends */
146 | }
147 | }
148 |
149 | $scope.alignMessage = (fromUserId) => {
150 | return fromUserId == UserId ? true : false;
151 | }
152 |
153 | $scope.logout = () => {
154 | appService.socketEmit(`logout`, UserId);
155 | $location.path(`/`);
156 | }
157 | });
--------------------------------------------------------------------------------
/client/js/ui-bootstrap-2.5.0.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * angular-ui-bootstrap
3 | * http://angular-ui.github.io/bootstrap/
4 |
5 | * Version: 2.5.0 - 2017-01-28
6 | * License: MIT
7 | */angular.module("ui.bootstrap",["ui.bootstrap.collapse","ui.bootstrap.tabindex","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.isClass","ui.bootstrap.datepicker","ui.bootstrap.position","ui.bootstrap.datepickerPopup","ui.bootstrap.debounce","ui.bootstrap.multiMap","ui.bootstrap.dropdown","ui.bootstrap.stackedMap","ui.bootstrap.modal","ui.bootstrap.paging","ui.bootstrap.pager","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]),angular.module("ui.bootstrap.collapse",[]).directive("uibCollapse",["$animate","$q","$parse","$injector",function(a,b,c,d){var e=d.has("$animateCss")?d.get("$animateCss"):null;return{link:function(d,f,g){function h(){r=!!("horizontal"in g),r?(s={width:""},t={width:"0"}):(s={height:""},t={height:"0"}),d.$eval(g.uibCollapse)||f.addClass("in").addClass("collapse").attr("aria-expanded",!0).attr("aria-hidden",!1).css(s)}function i(a){return r?{width:a.scrollWidth+"px"}:{height:a.scrollHeight+"px"}}function j(){f.hasClass("collapse")&&f.hasClass("in")||b.resolve(n(d)).then(function(){f.removeClass("collapse").addClass("collapsing").attr("aria-expanded",!0).attr("aria-hidden",!1),e?e(f,{addClass:"in",easing:"ease",css:{overflow:"hidden"},to:i(f[0])}).start()["finally"](k):a.addClass(f,"in",{css:{overflow:"hidden"},to:i(f[0])}).then(k)},angular.noop)}function k(){f.removeClass("collapsing").addClass("collapse").css(s),o(d)}function l(){return f.hasClass("collapse")||f.hasClass("in")?void b.resolve(p(d)).then(function(){f.css(i(f[0])).removeClass("collapse").addClass("collapsing").attr("aria-expanded",!1).attr("aria-hidden",!0),e?e(f,{removeClass:"in",to:t}).start()["finally"](m):a.removeClass(f,"in",{to:t}).then(m)},angular.noop):m()}function m(){f.css(t),f.removeClass("collapsing").addClass("collapse"),q(d)}var n=c(g.expanding),o=c(g.expanded),p=c(g.collapsing),q=c(g.collapsed),r=!1,s={},t={};h(),d.$watch(g.uibCollapse,function(a){a?l():j()})}}}]),angular.module("ui.bootstrap.tabindex",[]).directive("uibTabindexToggle",function(){return{restrict:"A",link:function(a,b,c){c.$observe("disabled",function(a){c.$set("tabindex",a?-1:null)})}}}),angular.module("ui.bootstrap.accordion",["ui.bootstrap.collapse","ui.bootstrap.tabindex"]).constant("uibAccordionConfig",{closeOthers:!0}).controller("UibAccordionController",["$scope","$attrs","uibAccordionConfig",function(a,b,c){this.groups=[],this.closeOthers=function(d){var e=angular.isDefined(b.closeOthers)?a.$eval(b.closeOthers):c.closeOthers;e&&angular.forEach(this.groups,function(a){a!==d&&(a.isOpen=!1)})},this.addGroup=function(a){var b=this;this.groups.push(a),a.$on("$destroy",function(c){b.removeGroup(a)})},this.removeGroup=function(a){var b=this.groups.indexOf(a);-1!==b&&this.groups.splice(b,1)}}]).directive("uibAccordion",function(){return{controller:"UibAccordionController",controllerAs:"accordion",transclude:!0,templateUrl:function(a,b){return b.templateUrl||"uib/template/accordion/accordion.html"}}}).directive("uibAccordionGroup",function(){return{require:"^uibAccordion",transclude:!0,restrict:"A",templateUrl:function(a,b){return b.templateUrl||"uib/template/accordion/accordion-group.html"},scope:{heading:"@",panelClass:"@?",isOpen:"=?",isDisabled:"=?"},controller:function(){this.setHeading=function(a){this.heading=a}},link:function(a,b,c,d){b.addClass("panel"),d.addGroup(a),a.openClass=c.openClass||"panel-open",a.panelClass=c.panelClass||"panel-default",a.$watch("isOpen",function(c){b.toggleClass(a.openClass,!!c),c&&d.closeOthers(a)}),a.toggleOpen=function(b){a.isDisabled||b&&32!==b.which||(a.isOpen=!a.isOpen)};var e="accordiongroup-"+a.$id+"-"+Math.floor(1e4*Math.random());a.headingId=e+"-tab",a.panelId=e+"-panel"}}}).directive("uibAccordionHeading",function(){return{transclude:!0,template:"",replace:!0,require:"^uibAccordionGroup",link:function(a,b,c,d,e){d.setHeading(e(a,angular.noop))}}}).directive("uibAccordionTransclude",function(){function a(){return"uib-accordion-header,data-uib-accordion-header,x-uib-accordion-header,uib\\:accordion-header,[uib-accordion-header],[data-uib-accordion-header],[x-uib-accordion-header]"}return{require:"^uibAccordionGroup",link:function(b,c,d,e){b.$watch(function(){return e[d.uibAccordionTransclude]},function(b){if(b){var d=angular.element(c[0].querySelector(a()));d.html(""),d.append(b)}})}}}),angular.module("ui.bootstrap.alert",[]).controller("UibAlertController",["$scope","$element","$attrs","$interpolate","$timeout",function(a,b,c,d,e){a.closeable=!!c.close,b.addClass("alert"),c.$set("role","alert"),a.closeable&&b.addClass("alert-dismissible");var f=angular.isDefined(c.dismissOnTimeout)?d(c.dismissOnTimeout)(a.$parent):null;f&&e(function(){a.close()},parseInt(f,10))}]).directive("uibAlert",function(){return{controller:"UibAlertController",controllerAs:"alert",restrict:"A",templateUrl:function(a,b){return b.templateUrl||"uib/template/alert/alert.html"},transclude:!0,scope:{close:"&"}}}),angular.module("ui.bootstrap.buttons",[]).constant("uibButtonConfig",{activeClass:"active",toggleEvent:"click"}).controller("UibButtonsController",["uibButtonConfig",function(a){this.activeClass=a.activeClass||"active",this.toggleEvent=a.toggleEvent||"click"}]).directive("uibBtnRadio",["$parse",function(a){return{require:["uibBtnRadio","ngModel"],controller:"UibButtonsController",controllerAs:"buttons",link:function(b,c,d,e){var f=e[0],g=e[1],h=a(d.uibUncheckable);c.find("input").css({display:"none"}),g.$render=function(){c.toggleClass(f.activeClass,angular.equals(g.$modelValue,b.$eval(d.uibBtnRadio)))},c.on(f.toggleEvent,function(){if(!d.disabled){var a=c.hasClass(f.activeClass);a&&!angular.isDefined(d.uncheckable)||b.$apply(function(){g.$setViewValue(a?null:b.$eval(d.uibBtnRadio)),g.$render()})}}),d.uibUncheckable&&b.$watch(h,function(a){d.$set("uncheckable",a?"":void 0)})}}}]).directive("uibBtnCheckbox",function(){return{require:["uibBtnCheckbox","ngModel"],controller:"UibButtonsController",controllerAs:"button",link:function(a,b,c,d){function e(){return g(c.btnCheckboxTrue,!0)}function f(){return g(c.btnCheckboxFalse,!1)}function g(b,c){return angular.isDefined(b)?a.$eval(b):c}var h=d[0],i=d[1];b.find("input").css({display:"none"}),i.$render=function(){b.toggleClass(h.activeClass,angular.equals(i.$modelValue,e()))},b.on(h.toggleEvent,function(){c.disabled||a.$apply(function(){i.$setViewValue(b.hasClass(h.activeClass)?f():e()),i.$render()})})}}}),angular.module("ui.bootstrap.carousel",[]).controller("UibCarouselController",["$scope","$element","$interval","$timeout","$animate",function(a,b,c,d,e){function f(a){for(var b=0;b
1){p[d].element.data(q,c.direction);var h=o.getCurrentIndex();angular.isNumber(h)&&p[h].element&&p[h].element.data(q,c.direction),a.$currentTransition=!0,e.on("addClass",p[d].element,function(b,c){"close"===c&&(a.$currentTransition=null,e.off("addClass",b))})}a.active=c.index,r=c.index,f(d),k()}}function h(a){for(var b=0;b0&&(m=c(l,b))}function l(){var b=+a.interval;n&&!isNaN(b)&&b>0&&p.length?a.next():a.pause()}var m,n,o=this,p=o.slides=a.slides=[],q="uib-slideDirection",r=a.active,s=!1;b.addClass("carousel"),o.addSlide=function(b,c){p.push({slide:b,element:c}),p.sort(function(a,b){return+a.slide.index-+b.slide.index}),(b.index===a.active||1===p.length&&!angular.isNumber(a.active))&&(a.$currentTransition&&(a.$currentTransition=null),r=b.index,a.active=b.index,f(r),o.select(p[h(b)]),1===p.length&&a.play())},o.getCurrentIndex=function(){for(var a=0;a0&&r===c?c>=p.length?(r=p.length-1,a.active=r,f(r),o.select(p[p.length-1])):(r=c,a.active=r,f(r),o.select(p[c])):r>c&&(r--,a.active=r),0===p.length&&(r=null,a.active=null)},o.select=a.select=function(b,c){var d=h(b.slide);void 0===c&&(c=d>o.getCurrentIndex()?"next":"prev"),b.slide.index===r||a.$currentTransition||g(b.slide,d,c)},a.indexOfSlide=function(a){return+a.slide.index},a.isActive=function(b){return a.active===b.slide.index},a.isPrevDisabled=function(){return 0===a.active&&a.noWrap()},a.isNextDisabled=function(){return a.active===p.length-1&&a.noWrap()},a.pause=function(){a.noPause||(n=!1,i())},a.play=function(){n||(n=!0,k())},b.on("mouseenter",a.pause),b.on("mouseleave",a.play),a.$on("$destroy",function(){s=!0,i()}),a.$watch("noTransition",function(a){e.enabled(b,!a)}),a.$watch("interval",k),a.$watchCollection("slides",j),a.$watch("active",function(a){if(angular.isNumber(a)&&r!==a){for(var b=0;b-1){var f=!1;a=a.split("");for(var g=e;g-1){a=a.split(""),c[e]="("+d.regex+")",a[e]="$";for(var f=e+1,g=e+d.key.length;g>f;f++)c[f]="",a[f]="$";a=a.join(""),b.push({index:e,key:d.key,apply:d.apply,matcher:d.regex})}}),{regex:new RegExp("^"+c.join("")+"$"),map:d(b,"index")}}function h(a){for(var b,c,d=[],e=0;e=a.length||"'"!==a.charAt(e+1))&&(d.push(i(a,c,e)),c=null);else if(e===a.length)for(;cc?!1:1===b&&c>28?29===c&&(a%4===0&&a%100!==0||a%400===0):3===b||5===b||8===b||10===b?31>c:!0}function l(a){return parseInt(a,10)}function m(a,b){return a&&b?q(a,b):a}function n(a,b){return a&&b?q(a,b,!0):a}function o(a,b){a=a.replace(/:/g,"");var c=Date.parse("Jan 01, 1970 00:00:00 "+a)/6e4;return isNaN(c)?b:c}function p(a,b){return a=new Date(a.getTime()),a.setMinutes(a.getMinutes()+b),a}function q(a,b,c){c=c?-1:1;var d=a.getTimezoneOffset(),e=o(b,d);return p(a,c*(e-d))}var r,s,t=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;this.init=function(){r=b.id,this.parsers={},this.formatters={},s=[{key:"yyyy",regex:"\\d{4}",apply:function(a){this.year=+a},formatter:function(a){var b=new Date;return b.setFullYear(Math.abs(a.getFullYear())),c(b,"yyyy")}},{key:"yy",regex:"\\d{2}",apply:function(a){a=+a,this.year=69>a?a+2e3:a+1900},formatter:function(a){var b=new Date;return b.setFullYear(Math.abs(a.getFullYear())),c(b,"yy")}},{key:"y",regex:"\\d{1,4}",apply:function(a){this.year=+a},formatter:function(a){var b=new Date;return b.setFullYear(Math.abs(a.getFullYear())),c(b,"y")}},{key:"M!",regex:"0?[1-9]|1[0-2]",apply:function(a){this.month=a-1},formatter:function(a){var b=a.getMonth();return/^[0-9]$/.test(b)?c(a,"MM"):c(a,"M")}},{key:"MMMM",regex:b.DATETIME_FORMATS.MONTH.join("|"),apply:function(a){this.month=b.DATETIME_FORMATS.MONTH.indexOf(a)},formatter:function(a){return c(a,"MMMM")}},{key:"MMM",regex:b.DATETIME_FORMATS.SHORTMONTH.join("|"),apply:function(a){this.month=b.DATETIME_FORMATS.SHORTMONTH.indexOf(a)},formatter:function(a){return c(a,"MMM")}},{key:"MM",regex:"0[1-9]|1[0-2]",apply:function(a){this.month=a-1},formatter:function(a){return c(a,"MM")}},{key:"M",regex:"[1-9]|1[0-2]",apply:function(a){this.month=a-1},formatter:function(a){return c(a,"M")}},{key:"d!",regex:"[0-2]?[0-9]{1}|3[0-1]{1}",apply:function(a){this.date=+a},formatter:function(a){var b=a.getDate();return/^[1-9]$/.test(b)?c(a,"dd"):c(a,"d")}},{key:"dd",regex:"[0-2][0-9]{1}|3[0-1]{1}",apply:function(a){this.date=+a},formatter:function(a){return c(a,"dd")}},{key:"d",regex:"[1-2]?[0-9]{1}|3[0-1]{1}",apply:function(a){this.date=+a},formatter:function(a){return c(a,"d")}},{key:"EEEE",regex:b.DATETIME_FORMATS.DAY.join("|"),formatter:function(a){return c(a,"EEEE")}},{key:"EEE",regex:b.DATETIME_FORMATS.SHORTDAY.join("|"),formatter:function(a){return c(a,"EEE")}},{key:"HH",regex:"(?:0|1)[0-9]|2[0-3]",apply:function(a){this.hours=+a},formatter:function(a){return c(a,"HH")}},{key:"hh",regex:"0[0-9]|1[0-2]",apply:function(a){this.hours=+a},formatter:function(a){return c(a,"hh")}},{key:"H",regex:"1?[0-9]|2[0-3]",apply:function(a){this.hours=+a},formatter:function(a){return c(a,"H")}},{key:"h",regex:"[0-9]|1[0-2]",apply:function(a){this.hours=+a},formatter:function(a){return c(a,"h")}},{key:"mm",regex:"[0-5][0-9]",apply:function(a){this.minutes=+a},formatter:function(a){return c(a,"mm")}},{key:"m",regex:"[0-9]|[1-5][0-9]",apply:function(a){this.minutes=+a},formatter:function(a){return c(a,"m")}},{key:"sss",regex:"[0-9][0-9][0-9]",apply:function(a){this.milliseconds=+a},formatter:function(a){return c(a,"sss")}},{key:"ss",regex:"[0-5][0-9]",apply:function(a){this.seconds=+a},formatter:function(a){return c(a,"ss")}},{key:"s",regex:"[0-9]|[1-5][0-9]",apply:function(a){this.seconds=+a},formatter:function(a){return c(a,"s")}},{key:"a",regex:b.DATETIME_FORMATS.AMPMS.join("|"),apply:function(a){12===this.hours&&(this.hours=0),"PM"===a&&(this.hours+=12)},formatter:function(a){return c(a,"a")}},{key:"Z",regex:"[+-]\\d{4}",apply:function(a){var b=a.match(/([+-])(\d{2})(\d{2})/),c=b[1],d=b[2],e=b[3];this.hours+=l(c+d),this.minutes+=l(c+e)},formatter:function(a){return c(a,"Z")}},{key:"ww",regex:"[0-4][0-9]|5[0-3]",formatter:function(a){return c(a,"ww")}},{key:"w",regex:"[0-9]|[1-4][0-9]|5[0-3]",formatter:function(a){return c(a,"w")}},{key:"GGGG",regex:b.DATETIME_FORMATS.ERANAMES.join("|").replace(/\s/g,"\\s"),formatter:function(a){return c(a,"GGGG")}},{key:"GGG",regex:b.DATETIME_FORMATS.ERAS.join("|"),formatter:function(a){return c(a,"GGG")}},{key:"GG",regex:b.DATETIME_FORMATS.ERAS.join("|"),formatter:function(a){return c(a,"GG")}},{key:"G",regex:b.DATETIME_FORMATS.ERAS.join("|"),formatter:function(a){return c(a,"G")}}],angular.version.major>=1&&angular.version.minor>4&&s.push({key:"LLLL",regex:b.DATETIME_FORMATS.STANDALONEMONTH.join("|"),apply:function(a){this.month=b.DATETIME_FORMATS.STANDALONEMONTH.indexOf(a)},formatter:function(a){return c(a,"LLLL")}})},this.init(),this.getParser=function(a){var b=f(a);return b&&b.apply||null},this.overrideParser=function(a,b){var c=f(a);c&&angular.isFunction(b)&&(this.parsers={},c.apply=b)}.bind(this),this.filter=function(a,c){if(!angular.isDate(a)||isNaN(a)||!c)return"";c=b.DATETIME_FORMATS[c]||c,b.id!==r&&this.init(),this.formatters[c]||(this.formatters[c]=h(c));var d=this.formatters[c];return d.reduce(function(b,c){return b+c(a)},"")},this.parse=function(c,d,e){if(!angular.isString(c)||!d)return c;d=b.DATETIME_FORMATS[d]||d,d=d.replace(t,"\\$&"),b.id!==r&&this.init(),this.parsers[d]||(this.parsers[d]=g(d,"apply"));var f=this.parsers[d],h=f.regex,i=f.map,j=c.match(h),l=!1;if(j&&j.length){var m,n;angular.isDate(e)&&!isNaN(e.getTime())?m={year:e.getFullYear(),month:e.getMonth(),date:e.getDate(),hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds(),milliseconds:e.getMilliseconds()}:(e&&a.warn("dateparser:","baseDate is not a valid date"),m={year:1900,month:0,date:1,hours:0,minutes:0,seconds:0,milliseconds:0});for(var o=1,p=j.length;p>o;o++){var q=i[o-1];"Z"===q.matcher&&(l=!0),q.apply&&q.apply.call(m,j[o])}var s=l?Date.prototype.setUTCFullYear:Date.prototype.setFullYear,u=l?Date.prototype.setUTCHours:Date.prototype.setHours;return k(m.year,m.month,m.date)&&(!angular.isDate(e)||isNaN(e.getTime())||l?(n=new Date(0),s.call(n,m.year,m.month,m.date),u.call(n,m.hours||0,m.minutes||0,m.seconds||0,m.milliseconds||0)):(n=new Date(e),s.call(n,m.year,m.month,m.date),u.call(n,m.hours,m.minutes,m.seconds,m.milliseconds))),n}},this.toTimezone=m,this.fromTimezone=n,this.timezoneToOffset=o,this.addDateMinutes=p,this.convertTimezoneToLocal=q}]),angular.module("ui.bootstrap.isClass",[]).directive("uibIsClass",["$animate",function(a){var b=/^\s*([\s\S]+?)\s+on\s+([\s\S]+?)\s*$/,c=/^\s*([\s\S]+?)\s+for\s+([\s\S]+?)\s*$/;return{restrict:"A",compile:function(d,e){function f(a,b,c){i.push(a),j.push({scope:a,element:b}),o.forEach(function(b,c){g(b,a)}),a.$on("$destroy",h)}function g(b,d){var e=b.match(c),f=d.$eval(e[1]),g=e[2],h=k[b];if(!h){var i=function(b){var c=null;j.some(function(a){var d=a.scope.$eval(m);return d===b?(c=a,!0):void 0}),h.lastActivated!==c&&(h.lastActivated&&a.removeClass(h.lastActivated.element,f),c&&a.addClass(c.element,f),h.lastActivated=c)};k[b]=h={lastActivated:null,scope:d,watchFn:i,compareWithExp:g,watcher:d.$watch(g,i)}}h.watchFn(d.$eval(g))}function h(a){var b=a.targetScope,c=i.indexOf(b);if(i.splice(c,1),j.splice(c,1),i.length){var d=i[0];angular.forEach(k,function(a){a.scope===b&&(a.watcher=d.$watch(a.compareWithExp,a.watchFn),a.scope=d)})}else k={}}var i=[],j=[],k={},l=e.uibIsClass.match(b),m=l[2],n=l[1],o=n.split(",");return f}}}]),angular.module("ui.bootstrap.datepicker",["ui.bootstrap.dateparser","ui.bootstrap.isClass"]).value("$datepickerSuppressError",!1).value("$datepickerLiteralWarning",!0).constant("uibDatepickerConfig",{datepickerMode:"day",formatDay:"dd",formatMonth:"MMMM",formatYear:"yyyy",formatDayHeader:"EEE",formatDayTitle:"MMMM yyyy",formatMonthTitle:"yyyy",maxDate:null,maxMode:"year",minDate:null,minMode:"day",monthColumns:3,ngModelOptions:{},shortcutPropagation:!1,showWeeks:!0,yearColumns:5,yearRows:4}).controller("UibDatepickerController",["$scope","$element","$attrs","$parse","$interpolate","$locale","$log","dateFilter","uibDatepickerConfig","$datepickerLiteralWarning","$datepickerSuppressError","uibDateParser",function(a,b,c,d,e,f,g,h,i,j,k,l){function m(b){a.datepickerMode=b,a.datepickerOptions.datepickerMode=b}function n(b){var c;if(angular.version.minor<6)c=b.$options||a.datepickerOptions.ngModelOptions||i.ngModelOptions||{},c.getOption=function(a){return c[a]};else{var d=b.$options.getOption("timezone")||(a.datepickerOptions.ngModelOptions?a.datepickerOptions.ngModelOptions.timezone:null)||(i.ngModelOptions?i.ngModelOptions.timezone:null);c=b.$options.createChild(i.ngModelOptions).createChild(a.datepickerOptions.ngModelOptions).createChild(b.$options).createChild({timezone:d})}return c}var o=this,p={$setViewValue:angular.noop},q={},r=[];b.addClass("uib-datepicker"),c.$set("role","application"),a.datepickerOptions||(a.datepickerOptions={}),this.modes=["day","month","year"],["customClass","dateDisabled","datepickerMode","formatDay","formatDayHeader","formatDayTitle","formatMonth","formatMonthTitle","formatYear","maxDate","maxMode","minDate","minMode","monthColumns","showWeeks","shortcutPropagation","startingDay","yearColumns","yearRows"].forEach(function(b){switch(b){case"customClass":case"dateDisabled":a[b]=a.datepickerOptions[b]||angular.noop;break;case"datepickerMode":a.datepickerMode=angular.isDefined(a.datepickerOptions.datepickerMode)?a.datepickerOptions.datepickerMode:i.datepickerMode;break;case"formatDay":case"formatDayHeader":case"formatDayTitle":case"formatMonth":case"formatMonthTitle":case"formatYear":o[b]=angular.isDefined(a.datepickerOptions[b])?e(a.datepickerOptions[b])(a.$parent):i[b];break;case"monthColumns":case"showWeeks":case"shortcutPropagation":case"yearColumns":case"yearRows":o[b]=angular.isDefined(a.datepickerOptions[b])?a.datepickerOptions[b]:i[b];break;case"startingDay":angular.isDefined(a.datepickerOptions.startingDay)?o.startingDay=a.datepickerOptions.startingDay:angular.isNumber(i.startingDay)?o.startingDay=i.startingDay:o.startingDay=(f.DATETIME_FORMATS.FIRSTDAYOFWEEK+8)%7;break;case"maxDate":case"minDate":a.$watch("datepickerOptions."+b,function(a){a?angular.isDate(a)?o[b]=l.fromTimezone(new Date(a),q.getOption("timezone")):(j&&g.warn("Literal date support has been deprecated, please switch to date object usage"),o[b]=new Date(h(a,"medium"))):o[b]=i[b]?l.fromTimezone(new Date(i[b]),q.getOption("timezone")):null,o.refreshView()});break;case"maxMode":case"minMode":a.datepickerOptions[b]?a.$watch(function(){return a.datepickerOptions[b]},function(c){o[b]=a[b]=angular.isDefined(c)?c:a.datepickerOptions[b],("minMode"===b&&o.modes.indexOf(a.datepickerOptions.datepickerMode)o.modes.indexOf(o[b]))&&(a.datepickerMode=o[b],a.datepickerOptions.datepickerMode=o[b])}):o[b]=a[b]=i[b]||null}}),a.uniqueId="datepicker-"+a.$id+"-"+Math.floor(1e4*Math.random()),a.disabled=angular.isDefined(c.disabled)||!1,angular.isDefined(c.ngDisabled)&&r.push(a.$parent.$watch(c.ngDisabled,function(b){a.disabled=b,o.refreshView()})),a.isActive=function(b){return 0===o.compare(b.date,o.activeDate)?(a.activeDateId=b.uid,!0):!1},this.init=function(b){p=b,q=n(p),a.datepickerOptions.initDate?(o.activeDate=l.fromTimezone(a.datepickerOptions.initDate,q.getOption("timezone"))||new Date,a.$watch("datepickerOptions.initDate",function(a){a&&(p.$isEmpty(p.$modelValue)||p.$invalid)&&(o.activeDate=l.fromTimezone(a,q.getOption("timezone")),o.refreshView())})):o.activeDate=new Date;var c=p.$modelValue?new Date(p.$modelValue):new Date;this.activeDate=isNaN(c)?l.fromTimezone(new Date,q.getOption("timezone")):l.fromTimezone(c,q.getOption("timezone")),p.$render=function(){o.render()}},this.render=function(){if(p.$viewValue){var a=new Date(p.$viewValue),b=!isNaN(a);b?this.activeDate=l.fromTimezone(a,q.getOption("timezone")):k||g.error('Datepicker directive: "ng-model" value must be a Date object')}this.refreshView()},this.refreshView=function(){if(this.element){a.selectedDt=null,this._refreshView(),a.activeDt&&(a.activeDateId=a.activeDt.uid);var b=p.$viewValue?new Date(p.$viewValue):null;b=l.fromTimezone(b,q.getOption("timezone")),p.$setValidity("dateDisabled",!b||this.element&&!this.isDisabled(b))}},this.createDateObject=function(b,c){var d=p.$viewValue?new Date(p.$viewValue):null;d=l.fromTimezone(d,q.getOption("timezone"));var e=new Date;e=l.fromTimezone(e,q.getOption("timezone"));var f=this.compare(b,e),g={date:b,label:l.filter(b,c),selected:d&&0===this.compare(b,d),disabled:this.isDisabled(b),past:0>f,current:0===f,future:f>0,customClass:this.customClass(b)||null};return d&&0===this.compare(b,d)&&(a.selectedDt=g),o.activeDate&&0===this.compare(g.date,o.activeDate)&&(a.activeDt=g),g},this.isDisabled=function(b){return a.disabled||this.minDate&&this.compare(b,this.minDate)<0||this.maxDate&&this.compare(b,this.maxDate)>0||a.dateDisabled&&a.dateDisabled({date:b,mode:a.datepickerMode})},this.customClass=function(b){return a.customClass({date:b,mode:a.datepickerMode})},this.split=function(a,b){for(var c=[];a.length>0;)c.push(a.splice(0,b));return c},a.select=function(b){if(a.datepickerMode===o.minMode){var c=p.$viewValue?l.fromTimezone(new Date(p.$viewValue),q.getOption("timezone")):new Date(0,0,0,0,0,0,0);c.setFullYear(b.getFullYear(),b.getMonth(),b.getDate()),c=l.toTimezone(c,q.getOption("timezone")),p.$setViewValue(c),p.$render()}else o.activeDate=b,m(o.modes[o.modes.indexOf(a.datepickerMode)-1]),a.$emit("uib:datepicker.mode");a.$broadcast("uib:datepicker.focus")},a.move=function(a){var b=o.activeDate.getFullYear()+a*(o.step.years||0),c=o.activeDate.getMonth()+a*(o.step.months||0);o.activeDate.setFullYear(b,c,1),o.refreshView()},a.toggleMode=function(b){b=b||1,a.datepickerMode===o.maxMode&&1===b||a.datepickerMode===o.minMode&&-1===b||(m(o.modes[o.modes.indexOf(a.datepickerMode)+b]),a.$emit("uib:datepicker.mode"))},a.keys={13:"enter",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down"};var s=function(){o.element[0].focus()};a.$on("uib:datepicker.focus",s),a.keydown=function(b){var c=a.keys[b.which];if(c&&!b.shiftKey&&!b.altKey&&!a.disabled)if(b.preventDefault(),o.shortcutPropagation||b.stopPropagation(),"enter"===c||"space"===c){if(o.isDisabled(o.activeDate))return;a.select(o.activeDate)}else!b.ctrlKey||"up"!==c&&"down"!==c?(o.handleKeyDown(c,b),o.refreshView()):a.toggleMode("up"===c?1:-1)},b.on("keydown",function(b){a.$apply(function(){a.keydown(b)})}),a.$on("$destroy",function(){for(;r.length;)r.shift()()})}]).controller("UibDaypickerController",["$scope","$element","dateFilter",function(a,b,c){function d(a,b){return 1!==b||a%4!==0||a%100===0&&a%400!==0?f[b]:29}function e(a){var b=new Date(a);b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();return b.setMonth(0),b.setDate(1),Math.floor(Math.round((c-b)/864e5)/7)+1}var f=[31,28,31,30,31,30,31,31,30,31,30,31];this.step={months:1},this.element=b,this.init=function(b){angular.extend(b,this),a.showWeeks=b.showWeeks,b.refreshView()},this.getDates=function(a,b){for(var c,d=new Array(b),e=new Date(a),f=0;b>f;)c=new Date(e),d[f++]=c,e.setDate(e.getDate()+1);return d},this._refreshView=function(){var b=this.activeDate.getFullYear(),d=this.activeDate.getMonth(),f=new Date(this.activeDate);f.setFullYear(b,d,1);var g=this.startingDay-f.getDay(),h=g>0?7-g:-g,i=new Date(f);h>0&&i.setDate(-h+1);for(var j=this.getDates(i,42),k=0;42>k;k++)j[k]=angular.extend(this.createDateObject(j[k],this.formatDay),{secondary:j[k].getMonth()!==d,uid:a.uniqueId+"-"+k});a.labels=new Array(7);for(var l=0;7>l;l++)a.labels[l]={abbr:c(j[l].date,this.formatDayHeader),full:c(j[l].date,"EEEE")};if(a.title=c(this.activeDate,this.formatDayTitle),a.rows=this.split(j,7),a.showWeeks){a.weekNumbers=[];for(var m=(11-this.startingDay)%7,n=a.rows.length,o=0;n>o;o++)a.weekNumbers.push(e(a.rows[o][m].date))}},this.compare=function(a,b){var c=new Date(a.getFullYear(),a.getMonth(),a.getDate()),d=new Date(b.getFullYear(),b.getMonth(),b.getDate());return c.setFullYear(a.getFullYear()),d.setFullYear(b.getFullYear()),c-d},this.handleKeyDown=function(a,b){var c=this.activeDate.getDate();if("left"===a)c-=1;else if("up"===a)c-=7;else if("right"===a)c+=1;else if("down"===a)c+=7;else if("pageup"===a||"pagedown"===a){var e=this.activeDate.getMonth()+("pageup"===a?-1:1);this.activeDate.setMonth(e,1),c=Math.min(d(this.activeDate.getFullYear(),this.activeDate.getMonth()),c)}else"home"===a?c=1:"end"===a&&(c=d(this.activeDate.getFullYear(),this.activeDate.getMonth()));this.activeDate.setDate(c)}}]).controller("UibMonthpickerController",["$scope","$element","dateFilter",function(a,b,c){this.step={years:1},this.element=b,this.init=function(a){angular.extend(a,this),a.refreshView()},this._refreshView=function(){for(var b,d=new Array(12),e=this.activeDate.getFullYear(),f=0;12>f;f++)b=new Date(this.activeDate),b.setFullYear(e,f,1),d[f]=angular.extend(this.createDateObject(b,this.formatMonth),{uid:a.uniqueId+"-"+f});a.title=c(this.activeDate,this.formatMonthTitle),a.rows=this.split(d,this.monthColumns),a.yearHeaderColspan=this.monthColumns>3?this.monthColumns-2:1},this.compare=function(a,b){var c=new Date(a.getFullYear(),a.getMonth()),d=new Date(b.getFullYear(),b.getMonth());return c.setFullYear(a.getFullYear()),d.setFullYear(b.getFullYear()),c-d},this.handleKeyDown=function(a,b){var c=this.activeDate.getMonth();if("left"===a)c-=1;else if("up"===a)c-=this.monthColumns;else if("right"===a)c+=1;else if("down"===a)c+=this.monthColumns;else if("pageup"===a||"pagedown"===a){var d=this.activeDate.getFullYear()+("pageup"===a?-1:1);this.activeDate.setFullYear(d)}else"home"===a?c=0:"end"===a&&(c=11);this.activeDate.setMonth(c)}}]).controller("UibYearpickerController",["$scope","$element","dateFilter",function(a,b,c){function d(a){return parseInt((a-1)/f,10)*f+1}var e,f;this.element=b,this.yearpickerInit=function(){e=this.yearColumns,f=this.yearRows*e,this.step={years:f}},this._refreshView=function(){for(var b,c=new Array(f),g=0,h=d(this.activeDate.getFullYear());f>g;g++)b=new Date(this.activeDate),b.setFullYear(h+g,0,1),c[g]=angular.extend(this.createDateObject(b,this.formatYear),{uid:a.uniqueId+"-"+g});a.title=[c[0].label,c[f-1].label].join(" - "),a.rows=this.split(c,e),a.columns=e},this.compare=function(a,b){return a.getFullYear()-b.getFullYear()},this.handleKeyDown=function(a,b){var c=this.activeDate.getFullYear();"left"===a?c-=1:"up"===a?c-=e:"right"===a?c+=1:"down"===a?c+=e:"pageup"===a||"pagedown"===a?c+=("pageup"===a?-1:1)*f:"home"===a?c=d(this.activeDate.getFullYear()):"end"===a&&(c=d(this.activeDate.getFullYear())+f-1),this.activeDate.setFullYear(c)}}]).directive("uibDatepicker",function(){return{templateUrl:function(a,b){return b.templateUrl||"uib/template/datepicker/datepicker.html"},scope:{datepickerOptions:"=?"},require:["uibDatepicker","^ngModel"],restrict:"A",controller:"UibDatepickerController",controllerAs:"datepicker",link:function(a,b,c,d){var e=d[0],f=d[1];e.init(f)}}}).directive("uibDaypicker",function(){return{templateUrl:function(a,b){return b.templateUrl||"uib/template/datepicker/day.html"},require:["^uibDatepicker","uibDaypicker"],restrict:"A",controller:"UibDaypickerController",link:function(a,b,c,d){var e=d[0],f=d[1];f.init(e)}}}).directive("uibMonthpicker",function(){return{templateUrl:function(a,b){return b.templateUrl||"uib/template/datepicker/month.html"},require:["^uibDatepicker","uibMonthpicker"],restrict:"A",controller:"UibMonthpickerController",link:function(a,b,c,d){var e=d[0],f=d[1];f.init(e)}}}).directive("uibYearpicker",function(){return{templateUrl:function(a,b){return b.templateUrl||"uib/template/datepicker/year.html"},require:["^uibDatepicker","uibYearpicker"],restrict:"A",controller:"UibYearpickerController",link:function(a,b,c,d){var e=d[0];angular.extend(e,d[1]),e.yearpickerInit(),e.refreshView()}}}),angular.module("ui.bootstrap.position",[]).factory("$uibPosition",["$document","$window",function(a,b){var c,d,e={normal:/(auto|scroll)/,hidden:/(auto|scroll|hidden)/},f={auto:/\s?auto?\s?/i,primary:/^(top|bottom|left|right)$/,secondary:/^(top|bottom|left|right|center)$/,vertical:/^(top|bottom)$/},g=/(HTML|BODY)/;return{getRawNode:function(a){return a.nodeName?a:a[0]||a},parseStyle:function(a){return a=parseFloat(a),
8 | isFinite(a)?a:0},offsetParent:function(c){function d(a){return"static"===(b.getComputedStyle(a).position||"static")}c=this.getRawNode(c);for(var e=c.offsetParent||a[0].documentElement;e&&e!==a[0].documentElement&&d(e);)e=e.offsetParent;return e||a[0].documentElement},scrollbarWidth:function(e){if(e){if(angular.isUndefined(d)){var f=a.find("body");f.addClass("uib-position-body-scrollbar-measure"),d=b.innerWidth-f[0].clientWidth,d=isFinite(d)?d:0,f.removeClass("uib-position-body-scrollbar-measure")}return d}if(angular.isUndefined(c)){var g=angular.element('');a.find("body").append(g),c=g[0].offsetWidth-g[0].clientWidth,c=isFinite(c)?c:0,g.remove()}return c},scrollbarPadding:function(a){a=this.getRawNode(a);var c=b.getComputedStyle(a),d=this.parseStyle(c.paddingRight),e=this.parseStyle(c.paddingBottom),f=this.scrollParent(a,!1,!0),h=this.scrollbarWidth(g.test(f.tagName));return{scrollbarWidth:h,widthOverflow:f.scrollWidth>f.clientWidth,right:d+h,originalRight:d,heightOverflow:f.scrollHeight>f.clientHeight,bottom:e+h,originalBottom:e}},isScrollable:function(a,c){a=this.getRawNode(a);var d=c?e.hidden:e.normal,f=b.getComputedStyle(a);return d.test(f.overflow+f.overflowY+f.overflowX)},scrollParent:function(c,d,f){c=this.getRawNode(c);var g=d?e.hidden:e.normal,h=a[0].documentElement,i=b.getComputedStyle(c);if(f&&g.test(i.overflow+i.overflowY+i.overflowX))return c;var j="absolute"===i.position,k=c.parentElement||h;if(k===h||"fixed"===i.position)return h;for(;k.parentElement&&k!==h;){var l=b.getComputedStyle(k);if(j&&"static"!==l.position&&(j=!1),!j&&g.test(l.overflow+l.overflowY+l.overflowX))break;k=k.parentElement}return k},position:function(c,d){c=this.getRawNode(c);var e=this.offset(c);if(d){var f=b.getComputedStyle(c);e.top-=this.parseStyle(f.marginTop),e.left-=this.parseStyle(f.marginLeft)}var g=this.offsetParent(c),h={top:0,left:0};return g!==a[0].documentElement&&(h=this.offset(g),h.top+=g.clientTop-g.scrollTop,h.left+=g.clientLeft-g.scrollLeft),{width:Math.round(angular.isNumber(e.width)?e.width:c.offsetWidth),height:Math.round(angular.isNumber(e.height)?e.height:c.offsetHeight),top:Math.round(e.top-h.top),left:Math.round(e.left-h.left)}},offset:function(c){c=this.getRawNode(c);var d=c.getBoundingClientRect();return{width:Math.round(angular.isNumber(d.width)?d.width:c.offsetWidth),height:Math.round(angular.isNumber(d.height)?d.height:c.offsetHeight),top:Math.round(d.top+(b.pageYOffset||a[0].documentElement.scrollTop)),left:Math.round(d.left+(b.pageXOffset||a[0].documentElement.scrollLeft))}},viewportOffset:function(c,d,e){c=this.getRawNode(c),e=e!==!1;var f=c.getBoundingClientRect(),g={top:0,left:0,bottom:0,right:0},h=d?a[0].documentElement:this.scrollParent(c),i=h.getBoundingClientRect();if(g.top=i.top+h.clientTop,g.left=i.left+h.clientLeft,h===a[0].documentElement&&(g.top+=b.pageYOffset,g.left+=b.pageXOffset),g.bottom=g.top+h.clientHeight,g.right=g.left+h.clientWidth,e){var j=b.getComputedStyle(h);g.top+=this.parseStyle(j.paddingTop),g.bottom-=this.parseStyle(j.paddingBottom),g.left+=this.parseStyle(j.paddingLeft),g.right-=this.parseStyle(j.paddingRight)}return{top:Math.round(f.top-g.top),bottom:Math.round(g.bottom-f.bottom),left:Math.round(f.left-g.left),right:Math.round(g.right-f.right)}},parsePlacement:function(a){var b=f.auto.test(a);return b&&(a=a.replace(f.auto,"")),a=a.split("-"),a[0]=a[0]||"top",f.primary.test(a[0])||(a[0]="top"),a[1]=a[1]||"center",f.secondary.test(a[1])||(a[1]="center"),b?a[2]=!0:a[2]=!1,a},positionElements:function(a,c,d,e){a=this.getRawNode(a),c=this.getRawNode(c);var g=angular.isDefined(c.offsetWidth)?c.offsetWidth:c.prop("offsetWidth"),h=angular.isDefined(c.offsetHeight)?c.offsetHeight:c.prop("offsetHeight");d=this.parsePlacement(d);var i=e?this.offset(a):this.position(a),j={top:0,left:0,placement:""};if(d[2]){var k=this.viewportOffset(a,e),l=b.getComputedStyle(c),m={width:g+Math.round(Math.abs(this.parseStyle(l.marginLeft)+this.parseStyle(l.marginRight))),height:h+Math.round(Math.abs(this.parseStyle(l.marginTop)+this.parseStyle(l.marginBottom)))};if(d[0]="top"===d[0]&&m.height>k.top&&m.height<=k.bottom?"bottom":"bottom"===d[0]&&m.height>k.bottom&&m.height<=k.top?"top":"left"===d[0]&&m.width>k.left&&m.width<=k.right?"right":"right"===d[0]&&m.width>k.right&&m.width<=k.left?"left":d[0],d[1]="top"===d[1]&&m.height-i.height>k.bottom&&m.height-i.height<=k.top?"bottom":"bottom"===d[1]&&m.height-i.height>k.top&&m.height-i.height<=k.bottom?"top":"left"===d[1]&&m.width-i.width>k.right&&m.width-i.width<=k.left?"right":"right"===d[1]&&m.width-i.width>k.left&&m.width-i.width<=k.right?"left":d[1],"center"===d[1])if(f.vertical.test(d[0])){var n=i.width/2-g/2;k.left+n<0&&m.width-i.width<=k.right?d[1]="left":k.right+n<0&&m.width-i.width<=k.left&&(d[1]="right")}else{var o=i.height/2-m.height/2;k.top+o<0&&m.height-i.height<=k.bottom?d[1]="top":k.bottom+o<0&&m.height-i.height<=k.top&&(d[1]="bottom")}}switch(d[0]){case"top":j.top=i.top-h;break;case"bottom":j.top=i.top+i.height;break;case"left":j.left=i.left-g;break;case"right":j.left=i.left+i.width}switch(d[1]){case"top":j.top=i.top;break;case"bottom":j.top=i.top+i.height-h;break;case"left":j.left=i.left;break;case"right":j.left=i.left+i.width-g;break;case"center":f.vertical.test(d[0])?j.left=i.left+i.width/2-g/2:j.top=i.top+i.height/2-h/2}return j.top=Math.round(j.top),j.left=Math.round(j.left),j.placement="center"===d[1]?d[0]:d[0]+"-"+d[1],j},adjustTop:function(a,b,c,d){return-1!==a.indexOf("top")&&c!==d?{top:b.top-d+"px"}:void 0},positionArrow:function(a,c){a=this.getRawNode(a);var d=a.querySelector(".tooltip-inner, .popover-inner");if(d){var e=angular.element(d).hasClass("tooltip-inner"),g=e?a.querySelector(".tooltip-arrow"):a.querySelector(".arrow");if(g){var h={top:"",bottom:"",left:"",right:""};if(c=this.parsePlacement(c),"center"===c[1])return void angular.element(g).css(h);var i="border-"+c[0]+"-width",j=b.getComputedStyle(g)[i],k="border-";k+=f.vertical.test(c[0])?c[0]+"-"+c[1]:c[1]+"-"+c[0],k+="-radius";var l=b.getComputedStyle(e?d:a)[k];switch(c[0]){case"top":h.bottom=e?"0":"-"+j;break;case"bottom":h.top=e?"0":"-"+j;break;case"left":h.right=e?"0":"-"+j;break;case"right":h.left=e?"0":"-"+j}h[c[1]]=l,angular.element(g).css(h)}}}}}]),angular.module("ui.bootstrap.datepickerPopup",["ui.bootstrap.datepicker","ui.bootstrap.position"]).value("$datepickerPopupLiteralWarning",!0).constant("uibDatepickerPopupConfig",{altInputFormats:[],appendToBody:!1,clearText:"Clear",closeOnDateSelection:!0,closeText:"Done",currentText:"Today",datepickerPopup:"yyyy-MM-dd",datepickerPopupTemplateUrl:"uib/template/datepickerPopup/popup.html",datepickerTemplateUrl:"uib/template/datepicker/datepicker.html",html5Types:{date:"yyyy-MM-dd","datetime-local":"yyyy-MM-ddTHH:mm:ss.sss",month:"yyyy-MM"},onOpenFocus:!0,showButtonBar:!0,placement:"auto bottom-left"}).controller("UibDatepickerPopupController",["$scope","$element","$attrs","$compile","$log","$parse","$window","$document","$rootScope","$uibPosition","dateFilter","uibDateParser","uibDatepickerPopupConfig","$timeout","uibDatepickerConfig","$datepickerPopupLiteralWarning",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){function q(b){var c=l.parse(b,x,a.date);if(isNaN(c))for(var d=0;d"),D.attr({"ng-model":"date","ng-change":"dateSelection(date)","template-url":B}),E=angular.element(D.children()[0]),E.attr("template-url",C),a.datepickerOptions||(a.datepickerOptions={}),K&&"month"===c.type&&(a.datepickerOptions.datepickerMode="month",a.datepickerOptions.minMode="month"),E.attr("datepicker-options","datepickerOptions"),K?G.$formatters.push(function(b){return a.date=l.fromTimezone(b,H.getOption("timezone")),b}):(G.$$parserName="date",G.$validators.date=s,G.$parsers.unshift(r),G.$formatters.push(function(b){return G.$isEmpty(b)?(a.date=b,b):(angular.isNumber(b)&&(b=new Date(b)),a.date=l.fromTimezone(b,H.getOption("timezone")),l.filter(a.date,x))})),G.$viewChangeListeners.push(function(){a.date=q(G.$viewValue)}),b.on("keydown",u),I=d(D)(a),D.remove(),z?h.find("body").append(I):b.after(I),a.$on("$destroy",function(){for(a.isOpen===!0&&(i.$$phase||a.$apply(function(){a.isOpen=!1})),I.remove(),b.off("keydown",u),h.off("click",t),F&&F.off("scroll",v),angular.element(g).off("resize",v);L.length;)L.shift()()})},a.getText=function(b){return a[b+"Text"]||m[b+"Text"]},a.isDisabled=function(b){"today"===b&&(b=l.fromTimezone(new Date,H.getOption("timezone")));var c={};return angular.forEach(["minDate","maxDate"],function(b){a.datepickerOptions[b]?angular.isDate(a.datepickerOptions[b])?c[b]=new Date(a.datepickerOptions[b]):(p&&e.warn("Literal date support has been deprecated, please switch to date object usage"),c[b]=new Date(k(a.datepickerOptions[b],"medium"))):c[b]=null}),a.datepickerOptions&&c.minDate&&a.compare(b,c.minDate)<0||c.maxDate&&a.compare(b,c.maxDate)>0},a.compare=function(a,b){return new Date(a.getFullYear(),a.getMonth(),a.getDate())-new Date(b.getFullYear(),b.getMonth(),b.getDate())},a.dateSelection=function(c){a.date=c;var d=a.date?l.filter(a.date,x):null;b.val(d),G.$setViewValue(d),y&&(a.isOpen=!1,b[0].focus())},a.keydown=function(c){27===c.which&&(c.stopPropagation(),a.isOpen=!1,b[0].focus())},a.select=function(b,c){if(c.stopPropagation(),"today"===b){var d=new Date;angular.isDate(a.date)?(b=new Date(a.date),b.setFullYear(d.getFullYear(),d.getMonth(),d.getDate())):(b=l.fromTimezone(d,H.getOption("timezone")),b.setHours(0,0,0,0))}a.dateSelection(b)},a.close=function(c){c.stopPropagation(),a.isOpen=!1,b[0].focus()},a.disabled=angular.isDefined(c.disabled)||!1,c.ngDisabled&&L.push(a.$parent.$watch(f(c.ngDisabled),function(b){a.disabled=b})),a.$watch("isOpen",function(d){d?a.disabled?a.isOpen=!1:n(function(){v(),A&&a.$broadcast("uib:datepicker.focus"),h.on("click",t);var d=c.popupPlacement?c.popupPlacement:m.placement;z||j.parsePlacement(d)[2]?(F=F||angular.element(j.scrollParent(b)),F&&F.on("scroll",v)):F=null,angular.element(g).on("resize",v)},0,!1):(h.off("click",t),F&&F.off("scroll",v),angular.element(g).off("resize",v))}),a.$on("uib:datepicker.mode",function(){n(v,0,!1)})}]).directive("uibDatepickerPopup",function(){return{require:["ngModel","uibDatepickerPopup"],controller:"UibDatepickerPopupController",scope:{datepickerOptions:"=?",isOpen:"=?",currentText:"@",clearText:"@",closeText:"@"},link:function(a,b,c,d){var e=d[0],f=d[1];f.init(e)}}}).directive("uibDatepickerPopupWrap",function(){return{restrict:"A",transclude:!0,templateUrl:function(a,b){return b.templateUrl||"uib/template/datepickerPopup/popup.html"}}}),angular.module("ui.bootstrap.debounce",[]).factory("$$debounce",["$timeout",function(a){return function(b,c){var d;return function(){var e=this,f=Array.prototype.slice.call(arguments);d&&a.cancel(d),d=a(function(){b.apply(e,f)},c)}}}]),angular.module("ui.bootstrap.multiMap",[]).factory("$$multiMap",function(){return{createNew:function(){var a={};return{entries:function(){return Object.keys(a).map(function(b){return{key:b,value:a[b]}})},get:function(b){return a[b]},hasKey:function(b){return!!a[b]},keys:function(){return Object.keys(a)},put:function(b,c){a[b]||(a[b]=[]),a[b].push(c)},remove:function(b,c){var d=a[b];if(d){var e=d.indexOf(c);-1!==e&&d.splice(e,1),d.length||delete a[b]}}}}}}),angular.module("ui.bootstrap.dropdown",["ui.bootstrap.multiMap","ui.bootstrap.position"]).constant("uibDropdownConfig",{appendToOpenClass:"uib-dropdown-open",openClass:"open"}).service("uibDropdownService",["$document","$rootScope","$$multiMap",function(a,b,c){var d=null,e=c.createNew();this.isOnlyOpen=function(a,b){var c=e.get(b);if(c){var d=c.reduce(function(b,c){return c.scope===a?c:b},{});if(d)return 1===c.length}return!1},this.open=function(b,c,g){if(d||a.on("click",f),d&&d!==b&&(d.isOpen=!1),d=b,g){var h=e.get(g);if(h){var i=h.map(function(a){return a.scope});-1===i.indexOf(b)&&e.put(g,{scope:b})}else e.put(g,{scope:b})}},this.close=function(b,c,g){if(d===b&&(a.off("click",f),a.off("keydown",this.keybindFilter),d=null),g){var h=e.get(g);if(h){var i=h.reduce(function(a,c){return c.scope===b?c:a},{});i&&e.remove(g,i)}}};var f=function(a){if(d&&d.isOpen&&!(a&&"disabled"===d.getAutoClose()||a&&3===a.which)){var c=d.getToggleElement();if(!(a&&c&&c[0].contains(a.target))){var e=d.getDropdownElement();a&&"outsideClick"===d.getAutoClose()&&e&&e[0].contains(a.target)||(d.focusToggleElement(),d.isOpen=!1,b.$$phase||d.$apply())}}};this.keybindFilter=function(a){if(d){var b=d.getDropdownElement(),c=d.getToggleElement(),e=b&&b[0].contains(a.target),g=c&&c[0].contains(a.target);27===a.which?(a.stopPropagation(),d.focusToggleElement(),f()):d.isKeynavEnabled()&&-1!==[38,40].indexOf(a.which)&&d.isOpen&&(e||g)&&(a.preventDefault(),a.stopPropagation(),d.focusDropdownEntry(a.which))}}}]).controller("UibDropdownController",["$scope","$element","$attrs","$parse","uibDropdownConfig","uibDropdownService","$animate","$uibPosition","$document","$compile","$templateRequest",function(a,b,c,d,e,f,g,h,i,j,k){function l(){b.append(o.dropdownMenu)}var m,n,o=this,p=a.$new(),q=e.appendToOpenClass,r=e.openClass,s=angular.noop,t=c.onToggle?d(c.onToggle):angular.noop,u=!1,v=i.find("body");b.addClass("dropdown"),this.init=function(){c.isOpen&&(n=d(c.isOpen),s=n.assign,a.$watch(n,function(a){p.isOpen=!!a})),u=angular.isDefined(c.keyboardNav)},this.toggle=function(a){return p.isOpen=arguments.length?!!a:!p.isOpen,angular.isFunction(s)&&s(p,p.isOpen),p.isOpen},this.isOpen=function(){return p.isOpen},p.getToggleElement=function(){return o.toggleElement},p.getAutoClose=function(){return c.autoClose||"always"},p.getElement=function(){return b},p.isKeynavEnabled=function(){return u},p.focusDropdownEntry=function(a){var c=o.dropdownMenu?angular.element(o.dropdownMenu).find("a"):b.find("ul").eq(0).find("a");switch(a){case 40:angular.isNumber(o.selectedOption)?o.selectedOption=o.selectedOption===c.length-1?o.selectedOption:o.selectedOption+1:o.selectedOption=0;break;case 38:angular.isNumber(o.selectedOption)?o.selectedOption=0===o.selectedOption?0:o.selectedOption-1:o.selectedOption=c.length-1}c[o.selectedOption].focus()},p.getDropdownElement=function(){return o.dropdownMenu},p.focusToggleElement=function(){o.toggleElement&&o.toggleElement[0].focus()},p.$watch("isOpen",function(e,n){var u=null,w=!1;if(angular.isDefined(c.dropdownAppendTo)){var x=d(c.dropdownAppendTo)(p);x&&(u=angular.element(x))}if(angular.isDefined(c.dropdownAppendToBody)){var y=d(c.dropdownAppendToBody)(p);y!==!1&&(w=!0)}if(w&&!u&&(u=v),u&&o.dropdownMenu&&(e?(u.append(o.dropdownMenu),b.on("$destroy",l)):(b.off("$destroy",l),l())),u&&o.dropdownMenu){var z,A,B,C=h.positionElements(b,o.dropdownMenu,"bottom-left",!0),D=0;if(z={top:C.top+"px",display:e?"block":"none"},A=o.dropdownMenu.hasClass("dropdown-menu-right"),A?(z.left="auto",B=h.scrollbarPadding(u),B.heightOverflow&&B.scrollbarWidth&&(D=B.scrollbarWidth),z.right=window.innerWidth-D-(C.left+b.prop("offsetWidth"))+"px"):(z.left=C.left+"px",z.right="auto"),!w){var E=h.offset(u);z.top=C.top-E.top+"px",A?z.right=window.innerWidth-(C.left-E.left+b.prop("offsetWidth"))+"px":z.left=C.left-E.left+"px"}o.dropdownMenu.css(z)}var F=u?u:b,G=u?q:r,H=F.hasClass(G),I=f.isOnlyOpen(a,u);if(H===!e){var J;J=u?I?"removeClass":"addClass":e?"addClass":"removeClass",g[J](F,G).then(function(){angular.isDefined(e)&&e!==n&&t(a,{open:!!e})})}if(e)o.dropdownMenuTemplateUrl?k(o.dropdownMenuTemplateUrl).then(function(a){m=p.$new(),j(a.trim())(m,function(a){var b=a;o.dropdownMenu.replaceWith(b),o.dropdownMenu=b,i.on("keydown",f.keybindFilter)})}):i.on("keydown",f.keybindFilter),p.focusToggleElement(),f.open(p,b,u);else{if(f.close(p,b,u),o.dropdownMenuTemplateUrl){m&&m.$destroy();var K=angular.element('');o.dropdownMenu.replaceWith(K),o.dropdownMenu=K}o.selectedOption=null}angular.isFunction(s)&&s(a,e)})}]).directive("uibDropdown",function(){return{controller:"UibDropdownController",link:function(a,b,c,d){d.init()}}}).directive("uibDropdownMenu",function(){return{restrict:"A",require:"?^uibDropdown",link:function(a,b,c,d){if(d&&!angular.isDefined(c.dropdownNested)){b.addClass("dropdown-menu");var e=c.templateUrl;e&&(d.dropdownMenuTemplateUrl=e),d.dropdownMenu||(d.dropdownMenu=b)}}}}).directive("uibDropdownToggle",function(){return{require:"?^uibDropdown",link:function(a,b,c,d){if(d){b.addClass("dropdown-toggle"),d.toggleElement=b;var e=function(e){e.preventDefault(),b.hasClass("disabled")||c.disabled||a.$apply(function(){d.toggle()})};b.on("click",e),b.attr({"aria-haspopup":!0,"aria-expanded":!1}),a.$watch(d.isOpen,function(a){b.attr("aria-expanded",!!a)}),a.$on("$destroy",function(){b.off("click",e)})}}}}),angular.module("ui.bootstrap.stackedMap",[]).factory("$$stackedMap",function(){return{createNew:function(){var a=[];return{add:function(b,c){a.push({key:b,value:c})},get:function(b){for(var c=0;c-1&&A>a&&(a=A),a}function m(a,b){var c=x.get(a).value,d=c.appendTo;x.remove(a),B=x.top(),B&&(A=parseInt(B.value.modalDomEl.attr("index"),10)),p(c.modalDomEl,c.modalScope,function(){var b=c.openedClass||w;y.remove(b,a);var e=y.hasKey(b);d.toggleClass(b,e),!e&&v&&v.heightOverflow&&v.scrollbarWidth&&(v.originalRight?d.css({paddingRight:v.originalRight+"px"}):d.css({paddingRight:""}),v=null),n(!0)},c.closedDeferred),o(),b&&b.focus?b.focus():d.focus&&d.focus()}function n(a){var b;x.length()>0&&(b=x.top().value,b.modalDomEl.toggleClass(b.windowTopClass||"",a))}function o(){if(t&&-1===l()){var a=u;p(t,u,function(){a=null}),t=void 0,u=void 0}}function p(b,c,d,e){function g(){g.done||(g.done=!0,a.leave(b).then(function(){d&&d(),b.remove(),e&&e.resolve()}),c.$destroy())}var h,i=null,j=function(){return h||(h=f.defer(),i=h.promise),function(){h.resolve()}};return c.$broadcast(z.NOW_CLOSING_EVENT,j),f.when(i).then(g)}function q(a){if(a.isDefaultPrevented())return a;var b=x.top();if(b)switch(a.which){case 27:b.value.keyboard&&(a.preventDefault(),e.$apply(function(){z.dismiss(b.key,"escape key press")}));break;case 9:var c=z.loadFocusElementList(b),d=!1;a.shiftKey?(z.isFocusInFirstItem(a,c)||z.isModalFocused(a,b))&&(d=z.focusLastFocusableElement(c)):z.isFocusInLastItem(a,c)&&(d=z.focusFirstFocusableElement(c)),d&&(a.preventDefault(),a.stopPropagation())}}function r(a,b,c){return!a.value.modalScope.$broadcast("modal.closing",b,c).defaultPrevented}function s(){Array.prototype.forEach.call(document.querySelectorAll("["+C+"]"),function(a){var b=parseInt(a.getAttribute(C),10),c=b-1;a.setAttribute(C,c),c||(a.removeAttribute(C),a.removeAttribute("aria-hidden"))})}var t,u,v,w="modal-open",x=h.createNew(),y=g.createNew(),z={NOW_CLOSING_EVENT:"modal.stack.now-closing"},A=0,B=null,C="data-bootstrap-modal-aria-hidden-count",D="a[href], area[href], input:not([disabled]):not([tabindex='-1']), button:not([disabled]):not([tabindex='-1']),select:not([disabled]):not([tabindex='-1']), textarea:not([disabled]):not([tabindex='-1']), iframe, object, embed, *[tabindex]:not([tabindex='-1']), *[contenteditable=true]",E=/[A-Z]/g;return e.$watch(l,function(a){u&&(u.index=a)}),c.on("keydown",q),e.$on("$destroy",function(){c.off("keydown",q)}),z.open=function(b,f){function g(a){function b(a){var b=a.parent()?a.parent().children():[];return Array.prototype.filter.call(b,function(b){return b!==a[0]})}if(a&&"BODY"!==a[0].tagName)return b(a).forEach(function(a){var b="true"===a.getAttribute("aria-hidden"),c=parseInt(a.getAttribute(C),10);c||(c=b?1:0),a.setAttribute(C,c+1),a.setAttribute("aria-hidden","true")}),g(a.parent())}var h=c[0].activeElement,k=f.openedClass||w;n(!1),B=x.top(),x.add(b,{deferred:f.deferred,renderDeferred:f.renderDeferred,closedDeferred:f.closedDeferred,modalScope:f.scope,backdrop:f.backdrop,keyboard:f.keyboard,openedClass:f.openedClass,windowTopClass:f.windowTopClass,animation:f.animation,appendTo:f.appendTo}),y.put(k,b);var m=f.appendTo,o=l();o>=0&&!t&&(u=e.$new(!0),u.modalOptions=f,u.index=o,t=angular.element(''),t.attr({"class":"modal-backdrop","ng-style":"{'z-index': 1040 + (index && 1 || 0) + index*10}","uib-modal-animation-class":"fade","modal-in-class":"in"}),f.backdropClass&&t.addClass(f.backdropClass),f.animation&&t.attr("modal-animation","true"),d(t)(u),a.enter(t,m),i.isScrollable(m)&&(v=i.scrollbarPadding(m),v.heightOverflow&&v.scrollbarWidth&&m.css({paddingRight:v.right+"px"})));var p;f.component?(p=document.createElement(j(f.component.name)),p=angular.element(p),p.attr({resolve:"$resolve","modal-instance":"$uibModalInstance",close:"$close($value)",dismiss:"$dismiss($value)"})):p=f.content,A=B?parseInt(B.value.modalDomEl.attr("index"),10)+1:0;var q=angular.element('');q.attr({"class":"modal","template-url":f.windowTemplateUrl,"window-top-class":f.windowTopClass,role:"dialog","aria-labelledby":f.ariaLabelledBy,"aria-describedby":f.ariaDescribedBy,size:f.size,index:A,animate:"animate","ng-style":"{'z-index': 1050 + $$topModalIndex*10, display: 'block'}",tabindex:-1,"uib-modal-animation-class":"fade","modal-in-class":"in"}).append(p),f.windowClass&&q.addClass(f.windowClass),f.animation&&q.attr("modal-animation","true"),m.addClass(k),f.scope&&(f.scope.$$topModalIndex=A),a.enter(d(q)(f.scope),m),x.top().value.modalDomEl=q,x.top().value.modalOpener=h,g(q)},z.close=function(a,b){var c=x.get(a);return s(),c&&r(c,b,!0)?(c.value.modalScope.$$uibDestructionScheduled=!0,c.value.deferred.resolve(b),m(a,c.value.modalOpener),!0):!c},z.dismiss=function(a,b){var c=x.get(a);return s(),c&&r(c,b,!1)?(c.value.modalScope.$$uibDestructionScheduled=!0,c.value.deferred.reject(b),m(a,c.value.modalOpener),!0):!c},z.dismissAll=function(a){for(var b=this.getTop();b&&this.dismiss(b.key,a);)b=this.getTop()},z.getTop=function(){return x.top()},z.modalRendered=function(a){var b=x.get(a);b&&b.value.renderDeferred.resolve()},z.focusFirstFocusableElement=function(a){return a.length>0?(a[0].focus(),!0):!1},z.focusLastFocusableElement=function(a){return a.length>0?(a[a.length-1].focus(),!0):!1},z.isModalFocused=function(a,b){if(a&&b){var c=b.value.modalDomEl;if(c&&c.length)return(a.target||a.srcElement)===c[0]}return!1},z.isFocusInFirstItem=function(a,b){return b.length>0?(a.target||a.srcElement)===b[0]:!1},z.isFocusInLastItem=function(a,b){return b.length>0?(a.target||a.srcElement)===b[b.length-1]:!1},z.loadFocusElementList=function(a){if(a){var b=a.value.modalDomEl;if(b&&b.length){var c=b[0].querySelectorAll(D);return c?Array.prototype.filter.call(c,function(a){return k(a)}):c}}},z}]).provider("$uibModal",function(){var a={options:{animation:!0,backdrop:!0,keyboard:!0},$get:["$rootScope","$q","$document","$templateRequest","$controller","$uibResolve","$uibModalStack",function(b,c,d,e,f,g,h){function i(a){return a.template?c.when(a.template):e(angular.isFunction(a.templateUrl)?a.templateUrl():a.templateUrl)}var j={},k=null;return j.getPromiseChain=function(){return k},j.open=function(e){function j(){return q}var l=c.defer(),m=c.defer(),n=c.defer(),o=c.defer(),p={result:l.promise,opened:m.promise,closed:n.promise,rendered:o.promise,close:function(a){return h.close(p,a)},dismiss:function(a){return h.dismiss(p,a)}};if(e=angular.extend({},a.options,e),e.resolve=e.resolve||{},e.appendTo=e.appendTo||d.find("body").eq(0),!e.appendTo.length)throw new Error("appendTo element not found. Make sure that the element passed is in DOM.");if(!e.component&&!e.template&&!e.templateUrl)throw new Error("One of component or template or templateUrl options is required.");var q;q=e.component?c.when(g.resolve(e.resolve,{},null,null)):c.all([i(e),g.resolve(e.resolve,{},null,null)]);var r;return r=k=c.all([k]).then(j,j).then(function(a){function c(b,c,d,e){b.$scope=g,b.$scope.$resolve={},d?b.$scope.$uibModalInstance=p:b.$uibModalInstance=p;var f=c?a[1]:a;angular.forEach(f,function(a,c){e&&(b[c]=a),b.$scope.$resolve[c]=a})}var d=e.scope||b,g=d.$new();g.$close=p.close,g.$dismiss=p.dismiss,g.$on("$destroy",function(){g.$$uibDestructionScheduled||g.$dismiss("$uibUnscheduledDestruction")});var i,j,k={scope:g,deferred:l,renderDeferred:o,closedDeferred:n,animation:e.animation,backdrop:e.backdrop,keyboard:e.keyboard,backdropClass:e.backdropClass,windowTopClass:e.windowTopClass,windowClass:e.windowClass,windowTemplateUrl:e.windowTemplateUrl,ariaLabelledBy:e.ariaLabelledBy,ariaDescribedBy:e.ariaDescribedBy,size:e.size,openedClass:e.openedClass,appendTo:e.appendTo},q={},r={};e.component?(c(q,!1,!0,!1),q.name=e.component,k.component=q):e.controller&&(c(r,!0,!1,!0),j=f(e.controller,r,!0,e.controllerAs),e.controllerAs&&e.bindToController&&(i=j.instance,i.$close=g.$close,i.$dismiss=g.$dismiss,angular.extend(i,{$resolve:r.$scope.$resolve},d)),i=j(),angular.isFunction(i.$onInit)&&i.$onInit()),e.component||(k.content=a[0]),h.open(p,k),m.resolve(!0)},function(a){m.reject(a),l.reject(a)})["finally"](function(){k===r&&(k=null)}),p},j}]};return a}),angular.module("ui.bootstrap.paging",[]).factory("uibPaging",["$parse",function(a){return{create:function(b,c,d){b.setNumPages=d.numPages?a(d.numPages).assign:angular.noop,b.ngModelCtrl={$setViewValue:angular.noop},b._watchers=[],b.init=function(a,e){b.ngModelCtrl=a,b.config=e,a.$render=function(){b.render()},d.itemsPerPage?b._watchers.push(c.$parent.$watch(d.itemsPerPage,function(a){b.itemsPerPage=parseInt(a,10),c.totalPages=b.calculateTotalPages(),b.updatePage()})):b.itemsPerPage=e.itemsPerPage,c.$watch("totalItems",function(a,d){(angular.isDefined(a)||a!==d)&&(c.totalPages=b.calculateTotalPages(),b.updatePage())})},b.calculateTotalPages=function(){var a=b.itemsPerPage<1?1:Math.ceil(c.totalItems/b.itemsPerPage);return Math.max(a||0,1)},b.render=function(){c.page=parseInt(b.ngModelCtrl.$viewValue,10)||1},c.selectPage=function(a,d){d&&d.preventDefault();var e=!c.ngDisabled||!d;e&&c.page!==a&&a>0&&a<=c.totalPages&&(d&&d.target&&d.target.blur(),b.ngModelCtrl.$setViewValue(a),b.ngModelCtrl.$render())},c.getText=function(a){return c[a+"Text"]||b.config[a+"Text"]},c.noPrevious=function(){return 1===c.page},c.noNext=function(){return c.page===c.totalPages},b.updatePage=function(){b.setNumPages(c.$parent,c.totalPages),c.page>c.totalPages?c.selectPage(c.totalPages):b.ngModelCtrl.$render()},c.$on("$destroy",function(){for(;b._watchers.length;)b._watchers.shift()()})}}}]),angular.module("ui.bootstrap.pager",["ui.bootstrap.paging","ui.bootstrap.tabindex"]).controller("UibPagerController",["$scope","$attrs","uibPaging","uibPagerConfig",function(a,b,c,d){
9 | a.align=angular.isDefined(b.align)?a.$parent.$eval(b.align):d.align,c.create(this,a,b)}]).constant("uibPagerConfig",{itemsPerPage:10,previousText:"« Previous",nextText:"Next »",align:!0}).directive("uibPager",["uibPagerConfig",function(a){return{scope:{totalItems:"=",previousText:"@",nextText:"@",ngDisabled:"="},require:["uibPager","?ngModel"],restrict:"A",controller:"UibPagerController",controllerAs:"pager",templateUrl:function(a,b){return b.templateUrl||"uib/template/pager/pager.html"},link:function(b,c,d,e){c.addClass("pager");var f=e[0],g=e[1];g&&f.init(g,a)}}}]),angular.module("ui.bootstrap.pagination",["ui.bootstrap.paging","ui.bootstrap.tabindex"]).controller("UibPaginationController",["$scope","$attrs","$parse","uibPaging","uibPaginationConfig",function(a,b,c,d,e){function f(a,b,c){return{number:a,text:b,active:c}}function g(a,b){var c=[],d=1,e=b,g=angular.isDefined(i)&&b>i;g&&(j?(d=Math.max(a-Math.floor(i/2),1),e=d+i-1,e>b&&(e=b,d=e-i+1)):(d=(Math.ceil(a/i)-1)*i+1,e=Math.min(d+i-1,b)));for(var h=d;e>=h;h++){var n=f(h,m(h),h===a);c.push(n)}if(g&&i>0&&(!j||k||l)){if(d>1){if(!l||d>3){var o=f(d-1,"...",!1);c.unshift(o)}if(l){if(3===d){var p=f(2,"2",!1);c.unshift(p)}var q=f(1,"1",!1);c.unshift(q)}}if(b>e){if(!l||b-2>e){var r=f(e+1,"...",!1);c.push(r)}if(l){if(e===b-2){var s=f(b-1,b-1,!1);c.push(s)}var t=f(b,b,!1);c.push(t)}}}return c}var h=this,i=angular.isDefined(b.maxSize)?a.$parent.$eval(b.maxSize):e.maxSize,j=angular.isDefined(b.rotate)?a.$parent.$eval(b.rotate):e.rotate,k=angular.isDefined(b.forceEllipses)?a.$parent.$eval(b.forceEllipses):e.forceEllipses,l=angular.isDefined(b.boundaryLinkNumbers)?a.$parent.$eval(b.boundaryLinkNumbers):e.boundaryLinkNumbers,m=angular.isDefined(b.pageLabel)?function(c){return a.$parent.$eval(b.pageLabel,{$page:c})}:angular.identity;a.boundaryLinks=angular.isDefined(b.boundaryLinks)?a.$parent.$eval(b.boundaryLinks):e.boundaryLinks,a.directionLinks=angular.isDefined(b.directionLinks)?a.$parent.$eval(b.directionLinks):e.directionLinks,b.$set("role","menu"),d.create(this,a,b),b.maxSize&&h._watchers.push(a.$parent.$watch(c(b.maxSize),function(a){i=parseInt(a,10),h.render()}));var n=this.render;this.render=function(){n(),a.page>0&&a.page<=a.totalPages&&(a.pages=g(a.page,a.totalPages))}}]).constant("uibPaginationConfig",{itemsPerPage:10,boundaryLinks:!1,boundaryLinkNumbers:!1,directionLinks:!0,firstText:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0,forceEllipses:!1}).directive("uibPagination",["$parse","uibPaginationConfig",function(a,b){return{scope:{totalItems:"=",firstText:"@",previousText:"@",nextText:"@",lastText:"@",ngDisabled:"="},require:["uibPagination","?ngModel"],restrict:"A",controller:"UibPaginationController",controllerAs:"pagination",templateUrl:function(a,b){return b.templateUrl||"uib/template/pagination/pagination.html"},link:function(a,c,d,e){c.addClass("pagination");var f=e[0],g=e[1];g&&f.init(g,b)}}}]),angular.module("ui.bootstrap.tooltip",["ui.bootstrap.position","ui.bootstrap.stackedMap"]).provider("$uibTooltip",function(){function a(a){var b=/[A-Z]/g,c="-";return a.replace(b,function(a,b){return(b?c:"")+a.toLowerCase()})}var b={placement:"top",placementClassPrefix:"",animation:!0,popupDelay:0,popupCloseDelay:0,useContentExp:!1},c={mouseenter:"mouseleave",click:"click",outsideClick:"outsideClick",focus:"blur",none:""},d={};this.options=function(a){angular.extend(d,a)},this.setTriggers=function(a){angular.extend(c,a)},this.$get=["$window","$compile","$timeout","$document","$uibPosition","$interpolate","$rootScope","$parse","$$stackedMap",function(e,f,g,h,i,j,k,l,m){function n(a){if(27===a.which){var b=o.top();b&&(b.value.close(),b=null)}}var o=m.createNew();return h.on("keyup",n),k.$on("$destroy",function(){h.off("keyup",n)}),function(e,k,m,n){function p(a){var b=(a||n.trigger||m).split(" "),d=b.map(function(a){return c[a]||a});return{show:b,hide:d}}n=angular.extend({},b,d,n);var q=a(e),r=j.startSymbol(),s=j.endSymbol(),t="';return{compile:function(a,b){var c=f(t);return function(a,b,d,f){function j(){P.isOpen?q():m()}function m(){O&&!a.$eval(d[k+"Enable"])||(u(),x(),P.popupDelay?H||(H=g(r,P.popupDelay,!1)):r())}function q(){s(),P.popupCloseDelay?I||(I=g(t,P.popupCloseDelay,!1)):t()}function r(){return s(),u(),P.content?(v(),void P.$evalAsync(function(){P.isOpen=!0,y(!0),U()})):angular.noop}function s(){H&&(g.cancel(H),H=null),J&&(g.cancel(J),J=null)}function t(){P&&P.$evalAsync(function(){P&&(P.isOpen=!1,y(!1),P.animation?G||(G=g(w,150,!1)):w())})}function u(){I&&(g.cancel(I),I=null),G&&(g.cancel(G),G=null)}function v(){E||(F=P.$new(),E=c(F,function(a){M?h.find("body").append(a):b.after(a)}),o.add(P,{close:t}),z())}function w(){s(),u(),A(),E&&(E.remove(),E=null,K&&g.cancel(K)),o.remove(P),F&&(F.$destroy(),F=null)}function x(){P.title=d[k+"Title"],S?P.content=S(a):P.content=d[e],P.popupClass=d[k+"Class"],P.placement=angular.isDefined(d[k+"Placement"])?d[k+"Placement"]:n.placement;var b=i.parsePlacement(P.placement);L=b[1]?b[0]+"-"+b[1]:b[0];var c=parseInt(d[k+"PopupDelay"],10),f=parseInt(d[k+"PopupCloseDelay"],10);P.popupDelay=isNaN(c)?n.popupDelay:c,P.popupCloseDelay=isNaN(f)?n.popupCloseDelay:f}function y(b){R&&angular.isFunction(R.assign)&&R.assign(a,b)}function z(){T.length=0,S?(T.push(a.$watch(S,function(a){P.content=a,!a&&P.isOpen&&t()})),T.push(F.$watch(function(){Q||(Q=!0,F.$$postDigest(function(){Q=!1,P&&P.isOpen&&U()}))}))):T.push(d.$observe(e,function(a){P.content=a,!a&&P.isOpen?t():U()})),T.push(d.$observe(k+"Title",function(a){P.title=a,P.isOpen&&U()})),T.push(d.$observe(k+"Placement",function(a){P.placement=a?a:n.placement,P.isOpen&&U()}))}function A(){T.length&&(angular.forEach(T,function(a){a()}),T.length=0)}function B(a){P&&P.isOpen&&E&&(b[0].contains(a.target)||E[0].contains(a.target)||q())}function C(a){27===a.which&&q()}function D(){var c=[],e=[],f=a.$eval(d[k+"Trigger"]);V(),angular.isObject(f)?(Object.keys(f).forEach(function(a){c.push(a),e.push(f[a])}),N={show:c,hide:e}):N=p(f),"none"!==N.show&&N.show.forEach(function(a,c){"outsideClick"===a?(b.on("click",j),h.on("click",B)):a===N.hide[c]?b.on(a,j):a&&(b.on(a,m),b.on(N.hide[c],q)),b.on("keypress",C)})}var E,F,G,H,I,J,K,L,M=angular.isDefined(n.appendToBody)?n.appendToBody:!1,N=p(void 0),O=angular.isDefined(d[k+"Enable"]),P=a.$new(!0),Q=!1,R=angular.isDefined(d[k+"IsOpen"])?l(d[k+"IsOpen"]):!1,S=n.useContentExp?l(d[e]):!1,T=[],U=function(){E&&E.html()&&(J||(J=g(function(){var a=i.positionElements(b,E,P.placement,M),c=angular.isDefined(E.offsetHeight)?E.offsetHeight:E.prop("offsetHeight"),d=M?i.offset(b):i.position(b);E.css({top:a.top+"px",left:a.left+"px"});var e=a.placement.split("-");E.hasClass(e[0])||(E.removeClass(L.split("-")[0]),E.addClass(e[0])),E.hasClass(n.placementClassPrefix+a.placement)||(E.removeClass(n.placementClassPrefix+L),E.addClass(n.placementClassPrefix+a.placement)),K=g(function(){var a=angular.isDefined(E.offsetHeight)?E.offsetHeight:E.prop("offsetHeight"),b=i.adjustTop(e,d,c,a);b&&E.css(b),K=null},0,!1),E.hasClass("uib-position-measure")?(i.positionArrow(E,a.placement),E.removeClass("uib-position-measure")):L!==a.placement&&i.positionArrow(E,a.placement),L=a.placement,J=null},0,!1)))};P.origScope=a,P.isOpen=!1,P.contentExp=function(){return P.content},d.$observe("disabled",function(a){a&&s(),a&&P.isOpen&&t()}),R&&a.$watch(R,function(a){P&&!a===P.isOpen&&j()});var V=function(){N.show.forEach(function(a){"outsideClick"===a?b.off("click",j):(b.off(a,m),b.off(a,j)),b.off("keypress",C)}),N.hide.forEach(function(a){"outsideClick"===a?h.off("click",B):b.off(a,q)})};D();var W=a.$eval(d[k+"Animation"]);P.animation=angular.isDefined(W)?!!W:n.animation;var X,Y=k+"AppendToBody";X=Y in d&&void 0===d[Y]?!0:a.$eval(d[Y]),M=angular.isDefined(X)?X:M,a.$on("$destroy",function(){V(),w(),P=null})}}}}}]}).directive("uibTooltipTemplateTransclude",["$animate","$sce","$compile","$templateRequest",function(a,b,c,d){return{link:function(e,f,g){var h,i,j,k=e.$eval(g.tooltipTemplateTranscludeScope),l=0,m=function(){i&&(i.remove(),i=null),h&&(h.$destroy(),h=null),j&&(a.leave(j).then(function(){i=null}),i=j,j=null)};e.$watch(b.parseAsResourceUrl(g.uibTooltipTemplateTransclude),function(b){var g=++l;b?(d(b,!0).then(function(d){if(g===l){var e=k.$new(),i=d,n=c(i)(e,function(b){m(),a.enter(b,f)});h=e,j=n,h.$emit("$includeContentLoaded",b)}},function(){g===l&&(m(),e.$emit("$includeContentError",b))}),e.$emit("$includeContentRequested",b)):m()}),e.$on("$destroy",m)}}}]).directive("uibTooltipClasses",["$uibPosition",function(a){return{restrict:"A",link:function(b,c,d){if(b.placement){var e=a.parsePlacement(b.placement);c.addClass(e[0])}b.popupClass&&c.addClass(b.popupClass),b.animation&&c.addClass(d.tooltipAnimationClass)}}}]).directive("uibTooltipPopup",function(){return{restrict:"A",scope:{content:"@"},templateUrl:"uib/template/tooltip/tooltip-popup.html"}}).directive("uibTooltip",["$uibTooltip",function(a){return a("uibTooltip","tooltip","mouseenter")}]).directive("uibTooltipTemplatePopup",function(){return{restrict:"A",scope:{contentExp:"&",originScope:"&"},templateUrl:"uib/template/tooltip/tooltip-template-popup.html"}}).directive("uibTooltipTemplate",["$uibTooltip",function(a){return a("uibTooltipTemplate","tooltip","mouseenter",{useContentExp:!0})}]).directive("uibTooltipHtmlPopup",function(){return{restrict:"A",scope:{contentExp:"&"},templateUrl:"uib/template/tooltip/tooltip-html-popup.html"}}).directive("uibTooltipHtml",["$uibTooltip",function(a){return a("uibTooltipHtml","tooltip","mouseenter",{useContentExp:!0})}]),angular.module("ui.bootstrap.popover",["ui.bootstrap.tooltip"]).directive("uibPopoverTemplatePopup",function(){return{restrict:"A",scope:{uibTitle:"@",contentExp:"&",originScope:"&"},templateUrl:"uib/template/popover/popover-template.html"}}).directive("uibPopoverTemplate",["$uibTooltip",function(a){return a("uibPopoverTemplate","popover","click",{useContentExp:!0})}]).directive("uibPopoverHtmlPopup",function(){return{restrict:"A",scope:{contentExp:"&",uibTitle:"@"},templateUrl:"uib/template/popover/popover-html.html"}}).directive("uibPopoverHtml",["$uibTooltip",function(a){return a("uibPopoverHtml","popover","click",{useContentExp:!0})}]).directive("uibPopoverPopup",function(){return{restrict:"A",scope:{uibTitle:"@",content:"@"},templateUrl:"uib/template/popover/popover.html"}}).directive("uibPopover",["$uibTooltip",function(a){return a("uibPopover","popover","click")}]),angular.module("ui.bootstrap.progressbar",[]).constant("uibProgressConfig",{animate:!0,max:100}).controller("UibProgressController",["$scope","$attrs","uibProgressConfig",function(a,b,c){function d(){return angular.isDefined(a.maxParam)?a.maxParam:c.max}var e=this,f=angular.isDefined(b.animate)?a.$parent.$eval(b.animate):c.animate;this.bars=[],a.max=d(),this.addBar=function(a,b,c){f||b.css({transition:"none"}),this.bars.push(a),a.max=d(),a.title=c&&angular.isDefined(c.title)?c.title:"progressbar",a.$watch("value",function(b){a.recalculatePercentage()}),a.recalculatePercentage=function(){var b=e.bars.reduce(function(a,b){return b.percent=+(100*b.value/b.max).toFixed(2),a+b.percent},0);b>100&&(a.percent-=b-100)},a.$on("$destroy",function(){b=null,e.removeBar(a)})},this.removeBar=function(a){this.bars.splice(this.bars.indexOf(a),1),this.bars.forEach(function(a){a.recalculatePercentage()})},a.$watch("maxParam",function(a){e.bars.forEach(function(a){a.max=d(),a.recalculatePercentage()})})}]).directive("uibProgress",function(){return{replace:!0,transclude:!0,controller:"UibProgressController",require:"uibProgress",scope:{maxParam:"=?max"},templateUrl:"uib/template/progressbar/progress.html"}}).directive("uibBar",function(){return{replace:!0,transclude:!0,require:"^uibProgress",scope:{value:"=",type:"@"},templateUrl:"uib/template/progressbar/bar.html",link:function(a,b,c,d){d.addBar(a,b,c)}}}).directive("uibProgressbar",function(){return{replace:!0,transclude:!0,controller:"UibProgressController",scope:{value:"=",maxParam:"=?max",type:"@"},templateUrl:"uib/template/progressbar/progressbar.html",link:function(a,b,c,d){d.addBar(a,angular.element(b.children()[0]),{title:c.title})}}}),angular.module("ui.bootstrap.rating",[]).constant("uibRatingConfig",{max:5,stateOn:null,stateOff:null,enableReset:!0,titles:["one","two","three","four","five"]}).controller("UibRatingController",["$scope","$attrs","uibRatingConfig",function(a,b,c){var d={$setViewValue:angular.noop},e=this;this.init=function(e){d=e,d.$render=this.render,d.$formatters.push(function(a){return angular.isNumber(a)&&a<<0!==a&&(a=Math.round(a)),a}),this.stateOn=angular.isDefined(b.stateOn)?a.$parent.$eval(b.stateOn):c.stateOn,this.stateOff=angular.isDefined(b.stateOff)?a.$parent.$eval(b.stateOff):c.stateOff,this.enableReset=angular.isDefined(b.enableReset)?a.$parent.$eval(b.enableReset):c.enableReset;var f=angular.isDefined(b.titles)?a.$parent.$eval(b.titles):c.titles;this.titles=angular.isArray(f)&&f.length>0?f:c.titles;var g=angular.isDefined(b.ratingStates)?a.$parent.$eval(b.ratingStates):new Array(angular.isDefined(b.max)?a.$parent.$eval(b.max):c.max);a.range=this.buildTemplateObjects(g)},this.buildTemplateObjects=function(a){for(var b=0,c=a.length;c>b;b++)a[b]=angular.extend({index:b},{stateOn:this.stateOn,stateOff:this.stateOff,title:this.getTitle(b)},a[b]);return a},this.getTitle=function(a){return a>=this.titles.length?a+1:this.titles[a]},a.rate=function(b){if(!a.readonly&&b>=0&&b<=a.range.length){var c=e.enableReset&&d.$viewValue===b?0:b;d.$setViewValue(c),d.$render()}},a.enter=function(b){a.readonly||(a.value=b),a.onHover({value:b})},a.reset=function(){a.value=d.$viewValue,a.onLeave()},a.onKeydown=function(b){/(37|38|39|40)/.test(b.which)&&(b.preventDefault(),b.stopPropagation(),a.rate(a.value+(38===b.which||39===b.which?1:-1)))},this.render=function(){a.value=d.$viewValue,a.title=e.getTitle(a.value-1)}}]).directive("uibRating",function(){return{require:["uibRating","ngModel"],restrict:"A",scope:{readonly:"=?readOnly",onHover:"&",onLeave:"&"},controller:"UibRatingController",templateUrl:"uib/template/rating/rating.html",link:function(a,b,c,d){var e=d[0],f=d[1];e.init(f)}}}),angular.module("ui.bootstrap.tabs",[]).controller("UibTabsetController",["$scope",function(a){function b(a){for(var b=0;bb.index?1:a.index0&&13>b:b>=0&&24>b;return c&&""!==a.hours?(a.showMeridian&&(12===b&&(b=0),a.meridian===y[1]&&(b+=12)),b):void 0}function i(){var b=+a.minutes,c=b>=0&&60>b;return c&&""!==a.minutes?b:void 0}function j(){var b=+a.seconds;return b>=0&&60>b?b:void 0}function k(a,b){return null===a?"":angular.isDefined(a)&&a.toString().length<2&&!b?"0"+a:a.toString()}function l(a){m(),x.$setViewValue(new Date(v)),n(a)}function m(){s&&s.$setValidity("hours",!0),t&&t.$setValidity("minutes",!0),u&&u.$setValidity("seconds",!0),x.$setValidity("time",!0),a.invalidHours=!1,a.invalidMinutes=!1,a.invalidSeconds=!1}function n(b){if(x.$modelValue){var c=v.getHours(),d=v.getMinutes(),e=v.getSeconds();a.showMeridian&&(c=0===c||12===c?12:c%12),a.hours="h"===b?c:k(c,!z),"m"!==b&&(a.minutes=k(d)),a.meridian=v.getHours()<12?y[0]:y[1],"s"!==b&&(a.seconds=k(e)),a.meridian=v.getHours()<12?y[0]:y[1]}else a.hours=null,a.minutes=null,a.seconds=null,a.meridian=y[0]}function o(a){v=q(v,a),l()}function p(a,b){return q(a,60*b)}function q(a,b){var c=new Date(a.getTime()+1e3*b),d=new Date(a);return d.setHours(c.getHours(),c.getMinutes(),c.getSeconds()),d}function r(){return(null===a.hours||""===a.hours)&&(null===a.minutes||""===a.minutes)&&(!a.showSeconds||a.showSeconds&&(null===a.seconds||""===a.seconds))}var s,t,u,v=new Date,w=[],x={$setViewValue:angular.noop},y=angular.isDefined(c.meridians)?a.$parent.$eval(c.meridians):g.meridians||f.DATETIME_FORMATS.AMPMS,z=angular.isDefined(c.padHours)?a.$parent.$eval(c.padHours):!0;a.tabindex=angular.isDefined(c.tabindex)?c.tabindex:0,b.removeAttr("tabindex"),this.init=function(b,d){x=b,x.$render=this.render,x.$formatters.unshift(function(a){return a?new Date(a):null});var e=d.eq(0),f=d.eq(1),h=d.eq(2);s=e.controller("ngModel"),t=f.controller("ngModel"),u=h.controller("ngModel");var i=angular.isDefined(c.mousewheel)?a.$parent.$eval(c.mousewheel):g.mousewheel;i&&this.setupMousewheelEvents(e,f,h);var j=angular.isDefined(c.arrowkeys)?a.$parent.$eval(c.arrowkeys):g.arrowkeys;j&&this.setupArrowkeyEvents(e,f,h),a.readonlyInput=angular.isDefined(c.readonlyInput)?a.$parent.$eval(c.readonlyInput):g.readonlyInput,this.setupInputEvents(e,f,h)};var A=g.hourStep;c.hourStep&&w.push(a.$parent.$watch(d(c.hourStep),function(a){A=+a}));var B=g.minuteStep;c.minuteStep&&w.push(a.$parent.$watch(d(c.minuteStep),function(a){B=+a}));var C;w.push(a.$parent.$watch(d(c.min),function(a){var b=new Date(a);C=isNaN(b)?void 0:b}));var D;w.push(a.$parent.$watch(d(c.max),function(a){var b=new Date(a);D=isNaN(b)?void 0:b}));var E=!1;c.ngDisabled&&w.push(a.$parent.$watch(d(c.ngDisabled),function(a){E=a})),a.noIncrementHours=function(){var a=p(v,60*A);return E||a>D||v>a&&C>a},a.noDecrementHours=function(){var a=p(v,60*-A);return E||C>a||a>v&&a>D},a.noIncrementMinutes=function(){var a=p(v,B);return E||a>D||v>a&&C>a},a.noDecrementMinutes=function(){var a=p(v,-B);return E||C>a||a>v&&a>D},a.noIncrementSeconds=function(){var a=q(v,F);return E||a>D||v>a&&C>a},a.noDecrementSeconds=function(){var a=q(v,-F);return E||C>a||a>v&&a>D},a.noToggleMeridian=function(){return v.getHours()<12?E||p(v,720)>D:E||p(v,-720)0};b.on("mousewheel wheel",function(b){E||a.$apply(e(b)?a.incrementHours():a.decrementHours()),b.preventDefault()}),c.on("mousewheel wheel",function(b){E||a.$apply(e(b)?a.incrementMinutes():a.decrementMinutes()),b.preventDefault()}),d.on("mousewheel wheel",function(b){E||a.$apply(e(b)?a.incrementSeconds():a.decrementSeconds()),b.preventDefault()})},this.setupArrowkeyEvents=function(b,c,d){b.on("keydown",function(b){E||(38===b.which?(b.preventDefault(),a.incrementHours(),a.$apply()):40===b.which&&(b.preventDefault(),a.decrementHours(),a.$apply()))}),c.on("keydown",function(b){E||(38===b.which?(b.preventDefault(),a.incrementMinutes(),a.$apply()):40===b.which&&(b.preventDefault(),a.decrementMinutes(),a.$apply()))}),d.on("keydown",function(b){E||(38===b.which?(b.preventDefault(),a.incrementSeconds(),a.$apply()):40===b.which&&(b.preventDefault(),a.decrementSeconds(),a.$apply()))})},this.setupInputEvents=function(b,c,d){if(a.readonlyInput)return a.updateHours=angular.noop,a.updateMinutes=angular.noop,void(a.updateSeconds=angular.noop);var e=function(b,c,d){x.$setViewValue(null),x.$setValidity("time",!1),angular.isDefined(b)&&(a.invalidHours=b,s&&s.$setValidity("hours",!1)),angular.isDefined(c)&&(a.invalidMinutes=c,t&&t.$setValidity("minutes",!1)),angular.isDefined(d)&&(a.invalidSeconds=d,u&&u.$setValidity("seconds",!1))};a.updateHours=function(){var a=h(),b=i();x.$setDirty(),angular.isDefined(a)&&angular.isDefined(b)?(v.setHours(a),v.setMinutes(b),C>v||v>D?e(!0):l("h")):e(!0)},b.on("blur",function(b){x.$setTouched(),r()?m():null===a.hours||""===a.hours?e(!0):!a.invalidHours&&a.hours<10&&a.$apply(function(){a.hours=k(a.hours,!z)})}),a.updateMinutes=function(){var a=i(),b=h();x.$setDirty(),angular.isDefined(a)&&angular.isDefined(b)?(v.setHours(b),v.setMinutes(a),C>v||v>D?e(void 0,!0):l("m")):e(void 0,!0)},c.on("blur",function(b){x.$setTouched(),r()?m():null===a.minutes?e(void 0,!0):!a.invalidMinutes&&a.minutes<10&&a.$apply(function(){a.minutes=k(a.minutes)})}),a.updateSeconds=function(){var a=j();x.$setDirty(),angular.isDefined(a)?(v.setSeconds(a),l("s")):e(void 0,void 0,!0)},d.on("blur",function(b){r()?m():!a.invalidSeconds&&a.seconds<10&&a.$apply(function(){a.seconds=k(a.seconds)})})},this.render=function(){var b=x.$viewValue;isNaN(b)?(x.$setValidity("time",!1),e.error('Timepicker 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.')):(b&&(v=b),C>v||v>D?(x.$setValidity("time",!1),a.invalidHours=!0,a.invalidMinutes=!0):m(),n())},a.showSpinners=angular.isDefined(c.showSpinners)?a.$parent.$eval(c.showSpinners):g.showSpinners,a.incrementHours=function(){a.noIncrementHours()||o(60*A*60)},a.decrementHours=function(){a.noDecrementHours()||o(60*-A*60)},a.incrementMinutes=function(){a.noIncrementMinutes()||o(60*B)},a.decrementMinutes=function(){a.noDecrementMinutes()||o(60*-B)},a.incrementSeconds=function(){a.noIncrementSeconds()||o(F)},a.decrementSeconds=function(){a.noDecrementSeconds()||o(-F)},a.toggleMeridian=function(){var b=i(),c=h();a.noToggleMeridian()||(angular.isDefined(b)&&angular.isDefined(c)?o(720*(v.getHours()<12?60:-60)):a.meridian=a.meridian===y[0]?y[1]:y[0])},a.blur=function(){x.$setTouched()},a.$on("$destroy",function(){for(;w.length;)w.shift()()})}]).directive("uibTimepicker",["uibTimepickerConfig",function(a){return{require:["uibTimepicker","?^ngModel"],restrict:"A",controller:"UibTimepickerController",controllerAs:"timepicker",scope:{},templateUrl:function(b,c){return c.templateUrl||a.templateUrl},link:function(a,b,c,d){var e=d[0],f=d[1];f&&e.init(f,b.find("input"))}}}]),angular.module("ui.bootstrap.typeahead",["ui.bootstrap.debounce","ui.bootstrap.position"]).factory("uibTypeaheadParser",["$parse",function(a){var b=/^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+([\s\S]+?)$/;return{parse:function(c){var d=c.match(b);if(!d)throw new Error('Expected typeahead specification in form of "_modelValue_ (as _label_)? for _item_ in _collection_" but got "'+c+'".');return{itemName:d[3],source:a(d[4]),viewMapper:a(d[2]||d[1]),modelMapper:a(d[1])}}}}]).controller("UibTypeaheadController",["$scope","$element","$attrs","$compile","$parse","$q","$timeout","$document","$window","$rootScope","$$debounce","$uibPosition","uibTypeaheadParser",function(a,b,c,d,e,f,g,h,i,j,k,l,m){function n(){P.moveInProgress||(P.moveInProgress=!0,P.$digest()),$()}function o(){P.position=F?l.offset(b):l.position(b),P.position.top+=b.prop("offsetHeight")}function p(a){var b;return angular.version.minor<6?(b=a.$options||{},b.getOption=function(a){return b[a]}):b=a.$options,b}var q,r,s=[9,13,27,38,40],t=200,u=a.$eval(c.typeaheadMinLength);u||0===u||(u=1),a.$watch(c.typeaheadMinLength,function(a){u=a||0===a?a:1});var v=a.$eval(c.typeaheadWaitMs)||0,w=a.$eval(c.typeaheadEditable)!==!1;a.$watch(c.typeaheadEditable,function(a){w=a!==!1});var x,y,z=e(c.typeaheadLoading).assign||angular.noop,A=c.typeaheadShouldSelect?e(c.typeaheadShouldSelect):function(a,b){var c=b.$event;return 13===c.which||9===c.which},B=e(c.typeaheadOnSelect),C=angular.isDefined(c.typeaheadSelectOnBlur)?a.$eval(c.typeaheadSelectOnBlur):!1,D=e(c.typeaheadNoResults).assign||angular.noop,E=c.typeaheadInputFormatter?e(c.typeaheadInputFormatter):void 0,F=c.typeaheadAppendToBody?a.$eval(c.typeaheadAppendToBody):!1,G=c.typeaheadAppendTo?a.$eval(c.typeaheadAppendTo):null,H=a.$eval(c.typeaheadFocusFirst)!==!1,I=c.typeaheadSelectOnExact?a.$eval(c.typeaheadSelectOnExact):!1,J=e(c.typeaheadIsOpen).assign||angular.noop,K=a.$eval(c.typeaheadShowHint)||!1,L=e(c.ngModel),M=e(c.ngModel+"($$$p)"),N=function(b,c){return angular.isFunction(L(a))&&r.getOption("getterSetter")?M(b,{$$$p:c}):L.assign(b,c)},O=m.parse(c.uibTypeahead),P=a.$new(),Q=a.$on("$destroy",function(){P.$destroy()});P.$on("$destroy",Q);var R="typeahead-"+P.$id+"-"+Math.floor(1e4*Math.random());b.attr({"aria-autocomplete":"list","aria-expanded":!1,"aria-owns":R});var S,T;K&&(S=angular.element(""),S.css("position","relative"),b.after(S),T=b.clone(),T.attr("placeholder",""),T.attr("tabindex","-1"),T.val(""),T.css({position:"absolute",top:"0px",left:"0px","border-color":"transparent","box-shadow":"none",opacity:1,background:"none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255)",color:"#999"}),b.css({position:"relative","vertical-align":"top","background-color":"transparent"}),T.attr("id")&&T.removeAttr("id"),S.append(T),T.after(b));var U=angular.element("");U.attr({id:R,matches:"matches",active:"activeIdx",select:"select(activeIdx, evt)","move-in-progress":"moveInProgress",query:"query",position:"position","assign-is-open":"assignIsOpen(isOpen)",debounce:"debounceUpdate"}),angular.isDefined(c.typeaheadTemplateUrl)&&U.attr("template-url",c.typeaheadTemplateUrl),angular.isDefined(c.typeaheadPopupTemplateUrl)&&U.attr("popup-template-url",c.typeaheadPopupTemplateUrl);var V=function(){K&&T.val("")},W=function(){P.matches=[],P.activeIdx=-1,b.attr("aria-expanded",!1),V()},X=function(a){return R+"-option-"+a};P.$watch("activeIdx",function(a){0>a?b.removeAttr("aria-activedescendant"):b.attr("aria-activedescendant",X(a))});var Y=function(a,b){return P.matches.length>b&&a?a.toUpperCase()===P.matches[b].label.toUpperCase():!1},Z=function(c,d){var e={$viewValue:c};z(a,!0),D(a,!1),f.when(O.source(a,e)).then(function(f){var g=c===q.$viewValue;if(g&&x)if(f&&f.length>0){P.activeIdx=H?0:-1,D(a,!1),P.matches.length=0;for(var h=0;h0&&i.slice(0,c.length).toUpperCase()===c.toUpperCase()?T.val(c+i.slice(c.length)):T.val("")}}else W(),D(a,!0);g&&z(a,!1)},function(){W(),z(a,!1),D(a,!0)})};F&&(angular.element(i).on("resize",n),h.find("body").on("scroll",n));var $=k(function(){P.matches.length&&o(),P.moveInProgress=!1},t);P.moveInProgress=!1,P.query=void 0;var _,aa=function(a){_=g(function(){Z(a)},v)},ba=function(){_&&g.cancel(_)};W(),P.assignIsOpen=function(b){J(a,b)},P.select=function(d,e){var f,h,i={};y=!0,i[O.itemName]=h=P.matches[d].model,f=O.modelMapper(a,i),N(a,f),q.$setValidity("editable",!0),q.$setValidity("parse",!0),B(a,{$item:h,$model:f,$label:O.viewMapper(a,i),$event:e}),W(),P.$eval(c.typeaheadFocusOnSelect)!==!1&&g(function(){b[0].focus()},0,!1)},b.on("keydown",function(b){if(0!==P.matches.length&&-1!==s.indexOf(b.which)){var c=A(a,{$event:b});if(-1===P.activeIdx&&c||9===b.which&&b.shiftKey)return W(),void P.$digest();b.preventDefault();var d;switch(b.which){case 27:b.stopPropagation(),W(),a.$digest();break;case 38:P.activeIdx=(P.activeIdx>0?P.activeIdx:P.matches.length)-1,P.$digest(),d=U[0].querySelectorAll(".uib-typeahead-match")[P.activeIdx],d.parentNode.scrollTop=d.offsetTop;break;case 40:P.activeIdx=(P.activeIdx+1)%P.matches.length,P.$digest(),d=U[0].querySelectorAll(".uib-typeahead-match")[P.activeIdx],d.parentNode.scrollTop=d.offsetTop;break;default:c&&P.$apply(function(){angular.isNumber(P.debounceUpdate)||angular.isObject(P.debounceUpdate)?k(function(){P.select(P.activeIdx,b)},angular.isNumber(P.debounceUpdate)?P.debounceUpdate:P.debounceUpdate["default"]):P.select(P.activeIdx,b)})}}}),b.on("focus",function(a){x=!0,0!==u||q.$viewValue||g(function(){Z(q.$viewValue,a)},0)}),b.on("blur",function(a){C&&P.matches.length&&-1!==P.activeIdx&&!y&&(y=!0,P.$apply(function(){angular.isObject(P.debounceUpdate)&&angular.isNumber(P.debounceUpdate.blur)?k(function(){P.select(P.activeIdx,a)},P.debounceUpdate.blur):P.select(P.activeIdx,a)})),!w&&q.$error.editable&&(q.$setViewValue(),P.$apply(function(){q.$setValidity("editable",!0),q.$setValidity("parse",!0)}),b.val("")),x=!1,y=!1});var ca=function(c){b[0]!==c.target&&3!==c.which&&0!==P.matches.length&&(W(),j.$$phase||a.$digest())};h.on("click",ca),a.$on("$destroy",function(){h.off("click",ca),(F||G)&&da.remove(),F&&(angular.element(i).off("resize",n),h.find("body").off("scroll",n)),U.remove(),K&&S.remove()});var da=d(U)(P);F?h.find("body").append(da):G?angular.element(G).eq(0).append(da):b.after(da),
10 | this.init=function(b){q=b,r=p(q),P.debounceUpdate=e(r.getOption("debounce"))(a),q.$parsers.unshift(function(b){return x=!0,0===u||b&&b.length>=u?v>0?(ba(),aa(b)):Z(b):(z(a,!1),ba(),W()),w?b:b?void q.$setValidity("editable",!1):(q.$setValidity("editable",!0),null)}),q.$formatters.push(function(b){var c,d,e={};return w||q.$setValidity("editable",!0),E?(e.$model=b,E(a,e)):(e[O.itemName]=b,c=O.viewMapper(a,e),e[O.itemName]=void 0,d=O.viewMapper(a,e),c!==d?c:b)})}}]).directive("uibTypeahead",function(){return{controller:"UibTypeaheadController",require:["ngModel","uibTypeahead"],link:function(a,b,c,d){d[1].init(d[0])}}}).directive("uibTypeaheadPopup",["$$debounce",function(a){return{scope:{matches:"=",query:"=",active:"=",position:"&",moveInProgress:"=",select:"&",assignIsOpen:"&",debounce:"&"},replace:!0,templateUrl:function(a,b){return b.popupTemplateUrl||"uib/template/typeahead/typeahead-popup.html"},link:function(b,c,d){b.templateUrl=d.templateUrl,b.isOpen=function(){var a=b.matches.length>0;return b.assignIsOpen({isOpen:a}),a},b.isActive=function(a){return b.active===a},b.selectActive=function(a){b.active=a},b.selectMatch=function(c,d){var e=b.debounce();angular.isNumber(e)||angular.isObject(e)?a(function(){b.select({activeIdx:c,evt:d})},angular.isNumber(e)?e:e["default"]):b.select({activeIdx:c,evt:d})}}}}]).directive("uibTypeaheadMatch",["$templateRequest","$compile","$parse",function(a,b,c){return{scope:{index:"=",match:"=",query:"="},link:function(d,e,f){var g=c(f.templateUrl)(d.$parent)||"uib/template/typeahead/typeahead-match.html";a(g).then(function(a){var c=angular.element(a.trim());e.replaceWith(c),b(c)(d)})}}}]).filter("uibTypeaheadHighlight",["$sce","$injector","$log",function(a,b,c){function d(a){return a.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}function e(a){return/<.*>/g.test(a)}var f;return f=b.has("$sanitize"),function(b,g){return!f&&e(b)&&c.warn("Unsafe use of typeahead please use ngSanitize"),b=g?(""+b).replace(new RegExp(d(g),"gi"),"$&"):b,f||(b=a.trustAsHtml(b)),b}}]),angular.module("ui.bootstrap.carousel").run(function(){!angular.$$csp().noInlineStyle&&!angular.$$uibCarouselCss&&angular.element(document).find("head").prepend(''),angular.$$uibCarouselCss=!0}),angular.module("ui.bootstrap.datepicker").run(function(){!angular.$$csp().noInlineStyle&&!angular.$$uibDatepickerCss&&angular.element(document).find("head").prepend(''),angular.$$uibDatepickerCss=!0}),angular.module("ui.bootstrap.position").run(function(){!angular.$$csp().noInlineStyle&&!angular.$$uibPositionCss&&angular.element(document).find("head").prepend(''),angular.$$uibPositionCss=!0}),angular.module("ui.bootstrap.datepickerPopup").run(function(){!angular.$$csp().noInlineStyle&&!angular.$$uibDatepickerpopupCss&&angular.element(document).find("head").prepend(''),angular.$$uibDatepickerpopupCss=!0}),angular.module("ui.bootstrap.tooltip").run(function(){!angular.$$csp().noInlineStyle&&!angular.$$uibTooltipCss&&angular.element(document).find("head").prepend(''),angular.$$uibTooltipCss=!0}),angular.module("ui.bootstrap.timepicker").run(function(){!angular.$$csp().noInlineStyle&&!angular.$$uibTimepickerCss&&angular.element(document).find("head").prepend(''),angular.$$uibTimepickerCss=!0}),angular.module("ui.bootstrap.typeahead").run(function(){!angular.$$csp().noInlineStyle&&!angular.$$uibTypeaheadCss&&angular.element(document).find("head").prepend(''),angular.$$uibTypeaheadCss=!0});
--------------------------------------------------------------------------------
/client/views/index.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 | Realtime Private Chat using Angular, Nodejs and Mysql
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/client/views/pages/auth.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
63 |
64 |
65 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/client/views/pages/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Chat History With {{data.selectedFriendName}}
20 |
21 |
22 |
23 | -
25 | {{messagePacket.message}}
26 |
27 |
28 |
29 |
30 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
Chat list
44 |
45 |
46 | - {{friend.username}}
51 |
52 |
53 | No one is online to chat, ask someone to Login.
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "private-chat-app-using-angularjs-nodejs-and-mongodb",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.4",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
10 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
11 | "requires": {
12 | "mime-types": "2.1.17",
13 | "negotiator": "0.6.1"
14 | }
15 | },
16 | "acorn": {
17 | "version": "5.3.0",
18 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz",
19 | "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==",
20 | "dev": true
21 | },
22 | "acorn-jsx": {
23 | "version": "3.0.1",
24 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
25 | "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
26 | "dev": true,
27 | "requires": {
28 | "acorn": "3.3.0"
29 | },
30 | "dependencies": {
31 | "acorn": {
32 | "version": "3.3.0",
33 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
34 | "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
35 | "dev": true
36 | }
37 | }
38 | },
39 | "after": {
40 | "version": "0.8.2",
41 | "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
42 | "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
43 | },
44 | "ajv": {
45 | "version": "5.5.2",
46 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
47 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
48 | "dev": true,
49 | "requires": {
50 | "co": "4.6.0",
51 | "fast-deep-equal": "1.0.0",
52 | "fast-json-stable-stringify": "2.0.0",
53 | "json-schema-traverse": "0.3.1"
54 | }
55 | },
56 | "ajv-keywords": {
57 | "version": "2.1.1",
58 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
59 | "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
60 | "dev": true
61 | },
62 | "ansi-escapes": {
63 | "version": "3.0.0",
64 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz",
65 | "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==",
66 | "dev": true
67 | },
68 | "ansi-regex": {
69 | "version": "2.1.1",
70 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
71 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
72 | "dev": true
73 | },
74 | "ansi-styles": {
75 | "version": "2.2.1",
76 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
77 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
78 | "dev": true
79 | },
80 | "argparse": {
81 | "version": "1.0.9",
82 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
83 | "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
84 | "dev": true,
85 | "requires": {
86 | "sprintf-js": "1.0.3"
87 | }
88 | },
89 | "array-flatten": {
90 | "version": "1.1.1",
91 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
92 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
93 | },
94 | "array-union": {
95 | "version": "1.0.2",
96 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
97 | "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
98 | "dev": true,
99 | "requires": {
100 | "array-uniq": "1.0.3"
101 | }
102 | },
103 | "array-uniq": {
104 | "version": "1.0.3",
105 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
106 | "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
107 | "dev": true
108 | },
109 | "arraybuffer.slice": {
110 | "version": "0.0.7",
111 | "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
112 | "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
113 | },
114 | "arrify": {
115 | "version": "1.0.1",
116 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
117 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
118 | "dev": true
119 | },
120 | "async-limiter": {
121 | "version": "1.0.0",
122 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
123 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
124 | },
125 | "babel-code-frame": {
126 | "version": "6.26.0",
127 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
128 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
129 | "dev": true,
130 | "requires": {
131 | "chalk": "1.1.3",
132 | "esutils": "2.0.2",
133 | "js-tokens": "3.0.2"
134 | },
135 | "dependencies": {
136 | "chalk": {
137 | "version": "1.1.3",
138 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
139 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
140 | "dev": true,
141 | "requires": {
142 | "ansi-styles": "2.2.1",
143 | "escape-string-regexp": "1.0.5",
144 | "has-ansi": "2.0.0",
145 | "strip-ansi": "3.0.1",
146 | "supports-color": "2.0.0"
147 | }
148 | },
149 | "strip-ansi": {
150 | "version": "3.0.1",
151 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
152 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
153 | "dev": true,
154 | "requires": {
155 | "ansi-regex": "2.1.1"
156 | }
157 | }
158 | }
159 | },
160 | "backo2": {
161 | "version": "1.0.2",
162 | "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
163 | "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
164 | },
165 | "balanced-match": {
166 | "version": "1.0.0",
167 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
168 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
169 | "dev": true
170 | },
171 | "base64-arraybuffer": {
172 | "version": "0.1.5",
173 | "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
174 | "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
175 | },
176 | "base64id": {
177 | "version": "1.0.0",
178 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
179 | "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY="
180 | },
181 | "better-assert": {
182 | "version": "1.0.2",
183 | "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
184 | "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
185 | "requires": {
186 | "callsite": "1.0.0"
187 | }
188 | },
189 | "bignumber.js": {
190 | "version": "4.0.4",
191 | "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.0.4.tgz",
192 | "integrity": "sha512-LDXpJKVzEx2/OqNbG9mXBNvHuiRL4PzHCGfnANHMJ+fv68Ads3exDVJeGDJws+AoNEuca93bU3q+S0woeUaCdg=="
193 | },
194 | "blob": {
195 | "version": "0.0.4",
196 | "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
197 | "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE="
198 | },
199 | "bluebird": {
200 | "version": "3.5.1",
201 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
202 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
203 | },
204 | "body-parser": {
205 | "version": "1.18.2",
206 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
207 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
208 | "requires": {
209 | "bytes": "3.0.0",
210 | "content-type": "1.0.4",
211 | "debug": "2.6.9",
212 | "depd": "1.1.2",
213 | "http-errors": "1.6.2",
214 | "iconv-lite": "0.4.19",
215 | "on-finished": "2.3.0",
216 | "qs": "6.5.1",
217 | "raw-body": "2.3.2",
218 | "type-is": "1.6.15"
219 | }
220 | },
221 | "brace-expansion": {
222 | "version": "1.1.8",
223 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
224 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
225 | "dev": true,
226 | "requires": {
227 | "balanced-match": "1.0.0",
228 | "concat-map": "0.0.1"
229 | }
230 | },
231 | "bytes": {
232 | "version": "3.0.0",
233 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
234 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
235 | },
236 | "caller-path": {
237 | "version": "0.1.0",
238 | "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
239 | "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
240 | "dev": true,
241 | "requires": {
242 | "callsites": "0.2.0"
243 | }
244 | },
245 | "callsite": {
246 | "version": "1.0.0",
247 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
248 | "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA="
249 | },
250 | "callsites": {
251 | "version": "0.2.0",
252 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
253 | "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
254 | "dev": true
255 | },
256 | "chalk": {
257 | "version": "2.3.0",
258 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
259 | "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
260 | "dev": true,
261 | "requires": {
262 | "ansi-styles": "3.2.0",
263 | "escape-string-regexp": "1.0.5",
264 | "supports-color": "4.5.0"
265 | },
266 | "dependencies": {
267 | "ansi-styles": {
268 | "version": "3.2.0",
269 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
270 | "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
271 | "dev": true,
272 | "requires": {
273 | "color-convert": "1.9.1"
274 | }
275 | },
276 | "supports-color": {
277 | "version": "4.5.0",
278 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
279 | "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
280 | "dev": true,
281 | "requires": {
282 | "has-flag": "2.0.0"
283 | }
284 | }
285 | }
286 | },
287 | "chardet": {
288 | "version": "0.4.2",
289 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
290 | "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
291 | "dev": true
292 | },
293 | "circular-json": {
294 | "version": "0.3.3",
295 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
296 | "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
297 | "dev": true
298 | },
299 | "cli-cursor": {
300 | "version": "2.1.0",
301 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
302 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
303 | "dev": true,
304 | "requires": {
305 | "restore-cursor": "2.0.0"
306 | }
307 | },
308 | "cli-width": {
309 | "version": "2.2.0",
310 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
311 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
312 | "dev": true
313 | },
314 | "co": {
315 | "version": "4.6.0",
316 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
317 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
318 | "dev": true
319 | },
320 | "color-convert": {
321 | "version": "1.9.1",
322 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
323 | "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
324 | "dev": true,
325 | "requires": {
326 | "color-name": "1.1.3"
327 | }
328 | },
329 | "color-name": {
330 | "version": "1.1.3",
331 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
332 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
333 | "dev": true
334 | },
335 | "component-bind": {
336 | "version": "1.0.0",
337 | "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
338 | "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
339 | },
340 | "component-emitter": {
341 | "version": "1.2.1",
342 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
343 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
344 | },
345 | "component-inherit": {
346 | "version": "0.0.3",
347 | "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
348 | "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
349 | },
350 | "concat-map": {
351 | "version": "0.0.1",
352 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
353 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
354 | "dev": true
355 | },
356 | "concat-stream": {
357 | "version": "1.6.0",
358 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
359 | "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
360 | "dev": true,
361 | "requires": {
362 | "inherits": "2.0.3",
363 | "readable-stream": "2.3.3",
364 | "typedarray": "0.0.6"
365 | }
366 | },
367 | "content-disposition": {
368 | "version": "0.5.2",
369 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
370 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
371 | },
372 | "content-type": {
373 | "version": "1.0.4",
374 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
375 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
376 | },
377 | "cookie": {
378 | "version": "0.3.1",
379 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
380 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
381 | },
382 | "cookie-signature": {
383 | "version": "1.0.6",
384 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
385 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
386 | },
387 | "core-util-is": {
388 | "version": "1.0.2",
389 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
390 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
391 | },
392 | "cross-spawn": {
393 | "version": "5.1.0",
394 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
395 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
396 | "dev": true,
397 | "requires": {
398 | "lru-cache": "4.1.1",
399 | "shebang-command": "1.2.0",
400 | "which": "1.3.0"
401 | }
402 | },
403 | "debug": {
404 | "version": "2.6.9",
405 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
406 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
407 | "requires": {
408 | "ms": "2.0.0"
409 | }
410 | },
411 | "deep-is": {
412 | "version": "0.1.3",
413 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
414 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
415 | "dev": true
416 | },
417 | "del": {
418 | "version": "2.2.2",
419 | "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
420 | "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
421 | "dev": true,
422 | "requires": {
423 | "globby": "5.0.0",
424 | "is-path-cwd": "1.0.0",
425 | "is-path-in-cwd": "1.0.0",
426 | "object-assign": "4.1.1",
427 | "pify": "2.3.0",
428 | "pinkie-promise": "2.0.1",
429 | "rimraf": "2.6.2"
430 | }
431 | },
432 | "depd": {
433 | "version": "1.1.2",
434 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
435 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
436 | },
437 | "destroy": {
438 | "version": "1.0.4",
439 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
440 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
441 | },
442 | "doctrine": {
443 | "version": "2.1.0",
444 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
445 | "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
446 | "dev": true,
447 | "requires": {
448 | "esutils": "2.0.2"
449 | }
450 | },
451 | "ee-first": {
452 | "version": "1.1.1",
453 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
454 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
455 | },
456 | "encodeurl": {
457 | "version": "1.0.1",
458 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
459 | "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
460 | },
461 | "engine.io": {
462 | "version": "3.1.4",
463 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.4.tgz",
464 | "integrity": "sha1-PQIRtwpVLOhB/8fahiezAamkFi4=",
465 | "requires": {
466 | "accepts": "1.3.3",
467 | "base64id": "1.0.0",
468 | "cookie": "0.3.1",
469 | "debug": "2.6.9",
470 | "engine.io-parser": "2.1.2",
471 | "uws": "0.14.5",
472 | "ws": "3.3.3"
473 | },
474 | "dependencies": {
475 | "accepts": {
476 | "version": "1.3.3",
477 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
478 | "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
479 | "requires": {
480 | "mime-types": "2.1.17",
481 | "negotiator": "0.6.1"
482 | }
483 | }
484 | }
485 | },
486 | "engine.io-client": {
487 | "version": "3.1.4",
488 | "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.4.tgz",
489 | "integrity": "sha1-T88TcLRxY70s6b4nM5ckMDUNTqE=",
490 | "requires": {
491 | "component-emitter": "1.2.1",
492 | "component-inherit": "0.0.3",
493 | "debug": "2.6.9",
494 | "engine.io-parser": "2.1.2",
495 | "has-cors": "1.1.0",
496 | "indexof": "0.0.1",
497 | "parseqs": "0.0.5",
498 | "parseuri": "0.0.5",
499 | "ws": "3.3.3",
500 | "xmlhttprequest-ssl": "1.5.5",
501 | "yeast": "0.1.2"
502 | }
503 | },
504 | "engine.io-parser": {
505 | "version": "2.1.2",
506 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz",
507 | "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==",
508 | "requires": {
509 | "after": "0.8.2",
510 | "arraybuffer.slice": "0.0.7",
511 | "base64-arraybuffer": "0.1.5",
512 | "blob": "0.0.4",
513 | "has-binary2": "1.0.2"
514 | }
515 | },
516 | "escape-html": {
517 | "version": "1.0.3",
518 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
519 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
520 | },
521 | "escape-string-regexp": {
522 | "version": "1.0.5",
523 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
524 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
525 | "dev": true
526 | },
527 | "eslint": {
528 | "version": "4.16.0",
529 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.16.0.tgz",
530 | "integrity": "sha512-YVXV4bDhNoHHcv0qzU4Meof7/P26B4EuaktMi5L1Tnt52Aov85KmYA8c5D+xyZr/BkhvwUqr011jDSD/QTULxg==",
531 | "dev": true,
532 | "requires": {
533 | "ajv": "5.5.2",
534 | "babel-code-frame": "6.26.0",
535 | "chalk": "2.3.0",
536 | "concat-stream": "1.6.0",
537 | "cross-spawn": "5.1.0",
538 | "debug": "3.1.0",
539 | "doctrine": "2.1.0",
540 | "eslint-scope": "3.7.1",
541 | "eslint-visitor-keys": "1.0.0",
542 | "espree": "3.5.2",
543 | "esquery": "1.0.0",
544 | "esutils": "2.0.2",
545 | "file-entry-cache": "2.0.0",
546 | "functional-red-black-tree": "1.0.1",
547 | "glob": "7.1.2",
548 | "globals": "11.2.0",
549 | "ignore": "3.3.7",
550 | "imurmurhash": "0.1.4",
551 | "inquirer": "3.3.0",
552 | "is-resolvable": "1.1.0",
553 | "js-yaml": "3.10.0",
554 | "json-stable-stringify-without-jsonify": "1.0.1",
555 | "levn": "0.3.0",
556 | "lodash": "4.17.4",
557 | "minimatch": "3.0.4",
558 | "mkdirp": "0.5.1",
559 | "natural-compare": "1.4.0",
560 | "optionator": "0.8.2",
561 | "path-is-inside": "1.0.2",
562 | "pluralize": "7.0.0",
563 | "progress": "2.0.0",
564 | "require-uncached": "1.0.3",
565 | "semver": "5.5.0",
566 | "strip-ansi": "4.0.0",
567 | "strip-json-comments": "2.0.1",
568 | "table": "4.0.2",
569 | "text-table": "0.2.0"
570 | },
571 | "dependencies": {
572 | "debug": {
573 | "version": "3.1.0",
574 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
575 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
576 | "dev": true,
577 | "requires": {
578 | "ms": "2.0.0"
579 | }
580 | }
581 | }
582 | },
583 | "eslint-scope": {
584 | "version": "3.7.1",
585 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
586 | "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
587 | "dev": true,
588 | "requires": {
589 | "esrecurse": "4.2.0",
590 | "estraverse": "4.2.0"
591 | }
592 | },
593 | "eslint-visitor-keys": {
594 | "version": "1.0.0",
595 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
596 | "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
597 | "dev": true
598 | },
599 | "espree": {
600 | "version": "3.5.2",
601 | "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz",
602 | "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==",
603 | "dev": true,
604 | "requires": {
605 | "acorn": "5.3.0",
606 | "acorn-jsx": "3.0.1"
607 | }
608 | },
609 | "esprima": {
610 | "version": "4.0.0",
611 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
612 | "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
613 | "dev": true
614 | },
615 | "esquery": {
616 | "version": "1.0.0",
617 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
618 | "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
619 | "dev": true,
620 | "requires": {
621 | "estraverse": "4.2.0"
622 | }
623 | },
624 | "esrecurse": {
625 | "version": "4.2.0",
626 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
627 | "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
628 | "dev": true,
629 | "requires": {
630 | "estraverse": "4.2.0",
631 | "object-assign": "4.1.1"
632 | }
633 | },
634 | "estraverse": {
635 | "version": "4.2.0",
636 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
637 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
638 | "dev": true
639 | },
640 | "esutils": {
641 | "version": "2.0.2",
642 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
643 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
644 | "dev": true
645 | },
646 | "etag": {
647 | "version": "1.8.1",
648 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
649 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
650 | },
651 | "express": {
652 | "version": "4.16.2",
653 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
654 | "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
655 | "requires": {
656 | "accepts": "1.3.4",
657 | "array-flatten": "1.1.1",
658 | "body-parser": "1.18.2",
659 | "content-disposition": "0.5.2",
660 | "content-type": "1.0.4",
661 | "cookie": "0.3.1",
662 | "cookie-signature": "1.0.6",
663 | "debug": "2.6.9",
664 | "depd": "1.1.2",
665 | "encodeurl": "1.0.1",
666 | "escape-html": "1.0.3",
667 | "etag": "1.8.1",
668 | "finalhandler": "1.1.0",
669 | "fresh": "0.5.2",
670 | "merge-descriptors": "1.0.1",
671 | "methods": "1.1.2",
672 | "on-finished": "2.3.0",
673 | "parseurl": "1.3.2",
674 | "path-to-regexp": "0.1.7",
675 | "proxy-addr": "2.0.2",
676 | "qs": "6.5.1",
677 | "range-parser": "1.2.0",
678 | "safe-buffer": "5.1.1",
679 | "send": "0.16.1",
680 | "serve-static": "1.13.1",
681 | "setprototypeof": "1.1.0",
682 | "statuses": "1.3.1",
683 | "type-is": "1.6.15",
684 | "utils-merge": "1.0.1",
685 | "vary": "1.1.2"
686 | },
687 | "dependencies": {
688 | "setprototypeof": {
689 | "version": "1.1.0",
690 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
691 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
692 | },
693 | "statuses": {
694 | "version": "1.3.1",
695 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
696 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
697 | }
698 | }
699 | },
700 | "external-editor": {
701 | "version": "2.1.0",
702 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz",
703 | "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==",
704 | "dev": true,
705 | "requires": {
706 | "chardet": "0.4.2",
707 | "iconv-lite": "0.4.19",
708 | "tmp": "0.0.33"
709 | }
710 | },
711 | "fast-deep-equal": {
712 | "version": "1.0.0",
713 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
714 | "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
715 | "dev": true
716 | },
717 | "fast-json-stable-stringify": {
718 | "version": "2.0.0",
719 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
720 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
721 | "dev": true
722 | },
723 | "fast-levenshtein": {
724 | "version": "2.0.6",
725 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
726 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
727 | "dev": true
728 | },
729 | "figures": {
730 | "version": "2.0.0",
731 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
732 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
733 | "dev": true,
734 | "requires": {
735 | "escape-string-regexp": "1.0.5"
736 | }
737 | },
738 | "file-entry-cache": {
739 | "version": "2.0.0",
740 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
741 | "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
742 | "dev": true,
743 | "requires": {
744 | "flat-cache": "1.3.0",
745 | "object-assign": "4.1.1"
746 | }
747 | },
748 | "finalhandler": {
749 | "version": "1.1.0",
750 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
751 | "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
752 | "requires": {
753 | "debug": "2.6.9",
754 | "encodeurl": "1.0.1",
755 | "escape-html": "1.0.3",
756 | "on-finished": "2.3.0",
757 | "parseurl": "1.3.2",
758 | "statuses": "1.3.1",
759 | "unpipe": "1.0.0"
760 | },
761 | "dependencies": {
762 | "statuses": {
763 | "version": "1.3.1",
764 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
765 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
766 | }
767 | }
768 | },
769 | "flat-cache": {
770 | "version": "1.3.0",
771 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
772 | "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
773 | "dev": true,
774 | "requires": {
775 | "circular-json": "0.3.3",
776 | "del": "2.2.2",
777 | "graceful-fs": "4.1.11",
778 | "write": "0.2.1"
779 | }
780 | },
781 | "forwarded": {
782 | "version": "0.1.2",
783 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
784 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
785 | },
786 | "fresh": {
787 | "version": "0.5.2",
788 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
789 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
790 | },
791 | "fs.realpath": {
792 | "version": "1.0.0",
793 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
794 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
795 | "dev": true
796 | },
797 | "functional-red-black-tree": {
798 | "version": "1.0.1",
799 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
800 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
801 | "dev": true
802 | },
803 | "glob": {
804 | "version": "7.1.2",
805 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
806 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
807 | "dev": true,
808 | "requires": {
809 | "fs.realpath": "1.0.0",
810 | "inflight": "1.0.6",
811 | "inherits": "2.0.3",
812 | "minimatch": "3.0.4",
813 | "once": "1.4.0",
814 | "path-is-absolute": "1.0.1"
815 | }
816 | },
817 | "globals": {
818 | "version": "11.2.0",
819 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.2.0.tgz",
820 | "integrity": "sha512-RDC7Tj17I/56wpVvCVLSXtnn2Fo6CQZ9vaj+ARn+qlzm/ozbKQZe+j9fvHZCbSq+4JSGjTpKEt7p/AA1IKXRFA==",
821 | "dev": true
822 | },
823 | "globby": {
824 | "version": "5.0.0",
825 | "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
826 | "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
827 | "dev": true,
828 | "requires": {
829 | "array-union": "1.0.2",
830 | "arrify": "1.0.1",
831 | "glob": "7.1.2",
832 | "object-assign": "4.1.1",
833 | "pify": "2.3.0",
834 | "pinkie-promise": "2.0.1"
835 | }
836 | },
837 | "graceful-fs": {
838 | "version": "4.1.11",
839 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
840 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
841 | "dev": true
842 | },
843 | "has-ansi": {
844 | "version": "2.0.0",
845 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
846 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
847 | "dev": true,
848 | "requires": {
849 | "ansi-regex": "2.1.1"
850 | }
851 | },
852 | "has-binary2": {
853 | "version": "1.0.2",
854 | "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz",
855 | "integrity": "sha1-6D26SfC5vk0CbSc2U1DZ8D9Uvpg=",
856 | "requires": {
857 | "isarray": "2.0.1"
858 | },
859 | "dependencies": {
860 | "isarray": {
861 | "version": "2.0.1",
862 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
863 | "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
864 | }
865 | }
866 | },
867 | "has-cors": {
868 | "version": "1.1.0",
869 | "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
870 | "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
871 | },
872 | "has-flag": {
873 | "version": "2.0.0",
874 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
875 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
876 | "dev": true
877 | },
878 | "http-errors": {
879 | "version": "1.6.2",
880 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
881 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
882 | "requires": {
883 | "depd": "1.1.1",
884 | "inherits": "2.0.3",
885 | "setprototypeof": "1.0.3",
886 | "statuses": "1.4.0"
887 | },
888 | "dependencies": {
889 | "depd": {
890 | "version": "1.1.1",
891 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
892 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
893 | }
894 | }
895 | },
896 | "iconv-lite": {
897 | "version": "0.4.19",
898 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
899 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
900 | },
901 | "ignore": {
902 | "version": "3.3.7",
903 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz",
904 | "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==",
905 | "dev": true
906 | },
907 | "imurmurhash": {
908 | "version": "0.1.4",
909 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
910 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
911 | "dev": true
912 | },
913 | "indexof": {
914 | "version": "0.0.1",
915 | "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
916 | "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
917 | },
918 | "inflight": {
919 | "version": "1.0.6",
920 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
921 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
922 | "dev": true,
923 | "requires": {
924 | "once": "1.4.0",
925 | "wrappy": "1.0.2"
926 | }
927 | },
928 | "inherits": {
929 | "version": "2.0.3",
930 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
931 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
932 | },
933 | "inquirer": {
934 | "version": "3.3.0",
935 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
936 | "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
937 | "dev": true,
938 | "requires": {
939 | "ansi-escapes": "3.0.0",
940 | "chalk": "2.3.0",
941 | "cli-cursor": "2.1.0",
942 | "cli-width": "2.2.0",
943 | "external-editor": "2.1.0",
944 | "figures": "2.0.0",
945 | "lodash": "4.17.4",
946 | "mute-stream": "0.0.7",
947 | "run-async": "2.3.0",
948 | "rx-lite": "4.0.8",
949 | "rx-lite-aggregates": "4.0.8",
950 | "string-width": "2.1.1",
951 | "strip-ansi": "4.0.0",
952 | "through": "2.3.8"
953 | }
954 | },
955 | "ipaddr.js": {
956 | "version": "1.5.2",
957 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
958 | "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
959 | },
960 | "is-fullwidth-code-point": {
961 | "version": "2.0.0",
962 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
963 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
964 | "dev": true
965 | },
966 | "is-path-cwd": {
967 | "version": "1.0.0",
968 | "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
969 | "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
970 | "dev": true
971 | },
972 | "is-path-in-cwd": {
973 | "version": "1.0.0",
974 | "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
975 | "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
976 | "dev": true,
977 | "requires": {
978 | "is-path-inside": "1.0.1"
979 | }
980 | },
981 | "is-path-inside": {
982 | "version": "1.0.1",
983 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
984 | "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
985 | "dev": true,
986 | "requires": {
987 | "path-is-inside": "1.0.2"
988 | }
989 | },
990 | "is-promise": {
991 | "version": "2.1.0",
992 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
993 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
994 | "dev": true
995 | },
996 | "is-resolvable": {
997 | "version": "1.1.0",
998 | "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
999 | "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
1000 | "dev": true
1001 | },
1002 | "isarray": {
1003 | "version": "1.0.0",
1004 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
1005 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
1006 | },
1007 | "isexe": {
1008 | "version": "2.0.0",
1009 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1010 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
1011 | "dev": true
1012 | },
1013 | "js-tokens": {
1014 | "version": "3.0.2",
1015 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
1016 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
1017 | "dev": true
1018 | },
1019 | "js-yaml": {
1020 | "version": "3.10.0",
1021 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
1022 | "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
1023 | "dev": true,
1024 | "requires": {
1025 | "argparse": "1.0.9",
1026 | "esprima": "4.0.0"
1027 | }
1028 | },
1029 | "json-schema-traverse": {
1030 | "version": "0.3.1",
1031 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
1032 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
1033 | "dev": true
1034 | },
1035 | "json-stable-stringify-without-jsonify": {
1036 | "version": "1.0.1",
1037 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
1038 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
1039 | "dev": true
1040 | },
1041 | "levn": {
1042 | "version": "0.3.0",
1043 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
1044 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
1045 | "dev": true,
1046 | "requires": {
1047 | "prelude-ls": "1.1.2",
1048 | "type-check": "0.3.2"
1049 | }
1050 | },
1051 | "lodash": {
1052 | "version": "4.17.4",
1053 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
1054 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
1055 | "dev": true
1056 | },
1057 | "lru-cache": {
1058 | "version": "4.1.1",
1059 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
1060 | "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
1061 | "dev": true,
1062 | "requires": {
1063 | "pseudomap": "1.0.2",
1064 | "yallist": "2.1.2"
1065 | }
1066 | },
1067 | "media-typer": {
1068 | "version": "0.3.0",
1069 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
1070 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
1071 | },
1072 | "merge-descriptors": {
1073 | "version": "1.0.1",
1074 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
1075 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
1076 | },
1077 | "methods": {
1078 | "version": "1.1.2",
1079 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
1080 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
1081 | },
1082 | "mime": {
1083 | "version": "1.4.1",
1084 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
1085 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
1086 | },
1087 | "mime-db": {
1088 | "version": "1.30.0",
1089 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
1090 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
1091 | },
1092 | "mime-types": {
1093 | "version": "2.1.17",
1094 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
1095 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
1096 | "requires": {
1097 | "mime-db": "1.30.0"
1098 | }
1099 | },
1100 | "mimic-fn": {
1101 | "version": "1.1.0",
1102 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
1103 | "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
1104 | "dev": true
1105 | },
1106 | "minimatch": {
1107 | "version": "3.0.4",
1108 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
1109 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1110 | "dev": true,
1111 | "requires": {
1112 | "brace-expansion": "1.1.8"
1113 | }
1114 | },
1115 | "minimist": {
1116 | "version": "0.0.8",
1117 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
1118 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
1119 | "dev": true
1120 | },
1121 | "mkdirp": {
1122 | "version": "0.5.1",
1123 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
1124 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
1125 | "dev": true,
1126 | "requires": {
1127 | "minimist": "0.0.8"
1128 | }
1129 | },
1130 | "ms": {
1131 | "version": "2.0.0",
1132 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1133 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
1134 | },
1135 | "mute-stream": {
1136 | "version": "0.0.7",
1137 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
1138 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
1139 | "dev": true
1140 | },
1141 | "mysql": {
1142 | "version": "2.15.0",
1143 | "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.15.0.tgz",
1144 | "integrity": "sha512-C7tjzWtbN5nzkLIV+E8Crnl9bFyc7d3XJcBAvHKEVkjrYjogz3llo22q6s/hw+UcsE4/844pDob9ac+3dVjQSA==",
1145 | "requires": {
1146 | "bignumber.js": "4.0.4",
1147 | "readable-stream": "2.3.3",
1148 | "safe-buffer": "5.1.1",
1149 | "sqlstring": "2.3.0"
1150 | }
1151 | },
1152 | "natural-compare": {
1153 | "version": "1.4.0",
1154 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
1155 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
1156 | "dev": true
1157 | },
1158 | "negotiator": {
1159 | "version": "0.6.1",
1160 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
1161 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
1162 | },
1163 | "object-assign": {
1164 | "version": "4.1.1",
1165 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1166 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
1167 | "dev": true
1168 | },
1169 | "object-component": {
1170 | "version": "0.0.3",
1171 | "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
1172 | "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE="
1173 | },
1174 | "on-finished": {
1175 | "version": "2.3.0",
1176 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
1177 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
1178 | "requires": {
1179 | "ee-first": "1.1.1"
1180 | }
1181 | },
1182 | "once": {
1183 | "version": "1.4.0",
1184 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1185 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1186 | "dev": true,
1187 | "requires": {
1188 | "wrappy": "1.0.2"
1189 | }
1190 | },
1191 | "onetime": {
1192 | "version": "2.0.1",
1193 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
1194 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
1195 | "dev": true,
1196 | "requires": {
1197 | "mimic-fn": "1.1.0"
1198 | }
1199 | },
1200 | "optionator": {
1201 | "version": "0.8.2",
1202 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
1203 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
1204 | "dev": true,
1205 | "requires": {
1206 | "deep-is": "0.1.3",
1207 | "fast-levenshtein": "2.0.6",
1208 | "levn": "0.3.0",
1209 | "prelude-ls": "1.1.2",
1210 | "type-check": "0.3.2",
1211 | "wordwrap": "1.0.0"
1212 | }
1213 | },
1214 | "os-tmpdir": {
1215 | "version": "1.0.2",
1216 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
1217 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
1218 | "dev": true
1219 | },
1220 | "parseqs": {
1221 | "version": "0.0.5",
1222 | "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
1223 | "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
1224 | "requires": {
1225 | "better-assert": "1.0.2"
1226 | }
1227 | },
1228 | "parseuri": {
1229 | "version": "0.0.5",
1230 | "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
1231 | "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
1232 | "requires": {
1233 | "better-assert": "1.0.2"
1234 | }
1235 | },
1236 | "parseurl": {
1237 | "version": "1.3.2",
1238 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
1239 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
1240 | },
1241 | "path-is-absolute": {
1242 | "version": "1.0.1",
1243 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1244 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
1245 | "dev": true
1246 | },
1247 | "path-is-inside": {
1248 | "version": "1.0.2",
1249 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
1250 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
1251 | "dev": true
1252 | },
1253 | "path-to-regexp": {
1254 | "version": "0.1.7",
1255 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1256 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
1257 | },
1258 | "pify": {
1259 | "version": "2.3.0",
1260 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
1261 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
1262 | "dev": true
1263 | },
1264 | "pinkie": {
1265 | "version": "2.0.4",
1266 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
1267 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
1268 | "dev": true
1269 | },
1270 | "pinkie-promise": {
1271 | "version": "2.0.1",
1272 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
1273 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
1274 | "dev": true,
1275 | "requires": {
1276 | "pinkie": "2.0.4"
1277 | }
1278 | },
1279 | "pluralize": {
1280 | "version": "7.0.0",
1281 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
1282 | "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
1283 | "dev": true
1284 | },
1285 | "prelude-ls": {
1286 | "version": "1.1.2",
1287 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
1288 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
1289 | "dev": true
1290 | },
1291 | "process-nextick-args": {
1292 | "version": "1.0.7",
1293 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
1294 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
1295 | },
1296 | "progress": {
1297 | "version": "2.0.0",
1298 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
1299 | "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
1300 | "dev": true
1301 | },
1302 | "proxy-addr": {
1303 | "version": "2.0.2",
1304 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
1305 | "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
1306 | "requires": {
1307 | "forwarded": "0.1.2",
1308 | "ipaddr.js": "1.5.2"
1309 | }
1310 | },
1311 | "pseudomap": {
1312 | "version": "1.0.2",
1313 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
1314 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
1315 | "dev": true
1316 | },
1317 | "qs": {
1318 | "version": "6.5.1",
1319 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
1320 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
1321 | },
1322 | "range-parser": {
1323 | "version": "1.2.0",
1324 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
1325 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
1326 | },
1327 | "raw-body": {
1328 | "version": "2.3.2",
1329 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
1330 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
1331 | "requires": {
1332 | "bytes": "3.0.0",
1333 | "http-errors": "1.6.2",
1334 | "iconv-lite": "0.4.19",
1335 | "unpipe": "1.0.0"
1336 | }
1337 | },
1338 | "readable-stream": {
1339 | "version": "2.3.3",
1340 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
1341 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
1342 | "requires": {
1343 | "core-util-is": "1.0.2",
1344 | "inherits": "2.0.3",
1345 | "isarray": "1.0.0",
1346 | "process-nextick-args": "1.0.7",
1347 | "safe-buffer": "5.1.1",
1348 | "string_decoder": "1.0.3",
1349 | "util-deprecate": "1.0.2"
1350 | }
1351 | },
1352 | "require-uncached": {
1353 | "version": "1.0.3",
1354 | "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
1355 | "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
1356 | "dev": true,
1357 | "requires": {
1358 | "caller-path": "0.1.0",
1359 | "resolve-from": "1.0.1"
1360 | }
1361 | },
1362 | "resolve-from": {
1363 | "version": "1.0.1",
1364 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
1365 | "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
1366 | "dev": true
1367 | },
1368 | "restore-cursor": {
1369 | "version": "2.0.0",
1370 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
1371 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
1372 | "dev": true,
1373 | "requires": {
1374 | "onetime": "2.0.1",
1375 | "signal-exit": "3.0.2"
1376 | }
1377 | },
1378 | "rimraf": {
1379 | "version": "2.6.2",
1380 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
1381 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
1382 | "dev": true,
1383 | "requires": {
1384 | "glob": "7.1.2"
1385 | }
1386 | },
1387 | "run-async": {
1388 | "version": "2.3.0",
1389 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
1390 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
1391 | "dev": true,
1392 | "requires": {
1393 | "is-promise": "2.1.0"
1394 | }
1395 | },
1396 | "rx-lite": {
1397 | "version": "4.0.8",
1398 | "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
1399 | "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
1400 | "dev": true
1401 | },
1402 | "rx-lite-aggregates": {
1403 | "version": "4.0.8",
1404 | "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
1405 | "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
1406 | "dev": true,
1407 | "requires": {
1408 | "rx-lite": "4.0.8"
1409 | }
1410 | },
1411 | "safe-buffer": {
1412 | "version": "5.1.1",
1413 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
1414 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
1415 | },
1416 | "semver": {
1417 | "version": "5.5.0",
1418 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
1419 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
1420 | "dev": true
1421 | },
1422 | "send": {
1423 | "version": "0.16.1",
1424 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
1425 | "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
1426 | "requires": {
1427 | "debug": "2.6.9",
1428 | "depd": "1.1.2",
1429 | "destroy": "1.0.4",
1430 | "encodeurl": "1.0.1",
1431 | "escape-html": "1.0.3",
1432 | "etag": "1.8.1",
1433 | "fresh": "0.5.2",
1434 | "http-errors": "1.6.2",
1435 | "mime": "1.4.1",
1436 | "ms": "2.0.0",
1437 | "on-finished": "2.3.0",
1438 | "range-parser": "1.2.0",
1439 | "statuses": "1.3.1"
1440 | },
1441 | "dependencies": {
1442 | "statuses": {
1443 | "version": "1.3.1",
1444 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
1445 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
1446 | }
1447 | }
1448 | },
1449 | "serve-static": {
1450 | "version": "1.13.1",
1451 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
1452 | "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==",
1453 | "requires": {
1454 | "encodeurl": "1.0.1",
1455 | "escape-html": "1.0.3",
1456 | "parseurl": "1.3.2",
1457 | "send": "0.16.1"
1458 | }
1459 | },
1460 | "setprototypeof": {
1461 | "version": "1.0.3",
1462 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
1463 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
1464 | },
1465 | "shebang-command": {
1466 | "version": "1.2.0",
1467 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
1468 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
1469 | "dev": true,
1470 | "requires": {
1471 | "shebang-regex": "1.0.0"
1472 | }
1473 | },
1474 | "shebang-regex": {
1475 | "version": "1.0.0",
1476 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
1477 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
1478 | "dev": true
1479 | },
1480 | "signal-exit": {
1481 | "version": "3.0.2",
1482 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
1483 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
1484 | "dev": true
1485 | },
1486 | "slice-ansi": {
1487 | "version": "1.0.0",
1488 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
1489 | "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
1490 | "dev": true,
1491 | "requires": {
1492 | "is-fullwidth-code-point": "2.0.0"
1493 | }
1494 | },
1495 | "socket.io": {
1496 | "version": "2.0.4",
1497 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz",
1498 | "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=",
1499 | "requires": {
1500 | "debug": "2.6.9",
1501 | "engine.io": "3.1.4",
1502 | "socket.io-adapter": "1.1.1",
1503 | "socket.io-client": "2.0.4",
1504 | "socket.io-parser": "3.1.2"
1505 | }
1506 | },
1507 | "socket.io-adapter": {
1508 | "version": "1.1.1",
1509 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz",
1510 | "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs="
1511 | },
1512 | "socket.io-client": {
1513 | "version": "2.0.4",
1514 | "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz",
1515 | "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=",
1516 | "requires": {
1517 | "backo2": "1.0.2",
1518 | "base64-arraybuffer": "0.1.5",
1519 | "component-bind": "1.0.0",
1520 | "component-emitter": "1.2.1",
1521 | "debug": "2.6.9",
1522 | "engine.io-client": "3.1.4",
1523 | "has-cors": "1.1.0",
1524 | "indexof": "0.0.1",
1525 | "object-component": "0.0.3",
1526 | "parseqs": "0.0.5",
1527 | "parseuri": "0.0.5",
1528 | "socket.io-parser": "3.1.2",
1529 | "to-array": "0.1.4"
1530 | }
1531 | },
1532 | "socket.io-parser": {
1533 | "version": "3.1.2",
1534 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.2.tgz",
1535 | "integrity": "sha1-28IoIVH8T6675Aru3Ady66YZ9/I=",
1536 | "requires": {
1537 | "component-emitter": "1.2.1",
1538 | "debug": "2.6.9",
1539 | "has-binary2": "1.0.2",
1540 | "isarray": "2.0.1"
1541 | },
1542 | "dependencies": {
1543 | "isarray": {
1544 | "version": "2.0.1",
1545 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
1546 | "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
1547 | }
1548 | }
1549 | },
1550 | "sprintf-js": {
1551 | "version": "1.0.3",
1552 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
1553 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
1554 | "dev": true
1555 | },
1556 | "sqlstring": {
1557 | "version": "2.3.0",
1558 | "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.0.tgz",
1559 | "integrity": "sha1-UluKT9Jtb3GqYegipsr5dtMa0qg="
1560 | },
1561 | "statuses": {
1562 | "version": "1.4.0",
1563 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
1564 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
1565 | },
1566 | "string-width": {
1567 | "version": "2.1.1",
1568 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
1569 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
1570 | "dev": true,
1571 | "requires": {
1572 | "is-fullwidth-code-point": "2.0.0",
1573 | "strip-ansi": "4.0.0"
1574 | }
1575 | },
1576 | "string_decoder": {
1577 | "version": "1.0.3",
1578 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
1579 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
1580 | "requires": {
1581 | "safe-buffer": "5.1.1"
1582 | }
1583 | },
1584 | "strip-ansi": {
1585 | "version": "4.0.0",
1586 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
1587 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
1588 | "dev": true,
1589 | "requires": {
1590 | "ansi-regex": "3.0.0"
1591 | },
1592 | "dependencies": {
1593 | "ansi-regex": {
1594 | "version": "3.0.0",
1595 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
1596 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
1597 | "dev": true
1598 | }
1599 | }
1600 | },
1601 | "strip-json-comments": {
1602 | "version": "2.0.1",
1603 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
1604 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
1605 | "dev": true
1606 | },
1607 | "supports-color": {
1608 | "version": "2.0.0",
1609 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
1610 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
1611 | "dev": true
1612 | },
1613 | "table": {
1614 | "version": "4.0.2",
1615 | "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
1616 | "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
1617 | "dev": true,
1618 | "requires": {
1619 | "ajv": "5.5.2",
1620 | "ajv-keywords": "2.1.1",
1621 | "chalk": "2.3.0",
1622 | "lodash": "4.17.4",
1623 | "slice-ansi": "1.0.0",
1624 | "string-width": "2.1.1"
1625 | }
1626 | },
1627 | "text-table": {
1628 | "version": "0.2.0",
1629 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
1630 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
1631 | "dev": true
1632 | },
1633 | "through": {
1634 | "version": "2.3.8",
1635 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
1636 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
1637 | "dev": true
1638 | },
1639 | "tmp": {
1640 | "version": "0.0.33",
1641 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
1642 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
1643 | "dev": true,
1644 | "requires": {
1645 | "os-tmpdir": "1.0.2"
1646 | }
1647 | },
1648 | "to-array": {
1649 | "version": "0.1.4",
1650 | "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
1651 | "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
1652 | },
1653 | "type-check": {
1654 | "version": "0.3.2",
1655 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
1656 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
1657 | "dev": true,
1658 | "requires": {
1659 | "prelude-ls": "1.1.2"
1660 | }
1661 | },
1662 | "type-is": {
1663 | "version": "1.6.15",
1664 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
1665 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
1666 | "requires": {
1667 | "media-typer": "0.3.0",
1668 | "mime-types": "2.1.17"
1669 | }
1670 | },
1671 | "typedarray": {
1672 | "version": "0.0.6",
1673 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
1674 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
1675 | "dev": true
1676 | },
1677 | "ultron": {
1678 | "version": "1.1.1",
1679 | "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
1680 | "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
1681 | },
1682 | "unpipe": {
1683 | "version": "1.0.0",
1684 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1685 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
1686 | },
1687 | "util-deprecate": {
1688 | "version": "1.0.2",
1689 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1690 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
1691 | },
1692 | "utils-merge": {
1693 | "version": "1.0.1",
1694 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1695 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
1696 | },
1697 | "uws": {
1698 | "version": "0.14.5",
1699 | "resolved": "https://registry.npmjs.org/uws/-/uws-0.14.5.tgz",
1700 | "integrity": "sha1-Z6rzPEaypYel9mZtAPdpEyjxSdw=",
1701 | "optional": true
1702 | },
1703 | "vary": {
1704 | "version": "1.1.2",
1705 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1706 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
1707 | },
1708 | "which": {
1709 | "version": "1.3.0",
1710 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
1711 | "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
1712 | "dev": true,
1713 | "requires": {
1714 | "isexe": "2.0.0"
1715 | }
1716 | },
1717 | "wordwrap": {
1718 | "version": "1.0.0",
1719 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
1720 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
1721 | "dev": true
1722 | },
1723 | "wrappy": {
1724 | "version": "1.0.2",
1725 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1726 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1727 | "dev": true
1728 | },
1729 | "write": {
1730 | "version": "0.2.1",
1731 | "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
1732 | "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
1733 | "dev": true,
1734 | "requires": {
1735 | "mkdirp": "0.5.1"
1736 | }
1737 | },
1738 | "ws": {
1739 | "version": "3.3.3",
1740 | "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
1741 | "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
1742 | "requires": {
1743 | "async-limiter": "1.0.0",
1744 | "safe-buffer": "5.1.1",
1745 | "ultron": "1.1.1"
1746 | }
1747 | },
1748 | "xmlhttprequest-ssl": {
1749 | "version": "1.5.5",
1750 | "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
1751 | "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
1752 | },
1753 | "yallist": {
1754 | "version": "2.1.2",
1755 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
1756 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
1757 | "dev": true
1758 | },
1759 | "yeast": {
1760 | "version": "0.1.2",
1761 | "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
1762 | "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
1763 | }
1764 | }
1765 | }
1766 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "private-chat-app-using-angularjs-nodejs-and-mongodb",
3 | "version": "1.0.0",
4 | "description": "This is a private chat application in angularjs and nodejs using Mysql as database.",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "Shashank Tiwari",
10 | "license": "ISC",
11 | "dependencies": {
12 | "body-parser": "^1.18.2",
13 | "express": "^4.16.2",
14 | "mysql": "^2.15.0",
15 | "socket.io": "^2.0.4"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Real Time chatting app
3 | * @author Shashank Tiwari
4 | */
5 | 'use strict';
6 |
7 | const express = require("express");
8 | const http = require('http');
9 | const socketio = require('socket.io');
10 | const bodyParser = require('body-parser');
11 |
12 | const socketEvents = require('./utils/socket');
13 | const routes = require('./utils/routes');
14 | const config = require('./utils/config');
15 |
16 |
17 | class Server{
18 |
19 | constructor(){
20 | this.port = process.env.PORT || 3000;
21 | this.host = `localhost`;
22 |
23 | this.app = express();
24 | this.http = http.Server(this.app);
25 | this.socket = socketio(this.http);
26 | }
27 |
28 | appConfig(){
29 | this.app.use(
30 | bodyParser.json()
31 | );
32 | new config(this.app);
33 | }
34 |
35 | /* Including app Routes starts*/
36 | includeRoutes(){
37 | new routes(this.app).routesConfig();
38 | new socketEvents(this.socket).socketConfig();
39 | }
40 | /* Including app Routes ends*/
41 |
42 | appExecute(){
43 |
44 | this.appConfig();
45 | this.includeRoutes();
46 |
47 | this.http.listen(this.port, this.host, () => {
48 | console.log(`Listening on http://${this.host}:${this.port}`);
49 | });
50 | }
51 |
52 | }
53 |
54 | const app = new Server();
55 | app.appExecute();
--------------------------------------------------------------------------------
/utils/config.js:
--------------------------------------------------------------------------------
1 | class Config{
2 |
3 | constructor(app){
4 | // Setting .html as the default template extension
5 | app.set('view engine', 'html');
6 |
7 | // Telling express where it can find the templates
8 | app.set('views', (__dirname + '/../views'));
9 |
10 | //Files
11 | app.use(require('express').static(require('path').join('client')));
12 |
13 | }
14 | }
15 | module.exports = Config;
--------------------------------------------------------------------------------
/utils/db.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Real Time chatting app
3 | * @author Shashank Tiwari
4 | */
5 |
6 | /**
7 | * Source code by https://codeburst.io/@MichalMecinski
8 | * https://codeburst.io/node-js-mysql-and-promises-4c3be599909b
9 | */
10 |
11 | const mysql = require('mysql');
12 |
13 | class Db {
14 | constructor(config) {
15 | this.connection = mysql.createPool({
16 | connectionLimit: 100,
17 | host: '127.0.0.1',
18 | user: 'root',
19 | password: 'root',
20 | database: 'chat',
21 | debug: false
22 | });
23 | }
24 | query(sql, args) {
25 | return new Promise((resolve, reject) => {
26 | this.connection.query(sql, args, (err, rows) => {
27 | if (err)
28 | return reject(err);
29 | resolve(rows);
30 | });
31 | });
32 | }
33 | close() {
34 | return new Promise((resolve, reject) => {
35 | this.connection.end(err => {
36 | if (err)
37 | return reject(err);
38 | resolve();
39 | });
40 | });
41 | }
42 | }
43 | module.exports = new Db();
--------------------------------------------------------------------------------
/utils/helper.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Real Time chatting app
3 | * @author Shashank Tiwari
4 | */
5 |
6 | 'user strict';
7 | const DB = require('./db');
8 |
9 | class Helper{
10 |
11 | constructor(app){
12 | this.db = DB;
13 | }
14 |
15 | async userNameCheck (username){
16 | return await this.db.query(`SELECT count(username) as count FROM user WHERE LOWER(username) = ?`, `${username}`);
17 | }
18 |
19 | async registerUser(params){
20 | try {
21 | return await this.db.query("INSERT INTO user (`username`,`password`,`online`) VALUES (?,?,?)", [params['username'],params['password'],'Y']);
22 | } catch (error) {
23 | console.error(error);
24 | return null;
25 | }
26 | }
27 |
28 | async loginUser(params){
29 | try {
30 | return await this.db.query(`SELECT id FROM user WHERE LOWER(username) = ? AND password = ?`, [params.username,params.password]);
31 | } catch (error) {
32 | return null;
33 | }
34 | }
35 |
36 | async userSessionCheck(userId){
37 | try {
38 | const result = await this.db.query(`SELECT online,username FROM user WHERE id = ? AND online = ?`, [userId,'Y']);
39 | if(result !== null){
40 | return result[0]['username'];
41 | }else{
42 | return null;
43 | }
44 | } catch (error) {
45 | return null;
46 | }
47 | }
48 |
49 | async addSocketId(userId, userSocketId){
50 | try {
51 | return await this.db.query(`UPDATE user SET socketid = ?, online= ? WHERE id = ?`, [userSocketId,'Y',userId]);
52 | } catch (error) {
53 | console.log(error);
54 | return null;
55 | }
56 | }
57 |
58 | async isUserLoggedOut(userSocketId){
59 | try {
60 | return await this.db.query(`SELECT online FROM user WHERE socketid = ?`, [userSocketId]);
61 | } catch (error) {
62 | return null;
63 | }
64 | }
65 |
66 | async logoutUser(userSocketId){
67 | return await this.db.query(`UPDATE user SET socketid = ?, online= ? WHERE socketid = ?`, ['','N',userSocketId]);
68 | }
69 |
70 | getChatList(userId, userSocketId){
71 | try {
72 | return Promise.all([
73 | this.db.query(`SELECT id,username,online,socketid FROM user WHERE id = ?`, [userId]),
74 | this.db.query(`SELECT id,username,online,socketid FROM user WHERE online = ? and socketid != ?`, ['Y',userSocketId])
75 | ]).then( (response) => {
76 | return {
77 | userinfo : response[0].length > 0 ? response[0][0] : response[0],
78 | chatlist : response[1]
79 | };
80 | }).catch( (error) => {
81 | console.warn(error);
82 | return (null);
83 | });
84 | } catch (error) {
85 | console.warn(error);
86 | return null;
87 | }
88 | }
89 |
90 | async insertMessages(params){
91 | try {
92 | return await this.db.query(
93 | "INSERT INTO message (`from_user_id`,`to_user_id`,`message`) values (?,?,?)",
94 | [params.fromUserId, params.toUserId, params.message]
95 | );
96 | } catch (error) {
97 | console.warn(error);
98 | return null;
99 | }
100 | }
101 |
102 | async getMessages(userId, toUserId){
103 | try {
104 | return await this.db.query(
105 | `SELECT id,from_user_id as fromUserId,to_user_id as toUserId,message FROM message WHERE
106 | (from_user_id = ? AND to_user_id = ? )
107 | OR
108 | (from_user_id = ? AND to_user_id = ? ) ORDER BY id ASC
109 | `,
110 | [userId, toUserId, toUserId, userId]
111 | );
112 | } catch (error) {
113 | console.warn(error);
114 | return null;
115 | }
116 | }
117 | }
118 | module.exports = new Helper();
--------------------------------------------------------------------------------
/utils/routes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Real Time chatting app
3 | * @author Shashank Tiwari
4 | */
5 |
6 | 'use strict';
7 |
8 | const helper = require('./helper');
9 | const path = require('path');
10 | class Routes{
11 |
12 | constructor(app){
13 |
14 | this.app = app;
15 | }
16 |
17 | appRoutes(){
18 | this.app.post('/usernameCheck',async (request,response) =>{
19 | const username = request.body.username;
20 | if (username === "" || username === undefined || username === null) {
21 | response.status(412).json({
22 | error : true,
23 | message : `username cant be empty.`
24 | });
25 | } else {
26 | const data = await helper.userNameCheck(username.toLowerCase());
27 | if (data[0]['count'] > 0) {
28 | response.status(401).json({
29 | error:true,
30 | message: 'This username is alreday taken.'
31 | });
32 | } else {
33 | response.status(200).json({
34 | error:false,
35 | message: 'This username is available.'
36 | });
37 | }
38 | }
39 | });
40 |
41 | this.app.post('/registerUser', async (request,response) => {
42 | const registrationResponse = {}
43 | const data = {
44 | username : (request.body.username).toLowerCase(),
45 | password : request.body.password
46 | };
47 | if(data.username === '') {
48 | registrationResponse.error = true;
49 | registrationResponse.message = `username cant be empty.`;
50 | response.status(412).json(registrationResponse);
51 | }else if(data.password === ''){
52 | registrationResponse.error = true;
53 | registrationResponse.message = `password cant be empty.`;
54 | response.status(412).json(registrationResponse);
55 | }else{
56 | const result = await helper.registerUser( data );
57 | if (result === null) {
58 | registrationResponse.error = true;
59 | registrationResponse.message = `User registration unsuccessful,try after some time.`;
60 | response.status(417).json(registrationResponse);
61 | } else {
62 | registrationResponse.error = false;
63 | registrationResponse.userId = result.insertId;
64 | registrationResponse.message = `User registration successful.`;
65 | response.status(200).json(registrationResponse);
66 | }
67 | }
68 | });
69 |
70 | this.app.post('/login',async (request,response) =>{
71 | const loginResponse = {}
72 | const data = {
73 | username : (request.body.username).toLowerCase(),
74 | password : request.body.password
75 | };
76 | if(data.username === '' || data.username === null) {
77 | loginResponse.error = true;
78 | loginResponse.message = `username cant be empty.`;
79 | response.status(412).json(loginResponse);
80 | }else if(data.password === '' || data.password === null){
81 | loginResponse.error = true;
82 | loginResponse.message = `password cant be empty.`;
83 | response.status(412).json(loginResponse);
84 | }else{
85 | const result = await helper.loginUser(data);
86 | if (result === null || result.length === 0) {
87 | loginResponse.error = true;
88 | loginResponse.message = `Invalid username and password combination.`;
89 | response.status(401).json(loginResponse);
90 | } else {
91 | loginResponse.error = false;
92 | loginResponse.userId = result[0].id;
93 | loginResponse.message = `User logged in.`;
94 | response.status(200).json(loginResponse);
95 | }
96 | }
97 | });
98 |
99 | this.app.post('/userSessionCheck', async (request,response) =>{
100 | const userId = request.body.userId;
101 | const sessionCheckResponse = {}
102 | if (userId == '') {
103 | sessionCheckResponse.error = true;
104 | sessionCheckResponse.message = `User Id cant be empty.`;
105 | response.status(412).json(sessionCheckResponse);
106 | }else{
107 | const username = await helper.userSessionCheck(userId);
108 | if (username === null || username === '') {
109 | sessionCheckResponse.error = true;
110 | sessionCheckResponse.message = `User is not logged in.`;
111 | response.status(401).json(sessionCheckResponse);
112 | }else{
113 | sessionCheckResponse.error = false;
114 | sessionCheckResponse.username = username;
115 | sessionCheckResponse.message = `User logged in.`;
116 | response.status(200).json(sessionCheckResponse);
117 | }
118 | }
119 | });
120 |
121 | this.app.post('/getMessages',async (request,response) => {
122 | const userId = request.body.userId;
123 | const toUserId = request.body.toUserId;
124 | const messages = {}
125 | if (userId === '') {
126 | messages.error = true;
127 | messages.message = `userId cant be empty.`;
128 | response.status(200).json(messages);
129 | }else{
130 | const result = await helper.getMessages( userId, toUserId);
131 | if (result === null) {
132 | messages.error = true;
133 | messages.message = `Internal Server error.`;
134 | response.status(500).json(messages);
135 | }else{
136 | messages.error = false;
137 | messages.messages = result;
138 | response.status(200).json(messages);
139 | }
140 | }
141 | });
142 |
143 | this.app.get('*',(request,response) =>{
144 | response.sendFile(path.join(__dirname + '../../client/views/index.html'));
145 | /*
146 | * OR one can define the template engine and use response.render();
147 | */
148 | });
149 | }
150 |
151 | routesConfig(){
152 | this.appRoutes();
153 | }
154 | }
155 | module.exports = Routes;
--------------------------------------------------------------------------------
/utils/socket.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Real Time chatting app
3 | * @author Shashank Tiwari
4 | */
5 | 'use strict';
6 |
7 | const path = require('path');
8 | const helper = require('./helper');
9 |
10 | class Socket{
11 |
12 | constructor(socket){
13 | this.io = socket;
14 | }
15 |
16 | socketEvents(){
17 |
18 | this.io.on('connection', (socket) => {
19 |
20 | /**
21 | * get the user's Chat list
22 | */
23 | socket.on('chat-list', async (userId) => {
24 |
25 | let chatListResponse = {};
26 |
27 | if (userId === '' && (typeof userId !== 'string' || typeof userId !== 'number')) {
28 |
29 | chatListResponse.error = true;
30 | chatListResponse.message = `User does not exits.`;
31 |
32 | this.io.emit('chat-list-response',chatListResponse);
33 | }else{
34 | const result = await helper.getChatList(userId, socket.id);
35 | this.io.to(socket.id).emit('chat-list-response', {
36 | error: result !== null ? false : true,
37 | singleUser: false,
38 | chatList: result.chatlist
39 | });
40 |
41 | socket.broadcast.emit('chat-list-response', {
42 | error: result !== null ? false : true,
43 | singleUser: true,
44 | chatList: result.userinfo
45 | });
46 | }
47 | });
48 | /**
49 | * send the messages to the user
50 | */
51 | socket.on('add-message', async (data) => {
52 |
53 | if (data.message === '') {
54 |
55 | this.io.to(socket.id).emit(`add-message-response`,`Message cant be empty`);
56 |
57 | }else if(data.fromUserId === ''){
58 |
59 | this.io.to(socket.id).emit(`add-message-response`,`Unexpected error, Login again.`);
60 |
61 | }else if(data.toUserId === ''){
62 |
63 | this.io.to(socket.id).emit(`add-message-response`,`Select a user to chat.`);
64 |
65 | }else{
66 | let toSocketId = data.toSocketId;
67 | const sqlResult = await helper.insertMessages({
68 | fromUserId: data.fromUserId,
69 | toUserId: data.toUserId,
70 | message: data.message
71 | });
72 | this.io.to(toSocketId).emit(`add-message-response`, data);
73 | }
74 | });
75 |
76 |
77 | /**
78 | * Logout the user
79 | */
80 | socket.on('logout', async () => {
81 | const isLoggedOut = await helper.logoutUser(socket.id);
82 | this.io.to(socket.id).emit('logout-response',{
83 | error : false
84 | });
85 | socket.disconnect();
86 | });
87 |
88 |
89 | /**
90 | * sending the disconnected user to all socket users.
91 | */
92 | socket.on('disconnect',async ()=>{
93 | const isLoggedOut = await helper.logoutUser(socket.id);
94 | setTimeout(async ()=>{
95 | const isLoggedOut = await helper.isUserLoggedOut(socket.id);
96 | if (isLoggedOut && isLoggedOut !== null) {
97 | socket.broadcast.emit('chat-list-response', {
98 | error: false,
99 | userDisconnected: true,
100 | socketId: socket.id
101 | });
102 | }
103 | },1000);
104 | });
105 |
106 | });
107 |
108 | }
109 |
110 | socketConfig(){
111 |
112 | this.io.use( async (socket, next) => {
113 | let userId = socket.request._query['userId'];
114 | let userSocketId = socket.id;
115 | const response = await helper.addSocketId( userId, userSocketId);
116 | if(response && response !== null){
117 | next();
118 | }else{
119 | console.error(`Socket connection failed, for user Id ${userId}.`);
120 | }
121 | });
122 |
123 | this.socketEvents();
124 | }
125 | }
126 | module.exports = Socket;
--------------------------------------------------------------------------------