angular.module('homepage', ['ngStorage', 'ui.router', 'trailicons', 'templates']);
angular.module('trailicons', []);
angular.module('templates', []);
angular.module('homepage').
controller('DemoController', function ($scope, AddTemplates, DataStoreSrvc, Server, TimelineService) {
var timelineData = DataStoreSrvc.getPosts();
var sidebarData = DataStoreSrvc.getSidebarData();
var widgetsData = DataStoreSrvc.getWidgetsData();
var data = {
timeline: timelineData,
sidebar: sidebarData,
widgets: widgetsData
};
DataStoreSrvc.resetAll();
$scope.data = data;
function getDemoData() {
TimelineService.setLoadingStatus(true);
Server.getDemoData()
.success(function (result) {
console.log(result);
AddTemplates.addData(result.data.templates);
TimelineService.setLoadingStatus(false);
});
}
getDemoData();
});
angular.module('homepage').
controller('HomeController', function ($scope, DataStoreSrvc, TemplateService) {
var timelineData = DataStoreSrvc.getPosts();
var sidebarData = DataStoreSrvc.getSidebarData();
var widgetsData = DataStoreSrvc.getWidgetsData();
var data = {
timeline: timelineData,
sidebar: sidebarData,
widgets: widgetsData
};
$scope.data = data;
TemplateService.getTemplates();
});
angular.module('homepage').
config(function($httpProvider) {
var interceptor = function($q, $location, $localStorage) {
function success(response) {
response.headers = response.headers || {};
if ($localStorage.token) {
response.headers.Authorization = 'Bearer ' + $localStorage.token;
}
return response;
}
function error(response) {
if (response.status === 401 || response.status === 403) {
$location.path('/#/login');
}
return $q.reject(response);
}
return function(promise) {
return promise.then(success, error);
};
};
$httpProvider.interceptors.push(interceptor);
}).
run(function($http, $localStorage, $rootScope, Authentication, MobileType, Server) {
function setMobileType() {
$rootScope.isMobile = MobileType.any();
}
// TODO load local storage templates on load
function initializeLocalStorage() {
if(!($localStorage.templates && $localStorage.templates.length)) {
$localStorage.templates = [];
}
else {
Server.ibsubmit({ 'templates': $localStorage.templates})
.success(function (result) {
console.log(result);
if(result.success) {
$localStorage.templates = [];
}
});
}
}
function initializeDefaults() {
// Set the token as header for your requests!
$http.defaults.headers.common['X-Auth-Token'] = $localStorage.token;
}
function initializeAuthentication() {
$rootScope.userDtls = Authentication.getUser();
$rootScope.isAuthenticated = Authentication.isAuthenticated();
}
function initialize() {
setMobileType();
initializeDefaults();
initializeLocalStorage();
initializeAuthentication();
}
initialize();
window.addEventListener("orientationchange", setMobileType, false);
window.addEventListener("resize", setMobileType, false);
});
angular.module("templates").run(["$templateCache", function($templateCache) {$templateCache.put("components/common-components/autocomplete/autocomplete.html","<div class=\"autocomplete\">\n <input class=\"inputtext\" type=\"text\" ng-model=\"enteredtext\" ng-keyup=\"filterItems()\"/>\n <div class=\"choices\" ng-show=\"isVisible.suggestions\">\n <div class=\"choice\" ng-repeat=\"choice in filteredChoices\"\n ng-click=\"selectItem(choice.index)\">{{choice.label}}</div>\n </div>\n</div>");
$templateCache.put("components/common-components/buble/buble.html","<div class=\"buble {{size}}x\">\n <span class=\"content\">\n <span class=\"title\">{{title}}</span>\n <span class=\"value\">{{value}}</span>\n </span>\n</div>");
$templateCache.put("components/common-components/calendar/calendar-dual.html","<div class=\"input-value-wrapper\">\n <div class=\"start\">\n <div class=\"show-date\">{{dates[\'START\'].date | date:\'d MMM yyyy\'}}</div>\n <calendar date=\"dates[\'START\']\"></calendar>\n </div>\n <div class=\"end\">\n <div class=\"show-date\">{{dates[\'END\'].date | date:\'d MMM yyyy\'}}</div>\n <calendar date=\"dates[\'END\']\"></calendar>\n </div>\n</div>");
$templateCache.put("components/common-components/calendar/calendar.html","<div class=\"calendar\">\n <div class=\"display-info\" ng-click=\"toggleCalendar()\">\n <span ng-show=\"options.isShowDate && options.isShowBefore\"\n class=\"show-date\">{{chosendate.date | date:\'d MMM yyyy\'}}</span>\n <span class=\"calendar-icon\">\n <span class=\"glyphicon glyphicon-calendar\"></span>\n </span>\n <span ng-show=\"options.isShowDate && !options.isShowBefore\"\n class=\"show-date\">{{chosendate.date | date:\'d MMM yyyy\'}}</span>\n </div>\n <div class=\"calendarwidget\" ng-show=\"isCalendarVisible\">\n <div class=\"calendar-head\">\n <span class=\"btn back\" ng-click=\"setDateMonth($event, -1)\"><<</span>\n <span class=\"date\">{{ tempDate | date:\'d MMM yyyy\'}}</span>\n <span class=\"btn frwd\" ng-click=\"setDateMonth($event, 1)\">>></span>\n </div>\n <div class=\"week-title\">\n <span class=\"day-title\" ng-repeat=\"title in weekTitle\">{{title}}</span>\n </div>\n <div class=\"week\" ng-repeat=\"week in weeks\">\n <span class=\"day {{selectionDay == day ? \'highlight\' : \'regular\'}}\"\n ng-repeat=\"day in week track by $index\"\n ng-click=\"dateClicked($event, day)\">{{day}}</span>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/common-components/checkbox/checkbox.html","<span class=\"checkbox\">\n <input type=\"checkbox\" id=\"{{::name}}\" name=\"cc\" ng-model=\"isChecked\"\n ng-click=\"markCheckboxFn({\'name\':name, \'isChecked\': isChecked})\"/>\n <label for=\"{{::name}}\">\n <span class=\"icon\"></span>\n <span class=\"label-text\">{{::label}}</span>\n </label>\n</span>\n");
$templateCache.put("components/common-components/editor/editor.html","<div>\n <div class=\"editorbox\" contenteditable=\"{{isEditable}}\" ng-model=\"note.editor\"\n ng-paste=\"handlePaste($event)\"><br></div>\n</div>");
$templateCache.put("components/common-components/fullscreen-dialog/fullscreen-dialog.html","");
$templateCache.put("components/common-components/repetition/repetition.html","<div class=\"repetition choose-one\">\n <div class=\"selector\">\n <div class=\"title\">\n Repeat\n </div>\n <div class=\"choices interval\">\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'ONCE\')\"\n ng-class=\"{\'chosen\' : defaults.repeat == \'ONCE\'}\"\n on-action=\"\'CLICK, [days, select, count, months], [false, false, false, false]\'\"\n scope-obj=\"isVisible\" chooseone=\"interval\">Once</button>\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'DALY\')\"\n ng-class=\"{\'chosen\' : defaults.repeat == \'DALY\'}\"\n on-action=\"\'CLICK, [days, select, count, months], [false, false, false, false]\'\"\n scope-obj=\"isVisible\" chooseone=\"interval\">Daily</button>\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'WEEK\')\"\n ng-class=\"{\'chosen\' : defaults.repeat == \'WEEK\'}\"\n on-action=\"\'CLICK, [days, select, count, months], [false, false, false, false]\'\"\n scope-obj=\"isVisible\" chooseone=\"interval\">Weekly</button>\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'MTLY\')\"\n ng-class=\"{\'chosen\' : defaults.repeat == \'MTLY\'}\"\n on-action=\"\'CLICK, [days, select, count, months], [false, false, false, false]\'\"\n scope-obj=\"isVisible\" chooseone=\"interval\">Monthly</button>\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'ANLY\')\"\n ng-class=\"{\'chosen\' : defaults.repeat == \'ANLY\'}\"\n on-action=\"\'CLICK, [days, select, count, months], [false, false, false, false]\'\"\n scope-obj=\"isVisible\" chooseone=\"interval\">Annually</button>\n </div>\n </div>\n <div class=\"selector\" ng-show=\"isVisible.days\">\n <div class=\"title aligntop\">\n Choose Days\n </div>\n <div class=\"choices\" on-action=\"\'CLICK, [count], true\'\" scope-obj=\"isVisible\">\n <div class=\"typeofday\">\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'WKDY\')\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth, choosedays], [true, true, false, false, false]\'\"\n scope-obj=\"isVisible\" chooseone=\"typeofday\">Weekday</button>\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'WKED\')\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth, choosedays], [true, true, false, false, false]\'\"\n scope-obj=\"isVisible\" chooseone=\"typeofday\">Weekend</button>\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'HLDY\')\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth, choosedays], [true, true, false, false, false]\'\"\n scope-obj=\"isVisible\" chooseone=\"typeofday\">Holiday</button>\n <button class=\"choice btn btn-choice\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth, choosedays], [false, false, false, false, true]\'\"\n scope-obj=\"isVisible\" chooseone=\"typeofday\">Choose</button>\n </div>\n <div class=\"dayofweek\" ng-show=\"isVisible.choosedays\">\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'MON\')\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth], [true, false, true, false]\'\"\n scope-obj=\"isVisible\" choosemany=\"dayofweek\">Mon</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'TUE\')\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth], [true, false, true, false]\'\"\n scope-obj=\"isVisible\" choosemany=\"dayofweek\">Tue</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'WED\')\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth], [true, false, true, false]\'\"\n scope-obj=\"isVisible\" choosemany=\"dayofweek\">Wed</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'THU\')\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth], [true, false, true, false]\'\"\n scope-obj=\"isVisible\" choosemany=\"dayofweek\">Thu</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'FRI\')\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth], [true, false, true, false]\'\"\n scope-obj=\"isVisible\" choosemany=\"dayofweek\">Fri</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'SAT\')\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth], [true, false, true, false]\'\"\n scope-obj=\"isVisible\" choosemany=\"dayofweek\">Sat</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'SUN\')\"\n on-action=\"\'CLICK, [count, countday, countchoosenday, countmonth], [true, false, true, false]\'\"\n scope-obj=\"isVisible\" choosemany=\"dayofweek\">Sun</button>\n </div>\n </div>\n </div>\n <div class=\"selector\" ng-show=\"isVisible.select\">\n <div class=\"title\">\n Select\n </div>\n <div class=\"choices choosemonthtype\">\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'ALL\')\"\n on-action=\"\'CLICK, [count, countmonth, months], [false, false, false]\'\"\n scope-obj=\"isVisible\" chooseone=\"choosemonthtype\">All</button>\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'CHSE\')\"\n on-action=\"\'CLICK, [count, countmonth, months], [false, true, true]\'\"\n scope-obj=\"isVisible\" chooseone=\"choosemonthtype\">Choose</button>\n <!-- <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'CONT\')\"\n on-action=\"\'CLICK, [count, countmonth, months], [true, true, false]\'\"\n scope-obj=\"isVisible\" chooseone=\"choosemonthtype\">Count</button> -->\n </div>\n </div>\n <div class=\"selector\" ng-show=\"isVisible.months\">\n <div class=\"title\">\n Choose Months\n </div>\n <div class=\"choices choosemonth\">\n <div class=\"typeofday\">\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'JAN\')\"\n choosemany=\"choosemonth\">Jan</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'FEB\')\"\n choosemany=\"choosemonth\">Feb</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'MAR\')\"\n choosemany=\"choosemonth\">Mar</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'APR\')\"\n choosemany=\"choosemonth\">Apr</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'MAY\')\"\n choosemany=\"choosemonth\">May</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'JUN\')\"\n choosemany=\"choosemonth\">Jun</button>\n </div>\n <div class=\"typeofday\">\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'JUL\')\"\n choosemany=\"choosemonth\">Jul</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'AUG\')\"\n choosemany=\"choosemonth\">Aug</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'SEP\')\"\n choosemany=\"choosemonth\">Sep</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'OCT\')\"\n choosemany=\"choosemonth\">Oct</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'NOV\')\"\n choosemany=\"choosemonth\">Nov</button>\n <button class=\"choice day btn btn-choice\" ng-click=\"selectOption(\'DEC\')\"\n choosemany=\"choosemonth\">Dec</button>\n </div>\n </div>\n </div>\n <!-- <div class=\"selector\" ng-show=\"isVisible.count\">\n <div class=\"title aligntop\">\n By Count\n </div>\n <div class=\"choices\">\n <div class=\"countmsg\" ng-show=\"isVisible.countday\">\n <button class=\"choice btn btn-choice\">nth</button>\n <button class=\"choice text\">weekday of the</button>\n <button class=\"choice btn btn-choice\">month</button>\n <button class=\"choice btn btn-choice\">year</button>\n </div>\n <div class=\"countmsg\" ng-show=\"isVisible.countchoosenday\">\n <button class=\"choice btn btn-choice\">nth</button>\n <button class=\"choice text\">tuesday of the</button>\n <button class=\"choice btn btn-choice\">month</button>\n <button class=\"choice btn btn-choice\">year</button>\n </div>\n <div class=\"countmsg\" ng-show=\"isVisible.countmonth\">\n <button class=\"choice btn btn-choice\">nth</button>\n <button class=\"choice text\">month of the year</button>\n </div>\n </div>\n </div> -->\n <!-- <pre>Message here</pre> -->\n</div>\n");
$templateCache.put("components/common-components/select-time/select-time.html","<div class=\"select-time panel\">\n <div class=\"choose-year\">\n <!-- Single button -->\n <div class=\"btn-group\">\n <button type=\"button\" class=\"btn btn-default dropdown-toggle active\" \n data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\n ng-click=\"isYearDdOpen = !isYearDdOpen\">\n <span class=\"year\">{{choosen.year}}</span>\n <span class=\"caret\"></span>\n </button>\n <ul class=\"dropdown-menu\" ng-class=\"{\'show\':isYearDdOpen}\">\n <li ng-repeat=\"year in years\" class=\"dropdown-menu-item\"\n ng-click=\"selectYear(year)\">\n {{year}}\n </li>\n </ul>\n </div>\n </div>\n <div class=\"choose-all\">\n <button type=\"button\" class=\"btn btn-default\" \n ng-class=\"{\'active\': \'ALL\' === choosen.month}\"\n ng-click=\"selectMonth(\'ALL\')\">\n ALL\n </button>\n </div>\n <div class=\"choose-month\">\n <div class=\"\" role=\"group\">\n <button type=\"button\" class=\"btn btn-default\" \n ng-class=\"{\'active\':$index === choosen.month}\" ng-repeat=\"month in months\"\n ng-click=\"selectMonth($index)\">\n {{month}}\n </button>\n </div>\n </div>\n</div>");
$templateCache.put("components/common-components/tags/tags-autocomplete.html","<div class=\'tags tags-autocomplete\'>\n <div class=\'btn-success tag-pill\' data-ng-repeat=\"tag in tags track by $index\">\n <span>{{tag.text}}</span>\n <div class=\'delete-tag\' data-ng-click=\'deleteTag($index)\'>×</div>\n </div>\n <autocomplete choices=\"choices\" enteredtext=\"enteredtext\" onselect=\"addTag()\"\n minlength=\"1\" result=\"tagobj\" type=\"type\"></autocomplete>\n</div>\n");
$templateCache.put("components/common-components/tags/tags-list.html","<div class=\"tags-list\">\n <span ng-hide=\"taglist.length > 0\">none</span>\n <span ng-show=\"taglist.length > 0\">\n <span ng-repeat=\"textitem in taglist\">\n <span>{{textitem.text}}{{ $index + 1 === taglist.length ? \"\" : \", \"}}</span>\n </span>\n </span>\n</div>\n");
$templateCache.put("components/common-components/tags/tags.html","<div class=\'tags\'>\n <div class=\'btn-success tag-pill\' data-ng-repeat=\"tag in tags\">\n <span>{{tag.text}}</span>\n <div class=\'delete-tag\' data-ng-click=\'deleteTag($index)\'>×</div>\n </div>\n <input type=\'text\' ng-model=\'enteredtext\' placeholder=\'{{placeholder}}\'/>\n</div>\n");
$templateCache.put("components/common-components/timepicker/timepicker.html","<div class=\"timepickerwidget\" ng-show=\"isTimePickerVisible\" ng-click=\"$event.stopPropagation()\">\n <div class=\"input-wrapper one first\">\n <button class=\"button button-up\" ng-click=\"setHour(1)\">\n <i class=\"glyphicon glyphicon-chevron-up\"></i>\n </button>\n <label class=\"form-control field\">{{selected.date | date:\'h\'}}</label>\n <button class=\"button button-down\" ng-click=\"setHour(-1)\">\n <i class=\"glyphicon glyphicon-chevron-down\"></i>\n </button>\n </div>\n <div class=\"input-wrapper one\">\n <button class=\"button button-up\" ng-click=\"setMins(5)\">\n <i class=\"glyphicon glyphicon-chevron-up\"></i>\n </button>\n <input type=\"number\" class=\"input form-control field\" maxlength=\"2\" ng-model=\"selected.mins\">\n <button class=\"button button-down\" ng-click=\"setMins(-5)\">\n <i class=\"glyphicon glyphicon-chevron-down\"></i>\n </button>\n </div>\n <div class=\"input-wrapper one last\">\n <button class=\"button button-up\" ng-click=\"setAMPM()\">\n <i class=\"glyphicon glyphicon-chevron-up\"></i>\n </button>\n <label class=\"form-control field\">{{selected.date | date:\'a\'}}</label>\n <button class=\"button button-down\" ng-click=\"setAMPM()\">\n <i class=\"glyphicon glyphicon-chevron-down\"></i>\n </button>\n </div>\n <div class=\"buttons\">\n <button class=\"btn btn-xs btn-danger button\" ng-click=\"setTimeAndHide()\">Save</button>\n <button class=\"btn btn-xs btn-danger button\" ng-click=\"resetTimeAndHide()\">Cancel</button>\n </div>\n</div>\n");
$templateCache.put("components/common-components/timeselector/timeselector.html","<div class=\"time-selector choose-one\">\n <div class=\"choose-time\">\n <button class=\"choice btn btn-danger\" chooseone=\"choosetime\">\n <timepicker time=\"time\" ng-click=\"selectOption(\'TIME\')\"></timepicker>\n </button>\n </div>\n <div class=\"choose-period\">\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'MRNG\')\" \n chooseone=\"choosetime\">Morning</button>\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'AFTN\')\" \n chooseone=\"choosetime\">Afternoon</button>\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'EVNG\')\" \n chooseone=\"choosetime\">Evening</button>\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'NGHT\')\" \n chooseone=\"choosetime\">Night</button>\n <button class=\"choice btn btn-choice fullday\" ng-click=\"selectOption(\'FLDY\')\"\n chooseone=\"choosetime\">Full Day</button>\n <button class=\"choice btn btn-choice fullday chosen\" ng-click=\"selectOption(\'NONE\')\"\n chooseone=\"choosetime\">None</button>\n </div>\n <div class=\"choose-all\">\n <button class=\"choice btn btn-choice\" ng-click=\"selectOption(\'FLDY\')\"\n chooseone=\"choosetime\">Full Day</button>\n <button class=\"choice btn btn-choice chosen\" ng-click=\"selectOption(\'NONE\')\"\n chooseone=\"choosetime\">None</button>\n </div>\n</div>");
$templateCache.put("components/common-components/title/title.html","<div class=\"inputfield title\">\n <input class=\"input-value\" type=\"text\" ng-model=\"note.title\" placeholder=\"Title\" \n onfocus=\"this.placeholder = \'\'\" onblur=\"this.placeholder = \'Title\'\">\n</div>");
$templateCache.put("components/common-components/totaltimeselector/totaltimeselector.html","<div class=\"total-time-selector choose-one\">\n <div class=\"choose-time\">\n <label class=\"choice-label\">Start Time</label>\n <button class=\"choice btn btn-danger\" choosemany=\"choosetime\">\n <timepicker time=\"times[\'START\']\" ng-click=\"selectOption(\'TIME\')\"></timepicker>\n </button>\n </div>\n <div class=\"choose-time end-time\">\n <label class=\"choice-label\">End Time</label>\n <button class=\"choice btn btn-danger\" choosemany=\"choosetime\">\n <timepicker time=\"times[\'END\']\" ng-click=\"selectOption(\'TIME\')\"></timepicker>\n </button>\n </div>\n</div>");
$templateCache.put("components/content-components/drawer/drawer-menu.html","<div class=\"drawer-menu\" ng-if=\"isMobile\">\n <div class=\"drawer-icon\">\n <i class=\"fa fa-bars menu-icon\" aria-hidden=\"true\" ng-click=\"toggleDrawer()\"></i>\n </div>\n <div class=\"menu-sidebar\" ng-show=\"isPanelVisible\">\n <div class=\"menu-item\">\n <a href=\"/#/home\" ng-click=\"hideDrawer()\">Home</a>\n </div>\n <div class=\"menu-item\">\n <a href=\"/#/comment\" ng-click=\"hideDrawer()\">Feedback</a>\n </div>\n <!-- <div class=\"menu-item\">\n <a href=\"/#/about\" ng-click=\"hideDrawer()\">About Us</a>\n </div> -->\n <div class=\"menu-item register\">\n <a href=\"/#/signup\" ng-click=\"hideDrawer()\">Register</a>\n </div>\n </div>\n</div>");
$templateCache.put("components/content-components/footer/footer.html","<div class=\"copyright-wrapper\">\n <div class=\"copyright text-center\">\n Copyright © 2016 InputBox\n </div>\n</div>\n");
$templateCache.put("components/content-components/header/header-menu.html","<div class=\"header-menu\">\n <div class=\"item hidden-xs\">\n <a href=\"/#/comment\">\n <i class=\"fa fa-comment-o\" aria-hidden=\"true\"></i>\n </a>\n </div>\n <div class=\"item\" ng-hide=\"isAuthenticated\">\n <a class=\"clickable\" href=\"/#/login\">Login</a>\n </div>\n <div class=\"item hidden-very-xs\" ng-hide=\"isAuthenticated\">\n <a class=\"btn clickable register\" href=\"/#/register\">Register</a>\n </div>\n <div class=\"item\" ng-show=\"isAuthenticated\">\n <a class=\"btn clickable register\" ng-click=\"logout()\">Log Out</a>\n </div>\n</div>\n");
$templateCache.put("components/content-components/header/header.html","<div class=\"header-wrapper\">\n <div class=\"header container\">\n <div class=\"title\">\n <drawer-menu></drawer-menu>\n <a class=\"inputbox-link\" ng-click=\"loadDefaultPage()\">INPUTBOX</a>\n </div>\n <header-menu></header-menu>\n </div>\n</div>\n");
$templateCache.put("components/content-components/home/home.html","<div class=\"container\">\n <div class=\"home col-xs-12 col-sm-12 col-md-12\" ng-init=\"getUser()\">\n <ng-transclude></ng-transclude>\n </div>\n</div>\n");
$templateCache.put("components/content-components/inputbox/inputbox.html","<div class=\"inputbox\">\n <div class=\"input-box-wrapper\">\n <div class=\"box clearfix\">\n <div class=\"box-content\" ng-if=\"currenttype == \'\'\">\n <div class=\"titlebar\">ADD NEW</div>\n <div class=\"flex-container items {{list.length}}\">\n <div class=\"item\" ng-repeat=\"item in list\" sgl-click=\"select(item.type)\" ng-dblclick=\"open(item.page)\">\n <div class=\"icon icon-fa-{{::item.icon}}\" ng-if=\"item.src != \'\'\">\n <i class=\"fa fa-{{::item.icon}}\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"title\">\n {{::item.name}}\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"forms\">\n <div class=\"note-tmplt\" ng-if=\"currenttype == \'NOTE\'\">\n <div class=\"titlebar\">NOTE</div>\n <form>\n <note-panel note=\"data.note\"></note-panel>\n </form>\n </div>\n <div class=\"list-tmplt\" ng-if=\"currenttype == \'LIST\'\">\n <div class=\"titlebar\">LIST</div>\n <form>\n <list-panel list=\"data.list\"></list-panel>\n </form>\n </div>\n <div class=\"activity-tmplt\" ng-if=\"currenttype == \'ACTY\'\">\n <div class=\"titlebar\">ACTIVITY</div>\n <form>\n <activity-panel activity=\"data.activity\"></activity-panel>\n </form>\n </div>\n <div class=\"mood-tmplt\" ng-if=\"currenttype == \'MOOD\'\">\n <div class=\"titlebar\">MOOD</div>\n <form>\n <div class=\"inputfield\">\n <label class=\"input-title\">Mark your mood level</label>\n <mood-panel mood=\"data.mood\"></mood-panel>\n </div>\n </form>\n </div>\n <div class=\"habit-tmplt\" ng-if=\"currenttype == \'HABT\'\">\n <div class=\"titlebar\">HABIT</div>\n <form>\n <habit-panel habit=\"data.habit\"></habit-panel>\n </form>\n </div>\n <div class=\"fitness-tmplt\" ng-if=\"currenttype == \'HLTH\'\">\n <div class=\"titlebar\">FITNESS</div>\n <form class=\"fitness-panel\">\n <fitness-panel fitness=\"data.fitness\"></fitness-panel>\n <!-- <div class=\"add-new\">\n ADD ANOTHER WORKOUT\n </div> -->\n </form>\n </div>\n <div class=\"food-tmplt\" ng-if=\"currenttype == \'FOOD\'\">\n <div class=\"titlebar\">FOOD</div>\n <form class=\"food-panel\">\n <food-panel food=\"data.food\"></food-panel>\n <!-- <div class=\"add-new\">\n ADD ANOTHER ITEM\n </div> -->\n </form>\n </div>\n <div class=\"money-tmplt\" ng-if=\"currenttype == \'MNEY\'\">\n <div class=\"titlebar\">MONEY</div>\n <form>\n <finance-panel finance=\"data.finance\"></finance-panel>\n <!-- <div class=\"add-new\">\n ADD ANOTHER EXPENSE\n </div> -->\n </form>\n </div>\n <div class=\"places-tmplt\" ng-if=\"currenttype == \'PLCS\'\">\n <div class=\"titlebar\">PLACE</div>\n <form>\n <place-panel place=\"data.place\"></place-panel>\n </form>\n </div>\n <div class=\"media-tmplt\" ng-if=\"currenttype == \'MDIA\'\">\n <div class=\"titlebar\">MEDIA</div>\n <form>\n <media-panel media=\"data.media\"></media-panel>\n </form>\n </div>\n <div class=\"people-tmplt\" ng-if=\"currenttype == \'PEPL\'\">\n <div class=\"titlebar\">PEOPLE</div>\n <form>\n <people-panel people=\"data.people\"></people-panel>\n </form>\n </div>\n <div class=\"calendar-tmplt\" ng-if=\"currenttype == \'CLDR\'\">\n <div class=\"titlebar\">CALENDAR</div>\n <form>\n <calendar-panel calendar=\"data.calendar\"></calendar-panel>\n </form>\n </div>\n </div>\n </div>\n <div class=\"snippet-options clearfix\">\n <div class=\"options calendar\" ng-if=\"currenttype != \'\' && currenttype != \'HABT\' && currenttype != \'CLDR\'\">\n <calendar date=\"selected\" options=\"{isShowDate: true, isShowBefore: false}\"></calendar>\n <span>-</span>\n <timepicker time=\"selected\"></timepicker>\n </div>\n <div class=\"options buttons\" ng-show=\"currenttype != \'\'\">\n <button type=\"submit\" class=\"btn btn-default\" id=\"reset\" ng-click=\"reset()\">Reset</button>\n <button type=\"submit\" class=\"btn button-submit\" id=\"submit\" ng-click=\"submit()\">Submit</button>\n </div>\n </div>\n </div>\n</div>");
$templateCache.put("components/content-components/login/commentpanel.html","<div class=\"row\">\n <style>\n .addcomment {\n font-weight: normal;\n text-align: center;\n text-transform: uppercase;\n }\n </style>\n <div class=\"col-xs-12 col-sm-8 col-sm-offset-2 col-md-10 col-md-offset-1\" ng-controller=\"commentPanelController\">\n <div class=\"signup-wall\">\n <form class=\"form-signin\" name=\"registerationForm\">\n <label class=\"addcomment full-width\" for=\"commentbox\">feeback and suggestions here</label>\n <textarea required class=\"full-width\" name=\"commentbox\" cols=\"30\" rows=\"10\"\n ng-model=\"comment\"></textarea>\n <button type=\"submit\" class=\"btn btn-lg btn-block btn-register ib-blue-bg\"\n ng-click=\"registerationForm.$valid && addcomment()\">Submit</button>\n <span class=\"clearfix\"></span>\n </form>\n </div>\n <div class=\"alert alert-info text-center\" role=\"alert\" ng-show=\"isMessageVisible\">{{::message}}</div>\n </div>\n</div>\n");
$templateCache.put("components/content-components/login/loginpanel.html","<div class=\"row\">\n <div class=\"col-xs-12 col-sm-6 col-sm-offset-3 col-md-10 col-md-offset-1\">\n <div class=\"account-wall\">\n <div class=\"user text-center\">\n <i class=\"fa fa-user\" aria-hidden=\"true\" style=\"font-size: 5em;\"></i>\n </div>\n <form class=\"form-signin\">\n <div class=\"inputfield\">\n <label class=\"input-title\">User Name</label>\n <input type=\"text\" ng-model=\"username\" placeholder=\"\" required autofocus=\"true\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Password</label>\n <input type=\"password\" ng-model=\"password\" placeholder=\"\" required>\n </div>\n <button type=\"submit\" class=\"btn btn-lg btn-primary btn-block btn-register\"\n ng-click=\"authenticate()\">Sign in</button>\n <span class=\"clearfix\"></span>\n </form>\n <div class=\"form-signin\">\n <div class=\"signup\">\n <p class=\"text-center\">New User</p>\n <a href=\"/#/signup\" class=\"text-center new-account\">\n <button type=\"submit\" class=\"btn btn-lg btn-success btn-block\">Sign Up</button>\n </a>\n </div>\n </div>\n <div class=\"alert alert-info text-center\" role=\"alert\" ng-show=\"isMessageVisible\">{{message}}</div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/content-components/login/registerpanel.html","<div class=\"row\">\n <div class=\"col-xs-12 col-sm-6 col-sm-offset-3 col-md-10 col-md-offset-1\">\n <div class=\"signup-wall\">\n <div class=\"register\" ng-hide=\"hasInvite\">\n <h3 class=\"message text-center\">\n <span>Get a</span>\n <span class=\"empahsis ib-pink-txt\" style=\"padding-left: 5px\">\n <i class=\"fa fa-rocket\" aria-hidden=\"true\"></i>\n <span>beta</span>\n </span>\n <span> version invite</span>\n </h3>\n <form class=\"form-signin\" name=\"registerationForm\">\n <div class=\"inputfield\">\n <label class=\"input-title\">Full Name</label>\n <input required type=\"text\" ng-model=\"data.fullname\" placeholder=\"\" autofocus=\"{{!hasInvite}}\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Email</label>\n <input required type=\"email\" ng-model=\"data.email\" placeholder=\"\">\n </div>\n <button type=\"submit\" class=\"btn btn-lg btn-primary btn-block btn-register\"\n ng-click=\"registerationForm.$valid && register() && fbq(\'track\', \'CompleteRegistration\');\">Register</button>\n <span class=\"clearfix\"></span>\n </form>\n </div>\n <div class=\"alert alert-info text-center\" role=\"alert\" ng-show=\"isRegisterMessageVisible\">{{message}}</div>\n <div class=\"invite-code\">\n <h3 class=\"text-center\">Got invite code?</h3>\n <form class=\"form-signin\" name=\"inviteForm\">\n <div class=\"inputfield\">\n <label class=\"input-title\">Invite Code</label>\n <input required type=\"text\" ng-model=\"invite.code\" placeholder=\"\" autofocus=\"{{hasInvite}}\">\n </div>\n <button type=\"submit\" class=\"btn btn-lg btn-success btn-block btn-register\"\n ng-click=\"inviteForm.$valid && checkInviteCode() && fbq(\'track\', \'UsedInviteCode\');\">Submit</button>\n <span class=\"clearfix\"></span>\n </form>\n </div>\n <div class=\"alert alert-info text-center\" role=\"alert\" ng-show=\"isInviteMessageVisible\">{{message}}</div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/content-components/login/signuppanel.html","<div class=\"row\">\n <div class=\"col-md-10 col-md-offset-1\">\n <div class=\"signup-wall\">\n <form class=\"form-signin\">\n <div class=\"inputfield\">\n <label class=\"input-title\">First Name</label>\n <input id=\"firstname\" maxlength=\"15\" required type=\"text\" pattern=\"[A-Za-z]*\"\n oninvalid=\"setCustomValidity(\'Please enter only Alphabets\')\" oninput=\"try{setCustomValidity(\'\')}catch(e){}\"\n ng-model=\"registrationInfo.firstName\" placeholder=\"\" autofocus=\"true\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Last Name</label>\n <input id=\"lastname\" maxlength=\"15\" required type=\"text\" pattern=\"[A-Za-z]*\"\n oninvalid=\"setCustomValidity(\'Please enter only Alphabets\')\" oninput=\"try{setCustomValidity(\'\')}catch(e){}\"\n ng-model=\"registrationInfo.lastName\" placeholder=\"\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Username</label>\n <input id=\"username\" maxlength=\"15\" required type=\"text\" pattern=\"[A-Za-z0-9]*\"\n oninvalid=\"setCustomValidity(\'Special characters not allowed\')\" oninput=\"try{setCustomValidity(\'\')}catch(e){}\"\n ng-model=\"registrationInfo.username\" placeholder=\"\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Password</label>\n <input required type=\"text\" ng-model=\"registrationInfo.password\" placeholder=\"\" class=\"nomargin\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Email</label>\n <input required type=\"email\" ng-model=\"registrationInfo.email\" placeholder=\"\"\n oninvalid=\"setCustomValidity(\'Please enter an email address\')\" oninput=\"try{setCustomValidity(\'\')}catch(e){}\">\n </div>\n <button type=\"submit\" class=\"btn btn-lg btn-primary btn-block btn-register\" ng-click=\"registerUser()\">Submit</button>\n <span class=\"clearfix\"></span>\n </form>\n <div class=\"alert alert-info text-center\" role=\"alert\" ng-show=\"isMessageVisible\">{{message}}</div>\n <div class=\"form-signin\">\n <div class=\"login\">\n <p class=\"text-center\">Already have an account</p>\n <a href=\"/#/login\" class=\"text-center new-account\">\n <button type=\"submit\" class=\"btn btn-lg btn-success btn-block\">Sign In</button>\n </a>\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/content-components/sidebar/sidebar-card.html","<div class=\"sidebar-card\">\n <!-- Habit with trail only -->\n <div class=\"details\" ng-if=\"data.type == \'HBTR\'\">\n <div class=\"row-one\">\n <checkbox label=\"data.label\" name=\"data.hashid\"\n is-checked=\"data.isChecked\" mark-checkbox-fn=\"markCheckbox(data.hashid, data.isChecked)\"></checkbox>\n <div class=\"info\">\n <trail binary=\"data.binaryTrail\"></trail>\n </div>\n </div>\n </div>\n <!-- Habit with trail and time -->\n <div class=\"details\" ng-if=\"data.type == \'HBTT\'\">\n <div class=\"row-one\">\n <checkbox label=\"data.label\" name=\"data.hashid\"\n is-checked=\"data.isChecked\" mark-checkbox-fn=\"markCheckbox(data.hashid, data.isChecked)\"></checkbox>\n <div class=\"info\">\n <trail binary=\"data.binaryTrail\"></trail>\n <div class=\"time\">{{data.date | date:\"h:mma\"}}</div>\n </div>\n </div>\n </div>\n <!-- Calendar reminder without time -->\n <div class=\"details\" ng-if=\"data.type == \'CMWT\'\">\n <div class=\"row-one\">\n <checkbox label=\"data.label ? data.label : \'Event\'\" name=\"data.hashid\"\n is-checked=\"data.isChecked\" mark-checkbox-fn=\"markCheckbox(data.hashid, data.isChecked)\"></checkbox>\n </div>\n </div>\n <!-- Calendar reminder based on time -->\n <div class=\"details\" ng-if=\"data.type == \'CRBT\'\">\n <div class=\"row-one\">\n <checkbox label=\"data.label ? data.label : \'Event\'\" name=\"data.hashid\"\n is-checked=\"data.isChecked\" mark-checkbox-fn=\"markCheckbox(data.hashid, data.isChecked)\"></checkbox>\n <div class=\"info\">\n <div class=\"time\">{{data.times[\'START\'].date | date:\"h:mma\"}}</div>\n </div>\n </div>\n </div>\n <!-- Calendar meeting with time and location -->\n <div class=\"details\" ng-if=\"data.type == \'CMTL\'\">\n <div class=\"row-one\">\n <checkbox label=\"data.label ? data.label : \'Event\'\" name=\"data.hashid\"\n is-checked=\"data.isChecked\" mark-checkbox-fn=\"markCheckbox(data.hashid, data.isChecked)\"></checkbox>\n <div class=\"info\">\n <div class=\"time\">\n {{ \"\" | datediff: data.times[\'START\'].date : data.times[\'END\'].date }}\n </div>\n </div>\n </div>\n <div class=\"row-two\">\n <div class=\"location\">\n <i class=\"fa fa-map-marker map-icon\" aria-hidden=\"true\"></i>\n <span class=\"text\">{{data.locationText}}</span>\n </div>\n <div class=\"time-range\">\n <div class=\"period\">{{data.times[\'START\'].date | date:\"h:mma\"}} - {{data.times[\'END\'].date | date:\"h:mma\"}}</div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/content-components/sidebar/sidebar-template.html","<div class=\"action-bar\">\n <div class=\"section\">\n <div class=\"title\">\n <span ng-show=\"isTodaysDate.isTrue\">Today</span>\n <span ng-hide=\"isTodaysDate.isTrue\">{{currentDate | date:\"d MMM yyyy\"}}</span>\n </div>\n <div class=\"content\">\n <div class=\"morning\">\n <div class=\"heading\">Morning</div>\n <div class=\"cards\" ng-repeat=\"item in data.all.current.morning\">\n <sidebar-card data=\"item\"></sidebar-card>\n </div>\n <div class=\"message\" ng-hide=\"data.all.current.morning.length > 0\">\n Nothing planned\n </div>\n </div>\n <div class=\"afternoon\">\n <div class=\"heading\">Afternoon</div>\n <div class=\"cards\" ng-repeat=\"item in data.all.current.afternoon\">\n <sidebar-card data=\"item\"></sidebar-card>\n </div>\n <div class=\"message\" ng-hide=\"data.all.current.afternoon.length > 0\">\n Nothing planned\n </div>\n </div>\n <div class=\"evening\">\n <div class=\"heading\">Evening</div>\n <div class=\"cards\" ng-repeat=\"item in data.all.current.evening\">\n <sidebar-card data=\"item\"></sidebar-card>\n </div>\n <div class=\"message\" ng-hide=\"data.all.current.evening.length > 0\">\n Nothing planned\n </div>\n </div>\n <div class=\"night\">\n <div class=\"heading\">Night</div>\n <div class=\"cards\" ng-repeat=\"item in data.all.current.night\">\n <sidebar-card data=\"item\"></sidebar-card>\n </div>\n <div class=\"message\" ng-hide=\"data.all.current.night.length > 0\">\n Nothing planned\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/content-components/timeline/timeline-template.html","<div class=\"timeline-template item {{itemType}}\"\n setequalheight=\'{\"main\": \".timeline-detail\", \"others\": [\"\", \".location .line\",\".timeline-bar\", \".details\"], \"offset\":[\"0\",\"{{iconOffset}}\",\"0\", \"0\"]}\'>\n <div class=\"location {{item.isLocationInfoAvailable ? \'\' : \'invisible\'}}\">\n <div class=\"timeline-item {{item.isInSameLocation?\'no-icon\':\'icon\'}}\">\n <i ng-hide=\"item.isInSameLocation\" class=\"{{item.locntype == \'UNKN\' ?\'fa fa-globe\':\'fa fa-globe\'}} {{item.type}}\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"timeline-item line\"></div>\n </div>\n <div class=\"timeline-bar\"></div>\n <div class=\"details\">\n <div class=\"timeline-info col-xs-3\">\n <type-and-time data=\"{\'type\': item.type, \'timestamp\': item.timestamp}\"></type-and-time>\n </div>\n <div class=\"timeline-detail col-xs-9\">\n <ng-include src=\"template\"/>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/content-components/timeline/timeline.html","<div class=\"timeline\">\n <h3 class=\"timeline-title hidden-xs\">Day Progress</h3>\n <!-- <pre ng-hide=\"isDemo\">{{templates | json}}</pre> -->\n <div class=\"timeline-item-pane\">\n <div class=\"date\">\n <div class=\"back\" ng-click=\"changeDate(-1)\">\n <i class=\"fa fa-angle-left\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"currentdate\">\n <div class=\"day\">{{currentDate | date:\"d MMM\"}}</div>\n <div class=\"dayofweek\">{{currentDate | date:\"EEEE\"}}</div>\n </div>\n <div class=\"next\" ng-click=\"changeDate(1)\">\n <i class=\"fa fa-angle-right\" aria-hidden=\"true\"></i>\n </div>\n </div>\n <div class=\"column\">\n <div class=\"item first\">\n <div class=\"location\" ng-click=\"reverseItems()\">\n <i class=\"fa fa-exchange\" aria-hidden=\"true\"\n ng-show=\"timelineItems.length > 0\"></i>\n </div>\n <div class=\"timeline-bar\"></div>\n <div class=\"details\" ng-class=\"{\'hide\': timelineItems.length === 0}\"></div>\n </div>\n <div ng-repeat=\"item in timelineItems\">\n <timeline-template item=\"item\"></timeline-template>\n </div>\n <div class=\"item message\" ng-hide=\"timelineItems.length > 0\">\n <div class=\"location none\"></div>\n <div class=\"timeline-bar\"></div>\n <div class=\"details\">\n <div class=\"icon\">\n <i ng-show=\"isLoading.value\" class=\"fa fa-cog fa-spin fa-fw\" aria-hidden=\"true\"></i>\n <i ng-show=\"!isLoading.value\" class=\"fa fa-anchor\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"text\">\n <span ng-show=\"isLoading.value\">Loading snippets</span>\n <span ng-show=\"!isLoading.value\">Nothing to show here</span>\n </div>\n </div>\n </div>\n <div class=\"item last\">\n <div class=\"location\">\n <div class=\"timeline-item {{::isLocationAvlbl ? \'line\' : \'none\'}}\">\n </div>\n </div>\n <div class=\"timeline-bar\"></div>\n <div class=\"details\"></div>\n </div>\n </div>\n </div>\n <div class=\"habit-item-pane visible-xs\">\n <div ng-repeat=\"item in habitItems\">\n <pre>{{item | json}}</pre><br>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/content-components/timeline/type-and-time.html","<div class=\"type-and-time {{::data.type | lowercase}}\">\n <div class=\"type\">\n <i class=\"fa fa-{{::data.type | typelabel}} icon\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"timestamp\">\n <div class=\"humantime\">{{::data.timestamp | date:\"h:mm a\"}}</div>\n </div>\n</div>");
$templateCache.put("components/feature-components/activity/activity-card.html","<div class=\"activity-card\">\n <div class=\"summary\">\n <div class=\"fields\">\n <div class=\"title field\">\n <div class=\"icon\">\n <i class=\"fa fa-file-text-o\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n {{::(item.data.activitytype ? item.data.activitytype : \'No Activity Type\')}}\n </div>\n </div>\n <div class=\"time field\">\n <div class=\"icon\">\n <i class=\"fa\" aria-hidden=\"true\"\n ng-class=\"\'fa-\' + (item.data.activitytype | activityicon)\"></i>\n </div>\n <div class=\"desc\">\n {{::(item.data.details ? item.data.details : \'No Activity Type\')}}\n </div>\n </div>\n </div>\n </div>\n</div>");
$templateCache.put("components/feature-components/activity/activity-panel.html","<div class=\"activity-panel\">\n <div class=\"activity-type\">\n <div class=\"inputfield\">\n <!-- Activity Panel: List activites and on selection of one, display note -->\n <label class=\"input-title\">Choose type</label>\n <div class=\"menu clearfix\">\n <div class=\"menuitem col-xs-4 col-sm-2\" ng-repeat=\"activityObj in activities\">\n <div class=\"icon\"></div>\n <button class=\"choice btn btn-choice activity\" chooseone=\"activity\"\n ng-click=\"setActivityType(activityObj.code)\">{{activityObj.desc}}</button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"activity-option\" ng-show=\"activity._.isVisible.subtype == true\">\n <!-- SLEEPING -->\n <div class=\"inputfield sleeping\" ng-show=\"activity._.isVisible.sleeptype == true\">\n <label class=\"input-title\">Select detail</label>\n <div class=\"menu clearfix\">\n <div class=\"menuitem col-xs-4 col-sm-2\">\n <div class=\"icon\"></div>\n <button class=\"choice btn btn-choice activity\" chooseone=\"subactivity\"\n ng-click=\"setActivitySubType(\'SLEEP\')\">Off to sleep</button>\n </div>\n <div class=\"menuitem col-xs-4 col-sm-2\">\n <div class=\"icon\"></div>\n <button class=\"choice btn btn-choice activity\" chooseone=\"subactivity\"\n ng-click=\"setActivitySubType(\'AWAKE\')\">Woke up</button>\n </div>\n </div>\n </div>\n <!-- MORE TEXT -->\n <div class=\"inputfield text\" ng-show=\"activity._.isVisible.details == true\">\n <label class=\"input-title\">{{activity.subtypeTitle}}</label>\n <input type=\"text\" name=\"\" class=\"\" ng-model=\"activity.details\"\n on-action=\"\'KEYUP, [whom, note], true\'\" scope-obj=\"activity._.isVisible\">\n </div>\n <div class=\"inputfield text\" ng-show=\"activity.activitytype == \'TRVLG\'\">\n <label class=\"input-title\">Via</label>\n <input type=\"text\" name=\"\" class=\"\" ng-model=\"activity.travellingvia\"\n on-action=\"\'KEYUP, [whom, note], true\'\" scope-obj=\"activity._.isVisible\">\n </div>\n </div>\n <div class=\"whom\" ng-show=\"activity._.isVisible.whom == true\">\n <div class=\"inputfield secondary-detail\">\n <label class=\"input-title\">Who is with you</label>\n <tags-autocomplete choices=\"activity._.names\" enteredtext=\"activity.whom.text\"\n minlength=\"1\" placeholder=\"\" result=\"activity.whom.peopleobj\" type=\"\'WHOM\'\"\n tags=\"activity.whom.taglist\"></tags-autocomplete>\n </div>\n </div>\n <div class=\"note\" ng-show=\"activity._.isVisible.note == true\">\n <div class=\"inputfield secondary-detail\">\n <label class=\"input-title\">More info</label>\n <editor scope-obj=\"activity.note\" is-editable=\"true\"></editor>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/calendar/calendar-card.html","<div class=\"calendar-card\">\n <div class=\"summary\">\n <div class=\"fields\">\n <div class=\"title field\">\n <div class=\"icon\">\n <i class=\"fa fa-file-text-o\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n {{::(item.data.title ? item.data.title : \'Event\')}}\n </div>\n </div>\n <div class=\"time field\" ng-show=\"item.data.time.code\">\n <div class=\"icon\">\n <i class=\"fa fa-at\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n Time: {{::item.data.time.code}}\n </div>\n </div>\n <div class=\"dates field\" ng-show=\"item.data.dates.START.isDateSet || item.data.dates.END.isDateSet\">\n <div class=\"icon\">\n <i class=\"fa fa-calendar-minus-o\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <div ng-show=\"item.data.dates.START.isDateSet\">\n From: {{::item.data.dates.START.date | date:\'d MMM yyyy\'}}\n </div>\n <div ng-show=\"item.data.dates.END.isDateSet\">\n Till: {{::item.data.dates.END.date | date:\'d MMM yyyy\'}}\n </div>\n </div>\n </div>\n <div class=\"repeats field\" ng-show=\"item.data.repetition.repeats\">\n <div class=\"icon\">\n <i class=\"fa fa-refresh\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n Repeats: {{::item.data.repetition.repeats}}\n </div>\n </div>\n <div class=\"where field\" ng-show=\"item.data.placetext\">\n <div class=\"icon\">\n <i class=\"fa fa-map-marker\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n Where: {{::item.data.placetext}}\n </div>\n </div>\n <div class=\"whom field\" ng-show=\"item.data.calendarwhotext\">\n <div class=\"icon\">\n <i class=\"fa fa-user\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n People: {{::(item.data.attendees.tagstext ? item.data.attendees.tagstext : \'None\')}}\n </div>\n </div>\n </div>\n </div>\n</div>");
$templateCache.put("components/feature-components/calendar/calendar-panel.html","<div class=\"calendar-panel\">\n <div class=\"inputfield\">\n <label class=\"input-title\">Title</label>\n <input class=\"input-value\" type=\"text\" ng-model=\"calendar.title\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Start & End Date</label>\n <calendar-dual dates=\"calendar.dates\"></calendar-dual>\n </div>\n <div class=\"inputfield\" on-action=\"\'CLICK, optional, true\'\" scope-obj=\"calendar._.isVisible\">\n <label class=\"input-title\">Choose Time</label>\n <totaltimeselector times=\"calendar.times\"></totaltimeselector>\n </div>\n <div class=\"inputfield\" ng-show=\"calendar._.isVisible.optional == true\">\n <label class=\"input-title\">Repeatition</label>\n <repetition repetition=\"calendar.repetition\" defaults=\"calendar.defaults\"></repetition>\n </div>\n <div class=\"inputfield\" ng-show=\"calendar._.isVisible.optional == true\">\n <label class=\"input-title\">Where</label>\n <autocomplete choices=\"calendar._.places\" enteredtext=\"calendar.placetext\" \n minlength=\"1\" result=\"calendar.placeobj\" type=\"\'WHERE\'\"></autocomplete>\n </div>\n <div class=\"inputfield\" ng-show=\"calendar._.isVisible.optional == true\">\n <label class=\"input-title\">Attendees</label>\n <tags-autocomplete choices=\"calendar._.attendees\" enteredtext=\"calendar.attendees.text\"\n minlength=\"1\" placeholder=\"\" result=\"calendar.attendees.attendeesobj\" type=\"\'WHOM\'\" \n tags=\"calendar.attendees.taglist\"></tags-autocomplete>\n </div>\n</div>");
$templateCache.put("components/feature-components/contact/contact.html","<div>\n <div class=\"content-wrapper\">\n <div class=\"quotation\"><h1 class=\"quote\">We know you are interested in many things. We let you know if any of your interest is losing your attention.</h1></div>\n </div>\n <div class=\"contact-wrapper content-wrapper\">\n <div class=\"contact\">\n <div class=\"contact-links\">\n <h1 class=\"contact-title\">Stay Interested</h1>\n <table class=\"contact-list\">\n <tbody>\n <tr class=\"item\"><td class=\"name\">Twitter</td><td class=\"link\"><a href=\"https://twitter.com/multiinterested\">twitter.com/multiinterested</a></td></tr>\n <tr class=\"item\"><td class=\"name\">Facebook</td><td class=\"link\"><a href=\"https://www.facebook.com/multi.interested\">facebook.com/multi.interested</a></td></tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/finance/finance-card.html","<div class=\"finance-card\">\n <div class=\"summary\" ng-repeat=\"finance in item.data.list\"\n ng-hide=\"finance.amount === \'\' && item.data.list.length > 1\">\n <div class=\"title field\">\n <div class=\"icon\">\n <i class=\"fa fa-file-text-o\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n {{::(finance.title ? finance.title : \'No Title\')}}\n </div>\n </div>\n <div class=\"fields\">\n <div class=\"amount field\">\n <div class=\"icon\">\n <i class=\"fa fa-money\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <span>Amount:</span>\n <span>{{::(finance.amount ? finance.amount : 0)}}</span>\n </div>\n </div>\n <div class=\"paidby field\" ng-show=\"finance.paidby.taglist.length > 0\">\n <div class=\"icon\">\n <i class=\"fa fa-user\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <span>Paid by:</span>\n <tags-list taglist=\"finance.paidby.taglist\"></tags-list>\n </div>\n </div>\n <div class=\"splitbtw field\"\n ng-show=\"finance.splitbtw.taglist.length > 0 && finance.splitbytype !== undefined\">\n <div class=\"icon\">\n <i class=\"fa fa-user\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <span>Split btw:</span>\n <tags-list taglist=\"finance.splitbtw.taglist\"></tags-list>\n </div>\n </div>\n <div class=\"splitbtw field\" ng-show=\"finance.splitbytype !== undefined\">\n <div class=\"icon\">\n <i class=\"fa fa-user\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <span>Split by:</span>\n <span>{{ finance.splitbytype | codeconvert }}</span>\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/finance/finance-member-info.html","<div class=\"memberinfo\">\n <div class=\"transaction splitequally\" ng-if=\"type === \'EQLY\'\">\n <div class=\"spent\" ng-if=\"details.name === \'Myself\'\">\n <!-- You spent/owe Person 321 -->\n <span class=\"desc\">\n <span class=\"text-capitalize\">You</span>\n <span ng-show=\"paidby[0].text === \'Myself\'\">spent</span>\n <span ng-show=\"paidby[0].text !== \'Myself\'\">owe <span class=\"text-capitalize\">{{paidby[0].text}}</span></span>\n </span>\n <span class=\"amount\" ng-show=\"details.amount && details.amount > 0\">{{details.amount / size}}</span>\n </div>\n <div class=\"owes\" ng-if=\"details.name !== \'Myself\'\">\n <!-- Person owes You/Someone 123 -->\n <span class=\"desc\">\n <span class=\"text-capitalize\">{{details.name}}</span>\n <span>owes</span>\n <span class=\"text-capitalize\" ng-show=\"paidby[0].text === \'Myself\'\">You</span>\n <span class=\"text-capitalize\" ng-show=\"paidby[0].text !== \'Myself\'\">{{paidby[0].text}}</span>\n </span>\n <span class=\"amount\" ng-show=\"details.amount && details.amount > 0\">{{details.amount / size}}</span>\n </div>\n </div>\n <div class=\"transaction splitbypayment\" ng-if=\"type === \'PMNT\'\">\n <div class=\"payment\">\n <span class=\"desc\">\n <span class=\"text-capitalize\">{{ details.name === \'Myself\' ? \'You\' : details.name }}</span>\n <span>paid</span>\n </span>\n <input class=\"amount-paid\" type=\"text\" ng-model=\"paidby[index].amount\">\n <span class=\"amount\">\n <span>of {{ details.amount }}</span>\n </span>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/finance/finance-panel.html","<div class=\"finance-panel\">\n <finance-summary data=\"finance\"></finance-summary>\n <div class=\"inputfield\">\n <label class=\"input-title\">Expense Title</label>\n <autocomplete choices=\"finance._.peoples\" enteredtext=\"finance.list[0].title\"\n minlength=\"1\" result=\"finance.list[0].expenseobj\" type=\"\'WHOM\'\"></autocomplete>\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Amount</label>\n <input class=\"input-value\" type=\"number\" ng-model=\"finance.list[0].amount\">\n </div>\n <div class=\"inputfield\" on-action=\"\'[CLICK, KEYUP], [splitbtw, splitby], [true, true]\'\"\n scope-obj=\"finance._.isVisible\">\n <label class=\"input-title\">Paid By</label>\n <tags-autocomplete choices=\"finance._.attendees\" enteredtext=\"finance.list[0].paidby.text\"\n minlength=\"1\" placeholder=\"\" result=\"finance.list[0].paidby.whomobj\" type=\"\'WHOM\'\"\n tags=\"finance.list[0].paidby.taglist\"></tags-autocomplete>\n </div>\n <div class=\"inputfield\" ng-show=\"finance._.isVisible.splitbtw === true\">\n <label class=\"input-title\">Split Between</label>\n <tags-autocomplete choices=\"finance._.attendees\" enteredtext=\"finance.list[0].splitbtw.text\"\n minlength=\"1\" placeholder=\"Me\" result=\"finance.list[0].splitbtw.whomobj\" type=\"\'WHOM\'\"\n tags=\"finance.list[0].splitbtw.taglist\"></tags-autocomplete>\n </div>\n <div class=\"inputfield\" ng-show=\"finance._.isVisible.splitby === true\">\n <label class=\"input-title\">Split By</label>\n <div class=\"payment-type\">\n <button class=\"choice btn btn-choice\" chooseone=\"choosetime\"\n ng-click=\"finance.list[0].splitbytype = \'EQLY\'\" ng-hide=\"finance.list[0].paidby.taglist.length > 1\">Equally</button>\n <!-- <button class=\"choice btn btn-choice\" chooseone=\"choosetime\"\n ng-click=\"finance.list[0].splitbytype = \'PRTS\'\" ng-hide=\"finance.list[0].paidby.taglist.length > 1\">Part</button>\n <button class=\"choice btn btn-choice\" chooseone=\"choosetime\"\n ng-click=\"finance.list[0].splitbytype = \'PRCT\'\" ng-hide=\"finance.list[0].paidby.taglist.length > 1\">Percent</button> -->\n <button class=\"choice btn btn-choice\" chooseone=\"choosetime\"\n ng-click=\"finance.list[0].splitbytype = \'PMNT\'\" ng-show=\"finance.list[0].paidby.taglist.length > 1\">Payment</button>\n </div>\n </div>\n <div class=\"sub-panel\" ng-hide=\"finance.list[0].splitbytype === undefined\">\n <div class=\"more-details\">\n <div class=\"members paid-by-one\" ng-if=\"finance.list[0].splitbytype !== \'PMNT\'\">\n <div class=\"member\" ng-repeat=\"person in finance.list[0].splitbtw.taglist\">\n <finance-member-info details=\"{\'name\': person.text, \'amount\': finance.list[0].amount}\" paidby=\"finance.list[0].paidby.taglist\"\n size=\"finance.list[0].splitbtw.taglist.length\" type=\"finance.list[0].splitbytype\"></finance-member-info>\n </div>\n </div>\n <div class=\"members paid-by-many\" ng-if=\"finance.list[0].splitbytype === \'PMNT\'\">\n <div class=\"member\" ng-repeat=\"person in finance.list[0].paidby.taglist\">\n <finance-member-info details=\"{\'name\': person.text, \'amount\': finance.list[0].amount}\" paidby=\"finance.list[0].paidby.taglist\"\n index=\"$index\" size=\"finance.list[0].splitbtw.taglist.length\" type=\"finance.list[0].splitbytype\"></finance-member-info>\n </div>\n <div class=\"remaining\" ng-show=\"finance.list[0].amount > 0\">\n <span>REMAINING</span>\n <span ng-class=\"{\'text-danger\': remainingAmount < 0}\"\n ng-bind=\"remainingAmount = (finance.list[0].amount - (finance.list[0].paidby.taglist | arraysum: {name: \'amount\'}) )\">\n {{ remainingAmount }}\n </span>\n <span>of {{ finance.list[0].amount }}</span>\n </div>\n </div>\n </div>\n </div>\n <div class=\"inputfield\">\n <button class=\"btn btn-default full-width add-another\" ng-click=\"addNewItem()\">ADD NEW</button>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/finance/finance-summary.html","<div class=\"finance-summary\" ng-show=\"financeList.length > 0\">\n <div class=\"heading\">\n Summary\n </div>\n <div class=\"all\">\n <div class=\"summary-item\" ng-repeat=\"financeitem in financeList = (finance.list | filterByIndex: { exclude: true, index: 0 })\">\n <div class=\"each\">\n <div class=\"heading\">\n <div class=\"title\">{{financeitem.title.length > 0 ? financeitem.title : \'No title\'}}</div>\n <div class=\"amount\">{{financeitem.amount ? financeitem.amount : \'No amount entered\'}}</div>\n </div>\n <div class=\"paidby\">\n <span class=\"title\">Paid by:</span>\n <tags-list taglist=\"financeitem.paidby.taglist\"></tags-list>\n </div>\n <div class=\"splitbtw\" ng-hide=\"financeitem.paidby.taglist.length === 1 && financeitem.paidby.taglist[0] === \'Myself\'\n && financeitem.splitbtw.taglist.length === 1 && financeitem.splitbtw.taglist[0] === \'Myself\'\">\n <span class=\"title\">Split between:</span>\n <tags-list taglist=\"financeitem.splitbtw.taglist\"></tags-list>\n </div>\n <div class=\"splitby\" ng-hide=\"financeitem.splitbytype === undefined\">\n <span class=\"title\">Split by:</span>\n <span class=\"type\">\n <span>{{financeitem.splitbytype | codeconvert}}</span>\n </span>\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/finance/finance-widget.html","<div class=\"widget finance\">\n <div class=\"title\">Money</div>\n <div class=\"content clearfix\">\n <div class=\"wd-row clearfix\" ng-if=\"stats.count > 0\">\n <div class=\"wd-label left col-xs-6\">\n <div class=\"desc\">Today</div>\n <div class=\"value\">{{stats.result.myself.amount_day}}</div>\n </div>\n <div class=\"wd-label right col-xs-6\">\n <div class=\"desc\">Month</div>\n <div class=\"value\">{{stats.result.myself.amount_month}}</div>\n </div>\n </div>\n <!-- <div class=\"wd-row clearfix\">\n <div class=\"wd-label right col-xs-6\">\n <div class=\"desc\">Borrowed</div>\n <div class=\"value\">{{data.borrowed}}</div>\n </div>\n <div class=\"wd-label left col-xs-6\">\n <div class=\"desc\">Lent</div>\n <div class=\"value\">{{data.lent}}</div>\n </div>\n </div>\n <div class=\"wd-centered col-xs-12\">\n <div class=\"wd-label\">\n <div class=\"desc\">Remaining</div>\n <div class=\"value\">{{data.remaining}}</div>\n </div>\n </div> -->\n <div class=\"under-construction text-center\" ng-if=\"stats.count === 0\">\n <div class=\"wait\">\n <i class=\"fa fa-plane\" aria-hidden=\"true\"></i>\n </div>\n <p class=\"message text-uppercase\">Money isnt so worthless</p>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/finance/finance.html","<div class=\"finance-list\">\n <select-time choosen=\"choosen\" get-data=\"getMoneyData\"></select-time>\n \n <h1 class=\"page-title\">\n <span class=\"title\">Finances</span>\n </h1>\n Search: <input ng-model=\"query\" />\n\n <div class=\"finance\" ng-repeat=\"expenses in finances track by $index\" ng-if=\"expenses\">\n <h3 class=\"month\">\n <span class=\"month-name\">{{$index | monthbyindex}}</span>\n <span class=\"month-expenses\">{{expenses.total = getTotal(filteredExpenses,\'amount\')}}</span>\n </h3>\n <div class=\"list\" ng-repeat=\"expense in filteredExpenses = (expenses | filter:query)\">\n <buble size=\"expense.size\" title=\"expense.title\" value=\"expense.amount\"></buble>\n </div>\n </div>\n</div>");
$templateCache.put("components/feature-components/fitness/fitness-card.html","<div class=\"fitness-card\">\n <div class=\"summary\" ng-repeat=\"workout in (item.data.list |\n filterByValue: {name: \'workouttitle\', type:\'EXCL\', value: \'\'})\">\n <div class=\"title field\">\n <div class=\"icon\">\n <i class=\"fa fa-file-text-o\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n {{::(workout.workouttitle ? workout.workouttitle : \'No Title\')}}\n </div>\n </div>\n <div class=\"sets\">\n <div class=\"set title-icon\" ng-show=\"workout.sets.length > 0\">\n <div class=\"repetition field\">\n <div class=\"icon\">\n <i class=\"fa fa-repeat\" aria-hidden=\"true\"></i>\n </div>\n </div>\n <div class=\"weight field\">\n <div class=\"icon\">\n <i class=\"fa fa-balance-scale\" aria-hidden=\"true\"></i>\n </div>\n </div>\n <div class=\"time field\">\n <div class=\"icon\">\n <i class=\"fa fa-clock-o\" aria-hidden=\"true\"></i>\n </div>\n </div>\n <div class=\"time field\">\n <div class=\"icon\">\n <i class=\"fa fa-arrows-h\" aria-hidden=\"true\"></i>\n </div>\n </div>\n </div>\n <div class=\"set\" ng-repeat=\"set in workout.sets\">\n <div>\n <div class=\"repetition field\">\n <div class=\"desc\">\n {{::(set.repetition != \'\' ? set.repetition : \'-\')}}\n </div>\n </div>\n <div class=\"weight field\">\n <div class=\"desc\">\n {{::(set.weight != \'\' ? set.weight : \'-\')}}\n </div>\n </div>\n <div class=\"time field\">\n <div class=\"desc\">\n {{::(set.time != \'\' ? set.time : \'-\')}}\n </div>\n </div>\n <div class=\"distance field\">\n <div class=\"desc\">\n {{::(set.distance != \'\' ? set.distance : \'-\')}}\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/fitness/fitness-panel.html","<div>\n <fitness-summary data=\"fitness\"></fitness-summary>\n <div class=\"inputfield\">\n <label class=\"input-title\">Workout Title</label>\n <autocomplete choices=\"fitness._.workouts\" enteredtext=\"fitness.list[0].workouttitle\" \n minlength=\"1\" result=\"fitness.workoutobj\" type=\"\'WORKOUT\'\"></autocomplete>\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Sets</label>\n <div class=\"items\" ng-repeat=\"set in fitness.list[0].sets\">\n <add-new-set data=\"fitness.list[0].sets\" index=\"$index\"></add-new-set>\n </div>\n </div>\n <div class=\"inputfield\">\n <button class=\"btn btn-default full-width add-another\"\n ng-click=\"addNewItem()\">ADD NEW WORKOUT</button>\n </div>\n</div>");
$templateCache.put("components/feature-components/fitness/fitness-set.html","<div class=\"input-value-wrapper\">\n <label class=\"input-value\">Set {{index + 1}}</label>\n <input class=\"input-value\" type=\"number\" ng-model=\"sets[index].repetition\" placeholder=\"Repetition\">\n <input class=\"input-value\" type=\"text\" ng-model=\"sets[index].weight\" placeholder=\"Weight\">\n <input class=\"input-value\" type=\"text\" ng-model=\"sets[index].time\" placeholder=\"Time\">\n <input class=\"input-value\" type=\"text\" ng-model=\"sets[index].distance\" placeholder=\"Distance\">\n</div>\n");
$templateCache.put("components/feature-components/fitness/fitness-summary.html","<div class=\"fitness-summary\" ng-show=\"fitnessList.length > 0\">\n <div class=\"heading\">\n Summary\n </div>\n <div class=\"workout\"\n ng-repeat=\"workout in fitnessList = (fitness.list | filterByIndex: { exclude: true, index: 0 })\">\n <div class=\"summary\">\n <div class=\"title\">{{ workout.workouttitle.length > 0 ? \'TITLE: \' : \'NO TITLE\'}}{{ workout.workouttitle }}</div>\n <div class=\"set\" ng-repeat=\"set in workout.sets\">\n <div class=\"set-details\" ng-show=\"set.repetition != \'\' || set.weight != \'\' || set.distance != \'\' || set.time != \'\'\">\n <div class=\"set-number\">Set {{ $index + 1}}</div>\n <div class=\"repetition\">{{set.repetition !== \'\' ? set.repetition : \'-\'}}</div>\n <div class=\"weight\">{{set.weight !== \'\' ? set.weight : \'-\'}}</div>\n <div class=\"distance\">{{set.distance !== \'\' ? set.distance : \'-\'}}</div>\n <div class=\"time\">{{set.time !== \'\' ? set.time : \'-\'}}</div>\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/fitness/fitness-widget.html","<div class=\"widget fitness\">\n <div class=\"title\">Workout</div>\n <div class=\"content clearfix\">\n <div class=\"info\" ng-hide=\"data.workouts.length === 0\">\n <div class=\"wd-row\">\n <div class=\"wd-values clearfix\" ng-repeat=\"workout in data.workouts\">\n <div class=\"wd-label left col-xs-6\">\n <div class=\"value\">{{workout.workouttitle}}</div>\n </div>\n <div class=\"wd-label right col-xs-6\">\n <div class=\"value\">{{workout.sets.length}} Sets</div>\n </div>\n <div class=\"wd-moreinfo col-xs-12\">\n {{ workout | workoutSummary }}\n </div>\n </div>\n </div>\n <div class=\"wd-centered col-xs-12\">\n <div class=\"wd-label\">\n <div class=\"value\">\n {{data.message}}\n </div>\n </div>\n </div>\n </div>\n <div class=\"under-construction text-center\" ng-show=\"data.workouts.length === 0\">\n <div class=\"wait\">\n <i class=\"fa fa-bed\" aria-hidden=\"true\"></i>\n </div>\n <p class=\"message text-uppercase\">Why no training</p>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/food/food-card.html","<div class=\"food-card\">\n <div class=\"food-template\">\n <div class=\"summary\">\n <div class=\"quantity field\">\n <div class=\"icon\">\n <i class=\"fa fa-cutlery\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <div class=\"\" ng-repeat=\"fooditem in fooditems = (item.data.list |\n filterByValue: {name: \'mealtype\', type:\'EXCL\', value: \'\'})\">\n <span class=\"title\">{{::(fooditem.foodtext ? fooditem.foodtext : \'No Title\')}}</span>\n <span class=\"qty\" ng-show=\"fooditem.qtytype != \'\'\">{{::fooditem.quantity}}</span>\n <span class=\"type\">{{::fooditem.qtytype | quantityType}}</span>\n </div>\n </div>\n </div>\n <div class=\"calories field\">\n <div class=\"icon\">\n <i class=\"fa fa-bolt\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n {{ item.data.list | totalCaloriesCount }} calories\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/food/food-panel.html","<div>\n <food-summary data=\"food\"></food-summary>\n <div class=\"inputfield first\">\n <label class=\"input-title\">Food Title</label>\n <autocomplete choices=\"food._.foodlist\" enteredtext=\"food.list[0].foodtext\"\n minlength=\"1\" result=\"food.foodobj\" type=\"\'FOOD\'\"></autocomplete>\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Food Type</label>\n <div class=\"food-type choose-one\">\n <button class=\"choice btn btn-choice\" chooseone=\"foodtype\"\n on-action=\"\'CLICK, [mealtype, solidfood, litrefood], [true, true, false]\'\"\n scope-obj=\"isVisible\" ng-click=\"setType(\'FOOD\')\">Food</button>\n <button class=\"choice btn btn-choice\" chooseone=\"foodtype\"\n on-action=\"\'CLICK, [mealtype, solidfood, litrefood], [true, false, true]\'\"\n scope-obj=\"isVisible\" ng-click=\"setType(\'DRNK\')\">Drink</button>\n </div>\n </div>\n <div class=\"inputfield\" ng-show=\"isVisible.mealtype\">\n <label class=\"input-title\">Food Quantity</label>\n <div class=\"quantity-selector choose-one\">\n <div class=\"choose-items\">\n <input class=\"quantity\" maxlength=\"5\" ng-model=\"food.list[0].quantity\" type=\"number\"/>\n </div>\n <div class=\"choose-container\">\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.solidfood\" ng-click=\"setQtyType(\'PCE\')\">Piece</button>\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.solidfood\" ng-click=\"setQtyType(\'TSP\')\">Tbsp</button>\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.solidfood\" ng-click=\"setQtyType(\'BWL\')\">Bowl</button>\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.litrefood\" ng-click=\"setQtyType(\'CUP\')\">Cup</button>\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.litrefood\" ng-click=\"setQtyType(\'GLS\')\">Glass</button>\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.litrefood\" ng-click=\"setQtyType(\'BTL\')\">Bottle</button>\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.litrefood\" ng-click=\"setQtyType(\'PTR\')\">Pitcher</button>\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.litrefood\" ng-click=\"setQtyType(\'TWR\')\">Tower</button>\n <button class=\"choice btn btn-choice weights\" chooseone=\"foodqty\"\n ng-show=\"isVisible.solidfood\" ng-click=\"setQtyType(\'ONC\')\">Ounce</button>\n <button class=\"choice btn btn-choice weights\" chooseone=\"foodqty\"\n ng-show=\"isVisible.solidfood\" ng-click=\"setQtyType(\'GRM\')\">Gram</button>\n <button class=\"choice btn btn-choice weights\" chooseone=\"foodqty\"\n ng-show=\"isVisible.litrefood\" ng-click=\"setQtyType(\'LTR\')\">Litre</button>\n </div>\n <div class=\"choose-weight\">\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.solidfood\" ng-click=\"setQtyType(\'ONC\')\">Ounce</button>\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.solidfood\" ng-click=\"setQtyType(\'GRM\')\">Gram</button>\n <button class=\"choice btn btn-choice\" chooseone=\"foodqty\"\n ng-show=\"isVisible.litrefood\" ng-click=\"setQtyType(\'LTR\')\">Litre</button>\n </div>\n </div>\n </div>\n <div class=\"inputfield calorie-count\" ng-show=\"isVisible.mealtype\">\n <label class=\"input-title\">Calorie Count</label>\n <input class=\"input-value\" type=\"number\" ng-model=\"food.list[0].count\">\n <label class=\"suggested-value {{food.list[0].qtytype}} {{food.list[0].count}}\"\n ng-show=\"food.list[0].qtytype != \'\' && (food.list[0].count == undefined || food.list[0].count == \'\')\">{{food.list[0].foodtext |\n caloriesCount: {\'foodtype\': food.list[0].mealtype, \'quantity\': food.list[0].quantity, \'qtytype\': food.list[0].qtytype, \'calories\': food.list[0].count} }} Cal</label>\n </div>\n <div class=\"inputfield\" ng-show=\"isVisible.mealtype\">\n <button class=\"btn btn-default full-width add-another\" ng-show=\"isVisible.mealtype\"\n ng-click=\"addNewItem()\">ADD NEW</button>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/food/food-summary.html","<div class=\"food-summary\" ng-show=\"filteredFoodList.length > 0 || filteredDrinksList.length > 0\">\n <div class=\"food foods\" ng-show=\"filteredFoodList.length > 0\">\n <div class=\"type\">\n <i class=\"fa fa-cutlery\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">FOOD Summary</div>\n <!-- Assign filtered food.list to filteredFoodList -->\n <div class=\"all\">\n <div class=\"food-summary\" ng-repeat=\"item in filteredFoodList = (food.list | filterMealType: \'FOOD\')\">\n <div class=\"each\">\n <div class=\"info\">\n <div class=\"title\">{{item.foodtext.length > 0 ? item.foodtext : \'No title\'}}</div>\n <div class=\"details\">\n <span class=\"qty\">\n {{item.quantity ? item.quantity : \'X\'}}\n </span>\n <span class=\"usage\">\n {{item.qtytype ? item.qtytype : \'items\' | codeconvert}}\n </span>\n </div>\n </div>\n <div class=\"amount\">{{item.foodtext\n | caloriesCount: {\'foodtype\': item.mealtype, \'quantity\': item.quantity, \'qtytype\': item.qtytype, \'calories\': item.count} }} Cal</div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"food drinks\" ng-show=\"filteredDrinksList.length > 0\">\n <div class=\"type\">\n <i class=\"fa fa-glass\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">DRINK Summary</div>\n <!-- Assign filtered food.list to filteredFoodList -->\n <div class=\"all\">\n <div class=\"food-summary\" ng-repeat=\"item in filteredDrinksList = (food.list | filterMealType: \'DRNK\')\">\n <div class=\"each\">\n <div class=\"info\">\n <div class=\"title\">{{item.foodtext.length > 0 ? item.foodtext : \'No title\'}}</div>\n <div class=\"details\">\n <span class=\"qty\">\n {{item.quantity ? item.quantity : \'X\'}}\n </span>\n <span class=\"usage\">\n {{item.qtytype ? item.qtytype : \'items\' | codeconvert}}\n </span>\n </div>\n </div>\n <div class=\"amount\">{{item.foodtext\n | caloriesCount: {\'foodtype\': item.mealtype, \'quantity\': item.quantity, \'qtytype\': item.qtytype, \'calories\': item.count} }} Cal</div>\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/food/food-widget.html","<div class=\"widget food\">\n <div class=\"title\">Food</div>\n <div class=\"content clearfix\">\n <div class=\"info\" ng-hide=\"data.calories.consumed === 0\">\n <div class=\"wd-row clearfix\">\n <div class=\"wd-label left col-xs-6\">\n <div class=\"desc\">Required</div>\n <div class=\"value\">{{data.calories.required}}</div>\n </div>\n <div class=\"wd-label right col-xs-6\">\n <div class=\"desc\">Consumed</div>\n <div class=\"value\">{{data.calories.consumed}}</div>\n </div>\n </div>\n <div class=\"wd-centered col-xs-12\">\n <div class=\"wd-label\">\n <div class=\"value\">{{data.calories.message}}</div>\n </div>\n </div>\n </div>\n <div class=\"under-construction text-center\" ng-show=\"data.calories.consumed === 0\">\n <div class=\"wait\">\n <i class=\"fa fa-hourglass-start\" aria-hidden=\"true\"></i>\n </div>\n <p class=\"message text-uppercase\">No food info available</p>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/habit/habit-card-detail.html","<div class=\"habit-card\">\n <div class=\"summary\">\n <div class=\"fields\">\n <div class=\"title field\">\n <div class=\"icon\">\n <i class=\"fa fa-file-text-o\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <span>{{::(item.data.title ? item.data.title : \'No Title\')}}</span>\n <span ng-if=\"isMobile\">\n <checkbox label=\"item.data.label\" name=\"item.data.hashid\" is-checked=\"item.data.isChecked\"\n mark-checkbox-fn=\"markCheckbox(item.data.hashid, item.data.isChecked)\"></checkbox>\n </span>\n </div>\n </div>\n <div class=\"repeats field\" ng-show=\"item.data.repetition.repeats\">\n <div class=\"icon\">\n <i class=\"fa fa-refresh\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n Repeats: {{::item.data.repetition.repeats}}\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/habit/habit-card.html","<habit-card-detail item=\"item\"></habit-card-detail>\n");
$templateCache.put("components/feature-components/habit/habit-panel.html","<div class=\"habit-panel\">\n <div class=\"inputfield\">\n <label class=\"input-title\">Name of the new habit</label>\n <input class=\"input-value\" type=\"text\" ng-model=\"habit.title\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Choose Time</label>\n <timeselector scope-obj=\"habit.time\"></timeselector>\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Repeatition</label>\n <repetition repetition=\"habit.repetition\" defaults=\"habit.defaults\"></repetition>\n </div>\n</div>");
$templateCache.put("components/feature-components/list/list-card.html","<div class=\"list-card\">\n <div class=\"summary\">\n <div class=\"title field\">\n <div class=\"icon\">\n <i class=\"fa fa-file-text-o\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n {{::(item.data.title ? item.data.title : \'No Title\')}}\n </div>\n </div>\n <div class=\"fields\">\n <div class=\"total field\">\n <div class=\"icon\">\n <i class=\"fa fa-info\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <list list=\"item.data.list\" is-disabled=\"true\"></list>\n </div>\n </div>\n </div>\n <div class=\"field\">\n <div class=\"icon\">\n <i class=\"fa fa-tags\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <tags-list taglist=\"item.data.tags.taglist\"></tags-list>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/list/list-panel.html","<div class=\"list-panel\">\n <title scope-obj=\"list\"></title>\n <div class=\"inputfield\" on-action=\"\'KEYUP, tags, true\'\" scope-obj=\"list._.isVisible\">\n <label class=\"input-title\">Create list here</label>\n <list list=\"list.list\" is-disabled=\"false\"></list>\n </div>\n <div class=\"inputfield\" ng-show=\"list._.isVisible.tags == true\">\n <label class=\"input-title\">Tags</label>\n <!-- <input class=\"input-value\" type=\"text\" ng-model=\"list.tags\"> -->\n <tags-autocomplete choices=\"list._.tags\" enteredtext=\"list.tags.text\"\n minlength=\"1\" placeholder=\"\" result=\"list.tags.tagobj\" type=\"\'WHOM\'\"\n tags=\"list.tags.taglist\"></tags-autocomplete>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/list/list.html","<div class=\"list\">\n <!-- pass only object, not primitive while using isolated scope directives -->\n <div ng-repeat=\"item in list track by $index\">\n <!-- need to pass parameters from scope into the directive methods, blank or non scope params are not passed to controller method -->\n <listitem list=\"list\" is-disabled=\"isDisabled\" itemindex=\"{index: $index}\"\n set-list=\"setList($index)\"></listitem>\n <list list=\"item.list\" is-disabled=\"isDisabled\" ng-if=\"item.list != undefined\"><list>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/media/media-panel.html","<div class=\"media-panel\">\n <div class=\"inputfield\">\n <label class=\"input-title\">Drag and Drop media file here</label>\n <input class=\"input-value\" type=\"text\" ng-model=\"media.upload\">\n <div class=\"file-upload\">\n <label for=\"inputId\">\n <img class=\"icon attach\" src=\"img/icons/common/attach.svg\" alt=\"\">\n </label>\n <input id=\"inputId\" type=\"file\" style=\"position: fixed; top: -100em\">\n </div>\n <div class=\"upload-status\">\n \n </div>\n <div class=\"upload-btn\">\n \n </div>\n </div>\n</div>");
$templateCache.put("components/feature-components/mood/mood-bar.html","<div class=\"{{data}}\">\n\n <div class=\"time\" ng-class=\"{\'invisible\': data.level < 0}\">{{data.timestamp | date: \'ha\'}}</div>\n <div class=\"bar\">\n <ul class=\"slots\">\n <li class=\"{{slot.type}}\" ng-repeat=\"slot in slots\"></li>\n </ul>\n </div>\n <div class=\"time\" ng-class=\"{\'invisible\': data.level >= 0}\">{{data.timestamp | date: \'ha\'}}</div>\n</div>");
$templateCache.put("components/feature-components/mood/mood-card.html","<div class=\"mood-card\">\n <div class=\"summary\">\n <div class=\"fields\">\n <div class=\"summary field\"><div class=\"icon\">\n <i class=\"fa fa-bar-chart\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n Mood: {{::item.data.label}}\n </div>\n </div>\n <div class=\"field\">\n <div class=\"icon\">\n <i class=\"fa fa-heart\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\" ng-show=\"{{::item.data.selectedFeelingsName != undefined}}\">\n Feeling: {{::item.data.selectedFeelingsName | arr2str}}\n </div>\n <div class=\"desc\" ng-hide=\"{{::item.data.selectedFeelingsName != undefined}}\">\n none\n </div>\n </div>\n\n </div>\n</div>\n</div>\n");
$templateCache.put("components/feature-components/mood/mood-panel.html","<div class=\"mood-panel\">\n <div class=\"item-btns\" on-action=\"\'CLICK, feeling, true\'\" scope-obj=\"mood._.isVisible\">\n <div class=\"item-btn\" ng-repeat=\"mooditem in moods\">\n <button type=\"button\" class=\"btn {{mooditem.btnClass}} {{mood.level == mooditem.level ? \'selected\' : \'\'}}\"\n ng-click=\"selectMood(mooditem.level)\">{{mooditem.level}}</button>\n <div class=\"label\"></div>\n </div>\n </div>\n\n <div class=\"feelings\" ng-show=\"mood._.isVisible.feeling == true\">\n <div class=\"inputfield\">\n <label class=\"input-title\">FEELING</label>\n <div class=\"feeling-list\" on-action=\"\'CLICK, note, true\'\" scope-obj=\"mood._.isVisible\">\n <button type=\"button\" ng-repeat=\"feeling in feelings\"\n class=\"btn btn-xs {{labelType}} {{selectedFeelingsByIndex[$index] ? \'selected\': \'\'}}\"\n ng-click=\"selectFeeling($index, feeling.code)\">{{feeling.name}}</button>\n </div>\n </div>\n </div>\n\n <div class=\"note\" ng-show=\"mood._.isVisible.note == true\">\n <div class=\"inputfield\">\n <label class=\"input-title\">Details here</label>\n <editor scope-obj=\"mood.note\" is-editable=\"true\"></editor>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/mood/mood-widget.html","<div class=\"widget mood\">\n <div class=\"title\">Mood</div>\n <div class=\"content\">\n <div class=\"moods\">\n <div class=\"mood-bar\" ng-repeat=\"mood in data.list | orderBy:\'timestamp\' | limitTo:7\">\n <mood-bar data=\"mood\"></mood-bar>\n </div>\n </div>\n <div class=\"baseline col-xs-12\" ng-show=\"data.list.length > 0\"></div>\n <div class=\"message\" ng-show=\"data.list.length == 0\">\n No mood recorded yet\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/note/note-card.html","<div class=\"note-card\">\n <div class=\"summary\">\n <div class=\"title field\">\n <div class=\"icon\">\n <i class=\"fa fa-file-text-o\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n {{::(item.data.title ? item.data.title : \'No Title\')}}\n </div>\n </div>\n <div class=\"fields\">\n <div class=\"summary field\">\n <div class=\"icon\">\n <i class=\"fa fa-pencil\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <editor scope-obj=\"item.data\" is-editable=\"false\"></editor>\n </div>\n </div>\n <div class=\"field\">\n <div class=\"icon\">\n <i class=\"fa fa-tags\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <tags-list taglist=\"item.data.tags.taglist\"></tags-list>\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/note/note-panel.html","<div class=\"note-panel\">\n <title scope-obj=\"note\"></title>\n <div class=\"inputfield\" on-action=\"\'KEYUP, tags, true\'\" scope-obj=\"note._.isVisible\">\n <label class=\"input-title\">Add your notes here</label>\n <editor scope-obj=\"note\" is-editable=\"true\"></editor>\n </div>\n <div class=\"inputfield\" ng-show=\"note._.isVisible.tags == true\">\n <label class=\"input-title\">Tags</label>\n <!-- <input class=\"input-value\" type=\"text\" ng-model=\"note.tags\"> -->\n <tags-autocomplete choices=\"note._.tags\" enteredtext=\"note.tags.text\"\n minlength=\"1\" placeholder=\"\" result=\"note.tags.tagobj\" type=\"\'WHOM\'\"\n tags=\"note.tags.taglist\"></tags-autocomplete>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/note/note.html","<div class=\"note-page\">\n <select-time choosen=\"choosen\" get-data=\"getNotesData\"></select-time>\n \n <h1 class=\"page-title\">Notes</h1>\n <div class=\"search-panel panel\">\n Search: <input ng-model=\"query\" />\n </div>\n <div class=\"notes\">\n <div class=\"note\" ng-repeat=\"note in filteredNotes = (notes | filter:query)\">\n <div class=\"panel panel-default\">\n <div class=\"panel-heading\">\n <h3 class=\"panel-title\">{{note.data.title}}</h3>\n </div>\n <div class=\"panel-body\">\n <editor scope-obj=\"note.data\" is-editable=\"false\"></editor>\n <div class=\"timestamp\">\n <span class=\"label label-default\">\n {{note.timestamp | date:\"d MMM yyyy h:mm a\"}}\n </span>\n <span class=\"label label-success\" ng-repeat=\"tag in note.data.tags.taglist\">\n {{tag.text}}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>");
$templateCache.put("components/feature-components/people/people-panel.html","<div class=\"people-panel\">\n Show people list and ask for last contact with the person\n <!-- <div class=\"inputfield\" on-action=\"\'KEYUP, details, true\'\" scope-obj=\"people.isVisible\">\n <label class=\"input-title\">Name</label>\n <input class=\"input-value\" type=\"text\" ng-model=\"people.name\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Mobile</label>\n <input class=\"input-value\" type=\"text\" ng-model=\"mobile\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Email</label>\n <input class=\"input-value\" type=\"text\" ng-model=\"email\">\n </div> -->\n <!-- <div class=\"inputfield\">\n <label class=\"input-title\">Social Networks</label>\n <input class=\"input-value\" type=\"text\" ng-model=\"\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Notes</label>\n <input class=\"input-value\" type=\"text\" ng-model=\"notes\">\n </div> -->\n</div>");
$templateCache.put("components/feature-components/place/place-card.html","<div class=\"place-card {{::item.type | lowercase}}\">\n <div class=\"summary\">\n <div class=\"fields\">\n <div class=\"title field\" ng-if=\"item.type == \'PLCS\'\">\n <div class=\"icon\">\n <i class=\"fa fa-file-text-o\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n {{::(item.data.title ? item.data.title : \'No Title\')}}\n </div>\n </div>\n <div class=\"reason field\" ng-if=\"item.type == \'PLCS\'\" ng-show=\"item.data.reason\">\n <div class=\"icon\">\n <i class=\"fa fa-question\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n {{::item.data.reason}}\n </div>\n </div>\n <div class=\"with-whom field\" ng-if=\"item.type == \'PLCS\'\">\n <div class=\"icon\">\n <i class=\"fa fa-user\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n <span ng-show=\"item.data.whom.taglist.length === 0\">By Myself</span>\n <span ng-show=\"item.data.whom.taglist.length > 0\">\n <tags-list taglist=\"item.data.whom.taglist\"></tags-list>\n </span>\n </div>\n </div>\n <div class=\"source field\" ng-if=\"item.type == \'CKIN\'\">\n <div class=\"icon\">\n <i class=\"fa fa-exchange\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"desc\">\n Source: {{::item.data.source}}\n </div>\n </div>\n </div>\n </div>\n</div>\n");
$templateCache.put("components/feature-components/place/place-panel.html","<div class=\"place-panel\">\n <div class=\"inputfield\" on-action=\"\'KEYUP, optional, true\'\" scope-obj=\"place._.isVisible\">\n <label class=\"input-title\">Where are you</label>\n <autocomplete choices=\"place._.places\" enteredtext=\"place.title\" \n minlength=\"1\" result=\"place.placeobj\" type=\"\'WHERE\'\"></autocomplete>\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Why are you here</label>\n <input class=\"input-value\" type=\"text\" ng-model=\"place.reason\">\n </div>\n <div class=\"inputfield\">\n <label class=\"input-title\">Who is with you</label>\n <tags-autocomplete choices=\"place._.places\" enteredtext=\"place.whom.text\"\n minlength=\"1\" placeholder=\"\" result=\"place.whom.placeobj\" type=\"\'WHOM\'\" \n tags=\"place.whom.taglist\"></tags-autocomplete>\n </div>\n</div>");}]);
angular.module('homepage').
directive('choosemany', function() {
return {
link: choosemanyLinker,
restrict: 'A',
replace: false
}
function choosemanyLinker(scope, element, attribute) {
var groupname = attribute.choosemany;
var parentname = attribute.namespace && typeof attribute.namespace == 'string' && attribute.namespace.length > 0
? '.' + attribute.namespace + ' ' : '';
var query = parentname + '[choosemany=' + groupname + ']';
element.bind('click', function() {
if(this.classList.contains('chosen')) {
this.classList.remove('chosen');
}
else {
this.classList.add('chosen');
}
})
}
});
angular.module('homepage').
directive('chooseone', function() {
return {
link: chosenLinker,
restrict: 'A',
replace: false
}
function chosenLinker(scope, element, attribute) {
var groupname = attribute.chooseone;
var parentname = attribute.namespace && typeof attribute.namespace == 'string' && attribute.namespace.length > 0
? '.' + attribute.namespace + ' ' : '';
var query = parentname + '[chooseone=' + groupname + ']';
element.bind('click', function() {
var elements = document.querySelectorAll(query);
for (var i = 0; i < elements.length; i++) {
var item = elements[i];
item.classList.remove('chosen');
}
this.classList.add('chosen');
})
}
});
angular.module('homepage').
directive('choosetoggle', function() {
return {
link: chosenLinker,
restrict: 'A',
replace: false
}
function chosenLinker(scope, element, attribute) {
element.bind('click', function() {
this.classList.toggle('chosen');
})
}
});
angular.module('homepage').
directive("contenteditable", function() {
return {
restrict: "A",
require: "ngModel",
link: function(scope, element, attrs, ngModel) {
function read() {
ngModel.$setViewValue(element.html() || "<br>");
}
ngModel.$render = function() {
element.html(ngModel.$viewValue || "<br>");
};
element.bind("blur keyup change", function() {
scope.$apply(read);
});
}
};
});
angular.module('homepage').
/**
* On action modifies an property on scope.
* It takes the following parameters:
* onAction attribute - (following values seper)
* type: type of action,
* item: item name on scope,
* value: value that is to be set for the item
* scopeObj attribute - the variable,
* on which the items needs to be modified.
*/
directive('onAction', function (StringUtility, $timeout) {
return {
restrict: 'A',
link: onActionLinkerFn,
scope: {
onAction: '=',
isVisible: '=scopeObj'
}
}
function onActionLinkerFn(scope, element, attribute) {
var parts = StringUtility.getPartsOfString(scope.onAction);
parts = convertPartToArray(parts);
parts = checkValues(parts);
var events = parts[0];
for(var index in events) {
var eventtype = events[index];
if(eventtype.toLowerCase() == 'KEYUP'.toLowerCase()) {
element.bind('keyup', function(event) {
setAttributes(event, scope, parts);
});
}
if(eventtype.toLowerCase() == 'CLICK'.toLowerCase()) {
element.bind('click', function(event) {
setAttributes(event, scope, parts);
});
}
}
}
function setAttributes(event, scope, parts) {
event.stopPropagation();
var attributes = parts[1];
var values = parts[2];
for(var index in attributes) {
var attribute = attributes[index].trim();
// convert value to boolean from string if string contains 'true' or 'false' value
var value = StringUtility.stringToBoolean(values[index].trim());
scope.isVisible[attribute] = value;
}
$timeout(function () {
scope.$apply();
})
}
/* Expand from one value to multiple if needed */
function checkValues(parts) {
var attributes = parts[1];
var values = parts[2];
if(attributes.length != values.length) {
var value = values[0];
var values = [];
for(var index in attributes) {
values.push(value);
}
parts[2] = values;
}
return parts;
}
/* Extract items from string and convert to array */
/**
* @return parts
* parts[1]: attributes
* parts[2]: values
*/
function convertPartToArray(parts) {
for(var index in parts) {
var part = parts[index];
if(typeof part == 'string') {
// convert string to array
parts[index] = [part.trim()];
}
}
return parts;
}
});
angular.module('homepage').
/**
* On action modifies an property on scope.
* It takes the following parameters:
* onActionToggle attribute - (following values seper)
* type: type of action,
* item: item name on scope,
* value: value that is to be set for the item
* scopeObj attribute - the variable,
* on which the items needs to be modified.
*/
directive('onActionToggle', function (StringUtility, $timeout) {
return {
restrict: 'A',
link: onActionToggleLinkerFn,
scope: {
onActionToggle: '=',
isVisible: '=scopeObj'
}
}
function onActionToggleLinkerFn(scope, element, attribute) {
var parts = StringUtility.getPartsOfString(scope.onActionToggle);
parts = convertPartToArray(parts);
parts = checkValues(parts);
setDefaultValues(scope, parts);
var events = parts[0];
for(var index in events) {
var eventtype = events[index];
if(eventtype.toLowerCase() == 'KEYUP'.toLowerCase()) {
element.bind('keyup', function(event) {
setAttributes(event, scope, parts);
});
}
if(eventtype.toLowerCase() == 'CLICK'.toLowerCase()) {
element.bind('click', function(event) {
setAttributes(event, scope, parts);
});
}
}
}
function setDefaultValues(scope, parts) {
var attributes = parts[1];
var values = parts[2];
for(var index in attributes) {
var attribute = attributes[index].trim();
// convert value to boolean from string if string contains 'true' or 'false' value
var value = StringUtility.stringToBoolean(values[index].trim());
scope.isVisible[attribute] = value;
}
$timeout(function () {
scope.$apply();
});
}
function setAttributes(event, scope, parts) {
event.stopPropagation();
var attributes = parts[1];
var values = parts[2];
for(var index in attributes) {
var attribute = attributes[index].trim();
scope.isVisible[attribute] = !scope.isVisible[attribute];
}
$timeout(function () {
scope.$apply();
});
}
/* Expand from one value to multiple if needed */
function checkValues(parts) {
var attributes = parts[1];
var values = parts[2];
if(attributes.length != values.length) {
var value = values[0];
var values = [];
for(var index in attributes) {
values.push(value);
}
parts[2] = values;
}
return parts;
}
/* Extract items from string and convert to array */
/**
* @return parts
* parts[1]: attributes
* parts[2]: values
*/
function convertPartToArray(parts) {
for(var index in parts) {
var part = parts[index];
if(typeof part == 'string') {
// convert string to array
parts[index] = [part.trim()];
}
}
return parts;
}
});
angular.module('homepage').
/**
* @param 'main' CSS Selector for element whose height is to be set on other elements
* @param 'others' Array of CSS Selector of elements whose height is to be set
* @param 'offset' Any variance required from the height being set to the element
*/
directive('setequalheight', function($timeout) {
return {
link: setequalheightLinker,
restrict: 'A',
replace: false
}
function setequalheightLinker(scope, element, attribute) {
window.addEventListener("orientationchange", setHeight, false);
window.addEventListener("resize", setHeight, false);
setHeight();
function setHeight() {
$timeout(function () {
scope.$apply(function(){
var params = JSON.parse(attribute.setequalheight);
var mainElement = element[0].querySelector(params.main);
var mainElementHeight = mainElement.offsetHeight;
for(var i=0; i<params.others.length; i++) {
var otherElement, offset;
if(params.others[i]=="") {
otherElement= element[0];
}
else {
otherElement= element[0].querySelector(params.others[i]);
}
if(otherElement && otherElement != null) {
offset = params.offset && params.offset[i] ? params.offset[i] : 0;
otherElement.style.height = (mainElementHeight - offset) + 'px';
}
}
});
});
}
}
});
angular.module("homepage").directive("sglClick", [
"$parse",
function($parse) {
return {
restrict: "A",
link: function(scope, element, attr) {
var fn = $parse(attr["sglClick"]);
var delay = 300,
clicks = 0,
timer = null;
element.on("click", function(event) {
clicks++; //count clicks
if (clicks === 1) {
timer = setTimeout(function() {
scope.$apply(function() {
fn(scope, { $event: event });
});
clicks = 0; //after action performed, reset counter
}, delay);
} else {
clearTimeout(timer); //prevent single-click action
clicks = 0; //after action performed, reset counter
}
});
}
};
}
]);
angular.module('homepage').
// ARRAY filters
filter('reverse', function() {
return function(items) {
return items.slice().reverse();
};
}).
filter('arr2str', function() {
return function(items) {
var string = '';
for(var index in items) {
var item = items[index];
if (index !== "0") string += ', ';
if (item !== undefined && item.length !== 0 && item !== '') {
string += item;
}
}
return string;
};
}).
filter('arraysum', function() {
return function(items, attribute) {
var sum = 0;
for(var index in items) {
var item = items[index];
if (item !== undefined && item[attribute.name] !== undefined) {
var value = parseInt(item[attribute.name]);
if(typeof value === "number") {
sum += value;
}
}
}
return sum;
};
}).
filter('filterByValue', function () {
/**
* Returns items by type and excludes if type is EXCL
* name: Name of the attribute whose value is to be compared
* type: INCL/INCLUDE or EXCL/EXCLUDE value whose value matches
* value: value of the attribute
* { name: String, type: String, value: String}
*/
return function (items, typeinfo) {
var filtered = [];
for (var index in items) {
var item = items[index];
if(typeinfo.type == 'INCL' || typeinfo.type == 'INCLUDE') {
if(item[typeinfo.name] === typeinfo.value) {
filtered.push(items[index]);
}
}
// Default type is 'EXCL' or 'EXCLUDE'
else {
if(item[typeinfo.name] !== typeinfo.value) {
filtered.push(items[index]);
}
}
}
return filtered;
};
}).
filter('filterByIndex', function () {
/**
* Returns items by type and excludes if exclude is set to 'true'
* { exclude: Boolean, index: Number }
*/
return function (items, indexinfo) {
var filtered = [];
// Exclude item at index mentioned from the returned list
for (var index in items) {
if(indexinfo.exclude === true) {
if(index != indexinfo.index) {
filtered.push(items[index]);
}
}
else {
if (index === indexinfo.index) {
filtered.push(items[index]);
}
}
}
return filtered;
};
});
angular.module('homepage').
filter('doubledigit', [function() {
return function (number) {
if(number < 10) {
return '0' + number;
}
else {
return number;
}
};
}]);
angular.module('homepage').
filter('codeconvert', function(CodeConvertSrvc) {
return function (code) {
var value = CodeConvertSrvc.getValue(code);
if(value === '') {
return code;
}
else {
return value;
}
};
});
angular.module('homepage').
// DATE filters
filter('datediff', function() {
/**
* Get the difference of dates
* @param {Object} attribute {'0': Date, '1': Date, type: 'String'}
* @return {Number} Difference of date in hours/days
*/
return function(input, date1, date2) {
var text = '';
var suffix = '';
var timestamp0 = new Date(date1).getTime();
var timestamp1 = new Date(date2).getTime();
var difference = Math.abs(timestamp0 - timestamp1) / 1000;
if (difference < 60) {
text = difference + ' sec';
}
else if (difference < 60*60) {
difference = Math.floor(difference/60);
text = difference + 'min';
}
else if (difference < 24*60*60) {
difference = Math.floor(difference/(60*60));
text = difference + ' hour';
}
suffix = difference == 1 ? '' : 's';
return text + suffix;
};
}).
filter('monthbyindex', function(DateUtility) {
var months = DateUtility.getMonthTitles();
return function(index) {
return months[index];
}
});
angular.module('custommodal', []).
controller('customModalController', function ($scope) {
$scope.showModal = false;
$scope.toggleModal = function(){
$scope.showModal = !$scope.showModal;
};
}).
directive('customModal', function () {
return {
controller: 'customModalController',
restrict: 'E',
replace: true,
transclude: true,
template: '<div ng-transclude></div>'
}
}).
directive('modal', function () {
return {
template: '<div class="modal fade">' +
'<div class="modal-dialog modal-sm">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>' +
'<h4 class="modal-title">{{ title }}</h4>' +
'</div>' +
'<div class="modal-body" ng-transclude></div>' +
'</div>' +
'</div>' +
'</div>',
restrict: 'E',
require: '^customModal',
replace:true,
transclude: true,
link: function postLink(scope, element, attrs) {
scope.title = attrs.title;
scope.$watch(attrs.visible, function(value) {
if(value == true)
$(element).modal('show');
else
$(element).modal('hide');
});
$(element).on('shown.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = true;
});
});
$(element).on('hidden.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = false;
});
});
}
};
});
angular.module('homepage').
run(function($rootScope, $state, $timeout, Authentication) {
$rootScope.isVisible = {
loading: false
};
$rootScope.currentRoute = {
name: ''
};
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
$rootScope.isVisible.loading = true;
if (toState.name == 'login' && Authentication.isAuthenticated()) {
// User is authenticated
$rootScope.currentRoute.name = "home";
$state.transitionTo("home");
event.preventDefault();
}
else if (toState.authenticate && !Authentication.isAuthenticated()) {
// User isn’t authenticated
$rootScope.currentRoute.name = "login";
$state.transitionTo("login");
event.preventDefault();
}
else if (!toState.authenticate) {
$rootScope.currentRoute.name = toState.name;
}
});
$rootScope.$on("$viewContentLoaded", function () {
$timeout(function () {
$rootScope.isVisible.loading = false;
}, 1000);
});
}).
config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/start');
$stateProvider.
// INDEX STATES ========================================
state('start', {
url: '/start',
templateUrl: '../../html/partials/partial-index.html',
authenticate: false
}).
// LOGIN ROUTES ========================================
state('login', {
url: '/login',
templateUrl: '../../html/partials/partial-login.html',
authenticate: false
}).
state('signup', {
url: '/signup',
templateUrl: '../../html/partials/partial-signup.html',
authenticate: false
}).
state('register', {
url: '/register',
templateUrl: '../../html/partials/partial-register.html',
authenticate: false
}).
state('comment', {
url: '/comment',
templateUrl: '../../html/partials/partial-comment.html',
authenticate: false
}).
// HOME PAGE AND MULTIPLE NAMED VIEWS ====================
state('home', {
url: '/home',
controller: 'HomeController',
templateUrl: '../../html/partials/partial-home.html',
authenticate: true
}).
state('demo', {
url: '/demo',
controller: 'DemoController',
templateUrl: '../../html/partials/partial-demo.html',
authenticate: false
}).
// NOTES ROUTES ========================================
state('notes', {
url: '/notes',
templateUrl: '../../html/partials/partial-notes.html',
authenticate: false
}).
// LIST ROUTES ========================================
state('list', {
url: '/list',
templateUrl: '../../html/partials/partial-list.html',
authenticate: false
}).
// CALENDAR ROUTES ====================================
state('calendar', {
url: '/calendar',
templateUrl: '../../html/partials/partial-calendar.html',
authenticate: false
}).
// CONTACTS ROUTES ====================================
state('contacts', {
url: '/contacts',
templateUrl: '../../html/partials/partial-contacts.html',
authenticate: false
}).
// HABIT ROUTES ====================================
state('habits', {
url: '/habits',
templateUrl: '../../html/partials/partial-habits.html',
authenticate: false
}).
// FITNESS ROUTES ===================================
state('fitness', {
url: '/fitness',
templateUrl: '../../html/partials/partial-fitness.html',
authenticate: false
}).
// FINANCE ROUTES ===================================
state('finance', {
url: '/finance',
templateUrl: '../../html/partials/partial-finance.html',
authenticate: true
}).
// PLACES ROUTES ====================================
state('places', {
url: '/places',
templateUrl: '../../html/partials/partial-places.html',
authenticate: false
}).
// ACTIVITY ROUTES ==================================
state('activity', {
url: '/activity',
templateUrl: '../../html/partials/partial-activity.html',
authenticate: false
});
});
angular.module('homepage').
factory('Server', function($http) {
return {
fblogin : function() {
return $http.get('/auth/user/facebook');
},
login : function(user) {
return $http.post('/auth/user/login', user);
},
logout : function() {
return $http.get('/auth/user/logout');
},
register: function(data) {
return $http.post('/auth/user/register', data);
},
signup: function(data) {
return $http.post('/auth/user/signup', data);
},
checkInvite: function (data) {
return $http.put('/auth/user/checkinvite', data);
},
addcomment: function (data) {
return $http.post('/api/comment/add', data);
},
ibsubmit: function (data) {
return $http.post('/api/inputbox/submit', data);
},
markTemplate: function (data) {
return $http.post('/api/inputbox/habit/mark', data);
},
getTemplates: function (data) {
return $http.post('/api/inputbox/gettemplates', data);
},
getDemoData: function () {
return $http.post('/api/inputbox/getdemodata', {});
},
getNotesData: function (data) {
return $http.post('/api/inputbox/notes/getdata', data);
},
getMoneyData: function (data) {
return $http.post('/api/inputbox/finance/getdata', data);
},
getMoneyWidgetData: function (data) {
return $http.post('/api/inputbox/finance/widget/getdata', data);
}
};
});
angular.module('homepage').
factory('CodeConvertSrvc', function () {
var codes = {
// FINANCE
'EQLY' : 'Equally',
'PMNT' : 'Payment',
// FOOD
'CUP' : 'Cup',
'GLS' : 'Glass',
'BTL' : 'Bottle',
'PTR' : 'Pitcher',
'TWR' : 'Tower',
'LTR' : 'Liter',
'PCE' : 'Pieces',
'TSP' : 'Tablespoon',
'BWL' : 'Bowl',
'ONC' : 'Ounce',
'GRM' : 'Gram'
};
function getValue(code) {
if(codes[code]) {
return codes[code];
}
else {
return '';
}
}
return {
getValue: getValue
};
});
angular.module('homepage').
// Store templates, location and widget data
factory('DataStoreSrvc', function (ArrayUtility, ProcessTimelineService, SidebarHelperSrvc, TemplatePreprocessor, TemplateTimelineService, WidgetHelperSrvc) {
/**
* Store all the data received till now from the server
*/
var DataStore = {
templates: []
};
/**
* Since we need to update the UI on change of items,
* we maintain seperate filtered object which would be updated
* on change of date.
*/
var FilteredData = {
templates: [],
habits: [],
widgets: WidgetHelperSrvc.getWidgetsData(),
sidebar: SidebarHelperSrvc.getSidebarData()
};
return {
/**
* Add new template to DataStore.
* Get templates for today and build new timeline based on it.
*/
add: function (template) {
if(!template) return;
TemplatePreprocessor.removeEmptyWorkoutAndSet(template);
DataStore.templates.push(template);
// Update timeline data
var templates = TemplateTimelineService.getItemsByDate(DataStore.templates);
templates = TemplateTimelineService.excludeItemsByType(templates, 'HABT');
var habits = TemplateTimelineService.getItemsByDate(DataStore.templates);
habits = TemplateTimelineService.filterItemsByType(habits, 'HABT');
// Preserve array reference after filtering
FilteredData.templates = ArrayUtility.reassignArray(FilteredData.templates, templates);
ProcessTimelineService.processTimeline(FilteredData.templates);
FilteredData.habits = ArrayUtility.reassignArray(FilteredData.habits, habits);
// Update widgets data
FilteredData.widgets = WidgetHelperSrvc.update(template);
// Update sidebar data
FilteredData.sidebar = SidebarHelperSrvc.update(template);
},
/**
* Get posts based on current selected date
*/
getPosts: function () {
var templates = TemplateTimelineService.getItemsByDate(DataStore.templates);
templates = TemplateTimelineService.excludeItemsByType(templates, 'HABT');
// Preserve array reference after filtering
FilteredData.templates = ArrayUtility.reassignArray(FilteredData.templates, templates);
ProcessTimelineService.processTimeline(FilteredData.templates);
return FilteredData.templates;
},
/**
* Get habits based on current selected date
*/
getHabits: function () {
var templates = TemplateTimelineService.getItemsByDate(DataStore.templates);
templates = TemplateTimelineService.filterItemsByType(templates, 'HABT');
// Preserve array reference after filtering
FilteredData.habits = ArrayUtility.reassignArray(FilteredData.habits, templates);
return FilteredData.habits;
},
/**
* Get widgets based on current selected date
*/
getWidgetsData: function () {
FilteredData.widgets = WidgetHelperSrvc.getWidgetsByDate();
return FilteredData.widgets;
},
/**
* Get sidebar based on current selected date
*/
getSidebarData: function () {
FilteredData.sidebar = SidebarHelperSrvc.getSidebarByDate();
return FilteredData.sidebar;
},
/**
* Update all content based on current selected date
*/
updateAll: function () {
// Update data based on current date
this.getPosts();
this.getHabits();
this.getWidgetsData();
this.getSidebarData();
},
/**
* Reset data store
*/
resetAll: function () {
DataStore.templates.length = 0;
WidgetHelperSrvc.resetAll();
SidebarHelperSrvc.resetAll();
}
};
});
angular.module('homepage').
factory('FoodNutritionSrvc', function (NutritionDataJSON) {
// Store list of foods with their nutrition details
var FoodsDataStore = {
foods: [],
drinks: []
};
/**
* Calculate matchindex based on the number of words matched against the foodname passed.
* @param {Array} titles List of titles all describing one food title
* @param {String} foodname Title of food entered by user
* @return {Object} bestmatch Best match matchindex and titleindex
*/
// TODO This doesnt account for errorneous names entered by user
// TODO This doesnt account for plural names
function matchFoodByName(titles, foodname) {
// Number of words matched against the foodname passed
var matchindex = 0; // Stores the current iteration matchindex
var bestmatch = { // Stores info about the past best match
matchindex: 0,
titleindex: -1,
lengthmatch: false
};
// match against all titles until matchindex and word count match for one title
for(var index in titles) {
var title = titles[index];
var words = title.split(" ");
var parts = foodname.split(" ");
// match words
for(var jndex in parts) {
var part = parts[jndex];
// TODO add polyfill added in ES6 though is an ES5 specification
// Array.indexOf() case insensitive
var isMatch = words.some(function(element) {
return part.toLowerCase() === element.toLowerCase();
});
if (isMatch) {
matchindex++;
}
}
// store in bestmatch if better than last match
if (bestmatch.matchindex < matchindex) {
bestmatch.matchindex = matchindex;
bestmatch.titleindex = parseInt(index);
}
// end search if matchindex and word count match
if(matchindex === parts.length) {
bestmatch.lengthmatch = true;
break;
}
}
return bestmatch;
}
/**
* Match foodname with all items titles in the list
* @param {Array} list [description]
* @param {String} foodname Title of food entered by user
* @return {Object} bestmatch Best match matchindex and titleindex
*/
function matchNames(list, foodname) {
var bestmatch = { // Stores info about the past best match
matchindex: 0,
titleindex: -1,
lengthmatch: false
};
for(var index in list) {
var titles = list[index].title;
var matchinfo = matchFoodByName(titles, foodname);
if(bestmatch.matchindex < matchinfo.matchindex) {
bestmatch.matchindex = matchinfo.matchindex;
bestmatch.titleindex = matchinfo.titleindex;
bestmatch.lengthmatch = matchinfo.lengthmatch;
if(bestmatch.lengthmatch === true) {
bestmatch.details = list[index];
break;
}
}
}
return bestmatch;
}
// Based on type array, look for foodname
// If not found in that array, look for other array(s)
function findMatch(foodtype, foodname) {
var bestmatch = { // Stores info about the past best match
matchindex: 0,
titleindex: -1
};
if(foodtype === 'FOOD') {
bestmatch = matchNames(FoodsDataStore.foods, foodname);
if (bestmatch.matchindex === 0) {
bestmatch = matchNames(FoodsDataStore.drinks, foodname);
}
}
else {
bestmatch = matchNames(FoodsDataStore.drinks, foodname);
if (bestmatch.matchindex === 0) {
bestmatch = matchNames(FoodsDataStore.foods, foodname);
}
}
return bestmatch;
}
/**
* Return conversion index based on the type entered by user w.r.t type in JSON
* possible values:
* FOOD - PCE, TSP, BWL, ONC, GRM
* DRNK - CUP, GLS, BTL, PTR, TWR, LTR
* @param {String} jsontype Type from the json
* @param {String} usertype Type entered by the user
* @return {Number} conversionindex conversion index
*/
function getConversionIndex(jsontype, usertype) {
var weightmap = {
'PCE': 10,
'TSP': 10,
'BWL': 100,
'ONC': 0.035,
'GRM': 1,
'CUP': 100,
'GLS': 200,
'BTL': 500,
'PTR': 1890,
'TWR': 3000,
'LTR': 1000
};
var conversionIndex = weightmap[usertype] / weightmap[jsontype];
return conversionIndex;
}
function calculateCalories(foodname, foodtype, quantity, qtytype) {
// Based on type array, look for foodname
// If not found in that array, look for other array(s)
// If no match found return X
var bestmatch = findMatch(foodtype, foodname);
// Once match is found, check if quantity type matches
// If it doesnt, use convertor to convert to nutrition type in json
// If it matches, calculate total calories, based on amount entered by user
if(bestmatch.matchindex > 0 && bestmatch.details !== undefined) {
var conversionIndex = getConversionIndex(bestmatch.details.qty.type, qtytype);
bestmatch.calories = conversionIndex * quantity * bestmatch.details.nutrition.calories;
}
else {
bestmatch.calories = bestmatch.details === undefined ? 0 : bestmatch.details.nutrition.calories;
}
return bestmatch;
}
/**
* Get Nutrition details from the food name
* @param {String} foodname [description]
* @param {String} foodtype [description]
* @param {Number} quantity [description]
* @param {String} qtytype [description]
* @return {Object} bestmatch object with bestmatch info and calorie count
*/
function getNutritionInfo(foodname, foodtype, quantity, qtytype) {
if(FoodsDataStore.foods.length === 0 || FoodsDataStore.drinks.length === 0) {
FoodsDataStore.foods = NutritionDataJSON.nutritionInfo.foods;
FoodsDataStore.drinks = NutritionDataJSON.nutritionInfo.drinks;
}
if(foodname === undefined) {
return { 'calories': 0 };
}
else {
return calculateCalories(foodname, foodtype, quantity, qtytype);
}
}
return {
getNutritionInfo: getNutritionInfo
};
}).
factory('NutritionDataJSON', function () {
// Keeping JSON inline so that there is no asyn call to be made, as it is problematic for implementing filters that use this service on load
// Stateful filter implementation is not changing data after first stable data, even though the filter is called with different params
var nutritionInfo = {"foods":[{"title":["Egg","Eggs","Egg boiled"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"80"}},{"title":["Egg Poached","Eggs Poached"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"80"}},{"title":["Egg Fried","Eggs Fried","Egg Fry"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"110"}},{"title":["Egg Omelet","Omelet","Omlate","Omelette","Egg Omelette"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"120"}},{"title":["Bread slice","Bread"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"45"}},{"title":["Bread slice with butter"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"90"}},{"title":["Chapati"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"60"}},{"title":["Puri"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"75"}},{"title":["Paratha"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"150"}},{"title":["Veggie"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":"150"}},{"title":["Idli"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"100"}},{"title":["Dosa","Plain Dosa"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"120"}},{"title":["Masala Dosa"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"250"}},{"title":["Sambar","Sambhar","Dal"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":"150"}},{"title":["Rajma Dal"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":"140"}},{"title":["Rice","Plain Rice"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":"120"}},{"title":["Fried Rice"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":"150"}},{"title":["Nan"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"150"}},{"title":["Curd"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":"100"}},{"title":["Veg Curry","Vegetable Curry"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":""}},{"title":["Salad"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":"100"}},{"title":["Papad"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"45"}},{"title":["Cutlet"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":"75"}},{"title":["Pickle"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"15"}},{"title":["Gobi Manchurian"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"60"}},{"title":["Soup"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":"75"}},{"title":["Fruit Bowl","Fruit Salad","Fruits"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"BWL"},"nutrition":{"calories":"150"}},{"title":["Gulab Jamun"],"foodtype":{"type":"FOOD","region":"INDN"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"140"}},{"title":["Cucumber","Kheera","Kakhadi"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"8"}},{"title":["Carrot","Gajar"],"foodtype":{"type":"FOOD","region":"GLBL"},"qty":{"amount":"1","type":"PCE"},"nutrition":{"calories":"41"}}],"drinks":[{"title":["Tea"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"CUP"},"nutrition":{"calories":"45"}},{"title":["Black Tea"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"CUP"},"nutrition":{"calories":"15"},"description":"Without milk and sugar"},{"title":["Coffee"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"CUP"},"nutrition":{"calories":"45"}},{"title":["Black Coffee"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"CUP"},"nutrition":{"calories":"15"},"description":"Without milk and sugar"},{"title":["Milk"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"GLS"},"nutrition":{"calories":"65"}},{"title":["Protein Milk","Protein Milk Shake"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"CUP"},"nutrition":{"calories":"125"}},{"title":["Horlicks Milk"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"GLS"},"nutrition":{"calories":"120"}},{"title":["Fruit Juice"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"GLS"},"nutrition":{"calories":"120"}},{"title":["Soft Drink"],"foodtype":{"type":"DRNK","region":"INDN"},"qty":{"amount":"1","type":"GLS"},"nutrition":{"calories":"90"}},{"title":["Diet Coke"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"GLS"},"nutrition":{"calories":"0"}},{"title":["Maaza"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"CUP"},"nutrition":{"calories":"54"}},{"title":["Beer"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"BTL"},"nutrition":{"calories":"200"}},{"title":["Soda"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"BTL"},"nutrition":{"calories":"20"}},{"title":["Milk Shake"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"GLS"},"nutrition":{"calories":"200"}},{"title":["Mosambi Juice","Sweet Lime Juice"],"foodtype":{"type":"DRNK","region":"GLBL"},"qty":{"amount":"1","type":"GLS"},"nutrition":{"calories":"100"}}]};
return {
nutritionInfo: nutritionInfo
};
});
angular.module('homepage').
// Store templates, location and widget data
factory('GlobalDataService', function (DateUtility) {
var selectedDate = new Date();
var isTodaysDate = {
isTrue: true
};
function getSelectedDate() {
return selectedDate;
}
function setSelectedDate(date) {
selectedDate.setTime(date.getTime());
isTodaysDateSelected(selectedDate);
}
/**
* Used to set sidebar title bar
* @param {Date} date Current date
* @return {Boolean} Is current date also the todays date
*/
function isTodaysDateSelected(date) {
if(date === undefined) {
date = selectedDate;
}
isTodaysDate.isTrue = DateUtility.getDateOnly(date).getTime() === DateUtility.getDateOnly(new Date()).getTime();
return isTodaysDate;
}
return {
getSelectedDate: getSelectedDate,
setSelectedDate: setSelectedDate,
isTodaysDateSelected: isTodaysDateSelected
};
});
angular.module('homepage').
factory('ReadJsonSrvc', function ($http) {
function readJson(filename) {
return $http.get('../../../json/' + filename + '.json');
}
return {
readJson: readJson
};
});
angular.module('homepage').
// Store templates, location and widget data
factory('TemplateService', function (AddTemplates, DateUtility, GlobalDataService, Server, Structs, TimelineService) {
var DateRange = new Structs.DateRange();
function setDateRange(date) {
if(DateRange.start === null || DateRange.end === null) {
DateRange.start = new Date(date);
DateRange.end = new Date(date);
return;
}
if(date.getTime() < DateRange.start.getTime()) {
DateRange.start = new Date(date);
}
else if(date.getTime() > DateRange.end.getTime()) {
DateRange.end = new Date(date);
}
}
function getTemplates() {
var date = GlobalDataService.getSelectedDate();
var isWithinDateRange = (DateRange.start !== null && DateRange.end !== null) ?
DateUtility.isBetweenDates(date, DateRange.start, DateRange.end, true, true) : false;
if(!isWithinDateRange) {
// Set DateRange
setDateRange(date);
TimelineService.setLoadingStatus(true);
// Send server current date timestamp (GMT) and timezone offset
Server.getTemplates({
'startTimestamp': DateUtility.getDateOnly(date).getTime(),
'endTimestamp': DateUtility.getDateEnd(date).getTime()
})
.success(function (result) {
console.log(result);
AddTemplates.addData(result.data.templates);
TimelineService.setLoadingStatus(false);
});
}
}
return {
getTemplates: getTemplates
};
}).
/**
* This is to keep functionality between user and demo data dashboard in sync
* @type {[type]}
*/
factory('AddTemplates', function (DataStoreSrvc) {
return {
addData: function (templates) {
// Add templates to data store
for(var index = 0; index < templates.length; index++) {
var template = templates[index];
DataStoreSrvc.add(template);
}
}
};
});
angular.module('homepage').
factory('Authentication', function($http, $localStorage, $rootScope) {
var _user = {};
function urlBase64Decode(str) {
var output = str.replace('-', '+').replace('_', '/');
switch (output.length % 4) {
case 0:
break;
case 2:
output += '==';
break;
case 3:
output += '=';
break;
default:
throw 'Illegal base64url string!';
}
return window.atob(output);
}
function getUserFromLocalStorage() {
var token = $localStorage.token;
var user = {};
if (typeof token !== 'undefined') {
var encoded = token.split('.')[1];
user = JSON.parse(urlBase64Decode(encoded));
}
return user;
}
function removeUserFromLocalStorage() {
delete $localStorage.token;
}
function getUser() {
_user = getUserFromLocalStorage();
return _user;
}
function setUser(token) {
if(token) {
$localStorage.token = token;
$rootScope.userDtls = getUser();
$rootScope.isAuthenticated = true;
}
}
function removeUser() {
removeUserFromLocalStorage();
$rootScope.userDtls = {};
$rootScope.isAuthenticated = false;
_user = {};
}
function isAuthenticated() {
return $rootScope.userDtls && $rootScope.userDtls.username !== undefined ? true : false;
}
function setHeaders() {
// Set the token as header for your requests!
$http.defaults.headers.common['X-Auth-Token'] = $localStorage.token;
}
return {
getUser: getUser,
setUser: setUser,
removeUser: removeUser,
isAuthenticated: isAuthenticated,
setHeaders: setHeaders
};
});
angular.module('homepage').
factory('SidebarHelperSrvc', function (DateUtility, TemplateTimelineService) {
// Store the original data templates copy here (READ ONLY)
var DataStore = {
habit: {
templates: []
},
calendar: {
templates: []
}
};
// Store processed data here. Do not reinitialise object references elsewhere
var sidebar = {
habit: new TaskItems(),
calendar: new TaskItems(),
all: new TaskItems()
};
// Object structure used to store habit and calendar tasks
function TaskItems() {
return {
pending: {},
current: {
morning: [],
afternoon: [],
evening: [],
night: []
},
future: {}
};
}
// NOTE: Any change within sidebar object will update the sidebar
// Complete sidebar object is passed to sidebar module
function resetSidebar(type) {
switch(type) {
case 'CLDR':
sidebar.calendar = new TaskItems();
break;
case 'HABT':
sidebar.habit = new TaskItems();
break;
default:
sidebar.habit = new TaskItems();
sidebar.calendar = new TaskItems();
break;
}
sidebar.all = new TaskItems();
}
function updateDataStore(data) {
if(data.type == 'HABT') {
DataStore.habit.templates.push(data);
}
if(data.type == 'CLDR') {
DataStore.calendar.templates.push(data);
}
}
function updateSidebarData(data) {
if(data.type == 'HABT') {
updateHabitData(data);
}
if(data.type == 'CLDR') {
updateCalendarData(data);
}
mergeAllData();
}
/**
* Adding entries that are to be shown for today
* @param {[type]} data [description]
* @return {[type]} [description]
*/
function updateHabitData(data) {
addItem(data);
}
function updateCalendarData(data) {
// CHECK DATE RANGE
// Add item, if today falls in date range
var today = new Date();
var from = data.data.dates.START.date;
var to = data.data.dates.END.date;
if(DateUtility.isBetweenDates(today, from, to, true, true)) {
addItem(data);
}
}
/**
* Merge habit and calendar item objects
* @return {[type]} [description]
*/
function mergeAllData() {
var morning = sidebar.habit.current.morning.concat(sidebar.calendar.current.morning);
var afternoon = sidebar.habit.current.afternoon.concat(sidebar.calendar.current.afternoon);
var evening = sidebar.habit.current.evening.concat(sidebar.calendar.current.evening);
var night = sidebar.habit.current.night.concat(sidebar.calendar.current.night);
// Assign new array instance
sidebar.all.current.morning = morning.slice();
sidebar.all.current.afternoon = afternoon.slice();
sidebar.all.current.evening = evening.slice();
sidebar.all.current.night = night.slice();
}
/**
* Form task item to be passed to template
* @param {[type]} data [description]
* @return {[type]} [description]
*/
function getItem(data) {
var item = {};
item.hashid = data.data.hashid;
item.isChecked = data.data.isChecked;
if(data.type == 'HABT') {
// Habit with trail and time
if(data.data.time.code == 'TIME') {
item.type = 'HBTT';
item.label = data.data.title;
item.date = data.data.time.date;
}
// Habit with trail only
else {
item.type = 'HBTR';
item.label = data.data.title;
}
}
if(data.type == 'CLDR') {
item.label = data.data.title ? data.data.title : 'Event';
// Calendar meeting with time and location
if(data.data.placetext && data.data.times.START.isDateSet) {
item.type = 'CMTL';
item.times = data.data.times;
item.locationText = data.data.placetext;
}
// Calendar reminder based on time
else if(data.data.times.START.isDateSet) {
item.type = 'CRBT';
item.times = data.data.times;
}
// Calendar reminder without time
else if(!data.data.times.START.isDateSet) {
item.type = 'CMWT';
}
}
return item;
}
/**
* Add item to sidebar data as per time information
*/
function addItemEntry(data, code) {
var today = new Date();
var time;
if(code == 'HABT') {
type = 'habit';
time = data.data.time.date;
code = data.data.time.code || 'TIME';
}
else if(code == 'CLDR') {
type = 'calendar';
time = data.data.times.START.date;
code = 'TIME';
}
time = new Date(time);
// CHECK TIME
// Add as per time else add to current time
if(code == 'MRNG' || (code == 'TIME' && (time.getHours() >= 6 && time.getHours() < 12))) {
sidebar[type].current.morning.push(getItem(data));
}
else if(code == 'AFTN' || (code == 'TIME' && (time.getHours() >= 12 && time.getHours() < 17))) {
sidebar[type].current.afternoon.push(getItem(data));
}
else if(code == 'EVNG' || (code == 'TIME' && (time.getHours() >= 17 && time.getHours() < 20))) {
sidebar[type].current.evening.push(getItem(data));
}
else if(code == 'NGHT' || (code == 'TIME' && (time.getHours() >= 20 && time.getHours() < 24))) {
sidebar[type].current.night.push(getItem(data));
}
else if(code == 'NONE' || code == 'FLDY' ||
(code == 'TIME' && (today.getHours() >= 0 && today.getHours() < 6))) {
if(today.getHours() >= 6 && today.getHours() < 12) {
sidebar[type].current.morning.push(getItem(data));
}
else if(today.getHours() >= 12 && today.getHours() < 17) {
sidebar[type].current.afternoon.push(getItem(data));
}
else if(today.getHours() >= 17 && today.getHours() < 20) {
sidebar[type].current.evening.push(getItem(data));
}
else {
sidebar[type].current.night.push(getItem(data));
}
}
}
function addItem(data) {
var days = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
// CHECK REPETITION
// If Once, check if timestamp matches today
// If Daily, add entry for today
// If Weekly, check if today falls in the choice made
// If Monthly, repeat on same day as timestamp each month
// If Annually, repeat on same date as timestamp each year
var repeats = data.data.repetition.repeats;
var today = new Date();
if(repeats == 'ONCE') {
if(DateUtility.compareDateOnly(data.timestamp, today) === 0) {
addItemEntry(data, data.type);
}
}
else if(repeats == 'DALY') {
addItemEntry(data, data.type);
}
else if(repeats == 'WEEK') {
var type = data.data.repetition.chooseday.type;
var dayofweek = days[today.getDay()];
var chosen = data.data.repetition.chooseday.days;
for(var index in chosen) {
var choice = chosen[index];
if(dayofweek == choice) {
addItemEntry(data, data.type);
}
}
}
else if(repeats == 'MTLY') {
if(today.getDate() == new Date(data.timestamp)) {
addItemEntry(data, data.type);
}
}
else if(repeats == 'ANLY') {
if(today.getDate() == new Date(data.timestamp).getDate()
& today.getMonth() == new Date(data.timestamp).getMonth()) {
addItemEntry(data, data.type);
}
}
}
return {
/**
* Initialize all the data using the list of templates received
*/
initialize: function (templates, type) {
// Reinitialize all data before processing all items
// Resetting without size check would empty all items,
// if habits or calendar items are null and no merge is called
if(templates.length > 0) {
resetSidebar(type);
}
// Process templates only applicable for today
templates = TemplateTimelineService.getItemsByDate(templates);
for(var index in templates) {
var template = templates[index];
updateSidebarData(template);
}
return sidebar;
},
getSidebarByDate: function (templates) {
this.initialize(DataStore.habit.templates, 'HABT');
this.initialize(DataStore.calendar.templates, 'CLDR');
return sidebar;
},
/**
* Return the sidebar object
*/
getSidebarData: function () {
return sidebar;
},
update: function (data) {
updateDataStore(data);
updateSidebarData(data);
return sidebar;
},
/**
* Reset data store
*/
resetAll: function () {
DataStore.habit.templates.length = 0;
DataStore.calendar.templates.length = 0;
resetSidebar();
}
}
});
angular.module('homepage').
// Store templates, location and widget data
factory('Structs', function ($rootScope, DataStoreSrvc, GlobalDataService, Server) {
function DateRange() {
return {
start: null,
end: null
}
}
return {
DateRange: DateRange
}
});
angular.module('homepage').
// Store templates, location and widget data
factory('TemplateTimelineService', function (GlobalDataService, TimelineService) {
function getItemsByDate(items, date) {
if(date) {
return TimelineService.getItemsByDate(items, date);
}
else {
return TimelineService.getItemsByDate(items, GlobalDataService.getSelectedDate());
}
}
/**
* Exclude items of type passed
* @param {Array} items List of items to be filtered
* @param {String} type Type of item to be excluded
* @return {Array} items Filtered items
*/
function excludeItemsByType(items, type) {
return items.filter(function (item) {
return item.type !== type;
});
}
/**
* Include items of type passed
* @param {Array} items List of items to be filtered
* @param {String} type Type of item to be included
* @return {Array} items Filtered items
*/
function filterItemsByType(items, type) {
return items.filter(function (item) {
return item.type === type;
});
}
return {
getItemsByDate: getItemsByDate,
excludeItemsByType: excludeItemsByType,
filterItemsByType: filterItemsByType
};
});
angular.module('homepage').
// Store templates, location and widget data
factory('TimelineService', function (ArrayUtility, DateUtility) {
var sortOrder = 'ASCDG';
var isLoading = {
value: false
};
function getItemsByDate(items, date) {
var filtered = [];
var givenDate = DateUtility.getDateOnly(new Date(date));
for(var index in items) {
var item = items[index];
var submitDate = DateUtility.getDateOnly(new Date(item.timestamp));
if(givenDate.getTime() == submitDate.getTime()) {
filtered.push(item);
}
}
return filtered;
}
function getSortOrder() {
return sortOrder;
}
function setSortOrder() {
sortOrder = (sortOrder === 'ASCDG') ? 'DSCDG' : 'ASCDG';
}
function getLoadingStatus() {
return isLoading;
}
function setLoadingStatus(value) {
isLoading.value = value;
}
return {
getSortOrder: getSortOrder,
setSortOrder: setSortOrder,
getLoadingStatus: getLoadingStatus,
setLoadingStatus: setLoadingStatus,
getItemsByDate: getItemsByDate
};
});
angular.module('homepage').
factory('ArrayUtility', function() {
return {
reassignArray: reassignArray
};
/**
* Reassign new array to original array preserving the original array reference
*/
function reassignArray(originalArray, newArray) {
// Empty original array keeping the original reference
originalArray.length = 0;
// Add all items of new array to original array
// originalArray.concat(newArray); This doesnt work with object arrays
for(var index in newArray) {
var item = newArray[index];
originalArray.push(item);
}
return originalArray;
}
});
angular.module('homepage').
factory('DateUtility', function() {
var monthShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
return {
getMonthTitles: getMonthTitles,
getTimeStr: getTimeStr,
getDateStr: getDateStr,
getDateOnly: getDateOnly,
getDateEnd: getDateEnd,
getMonthStart: getMonthStart,
getMonthEnd: getMonthEnd,
getMonthDateRange: getMonthDateRange,
getYearStart: getYearStart,
getYearEnd: getYearEnd,
getGmtTimestamp: getGmtTimestamp,
newDateSameRef: newDateSameRef,
compareDateOnly: compareDateOnly,
isBetweenDates: isBetweenDates
}
function getMonthTitles(isShort) {
var monthLong = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var monthShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
if(isShort) {
return monthShort;
} else {
return monthLong;
}
}
/**
* Get time from date as string
* @param {Date} date Date object/Timestamp
* @return {string} Time as string 'hh:mm:ss am/pm'
*/
function getTimeStr(date) {
date = new Date(date) || new Date();
var hours = date.getHours();
var minutes = date.getMinutes();
var seconds = date.getSeconds();
var ampm = hours >= 12 ? 'pm' : 'am';
hours = hours % 12;
hours = hours ? hours : 12; // the hour '0' should be '12'
minutes = minutes < 10 ? '0' + minutes : minutes;
seconds = seconds < 10 ? '0' + seconds : seconds;
var strTime = hours + ':' + minutes + ':' + seconds + ' ' + ampm;
return strTime;
}
/**
* Get date from date as string
* @param {Date} date Date object/Timestamp
* @return {string} Date as string 'dd MMM yyyy'
*/
function getDateStr(date) {
date = new Date(date) || new Date();
var monthShort = getMonthTitles(true);
return date.getDate() + ' ' + monthShort[date.getMonth()] + ' ' + date.getFullYear();
}
/**
* Get date only with time part set to zero
* @param {Date} date Date object/Timestamp
* @return {Date} Date object
*/
function getDateOnly(date) {
date = new Date(date);
return new Date(date.setHours(0,0,0,0));
}
/**
* Get date only with time part set to zero
* @param {Date} date Date object/Timestamp
* @return {Date} Date object
*/
function getDateEnd(date) {
date = new Date(date);
return new Date(date.setHours(23,59,59,999));
}
function getMonthStart(date) {
return new Date(date.getFullYear(), date.getMonth(), 1);
}
function getMonthEnd(date) {
return new Date(date.getFullYear(), date.getMonth() + 1, 0);
}
function getMonthDateRange(date) {
date = new Date(date);
var firstDay = getMonthStart(date);
var lastDay = getMonthEnd(date);
return {
start: getDateOnly(firstDay),
end: getDateEnd(lastDay)
};
}
function getYearStart(date) {
return new Date(date.getFullYear(), 0, 1);
}
function getYearEnd(date) {
return new Date(date.getFullYear(), 11, 31);
}
/**
* Convert timestamp from local timezone to GMT
* @param {Date} date Date/Timestamp
* @return {Number} Timestamp in GMT
*/
function getGmtTimestamp(date) {
if(!date) {
date = new Date();
}
// Timestamp in client time zone
var timestamp = new Date(date).getTime();
var offset = new Date().getTimezoneOffset(); // in minutes
// Convert local time to GMT
// TODO add or substract based on the offset value
timestamp = timestamp + (offset * 60 * 1000);
return timestamp;
}
/**
* Get latest date keeping the refrence of the passed date object
* @param {Date} date Date object/Timestamp
* @return {Date} Date object
*/
function newDateSameRef(date) {
date = new Date(date);
date.setTime(new Date().getTime());
return date;
}
/**
* Compare dates without comparing time
* @param {Date} date1 Date object/Timestamp
* @param {Date} date2 Date object/Timestamp
* @return {Number} Difference in dates after setting time to zero
*/
function compareDateOnly(date1, date2) {
date1 = getDateOnly(date1);
date2 = getDateOnly(date2);
var oneday = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var diff = (date1.getTime() - date1.getTime())/ oneday;
return diff;
}
/**
* Check if the given date falls between from and to date
* @param {Date} date Date to be compared
* @param {Date} fromDate From Date
* @param {Date} toDate To Date
* @param {Boolean} isFromInclusive Is from date inclusive
* @param {Boolean} isToInclusive Is to date inclusive
* @return {Boolean} [description]
*/
function isBetweenDates(date, fromDate, toDate, isFromInclusive, isToInclusive) {
var isWithinRange = false;
date = new Date(date);
fromDate = getDateOnly(fromDate);
toDate = getDateEnd(toDate);
if(isFromInclusive && isToInclusive) {
isWithinRange = date >= fromDate && date <= toDate;
}
else if(isFromInclusive) {
isWithinRange = date >= fromDate && date < toDate;
}
else if(isToInclusive) {
isWithinRange = date > fromDate && date <= toDate;
}
else {
isWithinRange = date > fromDate && date < toDate;
}
return isWithinRange;
}
});
angular.module('homepage').
factory('StringUtility', function() {
return {
getPartsOfString: getPartsOfString,
stringToBoolean: stringToBoolean
}
/**
* SPLIT the following string into three parts
* @param text
* @returns [part1, part2, part3]
*/
// TEST INPUTS
// var text = 'eventType, attributeName, value';
// var text = '[eventType1, eventType2, ..., eventTypeN], attributeName, value';
// var text = 'eventType, [attributeName1, attributeName2, ..., attributeNameN], value';
// var text = 'eventType, attributeName, [value1, value2, ..., valueN]';
// var text = 'eventType, [attributeName1, attributeName2, ..., attributeNameN], [value1, value2, ..., valueN]';
// var text = '[eventType1, eventType2, ..., eventTypeN], [attributeName1, attributeName2, ..., attributeNameN], [value1, value2, ..., valueN]';
function getPartsOfString(text) {
// if no square bracket found, split by comma
// else parse each part
// find comma separated part or square bracket part
var parts = [];
if(text.indexOf('[') > -1) {
return findPart(parts, text);
}
else {
return parts = text.split(',');
}
}
/**
* Recursively find parts of strings
* @param parts, text
* @return [part1, part2, part3]
*/
function findPart(parts, text) {
text = text.trim();
var indexOfComma = text.indexOf(',');
var indexOfOpenBracket = text.indexOf('[');
if(text.length != 0) {
// if part doesn't contain bracket
if(text.indexOf('[') == -1) {
var indexOfPartEnd = indexOfComma > -1 ? indexOfComma : text.trim().length;
parts.push(text.substring(0, indexOfPartEnd));
findPart(parts, text.substring(indexOfPartEnd + 1));
}
// if part contains bracket
else if(indexOfComma > indexOfOpenBracket) {
var indexOfCloseBracket = text.indexOf(']');
var partStr = text.substring(indexOfOpenBracket + 1, indexOfCloseBracket);
var partParts = partStr.split(',');
parts.push(partParts);
findPart(parts, text.substring(indexOfCloseBracket + 2));
}
else if(indexOfComma < indexOfOpenBracket) {
parts.push(text.substring(0, indexOfComma));
findPart(parts, text.substring(indexOfComma + 1));
}
}
return parts;
}
// convert value to boolean from string if string contains 'true' or 'false' value
function stringToBoolean(string){
switch(string.toLowerCase().trim()){
case "true": case "yes": case "1": return true;
case "false": case "no": case "0": case null: return false;
}
return string;
}
});
angular.module('homepage').
service('BrowserType', function($window) {
return function() {
var userAgent = $window.navigator.userAgent;
var browsers = {chrome: /chrome/i, safari: /safari/i, firefox: /firefox/i, ie: /internet explorer/i};
for(var key in browsers) {
if (browsers[key].test(userAgent)) {
return key;
}
};
return 'unknown';
}
}).
service('MobileType', function () {
return {
Android: function() {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function() {
return navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i);
},
any: function() {
// TODO make width as 480
var isWidthLessThanDesktop = window.innerWidth < 600;
return (this.Android() || this.BlackBerry() || this.iOS() || this.Opera() || this.Windows() || isWidthLessThanDesktop);
}
};
});
angular.module('homepage').
// Do widgets related calculations here and update the DataStoreSrvc 'DataStore.widgets'
factory('WidgetHelperSrvc', function (FoodNutritionSrvc, TemplateTimelineService) {
// Store the original data templates copy here (READ ONLY)
var DataStore = {
mood: {
templates: []
},
money: {
templates: []
},
food: {
templates: []
},
fitness: {
templates: []
}
};
var widgets = {};
widgets.mood = new MoodWidgetsData();
widgets.money = new MoneyWidgetsData();
widgets.food = new FoodWidgetsData();
widgets.fitness = new FitnessWidgetsData();
function MoodWidgetsData() {
return {
list: []
};
}
function MoneyWidgetsData() {
return {
received: 0,
spent: 0,
lent: 0,
borrowed: 0,
remaining: 0
};
}
function FoodWidgetsData() {
return {
calories: {
required: 0,
consumed: 0,
message: 'No food info recorded'
}
};
}
function FitnessWidgetsData() {
return {
workouts: [],
message: ''
};
}
function resetWidgets(type) {
type = type ? type : '';
switch(type) {
case 'MOOD':
widgets.mood = new MoodWidgetsData();
break;
case 'MNEY':
widgets.money = new MoneyWidgetsData();
break;
case 'FOOD':
widgets.food = new FoodWidgetsData();
break;
case 'HLTH':
widgets.fitness = new FitnessWidgetsData();
break;
default:
widgets.mood = new MoodWidgetsData();
widgets.money = new MoneyWidgetsData();
widgets.food = new FoodWidgetsData();
widgets.fitness = new FitnessWidgetsData();
}
}
function updateDataStore(data) {
if(data.type == 'FOOD') {
DataStore.food.templates.push(data);
}
else if(data.type == 'MOOD') {
DataStore.mood.templates.push(data);
}
else if(data.type == 'MNEY') {
DataStore.money.templates.push(data);
}
else if(data.type == 'HLTH') {
DataStore.fitness.templates.push(data);
}
}
function updateWidgetData(data) {
if(data.type == 'FOOD') {
updateFoodWidget(data);
}
else if(data.type == 'MOOD') {
updateMoodWidget(data);
}
else if(data.type == 'MNEY') {
updateMoneyWidget(data);
}
else if(data.type == 'HLTH') {
updateFitnessWidget(data);
}
}
/**
* Calculate total calories consumed throughout a given day
* @param {Object} data Object representing one snippet
* @return {Object} Returns object with attributes used on UI
*/
function updateFoodWidget(data) {
resetWidgets('FOOD');
var hasUnknown = false; // If any food calories is unknown
var totalcalories = 0;
var required = 2500;
var message = '';
var foods = TemplateTimelineService.getItemsByDate(DataStore.food.templates);
for(var index in foods) {
var food = foods[index];
for(var listindex in food.data.list) {
var fooditem = food.data.list[listindex];
if(fooditem.count) {
var value = parseInt(fooditem.count);
if(typeof value == 'number') {
totalcalories += value;
}
}
else if(fooditem.foodtext) {
var nutritionInfo = FoodNutritionSrvc.getNutritionInfo(fooditem.foodtext, fooditem.mealtype, fooditem.quantity, fooditem.qtytype);
var calories = parseInt(nutritionInfo.calories);
if(calories > 0) {
totalcalories += calories;
}
else {
hasUnknown = true;
}
}
}
}
var diff = required - totalcalories;
if(diff > 0) {
message = 'Going good';
}
else {
if(Math.abs(diff) < 1000) {
message = 'Little overloaded';
}
else {
message = 'Workout needed';
}
}
widgets.food.calories.message = message;
widgets.food.calories.consumed = hasUnknown ? totalcalories + ' + X Cal' : totalcalories;
widgets.food.calories.required = required;
}
function updateMoodWidget(data) {
resetWidgets('MOOD');
var moodLevel = parseInt(data.data.level);
moodLevel = typeof moodLevel == 'number' ? moodLevel : 0;
widgets.mood.list.push({level: moodLevel, timestamp: data.timestamp});
}
function updateMoneyWidget(data) {
resetWidgets('MNEY');
for(var index in DataStore.money.templates) {
var template = DataStore.money.templates[index];
var amount = parseInt(template.data.amount);
amount = amount && amount > 0 ? amount : 0;
if(template.data.financetype == 'PAID') {
if(template.data.whomobj || template.data.whom) {
widgets.money.lent += amount;
}
else {
widgets.money.spent += amount;
}
}
if(template.data.financetype == 'RCVD') {
if(template.data.whomobj || template.data.whom) {
widgets.money.borrowed += amount;
}
else {
widgets.money.received += amount;
}
}
}
var remaining = (widgets.money.received + widgets.money.borrowed) -
(widgets.money.lent + widgets.money.spent);
widgets.money.remaining = remaining;
}
/**
* Build list of info to be shown on fitness widget
* @param {Object} data Object representing one snippet
* @return {Object} Returns object with attributes used on UI
*/
function updateFitnessWidget(data) {
for(var index in data.data.list) {
var workout = data.data.list[index];
widgets.fitness.workouts.push(workout);
}
if(widgets.fitness.workouts.length > 0) {
widgets.fitness.message = "Keep burning calories";
}
}
return {
/**
* Initialize all the data using the list of templates received
*/
initialize: function (templates, type) {
// Reinitialize all data before processing all items
resetWidgets(type);
// Process templates only applicable for today
templates = TemplateTimelineService.getItemsByDate(templates);
for(var index in templates) {
var template = templates[index];
updateWidgetData(template);
}
},
getWidgetsByDate: function (templates) {
this.initialize(DataStore.mood.templates, 'MOOD');
this.initialize(DataStore.money.templates, 'MNEY');
this.initialize(DataStore.food.templates, 'FOOD');
this.initialize(DataStore.fitness.templates, 'HLTH');
return widgets;
},
/**
* Return the widget object
*/
getWidgetsData: function () {
return widgets;
},
/*
* Update widgets data based by performing calculations as per the template type passed
*/
update: function (template) {
updateDataStore(template);
updateWidgetData(template);
return widgets;
},
/**
* Reset data store
*/
resetAll: function () {
DataStore.mood.templates.length = 0;
DataStore.money.templates.length = 0;
DataStore.food.templates.length = 0;
DataStore.fitness.templates.length = 0;
}
};
});
angular.module('homepage').
factory('TemplatePreprocessor', function() {
function removeEmtpyFitnessSets(newtemplate, template) {
// Removing the empty sets from the original object
for(var index in newtemplate.data.list) {
var workout = newtemplate.data.list[index];
for(var jndex in workout.sets) {
var set = workout.sets[jndex];
if(set.distance === '' && set.repetition === '' && set.time === '' && set.weight === '') {
delete template.data.list[index].sets.splice(jndex, 1);
}
}
}
}
function removeEmptyFitnessWorkout(newtemplate, template) {
// Remvong the empty workouts from the original object
for(var index in newtemplate.data.list) {
var workout = newtemplate.data.list[index];
if(workout.sets.length === 0) {
delete template.data.list.splice(index, 1);
}
}
}
function fitnessTemplatePreprocessor(template) {
if(template.data.list && template.data.list.length > 0) {
var newtemplate = angular.copy(template);
removeEmtpyFitnessSets(newtemplate, template);
removeEmptyFitnessWorkout(newtemplate, template);
}
return template;
}
function removeEmptyWorkoutAndSet(template) {
if(template.type === 'HLTH') {
return fitnessTemplatePreprocessor(template);
}
}
return {
removeEmptyWorkoutAndSet: removeEmptyWorkoutAndSet
};
});
angular.module('homepage').
directive('autocomplete', function($timeout) {
return {
controller: 'autocompleteController',
restrict: 'E',
replace: true,
scope: {
choices: '=',
enteredtext: '=',
minlength: '=',
result: '=',
type: '=',
onselect: '&'
},
templateUrl: 'components/common-components/autocomplete/autocomplete.html'
};
}).
controller('autocompleteController', function($scope, $timeout) {
$scope.filteredChoices = [];
$scope.isVisible = {
suggestions: false
};
$scope.filterItems = function () {
if($scope.enteredtext && $scope.minlength <= $scope.enteredtext.length) {
$scope.filteredChoices = querySearch($scope.enteredtext);
$scope.isVisible.suggestions = $scope.filteredChoices.length > 0 ? true : false;
}
else {
$scope.isVisible.suggestions = false;
}
};
/**
* Takes one based index to save selected choice object
*/
$scope.selectItem = function (index) {
$scope.result = {'chosen': $scope.choices[index - 1], 'type': $scope.type};
$scope.enteredtext = $scope.result.chosen.label;
$scope.isVisible.suggestions = false;
$timeout(function () {
$scope.$apply();
if($scope.onselect) {
$scope.onselect();
}
});
};
/**
* Search for states... use $timeout to simulate
* remote dataservice call.
*/
function querySearch (query) {
if(!$scope.choices) return [];
// returns list of filtered items
return query ? $scope.choices.filter( createFilterFor(query) ) : [];
}
/**
* Create filter function for a query string
*/
function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);
return function filterFn(item) {
// Check if the given item matches for the given query
var label = angular.lowercase(item.label);
return (label.indexOf(lowercaseQuery) === 0);
};
}
});
angular.module('homepage').
directive('buble', function () {
return {
restrict: 'E',
replace: true,
scope: {
size: '=',
title: '=',
value: '='
},
transclude: true,
templateUrl: 'components/common-components/buble/buble.html'
}
});
angular.module('homepage').
directive('calendarDual', function () {
return {
restrict: 'E',
replace: true,
scope: {
dates: '='
},
templateUrl: 'components/common-components/calendar/calendar-dual.html'
}
});
angular.module('homepage').
directive('calendar', function () {
return {
controller: 'calendarController',
restrict: 'E',
replace: true,
scope: {
/**
* @type {Object} date Object containing attribute 'date'
*/
chosendate: '=date',
/**
* Object containing attributes:
* @type {Boolean} isShowDate Show textual date
* @type {Boolean} isShowBefore Show textual date before icon
*/
options: '='
},
templateUrl: 'components/common-components/calendar/calendar.html'
};
}).
controller('calendarController', ['$scope', '$timeout', function($scope, $timeout) {
var options = {
isWeekStartOnMonday: false
};
$scope.chosendate.date = $scope.chosendate.date instanceof Date ? $scope.chosendate.date : new Date();
$scope.tempDate = $scope.chosendate.date;
$scope.selectionDay = $scope.tempDate.getDate();
$scope.isCalendarVisible = false;
function daysInMonth(month,year) {
return new Date(year, month + 1, 0).getDate();
}
function getSelectionDate() {
return $scope.tempDate;
}
function setSelectionDate(date) {
$scope.tempDate = date;
$scope.selectionDay = $scope.tempDate.getDate();
}
function setDate(date) {
$scope.isCalendarVisible = false;
$scope.chosendate.date = date;
}
function getWeekTitle(isWeekStartOnMonday) {
if(isWeekStartOnMonday) {
return ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];
}
else {
return ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
}
}
function getCalendarItems(date) {
if(!date) {
date = new Date();
}
var year = date.getFullYear();
var month = date.getMonth();
var dayOfWeek = new Date(year, month, 1).getDay();
if (options.isWeekStartOnMonday) {
dayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek;
}
else {
dayOfWeek = dayOfWeek === 0 ? dayOfWeek : dayOfWeek + 1;
}
var totalDays = daysInMonth(month, year);
var items = [];
var weeks = [];
var week = [];
var weekindex = 0;
var paddingStr = '';
// add padding before items
for(var i = 0; i < dayOfWeek - 1; i++) {
items.push(paddingStr);
week.push(paddingStr);
}
for(var j = 1; j <= totalDays; j++) {
week.push(j);
items.push(j);
if(items.length%7 === 0) {
weeks[weekindex] = week;
week = [];
weekindex++;
}
}
// add padding after items
var listsize = items.length;
listsize = listsize > 28 ? 35 - listsize : listsize;
for(var k = 0; k < listsize; k++) {
items.push(paddingStr);
week.push(paddingStr);
}
weeks[weekindex] = week;
week = [];
return weeks;
}
$scope.toggleCalendar = function () {
$scope.isCalendarVisible = !$scope.isCalendarVisible;
};
$scope.setDateMonth = function($event, index) {
$event.stopPropagation();
var date = getSelectionDate();
date.setMonth(date.getMonth() + index);
setSelectionDate(date);
$scope.weeks = getCalendarItems(date);
};
$scope.dateClicked = function($event, day) {
$event.stopPropagation();
// Set indicator that date is selected by user not the default
$scope.chosendate.isDateSet = true;
// build date
var date = getSelectionDate();
date.setDate(day);
// update date string
setDate(date);
};
$scope.weekTitle = getWeekTitle(options.isWeekStartOnMonday)
$scope.weeks = getCalendarItems();
}]);
angular.module('homepage').
directive('checkbox', function () {
return {
controller: 'checkboxController',
restrict: 'E',
replace: true,
scope: {
label: '=',
name: '=',
isChecked: '=',
markCheckboxFn: '&'
},
transclude: true,
templateUrl: 'components/common-components/checkbox/checkbox.html'
}
}).
controller('checkboxController', function ($scope) {
// Setting default value for the checkbox
$scope.checked = $scope.checked ? $scope.checked : false;
});
angular.module('homepage').
directive('editor', function () {
return {
controller: 'EditorController',
restrict: 'E',
replace: true,
scope: {
note: '=scopeObj',
isEditable: '='
},
transclude: true,
templateUrl: 'components/common-components/editor/editor.html'
}
}).
controller('EditorController', function ($scope) {
$scope.handlePaste = function (event) {
//event.preventDefault();
//event.stopPropagation();
// var plaintext = event.originalEvent.clipboardData.getData('text/plain');
// document.execCommand('inserttext', false, plaintext);
};
});
angular.module('fullscreenDialogApp', []).
directive('fullscreenDialog', function () {
/**
* USAGE:
* Creates the full screen dialog
* <fullscreen-dialog><div class="dialog"></div></fullscreen-dialog>
*
* Holds the content of the dialog
* <fullscreen-dialog><div class="dialog"><div class="content"></div></div></fullscreen-dialog>
*/
return {
controller: 'fsDialogController',
link: fsDialogLinker,
restrict : 'E',
replace: true,
transclude: true,
scope: {
visible: '@'
},
template : '<div class="dialog-container"><ng-transclude></ng-transclude></div>'
}
function fsDialogLinker(scope, element, attribute) {
scope.$on('$destroy', function () {
var bodyElement = document.getElementsByTagName("body")[0];
bodyElement.classList.remove('noscroll');
});
}
}).
controller('fsDialogController', function ($scope) {
var bodyElement = document.getElementsByTagName("body")[0];
console.log(bodyElement);
if($scope.visible == 'true') {
$scope.showDialog();
}
else {
$scope.hideDialog();
}
$scope.showDialog = function () {
$scope.isPanelVisible = true;
bodyElement.classList.add('noscroll');
};
$scope.hideDialog = function () {
$scope.isPanelVisible = false;
bodyElement.classList.remove('noscroll');
};
});
angular.module('homepage').
directive('repetition', function () {
return {
controller: 'repetitionController',
restrict: 'E',
replace: true,
// Variables within this scope will be submitted back to server
scope: {
repetition: '=',
defaults: '='
},
transclude: true,
templateUrl: 'components/common-components/repetition/repetition.html'
}
}).
controller('repetitionController', function ($scope) {
function Repetition() {
return {
repeats: '',
chooseday: {
type: '',
days: []
},
choosemonth: {
type: '',
months: []
},
count: {
nth: '',
isMonthly: false
}
}
}
// Initialise defaults
$scope.defaults = $scope.defaults || {};
$scope.repetition = new Repetition();
$scope.repetition.repeats = $scope.defaults.repeat || 'DALY';
$scope.selectOption = function (code) {
var repetition = new Repetition();
switch(code) {
// repeats
case 'ONCE':
case 'DALY':
case 'WEEK':
case 'ANLY': {
repetition.repeats = code;
break;
}
case 'MTLY': {
repetition.repeats = code;
repetition.choosemonth.type = 'ALL';
break;
}
// choose days
case 'WKDY':
case 'WKED':
case 'HLDY': {
repetition.repeats = 'WEEK';
repetition.chooseday.type = code;
break;
}
case 'SUN':
case 'MON':
case 'TUE':
case 'WED':
case 'THU':
case 'FRI':
case 'SAT': {
repetition.repeats = 'WEEK';
repetition.chooseday.type = 'CHSE';
repetition.chooseday.days = $scope.repetition.chooseday.days;
var index = $scope.repetition.chooseday.days.indexOf(code);
if(index > -1) {
repetition.chooseday.days.splice(index, 1);
}
else {
repetition.chooseday.days.push(code);
}
break;
}
// select month options
case 'ALL':
case 'CHSE':
case 'CONT': {
repetition.repeats = 'MTLY';
repetition.choosemonth.type = code;
break;
}
// choose months
case 'JAN':
case 'FEB':
case 'MAR':
case 'APR':
case 'MAY':
case 'JUN':
case 'JUL':
case 'AUG':
case 'SEP':
case 'OCT':
case 'NOV':
case 'DEC': {
repetition.repeats = 'MTLY';
repetition.choosemonth.type = 'CHSE';
repetition.choosemonth.months = $scope.repetition.choosemonth.months;
var index = $scope.repetition.choosemonth.days.indexOf(code);
if(index > -1) {
repetition.choosemonth.days.splice(index, 1);
}
else {
repetition.choosemonth.days.push(code);
}
break;
}
// count
// TODO
}
$scope.repetition = repetition;
}
// Default visibility of individual panel
$scope.isVisible = {
days: false,
select: false,
months: false,
count: false
};
});
angular.module('homepage').
directive('selectTime', function () {
return {
controller: 'notePanelController',
restrict: 'E',
replace: true,
scope: {
choosen: '=',
getData: '='
},
transclude: true,
templateUrl: 'components/common-components/select-time/select-time.html'
}
}).
controller('notePanelController', function($scope, DateUtility) {
function getDateRange(index) {
var month, dateRange = {};
if (index === "ALL") {
dateRange.start = DateUtility.getYearStart(new Date());
dateRange.end = DateUtility.getYearEnd(new Date());
} else {
month = new Date($scope.choosen.year, index, 1);
dateRange = DateUtility.getMonthDateRange(month);
}
return dateRange;
}
$scope.years = [ 2018, 2017, 2016 ];
$scope.months = DateUtility.getMonthTitles(true);
$scope.isYearDdOpen = false;
$scope.selectMonth = function(index) {
var dateRange = getDateRange(index);
$scope.isYearDdOpen = false;
$scope.choosen.month = index;
$scope.getData(dateRange);
};
$scope.selectYear = function(year) {
var dateRange = getDateRange($scope.choosen.month);
$scope.isYearDdOpen = !$scope.isYearDdOpen;
$scope.choosen.year = year;
$scope.getData(dateRange);
};
});
angular.module('homepage').
directive('tagsList', function() {
return {
restrict: 'E',
replace: true,
scope: {
taglist: '='
},
templateUrl: 'components/common-components/tags/tags-list.html'
};
});
angular.module('homepage').
directive('tags', function() {
return {
restrict: 'E',
replace: true,
scope: {
tags: '='
},
link: tagLinker,
templateUrl: 'components/common-components/tags/tags.html'
};
}).
directive('tagsAutocomplete', function() {
return {
restrict: 'E',
replace: true,
scope: {
choices: '=',
/**
* Entered text not converted to tag
* @type {String}
*/
enteredtext: '=',
minlength: '=',
result: '=',
type: '=',
/**
* Tags list
* @type {Array}
*/
tags: '='
},
link: tagLinker,
templateUrl: 'components/common-components/tags/tags-autocomplete.html'
};
});
function tagLinker(scope, element, attribute) {
scope.placeholder = attribute.placeholder;
scope.addTag = function() {
if (scope.enteredtext !== undefined && scope.enteredtext.length === 0) {
return;
}
scope.tags.push({'text': scope.enteredtext});
scope.enteredtext = '';
return scope.enteredtext;
};
scope.deleteTag = function(index) {
if (scope.tags.length > 0 && scope.enteredtext.length === 0 && index === undefined) {
scope.tags.pop();
} else {
if (index !== undefined) {
// Remove item at index 'index'
scope.tags.splice(index, 1);
}
}
return scope.tags;
};
element.bind('keydown', function(event) {
var key = event.which;
if ((!event.shiftKey && key === 9) || key === 13 || key === 188) {
if(!(scope.enteredtext !== undefined && scope.enteredtext.length === 0)) {
event.preventDefault();
scope.$apply('addTag()');
}
}
else if (key === 8) {
scope.$apply('deleteTag()');
}
});
}
angular.module('homepage').
directive('timepicker', ['$compile', function($compile) {
function datepickerLinker(scope, element, attribute, controller) {
element.append('<span class="date" ng-click="toggleTimeWidget($event)">{{time.date | date:"hh:mm a"}}</span>');
element.append('<timeselection></timeselection>');
$compile(element)(scope);
}
return {
controller: 'timepickerController',
link: datepickerLinker,
scope: {
/**
* @type {Date} date Object with attribute 'date' Date object
* @type {Number} hour (Optional) Object with attribute hour from date object
* @type {Number} mins (Optional) Object with attribute minutes from date object
* @type {Number} secs (Optional) Object with attribute minutes from date object
* @type {Number} ampm (Optional) Object with attribute ampm for date object
*/
time: '='
},
restrict: 'E',
replace: true,
template: '<span class="timepicker"></span>'
};
}]).
controller('timepickerController', ['$scope', '$timeout', function($scope, $timeout) {
$scope.selected = {};
var options = {
seperator: ':',
clockType: '12HR'
};
initialise();
function initialise() {
$scope.selected.date = new Date();
// INITIALISE DATE HERE
if($scope.time.date) {
$scope.selected.date.setTime($scope.time.date.getTime());
}
else {
$scope.time.date = new Date();
}
setTime($scope.selected);
}
function setTime(time) {
time.mins = time.date.getMinutes();
}
$scope.setTimeObj = function() {
// Check for hour=12 else it would increment the date by one day
$scope.time.date.setHours($scope.selected.date.getHours());
$scope.time.date.setMinutes($scope.selected.mins);
};
$scope.resetTimeObj = function() {
$scope.selected.date.setTime($scope.time.date.getTime());
setTime($scope.selected);
};
$scope.isTimePickerVisible = false;
$scope.getTimePickerVisibility = function() {
return $scope.isTimePickerVisible;
};
$scope.setTimePickerVisibility = function(isVisible) {
$scope.isTimePickerVisible = isVisible;
// hack to update isTimePickerVisible
$timeout(function () { });
};
$scope.toggleTimeWidget = function($event) {
var isVisible = $scope.getTimePickerVisibility();
$scope.setTimePickerVisibility(!isVisible);
$scope.time.isDateSet = true;
};
}]).
directive('timeselection', function() {
return {
controller: 'timepickerwidgetController',
restrict: 'E',
require: '^timepicker',
replace: true,
templateUrl: 'components/common-components/timepicker/timepicker.html'
};
}).
controller('timepickerwidgetController', ['$scope', function($scope) {
$scope.setHour = function(increment) {
var hour = $scope.selected.date.getHours();
hour = hour + increment;
if(hour > 23) {
hour = hour - 24;
}
else if(hour < 0) {
hour = hour + 24;
}
$scope.selected.date.setHours(hour);
};
$scope.setMins = function(increment) {
$scope.selected.mins = parseInt($scope.selected.mins);
var modulus = $scope.selected.mins % 5;
if(increment == 5) {
if($scope.selected.mins + increment >= 60) {
$scope.selected.mins = 0;
}
else {
if(modulus !== 0) {
$scope.selected.mins += 5 - modulus;
}
else {
$scope.selected.mins += increment;
}
}
}
else if(increment == -5) {
if($scope.selected.mins <= 0) {
$scope.selected.mins = 55;
}
else {
if(modulus !== 0) {
$scope.selected.mins -= modulus;
}
else {
$scope.selected.mins += increment;
}
}
}
};
$scope.setAMPM = function() {
var hour = $scope.selected.date.getHours();
if(hour > 12) {
hour = hour - 12;
}
else {
hour = hour + 12;
}
$scope.selected.date.setHours(hour);
};
$scope.resetTimeAndHide = function() {
$scope.resetTimeObj();
$scope.toggleTimeWidget();
};
$scope.setTimeAndHide = function () {
$scope.setTimeObj();
$scope.toggleTimeWidget();
};
}]);
angular.module('homepage').
directive('timeselector', function () {
return {
controller: 'timeSelectorController',
restrict: 'E',
replace: true,
// Variables within this scope will be submitted back to server
scope: {
time: '=scopeObj'
},
transclude: true,
templateUrl: 'components/common-components/timeselector/timeselector.html'
}
}).
controller('timeSelectorController', function ($scope) {
$scope.time.code = 'NONE';
$scope.selectOption = function (code) {
$scope.time.code = code;
}
});
angular.module('homepage').
directive('title', function () {
return {
restrict: 'E',
replace: true,
scope: {
note: '=scopeObj'
},
templateUrl: 'components/common-components/title/title.html'
}
});
angular.module('homepage').
directive('totaltimeselector', function () {
return {
//controller: 'totalTimeSelectorController',
restrict: 'E',
replace: true,
// Variables within this scope will be submitted back to server
scope: {
times: '='
},
transclude: true,
templateUrl: 'components/common-components/totaltimeselector/totaltimeselector.html'
}
});
angular.module('trailicons').
directive('trail', function () {
var trailTmplt =
'<ul class="trail" ng-init="setTrailItems()">' +
'<li ng-repeat="item in items track by $index" class="{{item.class}}"></li>' +
'</ul>';
return {
controller: 'TrailController',
restrict: 'E',
replace: true,
scope: {
data: '=',
binary: '='
},
template: trailTmplt
}
}).
controller('TrailController', function ($scope) {
function getDateOnly(date) {
date = new Date(date);
return new Date(date.getFullYear(), date.getMonth(), date.getDate())
}
$scope.showModal = false;
$scope.toggleModal = function(){
$scope.showModal = !$scope.showModal;
};
$scope.setTrailItems = function () {
$scope.items = [];
// get only last 7 items from data
if($scope.binary == undefined || $scope.binary == '') {
var arr = $scope.data;
if(arr && arr.length >= 7) {
arr = arr.slice(Math.max(arr.length - 7, 0));
}
$scope.items = arr;
}
else {
// construct trail using binary data for demo
var splits = $scope.binary.split('');
for(var split in splits) {
var value = splits[split];
var itemclass = '';
switch (value) {
case '0':
itemclass = 'done';
break;
case '1':
itemclass = 'miss';
break;
default:
itemclass = 'none';
break;
}
$scope.items.push({'class': itemclass});
}
}
};
});
angular.module('homepage').
directive('drawerMenu', function () {
return {
controller: 'drawerMenuController',
link: showDrawerLinker,
restrict: 'E',
templateUrl: 'components/content-components/drawer/drawer-menu.html'
}
function showDrawerLinker(scope, element, attribute) {
scope.$on('$destroy', function () {
document.querySelector("body").classList.add('noscroll');
});
}
}).
controller('drawerMenuController', function ($scope) {
var bodyElement = document.querySelector("body");
$scope.isPanelVisible = false;
$scope.showDrawer = function () {
$scope.isPanelVisible = true;
bodyElement.classList.add('noscroll');
};
$scope.hideDrawer = function () {
$scope.isPanelVisible = false;
bodyElement.classList.remove('noscroll');
};
$scope.toggleDrawer = function () {
$scope.isPanelVisible = !$scope.isPanelVisible;
bodyElement.classList.toggle('noscroll');
}
});
angular.module('homepage').
directive('footer', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/content-components/footer/footer.html'
}
});
angular.module('homepage').
directive('headerMenu', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/content-components/header/header-menu.html',
controller: 'loginController'
}
}).
controller('loginController', function($scope, $window, Authentication, Server) {
$scope.login = function() {
Server.fblogin().
success(function(data) {
console.log(data);
});
};
$scope.logout = function() {
Server.logout().
success(function(data) {
Authentication.removeUser();
$window.location.href = '/#/';
});
};
});
angular.module('homepage').
directive('header', function () {
return {
controller: 'HeaderController',
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/content-components/header/header.html'
};
}).
controller('HeaderController', function ($scope, $state, $rootScope, $window, Authentication) {
$scope.loadDefaultPage = function () {
if($rootScope.currentRoute.name == "demo") {
$state.go("start");
}
else if($rootScope.isAuthenticated) {
$window.location.href = '/#/home';
}
else {
$state.go("start");
}
};
});
angular.module('homepage').
directive('home', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/content-components/home/home.html'
}
});
/*.
controller('HomeController', function($scope, $rootScope, Authentication) {
$scope.getUser = function() {
$rootScope.userDtls = Authentication.getUser();
$rootScope.isAuthenticated = Authentication.isAuthenticated();
}
});*/
angular.module('homepage').
directive('inputbox', function() {
return {
controller: 'BoxController',
restrict: 'E',
replace: true,
scope: {
isDemo: '='
},
transclude: true,
templateUrl: 'components/content-components/inputbox/inputbox.html'
};
}).
controller('BoxController', function($localStorage, $scope, $state, $timeout, DataStoreSrvc, DateUtility, InputboxDataSrvc, GlobalDataService, MobileType, Server, TemplatePreprocessor, TemplateService) {
function userdata() {
// '_' object contains info used only on UI side
return InputboxDataSrvc.moduleDefaultData();
}
// Keep only data properties that are having 'isHavingData' as true
function filterData(data) {
for (var key in data) {
if (data.hasOwnProperty(key) && data[key]._.isHavingData) {
// merge tag data within data fields
data[key] = mergeTagData(data[key]);
return data[key];
}
}
return {};
}
function mergeTagData(fields) {
for(var key in fields) {
if (fields.hasOwnProperty(key)) {
var field = fields[key];
if(field.taglist !== undefined && field.text !== undefined) {
if(field.text !== '') {
field.taglist.push(field.text);
}
if(field.taglist.length > 0) {
var tagstext = field.taglist[0];
for(var i=1; i<field.taglist.length; i++) {
tagstext += ', ' + field.taglist[i];
}
field.tagstext = tagstext;
}
}
}
}
return fields;
}
function reset() {
$scope.data = new userdata();
$scope.currenttype = '';
}
function preprocessor(details) {
if(details.type === 'CLDR' || details.type === 'HABT') {
details.isLatest = true;
}
if(details.type === 'HLTH') {
TemplatePreprocessor.removeEmptyWorkoutAndSet(details);
}
return details;
}
$scope.currenttype = '';
$scope.data = new userdata();
$scope.list = InputboxDataSrvc.templates;
$scope.isMobile = MobileType.any();
/**
* Object to hold date for the date and time picker
* @type {Object} selected Object containing 'date' attribute
*/
$scope.selected = {};
$scope.selected.date = new Date();
$scope.select = function(type) {
if(type === 'CLDR') return;
switch (type) {
case 'NOTE':
$scope.data.note._.isHavingData = true;
break;
case 'LIST':
$scope.data.list._.isHavingData = true;
break;
case 'ACTY':
$scope.data.activity._.isHavingData = true;
break;
case 'MOOD':
$scope.data.mood._.isHavingData = true;
break;
case 'HABT':
$scope.data.habit._.isHavingData = true;
break;
case 'HLTH':
$scope.data.fitness._.isHavingData = true;
break;
case 'FOOD':
$scope.data.food._.isHavingData = true;
break;
case 'MNEY':
$scope.data.finance._.isHavingData = true;
break;
case 'PLCS':
$scope.data.place._.isHavingData = true;
break;
case 'MDIA':
$scope.data.media._.isHavingData = true;
break;
case 'PEPL':
$scope.data.people._.isHavingData = true;
break;
case 'CLDR':
$scope.data.calendar._.isHavingData = true;
break;
default:
$scope.currenttype = '';
}
$scope.currenttype = type;
// Reset date maintaining the date reference
$scope.selected.date = DateUtility.newDateSameRef($scope.selected.date);
};
$scope.open = function(page) {
$state.transitionTo(page);
}
$scope.submit = function() {
if(!$scope.isDemo) {
var fieldsHavingData = filterData($scope.data);
delete fieldsHavingData._;
var details = {};
details.type = fieldsHavingData.type;
details.timestamp = new Date().getTime();
details.latertime = new Date($scope.selected.date).getTime();
details.data = fieldsHavingData;
delete details.data.type;
preprocessor(details);
console.log(details);
DataStoreSrvc.add(details);
GlobalDataService.setSelectedDate(new Date());
TemplateService.getTemplates();
DataStoreSrvc.updateAll();
reset();
var data = {
templates: [ details ]
};
Server.ibsubmit(data)
.success(function (result) {
console.log(result);
})
.error(function (message, status) {
console.log(message);
console.log(status);
$localStorage.templates.push(details);
});
}
else {
reset();
}
};
$scope.reset = function() {
reset();
};
}).
factory('InputboxDataSrvc', function () {
var choices =
[
{ index: 1, id: 'ABC1', label: 'One' },
{ index: 2, id: 'ABC2', label: 'Two' },
{ index: 3, id: 'ABC3', label: 'Three' },
{ index: 4, id: 'ABC4', label: 'Four' },
{ index: 5, id: 'ABC5', label: 'Five' },
{ index: 6, id: 'ABC6', label: 'Six' },
{ index: 7, id: 'ABC7', label: 'Seven' },
{ index: 8, id: 'ABC8', label: 'Eight' },
{ index: 9, id: 'ABC9', label: 'Nine' },
{ index: 10, id: 'ABC10', label: 'Ten' },
];
function moduleDefaultData() {
return {
activity: {
type: 'ACTY',
_ : {
isHavingData: false,
isVisible: {},
names: choices
},
whom: {
text: '',
taglist: []
}
},
calendar: {
type: 'CLDR',
_ : {
isHavingData: false,
isVisible: {},
places: choices,
attendees: choices
},
dates: {
START: {date: new Date(), isDateSet: false},
END: {date: new Date(), isDateSet: false}
},
times: {
START: {date: new Date(), isDateSet: false},
END: {date: new Date(), isDateSet: false}
},
attendees: {
text: '',
taglist: []
},
isChecked: false
},
finance: {
type: 'MNEY',
_ : {
isHavingData: false,
isVisible: {},
attendees: choices
}
},
fitness: {
type: 'HLTH',
_ : {
isHavingData: false,
isVisible: {},
workouts: choices
}
},
food: {
type: 'FOOD',
_ : {
isHavingData: false,
isVisible: {},
foodlist: choices
}
},
list: {
type: 'LIST',
_ : {
list: [],
isHavingData: false,
isVisible: {}
} ,
tags: {
text: '',
taglist: []
}
},
habit: {
type: 'HABT',
_ : {
isHavingData: false,
isVisible: {}
},
isChecked: false
},
mood: {
type: 'MOOD',
level: 999,
_ : {
isHavingData: false,
isVisible: {}
}
},
note: {
type: 'NOTE',
_ : {
isHavingData: false,
isVisible: {},
tags: choices
},
tags: {
text: '',
taglist: []
}
},
place: {
type: 'PLCS',
_ : {
isHavingData: false,
isVisible: {},
places: choices
},
whom: {
text: '',
taglist: []
}
}
};
}
// Templates without blank for flex based layouts
var templates = [
{
name: 'note',
type: 'NOTE',
page: 'notes',
src: 'img/icons/note.png',
icon: 'file-text-o'
},
/*{
name: 'list',
type: 'LIST',
src: 'img/icons/list.png',
icon: 'list'
},
{
name: 'mood',
type: 'MOOD',
src: 'img/icons/mood.png',
icon: 'meh-o'
},
{
name: 'activity',
type: 'ACTY',
src: 'img/icons/activity.png',
icon: 'gamepad'
},*/
{
name: 'food',
type: 'FOOD',
page: 'food',
src: 'img/icons/food.png',
icon: 'cutlery'
},
{
name: 'workout',
type: 'HLTH',
page: 'health',
src: 'img/icons/health.png',
icon: 'heartbeat'
},
{
name: 'money',
type: 'MNEY',
page: 'finance',
src: 'img/icons/finance.png',
icon: 'money'
},
{
name: 'place',
type: 'PLCS',
page: 'places',
src: 'img/icons/places.png',
icon: 'map-marker'
},
/*{
name: 'habit',
type: 'HABT',
src: 'img/icons/habit.png',
icon: 'refresh'
},
{
name: 'calendar',
type: 'CLDR',
src: 'img/icons/calendar.png',
icon: 'calendar'
}*/
];
return {
moduleDefaultData: moduleDefaultData,
templates: templates
};
});
angular.module('homepage').
directive('commentpanel', function() {
return {
controller: 'commentPanelController',
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/content-components/login/commentpanel.html'
}
}).
controller('commentPanelController', function ($scope, $timeout, Server) {
$scope.isMessageVisible = false;
$scope.message = "Comment posted successfully";
$scope.addcomment = function () {
Server.addcomment({comment: $scope.comment})
.success(function (data) {
$scope.comment = "";
$scope.isMessageVisible = true;
$timeout(function () {
$scope.isMessageVisible = false;
}, 3000);
});
}
});
angular.module('homepage').
directive('loginpanel', function() {
return {
controller: 'loginPanelController',
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/content-components/login/loginpanel.html'
};
}).
controller('loginPanelController', function($scope, $timeout, $window, Authentication, DataStoreSrvc, Server, TemplateService) {
$scope.authenticate = function() {
var user = {
username: $scope.username,
password: $scope.password
};
Server.login(user).
success(function(data) {
console.log(data);
if(data.token && data.success) {
Authentication.setUser(data.token);
Authentication.setHeaders();
DataStoreSrvc.resetAll();
$window.location.href = '/#/home';
TemplateService.getTemplates();
}
else {
$scope.message = data.message;
$scope.isMessageVisible = true;
$timeout(function () {
$scope.isMessageVisible = false;
}, 3000);
}
});
};
});
angular.module('homepage').
directive('registerpanel', function() {
return {
controller: 'registerPanelController',
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/content-components/login/registerpanel.html'
};
}).
controller('registerPanelController', function ($location, $scope, $timeout, Server) {
// FB Pixel: Track when a user expresses interest in your offering
fbq('track', 'Lead');
var params = $location.search();
console.log(params);
$scope.data = {};
$scope.invite = { code: ''};
$scope.isRegisterMessageVisible = false;
$scope.isInviteMessageVisible = false;
// Hide registration panel, if param 'hasinvite' set to true
$scope.hasInvite = params.hasinvite;
$scope.register = function () {
console.log($scope.data);
Server.register($scope.data)
.success(function (data) {
console.log(data);
if(data.success) {
}
$scope.data = {};
$scope.message = data.message;
$scope.isRegisterMessageVisible = true;
$timeout(function () {
$scope.isRegisterMessageVisible = false;
}, 3000);
});
};
$scope.checkInviteCode = function () {
Server.checkInvite($scope.invite)
.success(function (data) {
console.log(data);
$scope.invite.code = '';
if(data.success) {
$timeout(function () {
$location.path('/signup');
}, 2000);
}
$scope.message = data.message;
$scope.isInviteMessageVisible = true;
$timeout(function () {
$scope.isInviteMessageVisible = false;
}, 3000);
});
};
});
angular.module('homepage').
directive('signuppanel', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/content-components/login/signuppanel.html',
controller: 'signupPanelController'
};
}).
controller('signupPanelController', function($scope, $timeout, $window, Authentication, Server) {
$scope.isMessageVisible = false;
$scope.error = {
email: false,
username: false
};
$scope.registerUser = function() {
var userData = $scope.registrationInfo;
console.log(userData);
if(isValidData(userData)) {
Server.signup(userData).
success(function(data) {
console.log(data);
$scope.message = data.message;
if(data.success) {
$scope.isMessageVisible = true;
$scope.registrationInfo = {};
$timeout(function () {
Authentication.setUser(data.token);
$window.location.href = '/#/home';
}, 3000);
}
else {
$scope.isMessageVisible = true;
$timeout(function () {
$scope.isMessageVisible = false;
}, 3000);
}
});
}
};
function isValidData(data) {
if(!data) {
return false;
}
var count = 0;
for(var key in data) {
if(data.hasOwnProperty(key)) {
count++;
}
}
// Number of mandatory fields
if(count === 5) {
return true;
}
}
})
angular.module('homepage').
directive('sidebarCard', function () {
return {
controller: 'sidebarCardController',
restrict: 'E',
replace: true,
scope: {
data: '='
},
transclude: true,
templateUrl: 'components/content-components/sidebar/sidebar-card.html'
};
}).
controller('sidebarCardController', function ($scope, Server) {
$scope.markCheckbox = function (hashid, isChecked) {
var data = {
'hashid': hashid,
'isChecked': isChecked
};
Server.markTemplate(data)
.success(function (result) {
console.log(result);
});
};
});
angular.module('homepage').
directive('sidebarTemplate', function () {
return {
controller: 'sidebarTemplateController',
restrict: 'E',
replace: true,
scope: {
data: '='
},
transclude: true,
templateUrl: 'components/content-components/sidebar/sidebar-template.html'
};
}).
controller('sidebarTemplateController', function ($scope, DateUtility, GlobalDataService) {
$scope.currentDate = GlobalDataService.getSelectedDate();
$scope.isTodaysDate = GlobalDataService.isTodaysDateSelected();
});
angular.module('homepage').
directive('timelineTemplate', function () {
return {
controller: 'TimelineTemplateController',
link: TimelineTemplateLinkerFn,
restrict: 'E',
scope: {
item: '='
},
replace: true,
transclude: true,
templateUrl: 'components/content-components/timeline/timeline-template.html'
};
function TimelineTemplateLinkerFn(scope, element, attributes) {
var itemType = getItemTypeText(scope.item.type);
scope.itemType = itemType;
// Path of card template to be included using <ng-include src="template">
// !important: With this approach, controllers on the template would not be active
scope.template = 'components/feature-components/' + itemType + '/' + itemType + '-card.html';
}
function getItemTypeText(type) {
var title = '';
switch(type) {
case 'ACTY': title = 'activity'; break;
case 'NOTE': title = 'note'; break;
case 'LIST': title = 'list'; break;
case 'FOOD': title = 'food'; break;
case 'HLTH': title = 'fitness'; break;
case 'PLCS':
case 'CKIN': title = 'place'; break;
case 'MNEY': title = 'finance'; break;
case 'HABT': title = 'habit'; break;
case 'CLDR': title = 'calendar'; break;
case 'MOOD': title = 'mood'; break;
}
return title;
}
}).
controller('TimelineTemplateController', function ($scope, MobileType) {
$scope.iconOffset = MobileType.any() ? "32" : "48";
});
angular.module('homepage').
directive('timeline', function () {
function timelineLinkerFn(scope, element, attributes) {}
return {
controller: 'TimelineController',
link: timelineLinkerFn,
restrict: 'E',
replace: true,
scope: {
data: '=',
isDemo: '='
},
transclude: true,
templateUrl: 'components/content-components/timeline/timeline.html'
};
}).
controller('TimelineController',
function ($rootScope, $scope, $timeout, DataStoreSrvc, GlobalDataService, ProcessTimelineService,
TemplateService, TimelineService) {
console.log('TimelineController called()');
// Assigned reference of Timeline service object,
// so that this would get auto updated whenever data in the service changes
$scope.timelineItems = DataStoreSrvc.getPosts();
$scope.habitItems = DataStoreSrvc.getHabits();
$scope.isLoading = TimelineService.getLoadingStatus();
if($scope.isDemo) {
// Set demo dates to 7th Nov 2016 (Monday)
var date = new Date(1478525916000);
GlobalDataService.setSelectedDate(date);
}
$scope.currentDate = GlobalDataService.getSelectedDate();
/**
* Change date globally updating widgets, timeline and sidebar items as per new date
* @param {Number} value the number of days the current date is shifted
*/
$scope.changeDate = function (value) {
if(!$scope.isDemo) {
$scope.currentDate.setDate($scope.currentDate.getDate() + value);
GlobalDataService.setSelectedDate($scope.currentDate);
TemplateService.getTemplates();
DataStoreSrvc.updateAll();
}
};
/**
* Set sort order to reverse of current sort order
* and reverse timeline items
*/
$scope.reverseItems = function () {
TimelineService.setSortOrder();
DataStoreSrvc.updateAll();
};
}).
factory('ProcessTimelineService', function (DateUtility, TimelineService) {
// Arranges templates in ascending order
// Process location templates
// Items are reveresed using UI filter
function processTimeline(templates) {
if(templates && templates.length) {
processLocationTemplate(templates);
}
sortOrder = TimelineService.getSortOrder();
if(sortOrder === 'ASCDG') {
// sort timeline items in ascending order
templates.sort(function(a, b) {
return parseFloat(a.timestamp) - parseFloat(b.timestamp);
});
}
else if(sortOrder === 'DSCDG') {
// sort timeline items in decending order
templates.sort(function(a, b) {
return parseFloat(b.timestamp) - parseFloat(a.timestamp);
});
}
}
/**
* set location attibutes if location template is found
*/
function processLocationTemplate(templates) {
var isLocationInfoAvailable = false;
// sort post items in acending order
templates.sort(function(a, b) {
return parseFloat(a.latertime) - parseFloat(b.latertime);
});
for(var index = 0; index<templates.length; index++) {
var post = templates[index];
if(post.type === 'PLCS') {
isLocationInfoAvailable = true;
post.isInSameLocation = false;
post.isLocationInfoAvailable = isLocationInfoAvailable;
}
else {
post.isInSameLocation = true;
post.isLocationInfoAvailable = isLocationInfoAvailable;
}
post.timestamp = getTimestamp(post.timestamp, post.latertime);
post.humantime = DateUtility.getTimeStr(post.timestamp);
post.humandate = DateUtility.getDateStr(post.timestamp);
}
return (index);
}
/**
* Select timestamp from timestamp and latertime
* @param {Number} timestamp date at which snippet was submitted
* @param {Number} latertime past time selected from date-time picker
* @return {Number} time to be used for ordering timeline items
*/
function getTimestamp(timestamp, latertime) {
// If difference greater than 5min, return latertime
var diff = Math.abs(timestamp - latertime) / 1000;
if(diff > (5 * 60)) {
return latertime;
}
return timestamp;
}
// Get location data based on location object passed
function getLocationInfo(item) {
return {
type: 'PLCS',
locntype: item.locntype,
timestamp: item.time.checkin,
humandate: DateUtility.getDateStr(item.time.checkin),
humantime: DateUtility.getTimeStr(item.time.checkin),
data: { title: item.name, source: item.source }
};
}
return {
processTimeline: processTimeline
};
});
angular.module('homepage').
directive('typeAndTime', function () {
return {
restrict: 'E',
scope: {
data: '='
},
replace: true,
transclude: true,
templateUrl: 'components/content-components/timeline/type-and-time.html'
}
}).
filter('typelabel', function () {
return function (type) {
var title = '';
switch(type) {
case 'ACTY': title = 'gamepad'; break;
case 'NOTE': title = 'book'; break;
case 'LIST': title = 'list-ul'; break;
case 'FOOD': title = 'glass'; break;
case 'MOOD': title = 'meh-o'; break;
case 'HLTH': title = 'heartbeat'; break;
case 'CKIN': title = 'map-marker'; break;
case 'PLCS': title = 'location-arrow'; break;
case 'MNEY': title = 'rupee'; break;
case 'HABT': title = 'refresh'; break;
case 'CLDR': title = 'calendar'; break;
}
return title;
}
});
angular.module('homepage').
directive('activityCard', function () {
return {
restrict: 'E',
replace: true,
scope: {
data: '='
},
transclude: true,
templateUrl: 'components/feature-components/activity/activity-card.html'
};
}).
filter('activityicon', function () {
return function (code) {
var name = 'slack';
switch (code) {
case 'ATNDG': name = 'briefcase'; break;
case 'CLBTG': name = 'birthday-cake'; break;
case 'DRNKG': name = 'beer'; break;
case 'DRVNG': name = 'automobile'; break;
case 'EATNG': name = 'cutlery'; break;
case 'LSTNG': name = 'music'; break;
case 'METNG': name = 'calendar-check-o'; break;
case 'PLYNG': name = 'futbol-o'; break;
case 'REDNG': name = 'book'; break;
case 'RSTNG': name = 'bed'; break;
case 'RIDNG': name = 'motorcycle'; break;
case 'SHPNG': name = 'shopping-bag'; break;
case 'SNGNG': name = 'microphone'; break;
case 'SLPNG': name = 'bed'; break;
case 'THKNG': name = 'comment-o'; break;
case 'TRVLG': name = 'plane'; break;
case 'WTCNG': name = 'television'; break;
case 'WRKNG': name = 'briefcase'; break;
}
return name;
};
});
angular.module('homepage').
directive('activityPanel', function () {
return {
controller: 'activityPanelController',
restrict: 'E',
replace: true,
scope: {
activity: '='
},
templateUrl: 'components/feature-components/activity/activity-panel.html'
};
}).
controller('activityPanelController', function ($scope) {
$scope.activities = [
{ code: 'ATNDG', desc: 'Attending' },
{ code: 'CLBTG', desc: 'Celebrating' },
{ code: 'COOKG', desc: 'Cooking' },
{ code: 'DANCE', desc: 'Dancing' },
{ code: 'DRNKG', desc: 'Drinking' },
{ code: 'DRVNG', desc: 'Driving' },
{ code: 'EATNG', desc: 'Eating' },
{ code: 'LSTNG', desc: 'Listening' },
{ code: 'METNG', desc: 'Meeting' },
{ code: 'PLYNG', desc: 'Playing' },
{ code: 'REDNG', desc: 'Reading' },
{ code: 'RSTNG', desc: 'Resting' },
{ code: 'RIDNG', desc: 'Riding' },
{ code: 'SNGNG', desc: 'Driving' },
{ code: 'SHPNG', desc: 'Shopping' },
{ code: 'SLPNG', desc: 'Sleeping' },
{ code: 'THKNG', desc: 'Thinking' },
{ code: 'TRVLG', desc: 'Traveling' },
{ code: 'WLKNG', desc: 'Walking' },
{ code: 'WTCNG', desc: 'Watching' },
{ code: 'WRKNG', desc: 'Working' }
];
$scope.setActivityType = function (type) {
// Activities with subtypes
var subtypes = ['ATNDG', 'CLBTG', 'COOKG', 'DANCE', 'DRNKG', 'DRVNG', 'EATNG',
'LSTNG', 'METNG', 'PLYNG', 'REDNG', 'SHPNG', 'SLPNG', 'SNGNG',
'THKNG', 'TRVLG', 'WLKNG', 'WTCNG', 'WRKNG'];
// If more info panel to be shown for activity
var moreinfo = ['ATNDG', 'CLBTG', 'COOKG', 'DANCE', 'DRNKG', 'DRVNG', 'EATNG',
'LSTNG', 'METNG', 'PLYNG', 'REDNG', 'SHPNG', 'SNGNG',
'THKNG', 'TRVLG', 'WLKNG', 'WTCNG', 'WRKNG'];
$scope.activity.activitytype = type;
setTitle(type);
// If has subtype
if (subtypes.indexOf(type) != -1) {
$scope.activity._.isVisible.subtype = true;
// Show me more info input field
if (moreinfo.indexOf(type) != -1) {
$scope.activity._.isVisible.sleeptype = false;
$scope.activity._.isVisible.details = true;
}
else if ($scope.activity.activitytype == 'SLPNG') {
$scope.activity._.isVisible.sleeptype = true;
$scope.activity._.isVisible.details = false;
}
}
else {
$scope.activity._.isVisible.subtype = false;
$scope.activity._.isVisible.sleeptype = false;
$scope.activity._.isVisible.details = true;
}
};
$scope.setActivitySubType = function (type) {
$scope.activity.activitysubtype = type;
$scope.activity._.isVisible.whom = true;
$scope.activity._.isVisible.note = true;
};
function setTitle(type) {
// Set title for text input field
switch (type) {
case 'ATNDG':
$scope.activity.subtypeTitle = 'Event Name';
break;
case 'CLBTG':
$scope.activity.subtypeTitle = 'Event Name';
break;
case 'COOKG':
$scope.activity.subtypeTitle = 'Dishes Name';
break;
case 'DANCE':
$scope.activity.subtypeTitle = 'Dance Name';
break;
case 'DRNKG':
$scope.activity.subtypeTitle = 'Drink Name';
break;
case 'DRVNG':
$scope.activity.subtypeTitle = 'Vehicle Name';
break;
case 'EATNG':
$scope.activity.subtypeTitle = 'Food Name';
break;
case 'LSTNG':
$scope.activity.subtypeTitle = 'Listening To';
break;
case 'METNG':
$scope.activity.subtypeTitle = 'Meeting Title';
break;
case 'PLYNG':
$scope.activity.subtypeTitle = 'Sports Name';
break;
case 'REDNG':
case 'THKNG':
$scope.activity.subtypeTitle = 'About';
break;
case 'SNGNG':
$scope.activity.subtypeTitle = 'Singing';
break;
case 'SHPNG':
$scope.activity.subtypeTitle = 'Looking For';
break;
case 'TRVLG':
case 'WLKNG':
$scope.activity.subtypeTitle = 'To';
break;
case 'WTCNG':
$scope.activity.subtypeTitle = 'Watching';
break;
case 'WRKNG':
$scope.activity.subtypeTitle = 'On';
break;
}
}
});
angular.module('homepage').
directive('calendarCard', function () {
function CalendarCardLinkerFn(scope, element, attributes) {
}
return {
//controller: 'CalendarCardController',
//link: CalendarCardLinkerFn,
restrict: 'E',
replace: true,
scope: {
calendarData: '='
},
transclude: true,
templateUrl: 'components/feature-components/calendar/calendar-card.html'
}
});
angular.module('homepage').
directive('calendarPanel', function () {
return {
controller: 'calendarPanelController',
restrict: 'E',
replace: true,
scope: {
calendar: '='
},
templateUrl: 'components/feature-components/calendar/calendar-panel.html'
}
}).
controller('calendarPanelController', function ($scope, $timeout) {
// Repeat module default params
$scope.calendar.defaults = {repeat: 'ONCE'};
});
angular.module('homepage').
directive('contact', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/feature-components/contact/contact.html'
}
});
angular.module('homepage').
directive('financeCard', function () {
return {
controller: 'FinanceCardController',
restrict: 'E',
replace: true,
scope: {
financeData: '='
},
transclude: true,
templateUrl: 'components/feature-components/finance/finance-card.html'
}
}).
controller('FinanceCardController', function ($scope) {
$scope.financeData.currency = '8377;';
});
angular.module('homepage').
directive('financeMemberInfo', function () {
return {
controller: 'financeMemberInfoController',
restrict: 'E',
replace: true,
scope: {
details: '=',
index: '=',
paidby: '=',
size: '=',
type: '='
},
templateUrl: 'components/feature-components/finance/finance-member-info.html'
};
}).
controller('financeMemberInfoController', function ($scope) {
});
angular.module('homepage').
directive('financePanel', function () {
return {
controller: 'financePanelController',
restrict: 'E',
replace: true,
scope: {
finance: '='
},
templateUrl: 'components/feature-components/finance/finance-panel.html'
};
}).
controller('financePanelController', function ($scope) {
function setItem() {
return {
title: '',
amount: '',
paidby: {
text: '',
taglist: [{text: 'Myself'}]
},
splitbtw: {
text: '',
taglist: [{text: 'Myself'}]
}
};
}
$scope.finance._.isVisible = {};
$scope.finance.list = [];
$scope.finance.list[0] = setItem();
/**
* Remove the item from zeroth index and add it to list end and empty zeroth index
*/
$scope.addNewItem = function () {
var length = $scope.finance.list.length;
$scope.finance.list[length] = $scope.finance.list[0];
$scope.finance.list[0] = setItem();
// Reset view
$scope.finance._.isVisible = {};
// Remove class 'chosen'
var elements = document.querySelectorAll('.input-box-wrapper .finance-panel .chosen');
for(var i=0;i<elements.length;i++) {
elements[i].classList.remove('chosen');
}
};
});
angular.module('homepage').
directive('financeSummary', function () {
return {
restrict: 'E',
replace: true,
scope: {
finance: '=data'
},
transclude: true,
templateUrl: 'components/feature-components/finance/finance-summary.html'
};
});
angular.module('homepage').
directive('financeWidget', function () {
return {
controller: 'financeWidgetController',
restrict: 'E',
replace: true,
scope: {
data: '=',
isDemo: '='
},
transclude: true,
templateUrl: 'components/feature-components/finance/finance-widget.html'
};
}).
controller('financeWidgetController', function ($scope, DateUtility, Server) {
if($scope.isDemo === true) {
$scope.stats = {
count: 1,
result: {
myself: {
amount_day: 2505,
amount_month: 33778
}
}
};
}
else {
var monthRange = DateUtility.getMonthDateRange(new Date());
var data = {
startTimestamp: new Date(monthRange.start).getTime(),
endTimestamp: new Date(monthRange.end).getTime()
};
Server.getMoneyWidgetData(data)
.success(function (result) {
console.log(result);
$scope.stats = result;
});
}
});
angular.module('homepage').
directive('finance', function () {
return {
controller: 'FinanceController',
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'components/feature-components/finance/finance.html'
}
}).
controller('FinanceController', function ($scope, ArrayUtility, DateUtility, Server) {
$scope.finances = new Array(12);
function resetAll() {
$scope.total = 0;
ArrayUtility.reassignArray($scope.finances, []);
}
function addByMonth(item, timestamp) {
var finance = {
amount: item.amount,
title: item.title,
timestamp: timestamp
};
var financeMonthIndex = new Date(timestamp).getMonth();
if(!$scope.finances[financeMonthIndex]) {
$scope.finances[financeMonthIndex] = [];
}
$scope.finances[financeMonthIndex].push(finance);
$scope.total += finance.amount;
}
function calculateTotal(expenses, attrName) {
if(expenses) {
return expenses.reduce(function(total,current) {
if(current[attrName]) {
return total + current[attrName];
}
return total;
}, 0);
} else {
return 0;
}
};
resetAll();
$scope.getTotal = calculateTotal;
$scope.getMoneyData = function (dateRange) {
Server.getMoneyData(dateRange).success(function (result) {
resetAll();
var entries = result.documents;
entries.forEach(function(entry) {
entry.data.list.forEach(function(item) {
if(item.amount) {
addByMonth(item, entry.timestamp);
}
})
});
});
};
var currentMonthIndex = new Date().getMonth();
$scope.choosen = {
year: 2018,
month: currentMonthIndex
};
$scope.getMoneyData(DateUtility.
getMonthDateRange(new Date($scope.choosen.year, currentMonthIndex, 1)));
});
angular.module('homepage').
directive('fitnessCard', function () {
function FitnessCardLinkerFn(scope, element, attributes) {
}
return {
//controller: 'FitnessCardController',
//link: FitnessCardLinkerFn,
restrict: 'E',
replace: true,
scope: {
fitnessData: '='
},
transclude: true,
templateUrl: 'components/feature-components/fitness/fitness-card.html'
}
});
angular.module('homepage').
directive('fitnessPanel', function () {
return {
controller: 'fitnessPanelController',
restrict: 'E',
replace: true,
scope: {
fitness: '='
},
templateUrl: 'components/feature-components/fitness/fitness-panel.html'
}
}).
controller('fitnessPanelController', function ($scope) {
function Set() {
return {
repetition: '',
weight: '',
time: '',
distance: ''
}
}
function setItem() {
return {
workouttitle: '',
sets: [
new Set()
]
}
}
// Initialize list of fitness and its sets list
$scope.fitness.list = [
setItem()
];
/**
* Remove the item from zeroth index and add it to list end and empty zeroth index
*/
$scope.addNewItem = function () {
var length = $scope.fitness.list.length;
$scope.fitness.list[length] = $scope.fitness.list[0];
$scope.fitness.list[0] = setItem();
};
});
angular.module('homepage').
directive('addNewSet', function ($timeout) {
function Set() {
return {
repetition: '',
weight: '',
time: '',
distance: ''
}
}
return {
link: function (scope, element, attribute) {
element.on('keyup', function(event){
if(scope.index + 1 == scope.sets.length) {
var code = event.keyCode || event.which;
// Skip adding row if key pressed is 'Tab', 'Shift' or 'Esc'
if(!(code == 9 || code == 16 || code == 27)) {
console.log('keyup happening');
$timeout(function () {
scope.sets.push(new Set());
scope.$apply();
});
}
}
})
},
restrict: 'E',
replace: true,
scope: {
index: '=',
sets: '=data'
},
templateUrl: 'components/feature-components/fitness/fitness-set.html'
}
});
angular.module('homepage').
directive('fitnessSummary', function () {
return {
restrict: 'E',
replace: true,
scope: {
fitness: '=data'
},
templateUrl: 'components/feature-components/fitness/fitness-summary.html'
}
});
angular.module('homepage').
directive('fitnessWidget', function () {
return {
restrict: 'E',
replace: true,
scope: {
data: '='
},
transclude: true,
templateUrl: 'components/feature-components/fitness/fitness-widget.html'
};
}).
filter('workoutSummary', function () {
function getWorkoutSummary(workout) {
var text = "";
if(workout.sets) {
for (var index in workout.sets) {
var set = workout.sets[index];
if(set.repetition !== "") {
text += set.repetition;
if(set.weight !== "") {
text += "(" + set.weight + ")";
}
else if(set.distance !== "") {
text += "(" + set.distance + ")";
}
else if(set.time !== "") {
text += "(" + set.time + ")";
}
}
else if(set.distance !== "") {
text += set.distance;
if(set.time !== "") {
text += "(" + set.time + ")";
}
}
else if(set.weight !== "") {
text += set.weight;
if(set.time !== "") {
text += "(" + set.time + ")";
}
}
else if(set.time !== "") {
text += set.time;
}
if(index < (workout.sets.length - 1)) {
text += ", ";
}
}
}
return text;
}
return getWorkoutSummary;
});
angular.module('homepage').
directive('foodCard', function () {
function FoodCardLinkerFn(scope, element, attributes) {
}
return {
//controller: 'FoodCardController',
//link: FoodCardLinkerFn,
restrict: 'E',
replace: true,
scope: {
foodData: '='
},
transclude: true,
templateUrl: 'components/feature-components/food/food-card.html'
}
});
angular.module('homepage').
directive('foodPanel', function () {
return {
controller: 'foodPanelController',
restrict: 'E',
replace: true,
scope: {
food: '='
},
templateUrl: 'components/feature-components/food/food-panel.html'
};
}).
controller('foodPanelController', function ($scope) {
function setItem() {
return {
mealtype: '',
quantity: 1,
qtytype: ''
};
}
$scope.isVisible = {};
$scope.food.list = [];
$scope.food.list[0] = setItem();
/**
* @param {type}
* possible values: FOOD, DRNK
*/
$scope.setType = function (type) {
$scope.food.list[0].mealtype = type;
};
/**
* @param {type}
* possible values:
* FOOD - PCE, TSP, BWL, ONC, GRM
* DRNK - CUP, GLS, BTL, PTR, TWR, LTR;
*/
$scope.setQtyType = function (type) {
$scope.food.list[0].qtytype = type;
};
/**
* Remove the item from zeroth index and add it to list end and empty zeroth index
*/
$scope.addNewItem = function () {
var length = $scope.food.list.length;
$scope.food.list[length] = $scope.food.list[0];
$scope.food.list[0] = setItem();
// Reset view
$scope.isVisible = {};
// Remove class 'chosen'
var elements = document.querySelectorAll('.input-box-wrapper .food-panel .chosen');
for(var i=0;i<elements.length;i++) {
elements[i].classList.remove('chosen');
}
};
}).
filter('filterMealType', function () {
/**
* Returns items by type and excludes the first item in the list
*/
return function (items, type) {
var filtered = [];
for (var index in items) {
if(items[index].mealtype === type && index != 0) {
filtered.push(items[index]);
}
}
return filtered;
};
}).
filter('quantityType', function () {
/**
* Returns items by type and excludes the first item in the list
*/
return function (type) {
var text = '';
switch(type) {
// DRINKs
case 'CUP': text = 'Cup'; break;
case 'GLS': text = 'Glass'; break;
case 'BTL': text = 'Bottle'; break;
case 'PTR': text = 'Pitcher'; break;
case 'TWR': text = 'Tower'; break;
case 'LTR': text = 'Liter'; break;
//FOODs
case 'PCE': text = 'Pieces'; break;
case 'TSP': text = 'Table Spoon'; break;
case 'BWL': text = 'Bowl'; break;
case 'ONC': text = 'Ounce'; break;
case 'GRM': text = 'Gram'; break;
}
return text;
};
});
angular.module('homepage').
directive('foodSummary', function () {
return {
restrict: 'E',
replace: true,
scope: {
food: '=data'
},
transclude: true,
templateUrl: 'components/feature-components/food/food-summary.html'
};
}).
filter('caloriesCount', function(FoodNutritionSrvc) {
function getCaloriesCount(foodtitle, params) {
var value = "";
var foodtype = params.foodtype;
var quantity = params.quantity;
var qtytype = params.qtytype;
var calories = params.calories;
var nutritionInfo = FoodNutritionSrvc.getNutritionInfo(foodtitle, foodtype, quantity, qtytype);
if (calories > 0) {
value = calories;
}
else {
value = nutritionInfo.calories > 0 ? nutritionInfo.calories : 'X';
}
return value;
}
return getCaloriesCount;
}).
filter('totalCaloriesCount', function (FoodNutritionSrvc) {
function calculateTotalCalories(items) {
var nutritionInfo = null;
var totalCalories = 0;
var hasUnknown = false; // If any food calories is unknown
for(var index in items) {
var item = items[index];
var calories = item.count;
if (item.foodtext === undefined || item.foodtext === '') continue;
nutritionInfo = FoodNutritionSrvc.getNutritionInfo(item.foodtext, item.mealtype, item.quantity, item.qtytype);
if (calories > 0) {
totalCalories += parseInt(calories);
}
else if(nutritionInfo.calories > 0) {
totalCalories += parseInt(nutritionInfo.calories);
}
else {
hasUnknown = true;
}
}
if(totalCalories === 0) {
return 'X';
}
else {
if(hasUnknown === true) {
return totalCalories + " + X";
}
else {
return totalCalories;
}
}
}
return calculateTotalCalories;
});
angular.module('homepage').
directive('foodWidget', function () {
return {
restrict: 'E',
replace: true,
scope: {
data: '='
},
transclude: true,
templateUrl: 'components/feature-components/food/food-widget.html'
};
});
angular.module('homepage').
directive('habitCardDetail', function () {
function HabitCardLinkerFn(scope, element, attributes) {
}
return {
controller: 'HabitCardController',
//link: HabitCardLinkerFn,
restrict: 'E',
replace: true,
scope: {
item: '='
},
transclude: true,
templateUrl: 'components/feature-components/habit/habit-card-detail.html'
};
}).
controller('HabitCardController', function ($scope, MobileType, Server) {
$scope.isMobile = MobileType.any();
$scope.markCheckbox = function (hashid, isChecked) {
var data = {
'hashid': hashid,
'isChecked': isChecked
};
Server.markTemplate(data)
.success(function (result) {
console.log(result);
});
};
});
angular.module('homepage').
directive('habitPanel', function () {
return {
controller: 'habitPanelController',
restrict: 'E',
replace: true,
scope: {
habit: '='
},
templateUrl: 'components/feature-components/habit/habit-panel.html'
}
}).
controller('habitPanelController', function ($scope, $timeout) {
// Initialize defaults
$scope.habit.defaults = {repeat: 'DALY'};
$scope.habit.time = {};
$scope.habit.time.date = new Date();
$timeout(function () {
$scope.$apply();
});
});
angular.module('homepage').
directive('listCard', function () {
function ListCardLinkerFn(scope, element, attributes) {
}
return {
//controller: 'ListCardController',
//link: ListCardLinkerFn,
restrict: 'E',
replace: true,
scope: {
listData: '='
},
transclude: true,
templateUrl: 'components/feature-components/list/list-card.html'
}
});
angular.module('homepage').
directive('listPanel', function () {
return {
//controller: 'listPanelController',
restrict: 'E',
replace: true,
scope: {
list: '='
},
templateUrl: 'components/feature-components/list/list-panel.html'
};
});
angular.module('homepage').
directive('list', function($compile, $timeout, RecursionHelper) {
return {
compile: ListCompile,
controller: 'ListController',
link: ListLinker,
replace: true,
restrict: 'E',
scope: {
list: '=',
isDisabled: '='
},
templateUrl: 'components/feature-components/list/list.html'
};
function ListLinker(scope, element, attribute) {
$timeout(function() {});
}
function ListCompile(element) {
// Use the compile function from the RecursionHelper,
// And return the linking function(s) which it returns
return RecursionHelper.compile(element);
}
}).
directive('listitem', function($compile, $timeout) {
return {
// attributes are passed into the isolate scope of the directive
// and manipulated via the controller method passed into the isolate scope
link: ListItemLinker,
replace: true,
restrict: 'E',
scope: {
list: '=',
isDisabled: '=',
itemindex: '=',
setList: '&'
},
template: '<div class="listitem"><input class="input-field" type="text" ' +
'ng-disabled="isDisabled" ng-model="list[itemindex.index].value"/></div>'
};
function ListItemLinker(scope, element, attribute) {
element.on('keyup', function(event) {
event.stopPropagation();
var code = event.keyCode || event.which;
var itemindex = scope.itemindex.index;
if(code == 13) {
scope.setList();
$timeout(function() {
scope.$apply();
});
}
});
}
}).
controller('ListController', function($scope, ListHelper) {
var list = [
{
value: ''
}
];
// initialize list only if creating a list
if($scope.list === undefined) {
$scope.list = angular.copy(list);
}
$scope.setList = function(itemindex) {
var newitemindex = parseInt(itemindex) + 1;
var itemvalue = $scope.list[itemindex].value;
if(itemvalue !== undefined && typeof newitemindex == 'number') {
var listsize = $scope.list.length;
var item = {
value: ''
};
var isStartOfList = ListHelper.isCreatingList(itemvalue);
if(isStartOfList) {
// If last item of the list add one item to list end, before appending list
$scope.list.push(item);
$scope.list[itemindex].list = angular.copy(list);
}
else {
if(newitemindex == listsize){
$scope.list.push(item);
}
else {
// Insert item in between the array
// insert at new index, remove 0, item to be inserted
$scope.list.splice(newitemindex, 0, item);
}
}
}
};
}).
factory('ListHelper', function() {
return {
// Check if line ends with '::'
isCreatingList: function(line) {
line = line + '';
line = line.trim();
if(line.charAt(line.length - 1) == ':') {
if(line.charAt(line.length - 2) == ':') {
return true;
}
}
return false;
}
};
}).
factory('RecursionHelper', function($compile){
return {
/**
* Manually compiles the element, fixing the recursion loop.
* @param element
* @param [link] A post-link function, or an object with function(s) registered via pre and post properties.
* @returns An object containing the linking functions.
*/
compile: function(element, link){
// Normalize the link parameter
if(angular.isFunction(link)){
link = { post: link };
}
// Break the recursion loop by removing the contents
var contents = element.contents().remove();
var compiledContents;
return {
pre: (link && link.pre) ? link.pre : null,
/**
* Compiles and re-adds the contents
*/
post: function(scope, element){
// Compile the contents
if(!compiledContents){
compiledContents = $compile(contents);
}
// Re-add the compiled contents to the element
compiledContents(scope, function(clone){
element.append(clone);
});
// Call the post-linking function, if any
if(link && link.post){
link.post.apply(null, arguments);
}
}
};
}
};
});
angular.module('homepage').
directive('mediaPanel', function () {
return {
//controller: 'mediaPanelController',
restrict: 'E',
replace: true,
scope: {
media: '='
},
templateUrl: 'components/feature-components/media/media-panel.html'
}
});
angular.module('homepage').
directive('moodBar', function () {
return {
controller: 'moodBarController',
restrict: 'E',
replace: true,
scope: {
data: '='
},
transclude: true,
templateUrl: 'components/feature-components/mood/mood-bar.html'
}
}).
controller('moodBarController', function ($scope) {
function generateMoodSlots(level) {
var slots = [];
for(var i=3; i >= -3; i--) {
// Add neutral slot
if(i==0) {
slots.push({type: 'neutral'});
}
// Build positive mood bar
else if(level > 0) {
if(level >= i && i > 0) {
slots.push({type: 'positive'});
}
else {
slots.push({type: 'invisible'});
}
}
// Build negative mood bar
else if(level < 0) {
if(level <= i & i < 0) {
slots.push({type: 'negative'});
}
else {
slots.push({type: 'invisible'});
}
}
else {
slots.push({type: 'invisible'});
}
}
return slots;
}
$scope.slots = generateMoodSlots($scope.data.level);
});
angular.module('homepage').
directive('moodCard', function () {
function MoodCardLinkerFn(scope, element, attributes) {
}
return {
//controller: 'MoodCardController',
//link: MoodCardLinkerFn,
restrict: 'E',
replace: true,
scope: {
moodData: '='
},
transclude: true,
templateUrl: 'components/feature-components/mood/mood-card.html'
};
});
angular.module('homepage').
directive('moodPanel', function () {
return {
controller: 'moodPanelController',
restrict: 'E',
replace: true,
scope: {
mood: '='
},
templateUrl: 'components/feature-components/mood/mood-panel.html'
};
}).
controller('moodPanelController', function ($scope, $timeout) {
var moodsList = [
{ level: -3, name: 'very low', btnClass: 'btn-danger'},
{ level: -2, name: 'low', btnClass: 'btn-warning'},
{ level: -1, name: 'bad', btnClass: 'btn-warn'},
{ level: 0, name: 'neutral', btnClass: 'btn-grey'},
{ level: 1, name: 'good', btnClass: 'btn-mild'},
{ level: 2, name: 'high', btnClass: 'btn-info'},
{ level: 3, name: 'very high', btnClass: 'btn-primary'}
];
var feelingList = {
veryhigh: [
{ name:'Determined', code: 'DTRMD'},
{ name:'Ecstacy', code: 'ECSTY'},
{ name:'Exicited', code: 'EXCTD'},
{ name:'Focused', code: 'FOCSD'},
{ name:'Inspired', code: 'INPRD'},
{ name:'Motivated', code: 'MTVTD'},
{ name:'Overjoyed', code: 'OVRJD'},
{ name:'Pumped Up', code: 'PMPDU'}
],
high: [
{ name:'Amazed', code:'AMAZD'},
{ name:'Anticipating', code:'ANCTG'},
{ name:'Appreciated', code:'APCTD'},
{ name:'Brave', code:'BRAVE'},
{ name:'Beautiful', code:'BETFL'},
{ name:'Creative', code:'CRETV'},
{ name:'Celebrated', code:'CLBTD'},
{ name:'Confident', code:'COFDT'},
{ name:'Certain', code:'CRTAN'},
{ name:'Encouraged', code:'ECRGD'},
{ name:'Healthy', code:'HLTHY'},
{ name:'In Awe', code:'INAWE'},
{ name:'Interested', code:'ITRSD'},
{ name:'Refreshed', code:'RFRSD'},
{ name:'Successful', code:'SCFUL'},
{ name:'Surprised', code:'SUPRD'},
{ name:'Great', code:'GREAT'}
],
good: [
{ name:'Admired', code:'ADMRD'},
{ name:'Affectionate', code:'AFNAT'},
{ name:'Attracted', code:'ATRTD'},
{ name:'Composed', code:'CMPSD'},
{ name:'Calm', code:'CALMX'},
{ name:'Joy', code:'JOYXX'},
{ name:'Loved', code:'LOVED'},
{ name:'Healthy', code:'HLTHY'},
{ name:'Hopeful', code:'HOFUL'},
{ name:'Prepared', code:'PRPRD'},
{ name:'Refreshed', code:'RFRSD'},
{ name:'Good', code:'GOODX'}
],
neutral: [
{ name:'Affectionate', code:'AFNAT'},
{ name:'Attracted', code:'ATRTD'},
{ name:'Composed', code:'CMPSD'},
{ name:'Calm', code:'CALMX'},
{ name:'Content', code:'CNTNT'},
{ name:'Peaceful', code:'PCFUL'},
{ name:'Relaxed', code:'RLAXD'},
{ name:'Serenity', code:'NETRL'},
{ name:'Secure', code:'SECUR'},
{ name:'At ease', code:'ATESE'},
{ name:'Okay', code:'OKAYX'}
],
bad: [
{ name:'Boredom', code:'BORDM'},
{ name:'Composed', code:'CMPSD'},
{ name:'Calm', code:'CALMX'},
{ name:'Depressed', code:'DPRSD'},
{ name:'Doubtful', code:'DBFUL'},
{ name:'Fatigued', code:'FATGD'},
{ name:'Fearful', code:'FRFUL'},
{ name:'Ignored', code:'IGNRD'},
{ name:'Judged', code:'JUDGD'},
{ name:'Mistreated', code:'MSTRD'},
{ name:'Nervous', code:'NRVOS'},
{ name:'Rejected', code:'RJCTD'},
{ name:'Sad', code:'SADXX'},
{ name:'Scared', code:'SCRED'},
{ name:'Weak', code:'WEAKX'},
{ name:'Low', code:'LOWXX'}
],
low: [
{ name:'Annoyed', code:'ANOED'},
{ name:'Anxious', code:'ANXIS'},
{ name:'Burned Out', code:'BRNOT'},
{ name:'Disgust', code:'DSGST'},
{ name:'Defeated', code:'DEFTD'},
{ name:'Depressed', code:'DPRSD'},
{ name:'Embarassed', code:'EMBSD'},
{ name:'Grief', code:'GRIEF'},
{ name:'Hated', code:'HATED'},
{ name:'Hopeless', code:'HPLSS'},
{ name:'Offended', code:'OFNDD'},
{ name:'Victimised', code:'VTMSD'},
{ name:'Worried', code:'WRRED'},
{ name:'Low', code:'LOWXX'}
],
verylow: [
{ name:'Anger', code:'ANGER'},
{ name:'Depressed', code:'DPRSD'},
{ name:'Guilty', code:'GULTY'},
{ name:'Rage', code:'RAGEX'},
{ name:'Stressed', code:'STRSD'},
{ name:'Terified', code:'TRFID'},
{ name:'Worthless', code:'WRTLS'},
{ name:'Very Low', code:'VYLOW'}
]
};
$scope.moods = moodsList;
$scope.mood.selectedFeelingsCode = []; // List of feelings by code
$scope.mood.selectedFeelingsName = []; // List of feelings by name
$scope.selectedFeelingsByIndex = []; // List of feelings based on original index for CSS styling
$scope.selectMood = function (level) {
$scope.mood.level = level;
$scope.mood.selectedFeelingsCode = []; // reset selected feelings
$scope.mood.selectedFeelingsName = []; // reset selected feelings
$scope.selectedFeelingsByIndex = []; // reset selected feelings
switch(level) {
case 3: $scope.feelings = feelingList.veryhigh;
$scope.labelType = 'btn-primary';
$scope.mood.label = 'Very High';
break;
case 2: $scope.feelings = feelingList.high;
$scope.labelType = 'btn-info';
$scope.mood.label = 'High';
break;
case 1: $scope.feelings = feelingList.good;
$scope.labelType = 'btn-mild';
$scope.mood.label = 'Good';
break;
case 0: $scope.feelings = feelingList.neutral;
$scope.labelType = 'btn-grey';
$scope.mood.label = 'Okay';
break;
case -1: $scope.feelings = feelingList.bad;
$scope.labelType = 'btn-warn';
$scope.mood.label = 'Bad';
break;
case -2: $scope.feelings = feelingList.low;
$scope.labelType = 'btn-warning';
$scope.mood.label = 'Low';
break;
case -3: $scope.feelings = feelingList.verylow;
$scope.labelType = 'btn-danger';
$scope.mood.label = 'Very Low';
break;
default:
}
$timeout(function () {
$scope.$apply();
});
};
$scope.selectFeeling = function (index, code) {
var returnid = $scope.mood.selectedFeelingsCode.indexOf(code);
var feeling = $scope.feelings[index].name;
// Select or unselect the feeling
if(returnid === -1) {
$scope.mood.selectedFeelingsCode.push(code);
$scope.mood.selectedFeelingsName.push(feeling);
$scope.selectedFeelingsByIndex[index] = code;
}
else {
$scope.mood.selectedFeelingsCode.splice(returnid, 1);
$scope.mood.selectedFeelingsName.splice(returnid, 1);
$scope.selectedFeelingsByIndex.splice(index, 1);
}
$timeout(function () {
$scope.$apply();
});
};
});
angular.module('homepage').
directive('moodWidget', function () {
return {
controller: 'moodWidgetController',
restrict: 'E',
replace: true,
transclude: true,
scope: {
data: '='
},
templateUrl: 'components/feature-components/mood/mood-widget.html'
};
}).
controller('moodWidgetController', function ($scope) {
console.log($scope.data);
});
angular.module('homepage').
directive('noteCard', function () {
function NoteCardLinkerFn(scope, element, attributes) {
}
return {
//controller: 'NoteCardController',
//link: NoteCardLinkerFn,
restrict: 'E',
replace: true,
scope: {
noteData: '='
},
transclude: true,
templateUrl: 'components/feature-components/note/note-card.html'
}
});
angular.module('homepage').
directive('notePanel', function () {
return {
//controller: 'notePanelController',
restrict: 'E',
replace: true,
scope: {
note: '='
},
templateUrl: 'components/feature-components/note/note-panel.html'
}
});
angular.module('homepage').
directive('note', function () {
return {
controller: 'noteController',
restrict: 'E',
replace: true,
templateUrl: 'components/feature-components/note/note.html'
};
}).
controller('noteController', function($scope, DateUtility, Server) {
$scope.getNotesData = function (dateRange) {
Server.getNotesData(dateRange).success(function(result) {
console.log(result);
$scope.notes = result.documents;
});
};
var currentMonthIndex = new Date().getMonth();
$scope.choosen = {
year: 2018,
month: currentMonthIndex
};
$scope.getNotesData(DateUtility.
getMonthDateRange(new Date($scope.choosen.year, currentMonthIndex, 1)));
});
angular.module('homepage').
directive('peoplePanel', function () {
return {
//controller: 'peoplePanelController',
restrict: 'E',
replace: true,
scope: {
people: '='
},
templateUrl: 'components/feature-components/people/people-panel.html'
}
});
angular.module('homepage').
directive('placeCard', function () {
return {
//controller: 'PlaceCardController',
restrict: 'E',
replace: true,
scope: {
placeData: '='
},
transclude: true,
templateUrl: 'components/feature-components/place/place-card.html'
};
});
angular.module('homepage').
directive('placePanel', function () {
return {
//controller: 'placePanelController',
restrict: 'E',
replace: true,
scope: {
place: '='
},
templateUrl: 'components/feature-components/place/place-panel.html'
};
});