angular.module("rallly",["ui.router","ngResource","btford.modal","ngTagsInput","ngAnimate","ngFitText"]).config(["$stateProvider","$urlRouterProvider","$locationProvider",function(e,t,n){n.html5Mode(!0),t.otherwise("/notfound"),e.state("index",{url:"/",templateUrl:"templates/home.html",controller:"HomeCtrl"}).state("newevent",{url:"/new",templateUrl:"templates/newEvent/layout.html",controller:"NewEventCtrl"}).state("newevent.general",{templateUrl:"templates/newEvent/general.html"}).state("newevent.datetime",{templateUrl:"templates/newEvent/datetime.html"}).state("newevent.invite",{templateUrl:"templates/newEvent/invite.html"}).state("newevent.success",{templateUrl:"templates/newEvent/success.html"}).state("about",{url:"/about",templateUrl:"templates/about.html",controller:"AboutCtrl"}).state("notfound",{url:"/notfound",templateUrl:"templates/notfound.html"}).state("event",{url:"/:id",templateUrl:"templates/event.html",controller:"EventCtrl"}).state("editevent",{url:"/:id/edit",templateUrl:"templates/editevent.html",controller:"EditEventCtrl"}).state("verifyevent",{url:"/verify/:id/code/:code",controller:"VerificationCtrl"}).state("deleteevent",{url:"/delete/:id/code/:code",controller:"DeletionCtrl"})}]).factory("Event",["$resource",function(e){return e("/api/event/:id",{id:"@_id"},{update:{method:"PUT"},verify:{method:"GET",url:"/api/event/:id/code/:code"},destroy:{method:"DELETE",url:"/api/event/:id/code/:code"}})}]).factory("Participant",["$resource",function(e){return e("/api/event/:id/participant/:pid",{id:"@_id"},{update:{method:"PUT"}})}]).factory("Comment",["$resource",function(e){return e("/api/event/:id/comment/:cid",{id:"@_id"},{update:{method:"PUT"}})}]).factory("Title",function(){return{set:function(e){document.title=e}}}),angular.module("rallly").run(["$templateCache",function(e){e.put("templates/about.html",'
\n

What is Rallly?

\n
Rallly is a collaborative scheduling service that makes deciding on a date fast and easy.
\n

Hi, I\'m Luke!

\n

\n I created Rallly as side project to help me learn some new technologies. I decided to publish it because I thought other people might find it useful. Rallly is a completely free service. In fact it is even open source. You can look at the latest source code on Github.\n

\n
\n'),e.put("templates/confirmmodal.html",'
\n\n
\n
{{modal.title}}
\n
\n {{modal.message}}\n
\n
\n \n \n
\n
\n'),e.put("templates/editevent.html",'
\n
\n\n
Edit Event
\n
\n You can makes changes to your existing event by changing the fields in the form below.\n
\n\n
\n\n
\n\n
\n\n
\n\n
\n
\n\n
\n\n
\n\n
\n\n
\n \n \n Done\n
\n\n
\n\n
\n\n
\n'),e.put("templates/event.html",'
\n
\n
\n
\n
\n {{event.title}}\n Poll Closed\n Poll Open\n
\n
\n Created by {{event.creator.name}} • {{event.created | elapsed}}\n
\n
\n
\n \n
\n
\n
{{event.description}}
\n
\n Location:\n {{event.location}}\n
\n\n
\n
\n
\n\n
\n
\n Discussion\n
\n
\n You can discuss the event with your friends by leaving a comment below.\n
\n
\n\n
\n
\n
\n'),e.put("templates/home.html",'
\n
\n \n
\n
\n Schedule an Event\n
\n
\n Want to host an event but can’t decide on a date? Click on the button below to start!\n
\n \n
\n'),e.put("templates/notfound.html","

Error 404

\n

Not Found

\n"),e.put("templates/notification.html",'
\n
\n {{notification.title}}\n
\n
\n {{notification.message}}\n
\n
\n'),e.put("templates/directives/datePicker.html",'
\n
\n
\n \n \n {{title}}\n \n \n
\n
\n
\n Sun\n
\n
\n Mon\n
\n
\n Tue\n
\n
\n Wed\n
\n
\n Thu\n
\n
\n Fri\n
\n
\n Sat\n
\n
\n
\n
\n {{day.date | date : \'d\' }}\n
\n
\n
\n
\n'),e.put("templates/directives/discussion.html",'\n
\n
\n \n
\n
\n
\n \n
\n
\n
\n \n \n \n Make sure you fill in all the fields.\n \n
\n
\n
\n
\n'),e.put("templates/directives/poll.html",'
\n
\n {{event.participants.length}} participants\n
\n
\n
\n
\n {{d | date: \'EEE\'}}\n
\n
\n {{d | date: \'d\'}}\n
\n
\n {{d | date : \'MMM\'}}\n
\n {{selectedDate($index)}}\n
\n
\n
\n\n
\n
\n
\n
\n
\n
\n \n \n \n \n {{participant.name}}\n
\n
\n \n \n \n
\n
\n
\n \n \n \n \n
\n
\n
\n
\n
\n
\n \n \n \n {{example.name}}\n
\n
\n \n \n
\n
\n\n
\n
\n
\n
\n Fill in the form below to get started\n
\n
\n
\n
\n
\n
\n \n \n \n \n
\n
\n \n
\n
\n
\n \n
\n
\n
\n
\n'),e.put("templates/directives/timePicker.html",'
\n
\n
\n
\n {{date | date: \'EEE\'}}\n
\n
\n {{date | date: \'d\'}}\n
\n
\n {{date | date : \'MMM\'}}\n
\n \n
\n
\n
\n \n
\n
\n'),e.put("templates/form/dateForm.html",'
\n
Choose Dates
\n \n
\n
\n
\n
\n \n \n You need to select a few dates\n \n
\n\n
\n
\n
\n
\n'),e.put("templates/form/eventForm.html",'
\n
Event Details
\n
\n
\n
\n
\n
\n \n \n {{errors.title}}\n \n \n
\n
\n
\n
\n \n \n {{errors.location}}\n \n \n
\n
\n
\n
\n
\n \n \n
\n
\n
\n'),e.put("templates/form/participantsForm.html",'
\n
Invite Participants
\n
\n
\n
\n
\n \n \n \n\n
\n
\n
\n'),e.put("templates/form/settingsForm.html",'
\n
Settings
\n
\n
\n
\n
\n
\n Poll Status\n
\n
\n Let people vote on the poll.\n
\n
\n
\n
\n {{event.isClosed ? \'Closed\' : \'Open\' }}\n
\n
\n
\n
\n
\n
\n
\n
\n Notifications\n
\n
\n Send email notifications to the creator of this event.\n
\n
\n
\n
\n {{event.creator.allowNotifications ? \'Enabled\' : \'Disabled\' }}\n
\n
\n
\n
\n
\n
\n
\n
\n Delete Event\n
\n
\n Once you delete an event it will no longer be accessible.\n
\n
\n
\n \n
\n
\n
\n\n'),e.put("templates/form/timeForm.html",'
\n
Choose Times
\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n\n \n Time 1\n \n Time 2\n \n Time 3\n
\n
\n
\n {{d.date | date: \'EEE\'}}\n
\n
\n {{d.date | date: \'d\'}}\n
\n
\n {{d.date | date : \'MMM\'}}\n
\n \n
\n
\n \n
\n
\n'),e.put("templates/form/userForm.html",'
\n
Your Details
\n
\n
\n
\n
\n
\n \n \n {{errors.name}}\n \n \n
\n
\n
\n
\n \n \n {{errors.email}}\n \n \n
\n
\n
\n
\n'),e.put("templates/newEvent/datetime.html",'
\n\n
\n\n
\n \n \n
\n'),e.put("templates/newEvent/general.html",'
\n\n
\n\n
\n\n
\n\n
\n \n
\n'),e.put("templates/newEvent/invite.html",'
\n
\n
Summary
\n
\n
\n
\n
\n
\n Your Name\n
\n
\n {{event.creator.name}}\n
\n
\n
\n
\n Email\n
\n
\n {{event.creator.email}}\n
\n
\n
\n
\n Title\n
\n
\n {{event.title}}\n
\n
\n
\n
\n Location\n
\n
\n {{event.location}}\n
\n
\n
\n
\n Description\n
\n
{{event.description}}
\n
\n
\n
\n Dates\n
\n
\n
    \n
  • \n
    \n
    \n {{d | date: \'EEE\'}}\n
    \n
    \n {{d | date: \'d\'}}\n
    \n
    \n {{d | date : \'MMM\'}}\n
    \n
    \n
  • \n
\n
\n
\n
\n
\n
\n
\n\n
\n\n
\n \n \n
\n'),e.put("templates/newEvent/layout.html",'
\n\n
Schedule a New Event
\n
\n Fill in the form below to create your event and share it with your friends and colleagues.\n
\n
    \n
  1. \n General Details\n
  2. \n
  3. \n Dates & Times\n
  4. \n
  5. \n Create & Send\n
  6. \n
\n
\n
\n\n
\n
\n
\n'),e.put("templates/newEvent/success.html",'
\n
\n \n
\n
Event Created
\n
\n Your event has been created successfully! You should receive an email shortly with instructions to verify your email address.\n
\n
\n
\n
\n \n GO\n
\n
\n')}]),angular.module("rallly").controller("AboutCtrl",["Title",function(e){e.set("About Rallly")}]),angular.module("rallly").controller("AccountCtrl",["$scope","ConfirmModal",function(e){e.showNotice=function(){}}]),angular.module("rallly").controller("DeletionCtrl",["$state","Notification","Event",function(e,t,n){n.destroy({id:e.params.id,code:e.params.code},function(){new t({title:"Event deleted",message:"This event has been deleted",type:"success",timeout:5e3})},function(){new t({title:"Deletion Failed",message:"The event could not be deleted. Make sure that it exists and that the url is correct",type:"error"})}),e.go("event",{id:e.params.id})}]),angular.module("rallly").controller("EditEventCtrl",["$scope","$http","$state","$timeout","Event","ConfirmModal","Notification","Title",function(e,t,n,i,a,s,o,l){var d=n.params.id;e.event=a.get({id:d},function(){l.set("Edit: "+e.event.title),e.master=angular.copy(e.event)},function(){n.go("notfound")}),e.undoChanges=function(){e.event=angular.copy(e.master)},e.didChange=function(){return JSON.stringify(e.master)!=JSON.stringify(e.event)},e.didChangeDates=function(){return JSON.stringify(e.master.dates)!=JSON.stringify(e.event.dates)},e.submit=function(){if(e.form.$valid)if(e.didChangeDates()){new s({title:"Hold up!",message:"Changing the dates will reset all entries by the participants. Are you sure you want to do that?",confirmText:"Yes, I'm sure",isDestructive:!0,confirm:function(){e.event.participants=[],r()}})}else r();else{new o({title:"Not so fast",message:"Make sure you fill in all the required fields and try again.",type:"error"})}};var r=function(){a.update({id:d},e.event,function(){new o({title:"Changes Saved",message:"Your changes have been saved successfully.",type:"success"});e.master=angular.copy(e.event)})}}]),angular.module("rallly").controller("EventCtrl",["$scope","$http","$state","Title","Event","ConfirmModal",function(e,t,n,i,a,s){var o=n.params.id;e.event=a.get({id:o},function(){i.set(e.event.title),e.eventUrl=n.href("event",{id:e.event._id},{absolute:!0})},function(){n.go("notfound")}),e.openEvent=function(){e.event.isClosed=!1,a.update({id:o},e.event,function(){new s({title:"Event Open",message:"People can vote and comment on this event.",cancelText:"OK"})})},e.closeEvent=function(){e.event.isClosed=!0,a.update({id:o},e.event,function(){new s({title:"Event Closed",message:"People can no longer vote or comment on this event.",cancelText:"OK"})})},e.editEvent=function(){n.go("editevent",{id:e.event._id})}}]),angular.module("rallly").controller("HomeCtrl",["$scope","$state","Title",function(e,t,n){n.set("Rallly - Collaborative Scheduling"),e.newEvent=function(){t.go("newevent")}}]),angular.module("rallly").controller("NavigationCtrl",["$scope","$location",function(e,t){e.isActive=function(e){return t.path()==e?!0:!1}}]),angular.module("rallly").controller("NewEventCtrl",["$scope","$http","$state","Event","ConfirmModal","Notification",function(e,t,n,i,a){e.title="Schedule a New Event",e.description="Fill in the form below to create your event and share it with your friends and colleagues.",e.event={};var s=["newevent.general","newevent.datetime","newevent.invite"];e.page=1;var o=function(t){e.page=t,n.go(s[t-1])};o(e.page),e.submit=function(){e.form.$valid&&e.page==s.length?t.post("/api/event",e.event).success(function(t){e.event=t,e.eventUrl=n.href("event",{id:e.event._id},{absolute:!0}),e.page++,n.go("newevent.success")}).error(function(){new a({title:"Uh oh!",message:"There was an error creating your event. Please try again later.",cancelText:"OK"})}):e.form.$valid&&(e.form.$setPristine(),e.nextPage())},e.nextPage=function(){o(e.page+1)},e.prevPage=function(){o(e.page-1)}}]),angular.module("rallly").controller("VerificationCtrl",["Event","Notification","$state",function(e,t,n){e.verify({id:n.params.id,code:n.params.code},function(){new t({title:"Email Verified",message:"Your email has been verified. You will now be able to receive email notifications for this event",type:"success",timeout:5e3}) },function(){new t({title:"Verification Failed",message:"Your verification code has expired.",type:"error"})}),n.go("event",{id:n.params.id})}]),angular.module("rallly").filter("elapsed",["$filter",function(e){return function(t){if(t){var n=Date.parse(t),i=(new Date).getTime(),a=i-n,s=Math.floor(a/1e3),o=Math.floor(s/60),l=Math.floor(o/60),d=Math.floor(l/24);return d>30?"on "+e("date")(t,"MMMM d"):d>1?d+" days ago":1==d?"1 day ago":l>1?l+" hours ago":1==l?"an hour ago":o>1?o+" minutes ago":1==o?"a minute ago":"a few seconds ago"}}}]),angular.module("rallly").directive("backImg",function(){return function(e,t,n){var i=n.backImg;t.css({"background-image":"url(/images/"+i+".png)"})}}),angular.module("rallly").directive("datepicker",function(){return{restrict:"A",require:"ngModel",scope:{model:"=ngModel",control:"="},templateUrl:"templates/directives/datePicker.html",link:function(e,t,n,i){e.model=e.model||[],e.control=e.control||{},e.$watchCollection("model",function(e){i.$setViewValue(e),i.$validate()}),i.$validators.required=function(e){return e&&0!=e.length?!0:!1};var a=Date.today(),s=a.clone(),o=function(t){s=t;var n=s.clone().moveToFirstDayOfMonth(),i=n.getDay();n.add(i-7).days(),e.title=s.toString("MMMM yyyy");for(var o=new Array(42),l=0;l0)&&(e.model.splice(n,0,t.date),i=!0),n++;while(0==i)}},e.isActive=function(t,n){e.model=e.model||[];for(var i=0;i0;i||t.toggle()};t.toggle=function(){t.open=!t.open,t.open?(n.addClass("open"),e.bind("click",i)):(n.removeClass("open"),e.unbind("click",i))}}}}]),angular.module("rallly").service("FormHelper",function(){this.emailRegexString="^([\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4})?$",this.emailRegex=new RegExp(this.emailRegexString),this.prettyError=function(e,t){return e.required?t+" is required":e.pattern?t+" is invalid":e.maxlength?t+" is too long":!1}}).directive("userForm",["FormHelper",function(e){return{scope:{event:"=",form:"="},templateUrl:"templates/form/userForm.html",link:function(t){t.errors={},t.emailRegex=e.emailRegex,t.$watchCollection("form.name.$error",function(n){t.errors.name=e.prettyError(n,"Name")}),t.$watchCollection("form.email.$error",function(n){t.errors.email=e.prettyError(n,"Email")})}}}]).directive("eventForm",["FormHelper",function(e){return{scope:{event:"=",form:"="},templateUrl:"templates/form/eventForm.html",link:function(t){t.errors={},t.$watchCollection("form.title.$error",function(n){t.errors.title=e.prettyError(n,"Title")}),t.$watchCollection("form.location.$error",function(n){t.errors.location=e.prettyError(n,"Location")})}}}]).directive("dateForm",function(){return{scope:{event:"=",form:"="},templateUrl:"templates/form/dateForm.html"}}).directive("participantsForm",["FormHelper",function(e){return{scope:{event:"=",form:"="},templateUrl:"templates/form/participantsForm.html",link:function(t){t.emailRegex=e.emailRegexString}}}]).directive("settingsForm",["Event","ConfirmModal",function(e,t){return{scope:{event:"=",form:"="},templateUrl:"templates/form/settingsForm.html",link:function(n){n.deleteEvent=function(){n.deleteRequestSent||e.delete({id:n.event._id},function(){n.deleteRequestSent=!0;new t({title:"Delete Request Sent",message:"An email has been sent to the creator of this event with instructions to delete it.",cancelText:"OK"})})}}}}]).directive("switchToggle",function(){return{scope:{model:"=ngModel"},require:"ngModel",link:function(e,t,n,i){t.addClass("switch-toggle");var a=function(){e.model^"undefined"!=typeof n.invert?t.addClass("active"):t.removeClass("active")};e.$watch("model",a),t.bind("click",function(t){e.model=!e.model,i.$setViewValue(e.model,t)})}}}).directive("timeForm",["DatePickerService",function(e){return{scope:{event:"=",form:"="},templateUrl:"templates/form/timeForm.html",link:function(t){var n,i=!1,a=t.$watch("event.dates",function(s){s&&!i&&a(),i=!0,n=new e(t.event.dates),t.unsetDate=function(e){n.removeDate(e)}})}}}]).directive("timePicker",["$timeout",function(){return{scope:{model:"=ngModel"},require:"ngModel",link:function(e,t,n,i){i.$viewChangeListeners.push(function(){e.model=i.$modelValue}),i.$parsers.push(function(e){return e?Date.parse(e):void 0}),i.$validators.time=function(e){if(i.$isEmpty(e))return!0;var t=Date.parse(e);return t?(i.$setViewValue(t.toString("hh:mm tt")),i.$render(),!0):!1}}}}]),angular.module("rallly").directive("poll",["$timeout","Participant","ConfirmModal",function(e,t,n){return{restrict:"A",templateUrl:"templates/directives/poll.html",scope:{event:"="},link:function(e){e.defaults=[],e.participant={};var i=[];e.event.$promise.then(function(t){for(var n=["John Example","Jane Specimen","Mark Instance","Mary Case"],i=[],a=0;at)return!1;return!0},e.selectedDate=function(t){i[t]=0;for(var n=0;n