├── .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;b1){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 |
21 | 22 |
23 |
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 |
11 | 12 | 13 |
14 | 15 | 16 |
17 | 18 | 19 | 20 | 39 | 40 | 41 | 42 | 43 |
44 |
45 | 46 | 55 |
56 |
57 | 60 |
61 | 62 |
63 |
64 | 65 | 70 |
71 | 72 |
73 |
74 | 75 |
76 |
77 |
78 |
79 |
-------------------------------------------------------------------------------- /client/views/pages/home.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

Welcome {{ data.username }}

5 | 6 | 7 | 8 |
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; --------------------------------------------------------------------------------