sogo/UI/WebServerResources/js/Scheduler.services.js

2 lines
94 KiB
JavaScript

!function(){"use strict";function d(e){this.component=e,this.component.attendees&&_.forEach(this.component.attendees,function(e){e.image=d.$gravatar(e.email,32)}),this.workDaysOnly=!0,this.slotStartTimeLimit=new Date,this.slotStartTimeLimit.setMinutes(0),this.slotStartTimeLimit.setHours(d.dayStartHour),this.slotEndTimeLimit=new Date,this.slotEndTimeLimit.setMinutes(0),this.slotEndTimeLimit.setHours(d.dayEndHour),this.$days=[],this.$futureFreebusyData={},this.updateFreeBusyCoverage(),this.updateFreeBusy(),0==this.$days.length&&this.getDays()}d.$factory=["$q","$timeout","$log","sgSettings","Attendees_ROLES","Preferences","User","Card","Gravatar","Resource",function(e,t,n,i,a,o,r,s,c,l){return angular.extend(d,{$q:e,$timeout:t,$log:n,$settings:i,$User:r,$Preferences:o,$Card:s,$gravatar:c,$$resource:new l(i.activeUser("folderURL")+"Calendar",i.activeUser()),ROLES:a}),d.dayStartHour=parseInt(o.defaults.SOGoDayStartTime.split(":")[0]),d.dayEndHour=parseInt(o.defaults.SOGoDayEndTime.split(":")[0]),d}];try{angular.module("SOGo.SchedulerUI")}catch(e){angular.module("SOGo.SchedulerUI",["SOGo.Common"])}angular.module("SOGo.SchedulerUI").constant("Attendees_ROLES",{REQ_PARTICIPANT:"req-participant",OPT_PARTICIPANT:"opt-participant",NON_PARTICIPANT:"non-participant",CHAIR:"chair"}).factory("Attendees",d.$factory),d.timeToQuarters=function(e){return 4*e.getHours()+Math.ceil(e.getMinutes()/15)},d.prototype.getLength=function(){return this.component.attendees?this.component.attendees.length:0},d.prototype.initOrganizer=function(e){var t=this,e=e&&e.isSubscription?d.$User.$filter(e.owner).then(function(e){e=e[0];t.component.organizer={uid:e.uid,name:e.cn,email:e.c_email}}):(this.component.organizer||(this.component.organizer={uid:d.$settings.activeUser("login"),name:d.$settings.activeUser("identification"),email:d.$settings.activeUser("email")}),d.$q.when());e.then(function(){t.updateFreeBusyAttendee(t.component.organizer)})},d.prototype.add=function(e,t){var n,i,a=this,o=d.$q.when();return e&&((!this.component.attendees||t&&t.organizerCalendar)&&this.initOrganizer(t?t.organizerCalendar:null),e.$isList({expandable:!0})?o=(i=d.$Card.$find(e.container,e.c_name)).$id().then(function(e){_.forEach(i.refs,function(e){n={name:e.c_cn,email:e.$preferredEmail(t?t.partial:null),role:d.ROLES.REQ_PARTICIPANT,partstat:"needs-action",uid:e.c_uid,$avatarIcon:"person"},_.find(a.component.attendees,function(e){return e.email==n.email})||(n.image=d.$gravatar(n.email,32),a.component.attendees?a.component.attendees.push(n):a.component.attendees=[n],a.updateFreeBusyAttendee(n))})}):(n={uid:e.c_uid,domain:e.c_domain,isMSExchange:e.ismsexchange,isGroup:e.$isList(),isExpandableGroup:!1,isResource:e.isresource,name:e.c_cn,email:e.$$email,role:d.ROLES.REQ_PARTICIPANT,partstat:"needs-action",$avatarIcon:e.$avatarIcon},_.find(this.attendees,function(e){return e.email==n.email})||(e.$isList()&&d.$Preferences.defaults.SOGoLDAPGroupExpansionEnabled&&(o=e.$members().then(function(e){n.members=e,n.isExpandableGroup=!0})),n.image=d.$gravatar(n.email,32),this.component.attendees?_.findIndex(this.component.attendees,{email:n.email})<0&&this.component.attendees.push(n):this.component.attendees=[n],this.updateFreeBusyAttendee(n)))),o},d.prototype.nextRole=function(t){var e=_.values(d.ROLES),n=_.findIndex(e,function(e){return t.role===e});t.role=e[++n%4]},d.prototype.hasAttendee=function(e){var t=_.find(this.component.attendees,function(t){return _.find(e.emails,function(e){return e.value==t.email})});return angular.isDefined(t)},d.prototype.remove=function(t){var e=_.findIndex(this.component.attendees,function(e){return e.email==t.email});-1<e&&this.component.attendees.splice(e,1),delete this.$futureFreebusyData[t.uid]},d.prototype.updateFreeBusyCoverage=function(){var o,r,s,e,c={};this.component.start&&this.component.end&&(o=new Date(this.component.start.getTime()),r=new Date(this.component.end.getTime()),this.component.isAllDay?(o.setHours(d.dayStartHour),o.setMinutes(0),r.setHours(d.dayEndHour),r.setMinutes(0),s=e=0):(s=parseInt(o.getMinutes()/15+.5),e=parseInt(r.getMinutes()/15+.5)),o.setMinutes(15*s),r.setMinutes(15*e),_.forEach(o.beginOfDay().daysUpTo(r.beginOfDay()),function(e,t){var n,i=(e=e<o?new Date(o.getTime()):e).getDate(),a=e.getDayString();if(a===o.getDayString())for(n=e.getHours().toString(),c[a]={},c[a][n]=[];0<s;)c[a][n].push(0),s--;else e=e.beginOfDay(),c[a]={};for(;e.getTime()<r.getTime()&&e.getDate()==i;)n=e.getHours().toString(),angular.isUndefined(c[a][n])&&(c[a][n]=[]),c[a][n].push(1),e.addMinutes(15)}),this.freebusy=c)},d.prototype.coversFreeBusy=function(e,t,n){return this.freebusy&&angular.isDefined(this.freebusy[e])&&angular.isDefined(this.freebusy[e][t])&&1==this.freebusy[e][t][n]},d.prototype.getDays=function(e){var t,n,i,a=this;return e?(t=e,(n=new Date(e.getTime())).addMinutes(this.component.delta)):(t=this.component.start,n=this.component.end),(0===this.$days.length||_.findIndex(this.$days,["getDayString",t.getDayString()])<0||_.findIndex(this.$days,["getDayString",n.getDayString()])<0)&&(t=t.beginOfDay().addDays(-7),n=n.beginOfDay().addDays(7),i=d.$Preferences.$mdDateLocaleProvider.formatDate,this.$days.splice(0,this.$days.length),_.forEach(t.daysUpTo(n),function(e){e.$dateFormat=d.$Preferences.defaults.SOGoLongDateFormat,a.$days.push({stringWithSeparator:i(e),getDayString:e.getDayString()})})),this.$days},d.prototype.updateFreeBusy=function(t){var n=this,i=[];return 0<this.getLength()&&(this.component.organizer&&i.push(this.updateFreeBusyAttendee(this.component.organizer,t)),_.forEach(_.filter(this.component.attendees,"uid"),function(e){i.push(n.updateFreeBusyAttendee(e,t))})),d.$q.all(i)},d.prototype.updateFreeBusyAttendee=function(a,e){var t,n,o;if(a.uid)return n=a.uid,a.domain&&(n+="@"+a.domain),e={sday:(o=_.map(this.getDays(e),"getDayString"))[0],eday:o[o.length-1]},a.isMSExchange?(t=d.$$resource.userResource(),e.uid=n):t=d.$$resource.userResource(n),angular.isUndefined(a.freebusy)&&(a.freebusy={}),e=_.intersection(_.keys(a.freebusy),o).length!==o.length?t.fetch("freebusy.ifb","ajaxRead",e).then(function(i){_.forEach(o,function(e){var t;angular.isUndefined(a.freebusy[e])&&(a.freebusy[e]={}),angular.isUndefined(i[e])&&(i[e]={});for(var n=0;n<=23;n++)t=n.toString(),i[e][t]?a.freebusy[e][t]=[i[e][t][0],i[e][t][15],i[e][t][30],i[e][t][45]]:a.freebusy[e][t]=[0,0,0,0]})}):d.$q.when(),this.$futureFreebusyData[a.uid]=e},d.prototype.forwardFindDate=function(e){var t=null,n=this.endLimit-this.duration,i=0;for(this.firstStep?(i=Math.floor(4*this.start.getHours()+this.start.getMinutes()/15)+1,this.firstStep=!1):i=this.currentEntries.indexOf(0),-1<i&&i<this.startLimit&&(i=this.startLimit);!t&&-1<i&&i<=n;){for(var a,o=0;0===this.currentEntries[i]&&o<this.duration;)o++,i++;o==this.duration?(t=new Date,a=e.getTime()+9e5*(i-o),t.setTime(a)):i=this.currentEntries.indexOf(0,i+1)}return t},d.prototype.forwardAdjustCurrentStart=function(e){var t=e.getDay();0===t?e.addDays(1):6===t&&e.addDays(2)},d.prototype.backwardFindDate=function(e){var t,n=null,i=this.endLimit-this.duration;for(this.firstStep?(t=Math.floor(4*this.start.getHours()+this.start.getMinutes()/15)-1,this.firstStep=!1):t=this.currentEntries.lastIndexOf(0),i<t&&(t=i);!n&&t>=this.startLimit;){for(var a,o=0,r=t;0===this.currentEntries[r]&&o<this.duration;)o++,r++;o==this.duration?(n=new Date,a=e.getTime()+9e5*t,n.setTime(a)):t=this.currentEntries.lastIndexOf(0,t-1)}return d.$log.debug(["found = "+n,t]),n},d.prototype.backwardAdjustCurrentStart=function(e){var t=e.getDay();0==t?e.addDays(-2):6==t&&e.addDays(-1)},d.prototype.findSlot=function(e){var t=this;return this.direction=e,this.firstStep=!0,0<e?(this.findDate=this.forwardFindDate,this.adjustCurrentStart=this.forwardAdjustCurrentStart):(this.findDate=this.backwardFindDate,this.adjustCurrentStart=this.backwardAdjustCurrentStart),this.component.isAllDay?(this.start=this.component.start.clone(),this.start.setHours(d.dayStartHour),this.start.setMinutes(0),this.start.setSeconds(0),this.end=this.component.end.clone(),this.end.setHours(d.dayEndHour),this.end.setMinutes(0),this.end.setSeconds(0),this.startLimit=4*d.dayStartHour,this.endLimit=4*d.dayEndHour,this.duration=4*(d.dayEndHour-d.dayStartHour)):(this.start=this.component.start,this.end=this.component.end,this.startLimit=d.timeToQuarters(this.slotStartTimeLimit),this.endLimit=d.timeToQuarters(this.slotEndTimeLimit),this.duration=Math.ceil((this.end.getTime()-this.start.getTime())/9e5)),(e=this.component.start.clone()).setHours(0,0,0,0),this.workDaysOnly&&this.adjustCurrentStart(e),this.step(e).then(function(e){return t.component.start=new Date(e.getTime()),t.component.end=new Date(t.component.start.getTime()),t.component.end.addMinutes(t.component.delta),t.updateFreeBusyCoverage(),e}).catch(function(e){throw t.updateFreeBusy(),e})},d.prototype.mergeFreebusy=function(e){var a=this,o=e.getDayString();return this.updateFreeBusy(e).then(function(){var e,t,n,i;for(a.currentEntries=_.flatMap(a.component.organizer.freebusy[o]),e=0;e<a.component.attendees.length;e++)if((n=a.component.attendees[e]).freebusy&&n.role!==d.ROLES.NON_PARTICIPANT)for(i=_.flatMap(n.freebusy[o]),t=0;t<a.currentEntries.length;t++)a.currentEntries[t]+=i[t]})},d.prototype.step=function(t,n){var i=this;if(parseInt(n)){if(30<=n)return d.$q.reject(l("There's no free slot available for all attendees in the next 30 days. Please try a different date or length."))}else n=0;return this.mergeFreebusy(t).then(function(){var e=i.findDate(t);return e||(t.addDays(0<i.direction?1:-1),t.setHours(0,0,0,0),i.workDaysOnly&&i.adjustCurrentStart(t),i.step(t,n+1))})}}(),function(){"use strict";function c(e){this.init(e),this.name&&!this.id&&(e=c.$$resource.create("createFolder",this.name),this.$unwrap(e))}c.$factory=["$q","$timeout","$log","sgSettings","Resource","Preferences","Component","Acl",function(e,t,n,i,a,o,r,s){return angular.extend(c,{$q:e,$timeout:t,$log:n,$$resource:new a(i.activeUser("folderURL")+"Calendar",i.activeUser()),$Preferences:o,$Component:r,$$Acl:s,activeUser:i.activeUser(),$view:null}),c}];try{angular.module("SOGo.SchedulerUI")}catch(e){angular.module("SOGo.SchedulerUI",["SOGo.Common"])}angular.module("SOGo.SchedulerUI").value("CalendarSettings",{EventDragDayLength:96,EventDragHorizontalOffset:3,ConflictHTTPErrorCode:409}).factory("Calendar",c.$factory),c.$defaultCalendar=function(){var e;return"first"==c.$Preferences.defaults.SOGoDefaultCalendar&&(e=_.find(c.$findAll(null,!0),function(e){return e.active}))?e.id:"personal"},c.$add=function(n){var e=n.isWebCalendar?this.$webcalendars:n.isSubscription?this.$subscriptions:this.$calendars,t=_.findIndex(e,function(e,t){return"personal"==n.id||"personal"!=e.id&&0<e.name.localeCompare(n.name)});t<0?e.push(n):e.splice(t,0,n),c.$Preferences.settings.Calendar.FoldersOrder&&c.saveFoldersOrder(_.flatMap(c.$findAll(),"id")),c.$reloadAll()},c.$findAll=function(e,t){var n=this;if(e)this.$calendars=[],this.$subscriptions=[],this.$webcalendars=[],angular.forEach(e,function(e,t){e=new c(e);(e.isWebCalendar?n.$webcalendars:e.isSubscription?n.$subscriptions:n.$calendars).push(e)});else if(angular.isUndefined(this.$calendars))return this.$calendars=[],this.$subscriptions=[],this.$webcalendars=[],c.$$resource.fetch("calendarslist").then(function(e){return c.$findAll(e.calendars,t)});return t?_.union(this.$calendars,_.filter(this.$subscriptions,function(e){return e.isOwned||e.acls.objectCreator})):_.union(this.$calendars,this.$subscriptions,this.$webcalendars)},c.$reloadAll=function(){var n=this;c.$$resource.fetch("calendarslist").then(function(e){_.forEach(e.calendars,function(t){var e=t.isWebCalendar?n.$webcalendars:t.owner!=c.activeUser.login?n.$subscriptions:n.$calendars,e=_.find(e,function(e){return e.id==t.id});e&&e.init(t)})})},c.$get=function(t){var e=_.find(c.$calendars,function(e){return e.id==t});return e=(e=e||_.find(c.$subscriptions,function(e){return e.id==t}))||_.find(c.$webcalendars,function(e){return e.id==t})},c.$getIndex=function(e){var t=_.indexOf(_.map(c.$calendars,"id"),e);return t=(t=t<0?_.indexOf(_.map(c.$subscriptions,"id"),e):t)<0?_.indexOf(_.map(c.$webcalendars,"id"),e):t},c.$subscribe=function(e,t){var n=this;return c.$$resource.userResource(e).fetch(t,"subscribe").then(function(t){var e=new c(angular.extend({active:1},t));return _.find(n.$subscriptions,function(e){return e.id==t.id})||c.$add(e),e})},c.$addWebCalendar=function(n){var i=c.$q.defer();return _.find(this.$webcalendars,function(e){return e.urls.webCalendarURL==n})?i.reject():c.$$resource.post(null,"addWebCalendar",{url:n}).then(function(e){angular.extend(e,{isWebCalendar:!0,isEditable:!0,isRemote:!1,owner:c.activeUser.login,urls:{webCalendarURL:n}});var t=new c(e);c.$$resource.fetch(t.id,"reload").then(function(e){c.$log.debug(JSON.stringify(e,void 0,2)),c.$add(t),i.resolve()},function(e){401==e.status?i.resolve(t):i.reject()})},i.reject),i.promise},c.reloadWebCalendars=function(){var n=[];return _.forEach(this.$webcalendars,function(t){var e=c.$$resource.fetch(t.id,"reload");e.then(function(e){t.$error=!1},function(e){t.$error=l(e.statusText)}),n.push(e)}),c.$q.all(n)},c.$deleteComponents=function(e){var t={},n=[];return _.forEach(e,function(e){angular.isDefined(t[e.pid])||(t[e.pid]=[]),t[e.pid].push(e.id)}),_.forEach(t,function(e,t){n.push(c.$$resource.post(t,"batchDelete",{uids:e}))}),c.$q.all(n)},c.saveFoldersActivation=function(e){var t={};return _.forEach(e,function(e){e=c.$get(e);t[e.id]=e.active}),c.$$resource.post(null,"saveFoldersActivation",t)},c.saveFoldersOrder=function(e){return this.$$resource.post(null,"saveFoldersOrder",{folders:e}).then(function(){if(!(c.$Preferences.settings.Calendar.FoldersOrder=e))return c.$$resource.fetch("calendarslist").then(function(e){return c.$findAll(e.calendars)})})},c.prototype.init=function(e){this.color=this.color||"#AAAAAA",this.active=1,angular.extend(this,e),this.id&&(this.$acl=new c.$$Acl("Calendar/"+this.id)),this.isOwned=c.activeUser.isSuperUser||this.owner==c.activeUser.login,this.isSubscription=!this.isRemote&&this.owner!=c.activeUser.login,!angular.isUndefined(this.$shadowData)&&this.$shadowData.id||(this.$shadowData=this.$omit())},c.prototype.$id=function(){return this.id?c.$q.when(this.id):this.$futureCalendarData.then(function(e){return e.id||c.$q.reject()})},c.prototype.getClassName=function(e){return(e=angular.isUndefined(e)?"fg":e)+"-folder"+this.id},c.prototype.$rename=function(){var e,t,n=this;return this.name==this.$shadowData.name?c.$q.when():(t=this.isWebCalendar?c.$webcalendars:this.isSubscription?c.$subscriptions:c.$calendars,-1<(e=_.indexOf(_.map(t,"id"),this.id))?this.$save().then(function(){t.splice(e,1),c.$add(n)}):c.$q.reject())},c.prototype.$delete=function(){var e,t=this,n=this.isSubscription?(e=c.$$resource.fetch(this.id,"unsubscribe"),c.$subscriptions):(e=c.$$resource.remove(this.id),this.isWebCalendar?c.$webcalendars:c.$calendars);return e.then(function(){var e=_.indexOf(_.map(n,"id"),t.id);n.splice(e,1)})},c.prototype.$reset=function(){var n=this;angular.forEach(this,function(e,t){"constructor"!=t&&"$"!=t[0]&&delete n[t]}),angular.extend(this,this.$shadowData),this.$shadowData=this.$omit()},c.prototype.$save=function(){var t=this,n=c.$q.defer();return c.$$resource.save(this.id,this.$omit()).then(function(e){return t.$shadowData=t.$omit(),n.resolve(e)},function(e){return t.$reset(),n.reject(e)}),n.promise},c.prototype.setCredentials=function(e,t){var n=this,i=c.$q.defer();return c.$$resource.post(this.id,"set-credentials",{username:e,password:t}).then(function(){c.$$resource.fetch(n.id,"reload").then(function(e){c.$add(n),i.resolve()},function(e){401==e.status?i.reject(l("Wrong username or password.")):i.reject(e.statusText)})},i.reject),i.promise},c.prototype.export=function(){var e,t={type:"application/octet-stream",filename:this.name+".ics"},n=this.isSubscription?(e=this.urls.webDavICSURL.indexOf("/dav/"),e=(n=this.urls.webDavICSURL.substring(e+5).split(/\//))[0],e=c.$$resource.userResource(e),n.splice(n.length-2).join("/")):(e=c.$$resource,this.id+".ics");return e.open(n,"export",null,t)},c.prototype.$setActivation=function(){return c.$$resource.fetch(this.id,(this.active?"":"de")+"activateFolder")},c.prototype.$getComponent=function(e,t){return c.$Component.$find(this.id,e,t)},c.prototype.$unwrap=function(e){var t=this;this.$futureCalendarData=e.then(function(e){return c.$timeout(function(){return t.init(e),t})},function(e){t.isError=!0,angular.isObject(e)&&c.$timeout(function(){angular.extend(t,e)})})},c.prototype.$omit=function(){var n={};return angular.forEach(this,function(e,t){"constructor"!=t&&"$"!=t[0]&&(n[t]=angular.copy(e))}),n}}(),function(){"use strict";function u(e){var t;"function"!=typeof e.then?(this.init(e),this.pid&&!this.id&&(t=u.$$resource.newguid(this.pid),this.$unwrap(t),this.isNew=!0)):this.$unwrap(e)}u.$factory=["$q","$timeout","$log","$rootScope","sgSettings","sgComponent_STATUS","Attendees","Preferences","User","Card","Resource",function(e,t,n,i,a,o,r,s,c,l,d){return angular.extend(u,{STATUS:o,$q:e,$timeout:t,$log:n,$rootScope:i,$settings:a,$User:c,$Preferences:s,$Attendees:r,$Card:l,$$resource:new d(a.activeUser("folderURL")+"Calendar",a.activeUser()),timeFormat:"%H:%M",$query:{value:"",search:"title_Category_Location"},$queryEvents:{sort:"start",asc:1,filterpopup:"view_next7"},$queryTasks:{sort:"status",asc:1,filterpopup:"view_incomplete"},$refreshTimeout:null,$ghost:{}}),s.settings.Calendar.EventsFilterState&&(u.$queryEvents.filterpopup=s.settings.Calendar.EventsFilterState),s.settings.Calendar.TasksFilterState&&(u.$queryTasks.filterpopup=s.settings.Calendar.TasksFilterState),s.settings.Calendar.EventsSortingState&&(u.$queryEvents.sort=s.settings.Calendar.EventsSortingState[0],u.$queryEvents.asc=parseInt(s.settings.Calendar.EventsSortingState[1])),s.settings.Calendar.TasksSortingState&&(u.$queryTasks.sort=s.settings.Calendar.TasksSortingState[0],u.$queryTasks.asc=parseInt(s.settings.Calendar.TasksSortingState[1])),u.$queryTasks.show_completed=parseInt(s.settings.ShowCompletedTasks),u.$categories=s.defaults.SOGoCalendarCategoriesColors,s.defaults.SOGoTimeFormat&&(u.timeFormat=s.defaults.SOGoTimeFormat),u}];try{angular.module("SOGo.SchedulerUI")}catch(e){angular.module("SOGo.SchedulerUI",["SOGo.Common"])}angular.module("SOGo.SchedulerUI").constant("sgComponent_STATUS",{NOT_LOADED:0,DELAYED_LOADING:1,LOADING:2,LOADED:3,DELAYED_MS:300}).factory("Component",u.$factory),u.$selectedCount=function(){var e=0;return u.$events&&(e+=_.filter(u.$events,function(e){return e.selected}).length),u.$tasks&&(e+=_.filter(u.$tasks,function(e){return e.selected}).length),e},u.$startRefreshTimeout=function(e){u.$refreshTimeout&&u.$timeout.cancel(u.$refreshTimeout);var t,n=u.$Preferences.defaults.SOGoRefreshViewCheck;n&&"manually"!=n&&(t=angular.bind(u.$rootScope,u.$rootScope.$emit,"calendars:list"),u.$refreshTimeout=u.$timeout(t,1e3*n.timeInterval()))},u.$isLoading=function(){return u.$loaded==u.STATUS.LOADING},u.$filter=function(e,t){var n=this,i=new Date,a=i.getDate(),o=i.getMonth()+1,i=i.getFullYear(),r="$query"+e.capitalize(),o={day:i+(o<10?"0":"")+o+(a<10?"0":"")+a},s=!1;return u.$startRefreshTimeout(e),angular.extend(this.$query,o),t&&_.forEach(_.keys(t),function(e){s|=n.$query[e]&&t[e]!=u.$query[e],"reload"==e&&t[e]?s=!0:angular.isDefined(n.$query[e])?n.$query[e]=t[e]:n[r][e]=t[e]}),a=this.$$resource.fetch(null,e+"list",angular.extend(this[r],this.$query)),s&&(delete u[o="tasks"==e?"$events":"$tasks"],u.$log.debug("force reload of "+o)),this.$unwrapCollection(e,a)},u.$find=function(e,t,n){t=[e,t];return n&&t.push(n),new u(this.$$resource.fetch(t,"view"))},u.filterCategories=function(e){var t=new RegExp(e,"i");return _.filter(_.keys(u.$categories),function(e){return-1!=e.search(t)})},u.saveSelectedList=function(e){return this.$$resource.post(null,"saveSelectedList",{list:e+"ListView"})},u.$eventsBlocksForView=function(e,t){var n,i,a,o=u.$Preferences.defaults.SOGoFirstDayOfWeek;return"day"==e?(n="dayView",i=a=t):"multicolumnday"==e?(n="multicolumndayView",i=a=t):"week"==e?(n="weekView",i=t.beginOfWeek(o),(a=new Date).setTime(i.getTime()),a.addDays(6)):"month"==e&&(n="monthView",(i=t).setDate(1),i=i.beginOfWeek(o),(a=new Date).setTime(t.getTime()),a.setMonth(a.getMonth()+1),a.addDays(-1),a=a.endOfWeek(o)),this.$eventsBlocks(n,i,a)},u.$eventsBlocks=function(e,t,n){var s,c,l=[],d=[],i=u.$q.defer(),n={view:e.toLowerCase(),sd:t.getDayString(),ed:n.getDayString()};return this.$$resource.fetch(null,"eventsblocks",n).then(function(e){var o=function(e,t,n){var i=_.zipObject(this.eventsFields,t),t=new Date(1e3*i.c_startdate);return i.hour=t.getHourString(),i.blocks=[],i=new u(i),e.push(i),e},r=function(e){this[e.nbr].blocks.push(e),e.component=this[e.nbr],e.isFirst=1==this[e.nbr].blocks.length};u.$views=[],u.$timeout(function(){_.forEach(e,function(e,t){var n=[],i={},a={};for(e.eventsFields.splice(_.indexOf(e.eventsFields,"c_folder"),1,"pid"),e.eventsFields.splice(_.indexOf(e.eventsFields,"c_name"),1,"id"),e.eventsFields.splice(_.indexOf(e.eventsFields,"c_recurrence_id"),1,"occurrenceId"),e.eventsFields.splice(_.indexOf(e.eventsFields,"c_title"),1,"summary"),_.reduce(e.events,_.bind(o,e),n),_.forEach(_.flatten(e.blocks),_.bind(r,n)),_.forEach(_.flatten(e.allDayBlocks),_.bind(r,n)),0===l.length&&(l=_.flatMap(e.days,"date"),d=_.flatMap(e.days,"number")),s=0;s<e.blocks.length;s++){for(c=0;c<e.blocks[s].length;c++)e.blocks[s][c].dayIndex=s+t*e.blocks.length,e.blocks[s][c].dayNumber=d[s];i[l[s]]=e.blocks[s]}for(s=0;s<e.allDayBlocks.length;s++){for(c=0;c<e.allDayBlocks[s].length;c++)e.allDayBlocks[s][c].dayIndex=s+t*e.allDayBlocks.length,e.allDayBlocks[s][c].dayNumber=d[s];a[l[s]]=e.allDayBlocks[s]}u.$log.debug("blocks ready ("+_.flatten(e.blocks).length+")"),u.$log.debug("all day blocks ready ("+_.flatten(e.allDayBlocks).length+")"),n={blocks:i,allDayBlocks:a},e.id&&e.calendarName&&(n.id=e.id,n.calendarName=e.calendarName),u.$views.push(n)}),i.resolve(u.$views)})},i.reject),i.promise},u.$unwrapCollection=function(t,e){var n=[];return u.$loaded=u.STATUS.DELAYED_LOADING,u.$timeout(function(){u.$loaded!=u.STATUS.LOADED&&(u.$loaded=u.STATUS.LOADING)},u.STATUS.DELAYED_MS),e.then(function(e){return u.$timeout(function(){var i=_.invokeMap(e.fields,"toLowerCase");return i.splice(_.indexOf(i,"c_folder"),1,"pid"),i.splice(_.indexOf(i,"c_name"),1,"id"),i.splice(_.indexOf(i,"c_recurrence_id"),1,"occurrenceId"),"events"==t?(_.forEach(e[t],function(e,t){_.forEach(e.days,function(n,e){_.forEach(n.events,function(e,t){e=new u(_.zipObject(i,e));n.events[t]=e})})}),n=e[t]):"tasks"==t&&_.reduce(e[t],function(e,t,n){t=new u(_.zipObject(i,t));return e.push(t),e},n),u.$log.debug("list of "+t+" ready ("+_.size(n)+")"),u["$"+t]=n,u.$loaded=u.STATUS.LOADED,n})})},u.$resetGhost=function(){this.$ghost.pointerHandler=null,this.$ghost.component=null,this.$ghost.startHour=null,this.$ghost.endHour=null},u.$parseDate=function(e,t){var n=e.substring(0,10).split("-");return t&&t.no_time?new Date(parseInt(n[0]),parseInt(n[1])-1,parseInt(n[2])):(e=e.substring(11,16).split(":"),new Date(parseInt(n[0]),parseInt(n[1])-1,parseInt(n[2]),parseInt(e[0]),parseInt(e[1]),0,0))},u.prototype.init=function(e){this.categories=[],this.repeat={},this.alarm={action:"display",quantity:5,unit:"MINUTES",reference:"BEFORE",relation:"START"},this.status="not-specified",this.delta=60,angular.extend(this,e),"vevent"==this.component?this.type="appointment":"vtodo"==this.component&&(this.type="task"),this.startDate?angular.isString(this.startDate)?this.start=u.$parseDate(this.startDate):this.start=this.startDate:"appointment"==this.type&&(this.start=new Date,this.start.setMinutes(15*Math.round(this.start.getMinutes()/15))),this.endDate?(this.end=u.$parseDate(this.endDate),this.delta=this.start.minutesTo(this.end)):"appointment"==this.type&&this.setDelta(this.delta),this.dueDate&&(this.due=u.$parseDate(this.dueDate)),this.completedDate?this.completed=u.$parseDate(this.completedDate):"task"==this.type&&(this.completed=new Date),this.c_category&&(this.categories=_.invokeMap(_.filter(this.c_category,function(e){return u.$Preferences.defaults.SOGoCalendarCategoriesColors[e]}),"asCSSIdentifier")),this.$isRecurrent=angular.isDefined(e.repeat),this.repeat.days?(t=_.find(this.repeat.days,function(e){return angular.isDefined(e.occurrence)}))&&("yearly"==this.repeat.frequency&&(this.repeat.year={byday:!0}),this.repeat.month={type:"byday",occurrence:t.occurrence.toString(),day:t.day}):this.repeat.days=[],this.repeat.dates?(this.repeat.frequency="custom",_.forEach(this.repeat.dates,function(e,t,n){angular.isString(e)&&(n[t]=u.$parseDate(e))})):angular.isUndefined(this.repeat.frequency)&&(this.repeat.frequency="never"),angular.isUndefined(this.repeat.interval)&&(this.repeat.interval=1),angular.isUndefined(this.repeat.monthdays)?this.repeat.monthdays=[]:0<this.repeat.monthdays.length&&(this.repeat.month={type:"bymonthday"}),angular.isUndefined(this.repeat.month)&&(this.repeat.month={}),angular.isUndefined(this.repeat.month.occurrence)&&angular.extend(this.repeat.month,{occurrence:"1",day:"SU"}),angular.isUndefined(this.repeat.months)&&(this.repeat.months=[]),angular.isUndefined(this.repeat.year)&&(this.repeat.year={}),this.repeat.count?this.repeat.end="count":this.repeat.until?(this.repeat.end="until",angular.isString(this.repeat.until)&&(this.repeat.until=u.$parseDate(this.repeat.until,{no_time:!0}))):this.repeat.end="never",this.$hasCustomRepeat=this.hasCustomRepeat();var t,n="appointment"==this.type?"Events":"Tasks";this.isNew?(this.classification=u.$Preferences.defaults["SOGoCalendar"+n+"DefaultClassification"].toLowerCase(),(t=/-PT?([0-9]+)([MHDW])/.exec(u.$Preferences.defaults.SOGoCalendarDefaultReminder))&&(this.$hasAlarm=!0,this.alarm.quantity=parseInt(t[1]),this.alarm.unit={M:"MINUTES",H:"HOURS",D:"DAYS",W:"WEEKS"}[t[2]]),this.sendAppointmentNotifications=u.$Preferences.defaults.SOGoAppointmentSendEMailNotifications):(angular.isUndefined(e.$hasAlarm)&&(this.$hasAlarm=angular.isDefined(e.alarm)),angular.isUndefined(e.classification)&&(this.classification=u.$Preferences.defaults["SOGoCalendar"+n+"DefaultClassification"].toLowerCase())),this.destinationCalendar=this.pid,this.selected=!1},u.prototype.initAttendees=function(){this.$attendees=new u.$Attendees(this)},u.prototype.hasCustomRepeat=function(){return angular.isUndefined(this.occurrenceId)&&angular.isDefined(this.repeat)&&(1<this.repeat.interval||angular.isDefined(this.repeat.days)&&0<this.repeat.days.length||angular.isDefined(this.repeat.monthdays)&&0<this.repeat.monthdays.length||angular.isDefined(this.repeat.months)&&0<this.repeat.months.length||angular.isDefined(this.repeat.month)&&angular.isDefined(this.repeat.month.type)||angular.isDefined(this.repeat.dates)&&0<this.repeat.dates.length)},u.prototype.isEditable=function(){return!this.occurrenceId&&!this.isReadOnly},u.prototype.isEditableOccurrence=function(){return this.occurrenceId&&!this.isReadOnly},u.prototype.isInvitation=function(){return!this.occurrenceId&&this.userHasRSVP},u.prototype.isInvitationOccurrence=function(){return this.occurrenceId&&this.userHasRSVP},u.prototype.isMovable=function(){return!this.isReadOnly||this.userHasRSVP},u.prototype.showPercentComplete=function(){return"task"==this.type&&0<this.percentComplete&&"cancelled"!=this.status},u.prototype.enablePercentComplete=function(){return"task"==this.type&&"not-specified"!=this.status&&"cancelled"!=this.status},u.prototype.markAsCompleted=function(){var e,t=this;return"task"==this.type?(e=u.$Preferences.$mdDateLocaleProvider,this.percentComplete=100,this.completed=new Date,this.completed.$dateFormat=u.$Preferences.defaults.SOGoLongDateFormat,this.status="completed",this.localizedCompletedDate=e.formatDate(this.completed),this.localizedCompletedTime=e.formatTime(this.completed),this.$save().catch(function(){t.$reset()})):u.$q.reject("Only tasks can be mark as completed")},u.prototype.setDelta=function(e){var t;e<0&&((t=new Date(this.start.getTime())).setMinutes(15*Math.round(t.getMinutes()/15)),t.addMinutes(e),this.start=t,e*=-1),this.delta=e,this.end=new Date(this.start.getTime()),this.end.setMinutes(15*Math.round(this.end.getMinutes()/15)),this.end.addMinutes(this.delta)},u.prototype.getClassName=function(e){return(e=angular.isUndefined(e)?"fg":e)+"-folder"+(this.destinationCalendar||this.c_folder||this.pid)},u.prototype.canRemindAttendeesByEmail=function(){return"email"==this.alarm.action&&!this.isReadOnly&&this.attendees&&0<this.attendees.length},u.prototype.addAttachUrl=function(e){if(angular.isUndefined(this.attachUrls))this.attachUrls=[{value:e}];else{for(var t=0;t<this.attachUrls.length&&this.attachUrls[t].value!=e;t++);t==this.attachUrls.length&&this.attachUrls.push({value:e})}return this.attachUrls.length-1},u.prototype.deleteAttachUrl=function(e){-1<e&&this.attachUrls.length>e&&this.attachUrls.splice(e,1)},u.prototype.$addDueDate=function(){this.due=new Date,this.due.setMinutes(15*Math.round(this.due.getMinutes()/15)),this.dueDate=this.due.toISOString()},u.prototype.$deleteDueDate=function(){delete this.due,delete this.dueDate},u.prototype.$addStartDate=function(){this.start=new Date,this.start.setMinutes(15*Math.round(this.start.getMinutes()/15))},u.prototype.$deleteStartDate=function(){delete this.start,delete this.startDate},u.prototype.$addRecurrenceDate=function(){var e=new Date;e.setMinutes(15*Math.round(e.getMinutes()/15)),angular.isUndefined(this.repeat.dates)&&(this.repeat={frequency:"custom",dates:[]}),this.repeat.dates.push(e)},u.prototype.$deleteRecurrenceDate=function(e){-1<e&&this.repeat&&this.repeat.dates&&this.repeat.dates.length>e&&this.repeat.dates.splice(e,1)},u.prototype.$reset=function(){var n=this;angular.forEach(this,function(e,t){"constructor"!=t&&"$"!=t[0]&&delete n[t]}),this.init(this.$shadowData),this.$shadowData=this.$omit()},u.prototype.$reply=function(){var e,t=this,n=[this.pid,this.id];return this.occurrenceId&&n.push(this.occurrenceId),e={reply:this.reply,delegatedTo:this.delegatedTo,alarm:this.$hasAlarm?this.alarm:{},classification:this.classification},u.$$resource.save(n,e,{action:"rsvpAppointment"}).then(function(e){return t.$shadowData=t.$omit(),e})},u.prototype.$adjust=function(e){var t=[this.pid,this.id];return _.every(_.values(e),function(e){return 0===e})?u.$q.when():(this.occurrenceId&&t.push(this.occurrenceId),u.$log.debug("adjust "+t.join("/")+" "+JSON.stringify(e)),u.$$resource.save(t,e,{action:"adjust"}))},u.prototype.$save=function(e){var t,n,i=this,a=this.$omit(),o=u.$Preferences.$mdDateLocaleProvider;return a.startDate=a.start?a.start.format(o,"%Y-%m-%d"):"",a.startTime=a.start?a.start.format(o,"%H:%M"):"",a.endDate=a.end?a.end.format(o,"%Y-%m-%d"):"",a.endTime=a.end?a.end.format(o,"%H:%M"):"",a.dueDate=a.due?a.due.format(o,"%Y-%m-%d"):"",a.dueTime=a.due?a.due.format(o,"%H:%M"):"",a.completedDate=a.completed?a.completed.format(o,"%Y-%m-%d"):"",this.hasCustomRepeat()?"monthly"==this.repeat.frequency&&this.repeat.month.type&&"byday"==this.repeat.month.type&&"relative"!=this.repeat.month.day||"yearly"==this.repeat.frequency&&this.repeat.year.byday?(delete a.repeat.monthdays,a.repeat.days=[{day:this.repeat.month.day,occurrence:this.repeat.month.occurrence.toString()}]):"monthly"!=this.repeat.frequency&&"yearly"!=this.repeat.frequency||!this.repeat.month.type?"custom"==this.repeat.frequency&&this.repeat.dates&&_.forEach(a.repeat.dates,function(e,t,n){n[t]={date:e.format(o,"%Y-%m-%d"),time:e.format(o,"%H:%M")}}):(delete a.repeat.days,"relative"==this.repeat.month.day&&(a.repeat.monthdays=[this.repeat.month.occurrence])):this.repeat.frequency&&"never"!=this.repeat.frequency&&(a.repeat={frequency:this.repeat.frequency}),a.startDate&&this.repeat.frequency&&"never"!=this.repeat.frequency?"until"==this.repeat.end&&this.repeat.until?a.repeat.until=this.repeat.until.stringWithSeparator("-"):"count"==this.repeat.end&&this.repeat.count?a.repeat.count=this.repeat.count:(delete a.repeat.until,delete a.repeat.count):delete a.repeat,"not-specified"==this.status?delete a.status:"completed"!=this.status&&delete a.completedDate,(a.startDate||a.dueDate)&&this.$hasAlarm?!this.alarm.action||"email"!=this.alarm.action||this.attendees&&0<this.attendees.length||(a.alarm.attendees=0,a.alarm.organizer=1):a.alarm={},n=[this.pid,this.id],this.isNew&&(t={action:"saveAs"+this.type.capitalize()}),this.occurrenceId&&n.push(this.occurrenceId),angular.extend(a,e),u.$$resource.save(n,a,t).then(function(e){return i.$shadowData=i.$omit(),e})},u.prototype.remove=function(e){var t=[this.pid,this.id];return e&&this.occurrenceId&&t.push(this.occurrenceId),u.$$resource.remove(t)},u.prototype.$unwrap=function(e){var t=this;this.$futureComponentData=e,this.$futureComponentData.then(function(e){t.init(e),t.$shadowData=t.$omit()},function(e){angular.extend(t,e),t.isError=!0,u.$log.error(t.error)})},u.prototype.$omit=function(){var n={};return angular.forEach(this,function(e,t){"constructor"==t||"$hasAlarm"!=t&&"$"==t[0]||"blocks"==t||(n[t]=angular.copy(e))}),n},u.prototype.repeatDescription=function(){var e=null;return e=this.repeat?l("repeat_"+this.repeat.frequency.toUpperCase()):e},u.prototype.alarmDescription=function(){var e,t=null;return this.alarm&&(e=["reminder",this.alarm.quantity],0<this.alarm.quantity&&e.push(this.alarm.unit.toUpperCase(),this.alarm.reference.toUpperCase()),(e=e.join("_"))===(t=l(e))&&(t=[this.alarm.quantity,l("reminder_"+this.alarm.unit.toUpperCase()),l("reminder_"+this.alarm.reference.toUpperCase())].join(" "))),t},u.prototype.copyTo=function(e){return u.$$resource.post([this.pid,this.id],"copy",{destination:e})},u.prototype.moveTo=function(e){return u.$$resource.post([this.pid,this.id],"move",{destination:e})},u.prototype.toString=function(){return"[Component "+this.id+"]"}}(),function(){"use strict";function y(t,n,i,a,o,r,s,e,c,d){var u,h=this,p=[];function m(e,t){var n;if("week"==a.view)n=h.selectedDate.beginOfWeek(c.defaults.SOGoFirstDayOfWeek).addDays(7*t);else if("month"==a.view)(n=h.selectedDate).setDate(1),n.setMonth(n.getMonth()+t);else for(n=h.selectedDate.addDays(t);!h.isSelectableDay(n);)n=n.addDays(t);h.changeDate(e,n)}function f(e){"month"==a.view?(e.setDate(1),e.setHours(12),e.$dateFormat="%B %Y"):"week"==a.view?(e.setTime(e.beginOfWeek(c.defaults.SOGoFirstDayOfWeek).getTime()),e.$dateFormat=l("Week %d").replace("%d","%U")):e.$dateFormat="%A"}function g(){e.$eventsBlocksForView(a.view,a.day.asDate()).then(function(e){for(var t,n,i=0;i<e.length;i++)n=e[i],h.views[i]?(_.forEach(n.allDayBlocks,function(e,t){h.views[i].allDayBlocks[t]=e}),_.forEach(n.blocks,function(e,t){h.views[i].blocks[t]=e})):h.views[i]=n,n.id&&(h.views[i].calendar=new s({id:n.id,name:n.calendarName}));for(t=h.views.length;i<=t;t--)h.views.splice(t,1)})}this.$onInit=function(){var e;angular.isUndefined(y.expandedAllDays)&&(y.expandedAllDays=!1),this.selectedDate=a.day.asDate(),this.selectableDays=_.map(c.defaults.SOGoCalendarWeekdays,function(e){return _.indexOf(["SU","MO","TU","WE","TH","FR","SA"],e)}),this.expandedAllDays=y.expandedAllDays,this.views=d,(e=p).push(r.createHotkey({key:l("hotkey_today"),description:l("Today"),callback:h.changeDate,args:new Date})),e.push(r.createHotkey({key:l("hotkey_dayview"),description:l("Day"),callback:h.changeView,args:"day"})),e.push(r.createHotkey({key:l("hotkey_weekview"),description:l("Week"),callback:h.changeView,args:"week"})),e.push(r.createHotkey({key:l("hotkey_monthview"),description:l("Month"),callback:h.changeView,args:"month"})),e.push(r.createHotkey({key:l("hotkey_multicolumndayview"),description:l("Multicolumn Day View"),callback:h.changeView,args:"multicolumnday"})),e.push(r.createHotkey({key:"left",description:l("Move backward"),callback:m,args:-1})),e.push(r.createHotkey({key:"right",description:l("Move forward"),callback:m,args:1})),_.forEach(e,function(e){r.registerHotkey(e)}),f(this.selectedDate),u=n.$on("calendars:list",g),t.$on("$destroy",function(){u(),_.forEach(p,function(e){r.deregisterHotkey(e)})})},this.toggleAllDays=function(){y.expandedAllDays=!y.expandedAllDays,this.expandedAllDays=y.expandedAllDays},this.changeDate=function(e,t){e=t?t.getDayString():angular.element(e.currentTarget).attr("date");t&&f(t),i.go("calendars.view",{day:e})},this.changeView=function(e,t){i.go("calendars.view",{view:t})},this.printView=function(e,t){o.show({parent:angular.element(document.body),clickOutsideToClose:!0,escapeToClose:!0,templateUrl:"UIxCalPrintDialog",controller:$,controllerAs:"$PrintDialogController",locals:{calendarView:a.view,visibleList:e?void 0:t}})},this.isSelectableDay=function(e){return _.includes(h.selectableDays,e.getDay())}}function $(e,t,n,i,a,o,r,s,c,l,d,u){var h=this,p={day:"portrait",week:"landscape",month:"landscape",multicolumnday:"landscape"};this.$onInit=function(){this.pageSize="letter",this.workingHoursOnly=!0,this.calendarView=d,this.orientation=p[this.calendarView],this.visibleList=u,angular.element(document.body).addClass(this.orientation),t.$watch(function(){return h.pageSize},angular.bind(this,function(e,t){angular.element(document.body).removeClass(t),angular.element(document.body).addClass(e)}))},this.$onDestroy=function(){angular.element(document.body).removeClass(["portrait","landscape","letter","legal","a4"])},this.print=function(e){return n.print(),e.stopPropagation(),!1},this.close=function(){a.hide()}}y.$inject=["$scope","$rootScope","$state","$stateParams","$mdDialog","sgHotkeys","Calendar","Component","Preferences","stateEventsBlocks"],$.$inject=["$rootScope","$scope","$window","$stateParams","$mdDialog","$log","Dialog","sgSettings","Preferences","Calendar","calendarView","visibleList"],angular.module("SOGo.SchedulerUI").controller("CalendarController",y)}(),function(){"use strict";function e(d,t,a,u,e,h,n,i,o,p,m,f,g){var r,s,c=this,y=[];function $(e,t){(t&&t.reload||c.componentType!=e)&&(angular.isUndefined(g["$"+e])&&g.$filter(e),c.unselectComponents(),c.componentType=e,g.saveSelectedList(e))}function v(){c.mode.search=!0,i("search")}function C(t,n,i){var e;n.viewable&&(e=a.when(),(e=angular.isUndefined(n.$futureComponentData)?(n=f.$get(n.pid).$getComponent(n.id,n.occurrenceId)).$futureComponentData:e).then(function(){var e="UIx"+i.capitalize()+"ViewTemplate";h.show({parent:angular.element(document.body),targetEvent:t,clickOutsideToClose:!0,escapeToClose:!0,templateUrl:e,controller:"ComponentController",controllerAs:"editor",locals:{stateComponent:n}})}))}function b(e,t,n){var i;n?((i=n).initAttendees(),i.$attendees.updateFreeBusy()):i=new g({pid:f.$defaultCalendar(),type:t});t="UIx"+t.capitalize()+"EditorTemplate";return h.show({parent:angular.element(document.body),targetEvent:e,clickOutsideToClose:!0,escapeToClose:!0,templateUrl:t,controller:"ComponentEditorController",controllerAs:"editor",locals:{stateComponent:i}})}function D(e){var t,n,i,a,o;function r(e,t,n,i){e.updateThisOccurrence=function(){n.$adjust(i).then(t.hide,function(e){t.cancel().then(function(){s(e,n,i)},function(){})})},e.updateAllOccurrences=function(){delete n.occurrenceId,n.$adjust(i).then(t.hide,function(e){t.cancel().then(function(){s(e,n,i)},function(){})})}}function s(e,t,n){e.status==m.ConflictHTTPErrorCode&&e.data&&e.data.message&&angular.isObject(e.data.message)&&h.show({parent:angular.element(document.body),clickOutsideToClose:!1,escapeToClose:!1,templateUrl:"UIxAttendeeConflictDialog",controller:c,controllerAs:"$AttendeeConflictDialogController",locals:{component:t,params:n,conflictError:e.data.message}}).then(function(){d.$emit("calendars:list")},function(){})}function c(e,t,n,i,a){this.conflictError=a,this.cancel=t.cancel,this.save=function(){n.$adjust(angular.extend({ignoreConflicts:!0},i)).then(t.hide)}}t=g.$ghost.component,o=g.$ghost.pointerHandler,t.isNew?(n=o.originalEventCoordinates,a=o.currentEventCoordinates,t.summary="",t.isAllDay&&(a.duration-=96),a.start<n.start&&(a.duration*=-1),t.setDelta(15*a.duration),b(null,"appointment",t).catch().finally(function(){u(function(){g.$resetGhost()})})):(a=o.currentEventCoordinates.getDelta(o.originalEventCoordinates),i={days:a.dayNumber,start:15*a.start,duration:15*a.duration},o.originalCalendar&&0!==a.dayNumber&&(a=o.currentEventCoordinates.dayNumber,o=_.filter(f.$findAll(),{active:1}),i.destination=o[a].id,i.days=0),t.isException||!t.occurrenceId?t.$adjust(i).then(function(){d.$emit("calendars:list"),p.getAlarms()},function(e){s(e,t,i)}).finally(function(){u(function(){g.$resetGhost()})}):t.occurrenceId&&h.show({clickOutsideToClose:!0,escapeToClose:!0,locals:{component:t,params:i},template:['<md-dialog flex="50" sm-flex="80" xs-flex="90">',' <md-dialog-content class="md-dialog-content">'," <p>"+l("editRepeatingItem")+"</p>"," </md-dialog-content>"," <md-dialog-actions>",' <md-button ng-click="updateThisOccurrence()">'+l("button_thisOccurrenceOnly")+"</md-button>",' <md-button ng-click="updateAllOccurrences()">'+l("button_allOccurrences")+"</md-button>"," </md-dialog-actions>","</md-dialog>"].join(""),controller:r}).then(function(){d.$emit("calendars:list")},function(){}).finally(function(){u(function(){g.$resetGhost()})})),r.$inject=["$scope","$mdDialog","component","params"],c.$inject=["$scope","$mdDialog","component","params","conflictError"]}s={title:"Title",location:"Location",calendarName:"Calendar",start:"Start",priority:"Priority",category:"Category",status:"Status",events:{end:"End"},tasks:{end:"Due Date"}},c.component=g,c.componentType="events",c.selectedList=0,c.selectComponentType=$,c.unselectComponents=function(){_.forEach(g["$"+c.componentType],function(e){e.selected=!1}),c.mode.multiple=0},c.selectAll=function(){_.forEach(g["$"+c.componentType],function(e){e.selected=!0}),c.mode.multiple=g["$"+c.componentType].length},c.searchMode=v,c.toggleComponentSelection=function(e,t){t.selected=!t.selected,c.mode.multiple+=t.selected?1:-1,e.preventDefault(),e.stopPropagation()},c.confirmDeleteSelectedComponents=function(){o.confirm(l("Warning"),l("Are you sure you want to delete the selected components?"),{ok:l("Delete")}).then(function(){var e=_.filter(g["$"+c.componentType],function(e){return e.selected});f.$deleteComponents(e).then(function(){c.mode.multiple=0,d.$emit("calendars:list")})})},c.openEvent=function(e,t){C(e,t,"appointment")},c.openTask=function(e,t){C(e,t,"task")},c.newComponent=b,c.filter=function(e){{if(!e)return g["$query"+c.componentType.capitalize()].filterpopup;g.$filter(c.componentType,{filterpopup:e})}},c.filteredBy=function(e){return g["$query"+c.componentType.capitalize()].filterpopup==e},c.sort=function(e){{if(!e){var t=g["$query"+c.componentType.capitalize()].sort;return s[t]||s[c.componentType][t]}g.$filter(c.componentType,{sort:e})}},c.sortedBy=function(e){return g["$query"+c.componentType.capitalize()].sort==e},c.reload=function(){g.$loaded=g.STATUS.LOADING,f.reloadWebCalendars().finally(function(){d.$emit("calendars:list")})},c.cancelSearch=function(){c.mode.search=!1,g.$filter(c.componentType,{value:""})},c.mode={search:!1,multiple:0},this.$onInit=function(){var e;(e=y).push(n.createHotkey({key:l("hotkey_search"),description:l("Search"),callback:v})),e.push(n.createHotkey({key:l("hotkey_create_event"),description:l("Create a new event"),callback:b,args:"appointment"})),e.push(n.createHotkey({key:l("hotkey_create_task"),description:l("Create a new task"),callback:b,args:"task"})),_.forEach(e,function(e){n.registerHotkey(e)}),r="events","tasksListView"==p.settings.Calendar.SelectedList&&(c.selectedList=1,r="tasks"),$(r,{reload:!0}),d.$on("calendars:list",function(){g.$filter(c.componentType,{reload:!0})}),d.$on("calendar:dragend",D),t.$on("$destroy",function(){_.forEach(y,function(e){n.deregisterHotkey(e)})})},this.ascending=function(){return g["$query"+c.componentType.capitalize()].asc}}e.$inject=["$rootScope","$scope","$q","$timeout","$state","$mdDialog","sgHotkeys","sgFocus","Dialog","Preferences","CalendarSettings","Calendar","Component"],angular.module("SOGo.SchedulerUI").controller("CalendarListController",e)}(),function(){"use strict";function e(o,e,t,i,n,r,a,s,c,d,u,h){var p=this;this.activeUser=d.activeUser,this.service=h,this.filter={name:""},this.sortableMode=!1,this.sortableCalendars={scrollableContainer:"#sidenav-content",containment:"md-list",orderChanged:function(){h.saveFoldersOrder(_.flatMap(h.$findAll(),"id"))},accept:function(e,t,n){return e.sortableScope.element[0]==t.element[0]}},this.$onInit=function(){p.categories=_.map(u.defaults.SOGoCalendarCategories,function(e){return{id:e.asCSSIdentifier(),name:e,color:u.defaults.SOGoCalendarCategoriesColors[e]}}),e.$watch(function(){return _.union(_.map(h.$calendars,function(e){return _.pick(e,["id","active","color"])}),_.map(h.$subscriptions,function(e){return _.pick(e,["id","active","color"])}),_.map(h.$webcalendars,function(e){return _.pick(e,["id","active","color"])}))},function(e,n){var t=_.intersectionBy(e,n,"id"),i=_.map(_.filter(t,function(e){var t=_.find(n,{id:e.id});return!_.isEqual(e,t)}),"id"),a=h.$q.when();0<i.length&&(r.debug(i.join(", ")+" changed"),a=h.saveFoldersActivation(i)),(0<i.length||t.length!=e.length||t.length!=n.length)&&a.then(function(){o.$emit("calendars:list")})},!0)},this.centerIsClose=function(e){return e&&n(s["gt-xs"])},this.toggleSortableMode=function(){this.sortableMode=!p.sortableMode,this.filter.name=""},this.resetSort=function(){h.saveFoldersOrder()},this.newCalendar=function(e){c.prompt(l("New calendar"),l("Name of the Calendar")).then(function(e){var t=new h({name:e,isEditable:!0,isRemote:!1,owner:UserLogin});t.$id().then(function(){h.$add(t)}).catch(_.noop)})},this.addWebCalendar=function(){function n(e,n,t,i){var a=this,o=t.split("/")[2];a.title=l("Please identify yourself to %{0}").formatted(o),a.url=t,a.authenticate=function(t){!t.$valid&&t.$error.required||i.setCredentials(a.username,a.password).then(function(e){n.hide()},function(e){t.password.$setValidity("credentials",!1)})},a.cancel=function(){n.cancel()}}c.prompt(l("Subscribe to a web calendar..."),l("URL of the Calendar"),{inputType:"url"}).then(function(t){h.$addWebCalendar(t).then(function(e){angular.isObject(e)&&i.show({parent:angular.element(document.body),clickOutsideToClose:!0,escapeToClose:!0,templateUrl:"UIxWebCalendarAuthDialog",controller:n,controllerAs:"$WebCalendarAuthDialogController",locals:{url:t,calendar:e}})}).catch(_.noop)}).catch(_.noop),n.$inject=["scope","$mdDialog","url","calendar"]},this.subscribeToFolder=function(e){r.debug("subscribeToFolder "+e.owner+e.name),h.$subscribe(e.owner,e.name).then(function(e){a.show(a.simple().textContent(l("Successfully subscribed to calendar")).position("top right").hideDelay(3e3))})}}e.$inject=["$rootScope","$scope","$window","$mdDialog","$mdMedia","$log","$mdToast","sgConstant","Dialog","sgSettings","Preferences","Calendar"],angular.module("SOGo.SchedulerUI").controller("CalendarsController",e)}(),function(){"use strict";function e(t,o,r,s,n,e,i,a,c,d){var u,h=this;function p(i,a){c.$findAll().then(function(e){var t=_.find(e,function(e){if(0===e.id)return e}),n=r.defer();t.$getMailboxes().then(function(e){t.$newMessage().then(function(e){angular.extend(e.editable,{to:a,subject:h.component.summary}),s.show({parent:angular.element(document.body),targetEvent:i,clickOutsideToClose:!1,escapeToClose:!1,templateUrl:"../Mail/UIxMailEditor",controller:"MessageEditorController",controllerAs:"editor",onComplete:function(e,t){return n.resolve(t)},locals:{stateParent:o,stateAccount:t,stateMessage:e,onCompletePromise:function(){return n.promise}}})})})}),i.preventDefault(),i.stopPropagation()}this.$onInit=function(){this.calendarService=e,this.service=i,this.component=d,this.organizer=[d.organizer]},this.close=function(){s.hide()},this.highPriority=function(){return this.component&&this.component.priority&&this.component.priority<5},this.cardFilter=function(e){return a.$filterAll(e)},this.newMessageWithAllRecipients=function(e){p(e,_.map(this.component.attendees,function(e){return e.name+" <"+e.email+">"}))},this.newMessageWithRecipient=function(e,t,n){p(e,[t+" <"+n+">"])},this.edit=function(){var t="vevent"==this.component.component?"Appointment":"Task";s.hide().then(function(){var e="UIx"+t+"EditorTemplate";s.show({parent:angular.element(document.body),clickOutsideToClose:!0,escapeToClose:!0,templateUrl:e,controller:"ComponentEditorController",controllerAs:"editor",locals:{stateComponent:h.component}})})},this.editAllOccurrences=function(){(u=e.$get(this.component.pid).$getComponent(this.component.id)).$futureComponentData.then(function(){h.component=u,h.edit()})},this.reply=function(e){(e||this.component).$reply().then(function(){t.$emit("calendars:list"),n.getAlarms(),s.hide()})},this.replyAllOccurrences=function(){(u=e.$get(this.component.pid).$getComponent(this.component.id)).$futureComponentData.then(function(){u.reply=h.component.reply,u.delegatedTo=h.component.delegatedTo,u.$hasAlarm=h.component.$hasAlarm,u.classification=h.component.classification,u.alarm=h.component.alarm,h.reply(u)})},this.deleteOccurrence=function(){this.component.remove(!0).then(function(){t.$emit("calendars:list"),s.hide()})},this.deleteAllOccurrences=function(){this.component.remove().then(function(){t.$emit("calendars:list"),s.hide()})},this.toggleRawSource=function(n){e.$$resource.post(this.component.pid+"/"+this.component.id,"raw").then(function(e){function t(e,t,n){e.data=n,e.close=function(){t.hide()}}s.hide(),s.show({parent:angular.element(document.body),targetEvent:n,clickOutsideToClose:!0,escapeToClose:!0,template:['<md-dialog flex="40" flex-sm="80" flex-xs="100" aria-label="'+l("View Raw Source")+'">',' <md-dialog-content class="md-dialog-content">',' <pre ng-bind-html="data"></pre>'," </md-dialog-content>"," <md-dialog-actions>",' <md-button ng-click="close()">'+l("Close")+"</md-button>"," </md-dialog-actions>","</md-dialog>"].join(""),controller:t,locals:{data:e}}),t.$inject=["scope","$mdDialog","data"]})},this.copySelectedComponent=function(e){this.component.copyTo(e).then(function(){s.hide(),t.$emit("calendars:list")})},this.moveSelectedComponent=function(e){this.component.moveTo(e).then(function(){s.hide(),t.$emit("calendars:list")})}}function t(n,e,u,t,h,i,a,o,r,s,c,d,p,m,f,g,y,$,v){var C,b,D,w,S=this;function k(){var e;S.attendeesEditor.containerElement||(S.attendeesEditor.containerElement=a[0].querySelector("#freebusy")),e=a[0].querySelector("#freebusy_day_"+S.component.start.getDayString()),S.attendeesEditor.containerElement&&e&&(e=e.offsetLeft-S.attendeesEditor.containerElement.offsetLeft,S.attendeesEditor.containerElement.scrollLeft=e)}function E(e){S.adjustStartTime(),S.adjustEndTime(),S.component.$attendees.findSlot(e).then(function(){S.startTime=new Date(S.component.start.getTime()),S.endTime=new Date(S.component.end.getTime())}).catch(function(e){S.component.start=new Date(S.component.start.getTime()+1),h(k),r.show({template:["<md-toast>",' <div class="md-toast-content">',' <md-icon class="md-warn md-hue-1">error_outline</md-icon>'," <span flex>"+e+"</span>"," </div>","</md-toast>"].join(""),hideDelay:5e3,position:"top right"})}).finally(function(){h(k)})}function T(){_.has(S.component,"$attendees")&&(S.component.$attendees.updateFreeBusyCoverage(),S.component.$attendees.updateFreeBusy(),h(k))}this.$onInit=function(){this.service=p,this.component=v,this.categories={},this.showRecurrenceEditor=this.component.$hasCustomRepeat,this.showAttendeesEditor=this.component.attendees&&this.component.attendees.length,"appointment"==this.component.type&&(this.component.initAttendees(),this.attendeeConflictError=!1,this.attendeesEditor={days:this.component.$attendees.$days,hours:function(){for(var e=[],t=0;t<=23;t++)e.push(t.toString());return e}(),containerElement:a[0].querySelector("#freebusy")}),this.component.start&&(C=new Date(this.component.start.getTime()),this.startTime=new Date(this.component.start.getTime())),this.component.end&&(b=new Date(this.component.end.getTime()),this.endTime=new Date(this.component.end.getTime())),this.component.due&&(new Date(this.component.due.getTime()),this.dueTime=new Date(this.component.due.getTime())),this.component.attendees&&h(k),D=parseInt($.defaults.SOGoDayStartTime),w=parseInt($.defaults.SOGoDayEndTime)},this.addAttachUrl=function(){var e=this.component.addAttachUrl("");s("attachUrl_"+e)},this.toggleRecurrenceEditor=function(){this.showRecurrenceEditor=!this.showRecurrenceEditor,this.component.$hasCustomRepeat=this.showRecurrenceEditor},this.toggleAttendeesEditor=function(){this.showAttendeesEditor=!this.showAttendeesEditor},this.recurrenceMonthDaysAreRequired=function(){return this.component&&"monthly"==this.component.repeat.frequency&&"bymonthday"==this.component.repeat.month.type},this.frequencies=function(){return _.filter(i.repeatFrequencies,function(e){return"custom"!=e[0]||"custom"==S.component.repeat.frequency})},this.changeFrequency=function(){"custom"==this.component.repeat.frequency&&(this.showRecurrenceEditor=!0)},this.changeCalendar=function(){this.component.attendees&&0<this.component.attendees.length&&this.component.$attendees.initOrganizer(p.$get(this.component.destinationCalendar))},this.cardFilter=function(e){return g.$filterAll(e)},this.addAttendee=function(e,t){var n,i,a=!this.component.attendees||0===this.component.attendees.length,o=p.$get(this.component.destinationCalendar),r=a?{organizerCalendar:o}:{},s=[],c=/([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)/i;function l(e){var t=e.match(c)[0],n=e.replace(new RegExp(" *<?"+t+">? *"),"");return S.showAttendeesEditor|=a,S.searchText="",S.cardFilter(t).then(function(e){return e.length?e[0]:new y({c_cn:_.trim(n,' "'),emails:[{value:t}]})}).catch(function(e){return new y({c_cn:_.trim(n,' "'),emails:[{value:t}]})})}function d(e){if(!S.component.$attendees.hasAttendee(e))return S.component.$attendees.add(e,r)}if(t&&(r.partial=t),angular.isString(e)){for(i="",n=0;n<e.length;n++)9!=e.charCodeAt(n)&&32!=e.charCodeAt(n)&&44!=e.charCodeAt(n)&&59!=e.charCodeAt(n)||!c.test(i)?i+=e.charAt(n):(s.push(l(i).then(d)),i="");i&&c.test(i)&&s.push(l(i).then(d))}else angular.isDefined(e)&&(this.component.$attendees.hasAttendee(e)||s.push(this.component.$attendees.add(e,r)),this.showAttendeesEditor|=a);return _.has(this.component,"$attendees")&&h(k),u.all(s)},this.expandAttendee=function(e){0<e.members.length&&(this.component.$attendees.remove(e),_.forEach(e.members,function(e){S.component.$attendees.add(e)}))},this.removeAttendee=function(e,t){this.component.$attendees.remove(e),0===this.component.$attendees.getLength()&&(this.showAttendeesEditor=!1,this.component.$attendees.remove(this.component.organizer)),t.$setDirty()},this.defaultIconForAttendee=function(e){return e.isGroup?"group":e.isResource?"meeting_room":"person"},this.nextSlot=function(){E(1)},this.previousSlot=function(){E(-1)},this.priorityLevel=function(){if(this.component&&this.component.priority)return 5<this.component.priority?l("low"):4<this.component.priority?l("normal"):l("high")},this.changeAlarmRelation=function(e){e.alarmRelation&&("task"==this.component.type&&this.component.$hasAlarm&&(this.component.start||this.component.due)&&(!this.component.start&&"START"==this.component.alarm.relation||!this.component.due&&"END"==this.component.alarm.relation)?e.alarmRelation.$setValidity("alarm",!1):e.alarmRelation.$setValidity("alarm",!0))},this.onAlarmChange=function(e){"task"===this.component.type&&(this.component.start||"START"!=this.component.alarm.relation?this.component.due||"END"!=this.component.alarm.relation||(this.component.alarm.relation="START"):this.component.alarm.relation="END",this.changeAlarmRelation(e))},this.save=function(t,e){this.adjustStartTime(),this.adjustEndTime(),this.changeAlarmRelation(t),this.addAttendee(this.searchText).then(function(){t.$valid&&S.component.$save(e).then(function(e){n.$emit("calendars:list"),$.getAlarms(),o.hide()},function(e){e.status==d.ConflictHTTPErrorCode?S.attendeeConflictError=_.isObject(e.data.message)?e.data.message:{reject:e.data.message}:S.edit(t)})})},this.reset=function(e){this.component.$reset(),e.$setPristine()},this.cancel=function(e){this.reset(e),this.component.isNew&&(this.component=null),o.hide()},this.edit=function(e){this.attendeeConflictError=!1,e.$setPristine(),e.$setDirty()},this.addStartDate=function(e){this.component.$addStartDate(),C=new Date(this.component.start.getTime()),this.startTime=new Date(this.component.start.getTime()),this.component.due||(this.component.alarm.relation="START"),this.changeAlarmRelation(e),e.$setDirty()},this.removeStartDate=function(e){this.component.$deleteStartDate(),this.component.due&&(this.component.alarm.relation="END"),this.changeAlarmRelation(e),e.$setDirty()},this.addDueDate=function(e){this.component.$addDueDate(),new Date(this.component.due.getTime()),this.dueTime=new Date(this.component.due.getTime()),this.component.start||(this.component.alarm.relation="END"),this.changeAlarmRelation(e),e.$setDirty()},this.removeDueDate=function(e){this.component.$deleteDueDate(),this.component.start&&(this.component.alarm.relation="START"),this.changeAlarmRelation(e),e.$setDirty()},this.adjustAllDay=function(){this.component.isAllDay||(this.component.start.setHours(D),this.component.start.setMinutes(0),this.startTime=new Date(this.component.start.getTime()),C=new Date(this.component.start.getTime()),this.component.end.setHours(w),this.component.end.setMinutes(0),this.endTime=new Date(this.component.end.getTime()),b=new Date(this.component.end.getTime()),this.component.delta=this.component.start.minutesTo(this.component.end)),this.component.$attendees.updateFreeBusyCoverage()},this.adjustStartTime=function(){this.component.start&&this.startTime&&(this.component.start.setHours(this.startTime.getHours()),this.component.start.setMinutes(this.startTime.getMinutes()),0!=C.valueOf()-this.component.start.valueOf()&&(C=new Date(this.component.start.getTime()),"appointment"===this.component.type&&(this.component.end=new Date(this.component.start.getTime()),this.component.end.addMinutes(this.component.delta),this.endTime=new Date(this.component.end.getTime()),b=new Date(this.component.end.getTime())),T()))},this.adjustEndTime=function(){var e;this.component.end&&this.endTime&&(this.component.end.setHours(this.endTime.getHours()),this.component.end.setMinutes(this.endTime.getMinutes()),0!=b.valueOf()-this.component.end.valueOf()&&(this.startTime&&(this.component.start.setHours(this.startTime.getHours()),this.component.start.setMinutes(this.startTime.getMinutes())),(e=this.component.start.minutesTo(this.component.end))<0?(this.component.end=new Date(b.getTime()),this.endTime=new Date(this.component.end.getTime())):(this.component.delta=e,b=new Date(this.component.end.getTime())),T()))},this.adjustDueTime=function(){this.component.due&&this.dueTime&&(this.component.due.setHours(this.dueTime.getHours()),this.component.due.setMinutes(this.dueTime.getMinutes()),new Date(this.component.due.getTime()))}}e.$inject=["$rootScope","$scope","$q","$mdDialog","Preferences","Calendar","Component","AddressBook","Account","stateComponent"],t.$inject=["$rootScope","$scope","$q","$log","$timeout","$window","$element","$mdDialog","$mdToast","sgFocus","User","CalendarSettings","Calendar","Component","Attendees","AddressBook","Card","Preferences","stateComponent"],angular.module("SOGo.SchedulerUI").controller("ComponentController",e).controller("ComponentEditorController",t)}(),function(){"use strict";function e(n,i){this.day=n.day,this.dayNumber=n.dayNumber,this.dayString=n.dayString,this.calendarData=function(){var t,e;return n.calendar?(t=n.calendar,e=_.filter(i.$findAll(),{active:1}),e=_.findIndex(e,function(e){return e.id==t}),{pid:t,index:e}):null}}e.$inject=["$scope","Calendar"],angular.module("SOGo.SchedulerUI").directive("sgCalendarDay",function(){return{restrict:"E",scope:{day:"@sgDay",dayNumber:"@sgDayNumber",dayString:"@sgDayString",calendar:"@sgCalendar"},controller:e}})}(),function(){"use strict";function e(a){return{restrict:"E",scope:{block:"=sgBlock",clickBlock:"&sgClick"},replace:!0,template:function(e,t){t=_.has(t,"sgCalendarGhost")?"":"::";return['<div class="sg-event"'," ng-class=\"{'sg-event--dragging': block.dragging}\">",' <div class="eventInside"',' ng-click="clickBlock({clickEvent: $event, clickComponent: block.component})">',' <div class="sg-category" ng-repeat="category in '+t+'block.component.categories"',' ng-class="'+t+"('bg-category' + category)\"",' ng-style="'+t+"{ right: ($index * 10) + '%' }\"></div>",' <div class="text">',' <span ng-show="'+t+'block.component.c_priority" class="sg-priority">{{'+t+"block.component.c_priority}}</span>"," {{ "+t+"block.component.summary }}",' <span class="sg-icons">',' <md-icon ng-if="'+t+'block.component.occurrenceId">repeat</md-icon>',' <md-icon ng-if="'+t+'block.component.c_nextalarm">alarm</md-icon>',' <md-icon ng-if="'+t+'block.component.c_classification == 2">visibility_off</md-icon>',' <md-icon ng-if="'+t+'block.component.c_classification == 1">vpn_key</md-icon>'," </span>",' <div class="secondary" ng-if="'+t+'block.component.c_location">',' <md-icon>place</md-icon> <span ng-bind="'+t+'block.component.c_location"></span>'," </div>",' <div class="secondary md-truncate" ng-if="'+t+'showCalendarName"',' ng-bind="'+t+'block.component.calendarName"></div>'," </div>"," </div>",' <div class="ghostStartHour" ng-if="block.startHour">{{ block.startHour }}</div>',' <div class="ghostEndHour" ng-if="block.endHour">{{ block.endHour }}</div>',"</div>"].join("")},link:function(e,t,n){var i;_.has(n,"sgCalendarGhost")||(i=90/e.block.siblings,n=e.block.position*i,i=100-(e.block.position+1)*i,t.css("left",n+"%"),t.css("right",i+"%"),e.block.component&&e.block.component.c_isallday||(t.addClass("starts"+e.block.start),t.addClass("lasts"+e.block.length)),e.block.userState&&t.addClass("sg-event--"+e.block.userState),e.block.component&&(e.showCalendarName=a.activeUser.login!==e.block.component.c_owner,t.addClass("bg-folder"+e.block.component.pid),t.addClass("contrast-bdr-folder"+e.block.component.pid),0===e.block.component.c_isopaque&&t.addClass("sg-event--transparent"),0===e.block.component.c_status&&t.addClass("sg-event--cancelled")))}}}e.$inject=["Calendar"],angular.module("SOGo.SchedulerUI").directive("sgCalendarDayBlock",e)}(),function(){"use strict";angular.module("SOGo.SchedulerUI").directive("sgCalendarDayTable",function(){return{restrict:"E",scope:{blocks:"=sgBlocks",day:"@sgDay",clickBlock:"&sgClick"},template:["<sg-calendar-day-block",' class="sg-draggable-calendar-block"',' ng-repeat="block in blocks[day]"',' sg-block="block"',' sg-click="clickBlock({event: clickEvent, component: clickComponent})"/>'].join("")}})}(),function(){"use strict";function e(r,e,f,g,s){return{restrict:"A",require:["^sgCalendarDay","^sgCalendarScrollView"],link:function(c,l,e,t){var n,d,u,h,p;n=l[0],d=t[0],u=t[1],h=-1,l.addClass("sg-event--ghost md-whiteframe-3dp ng-hide");var i=r.$on("calendar:dragstart",function(){var e,t;c.block=s.$ghost,(t=d.calendarData())&&(h=t.index,e=t.pid,p=c.block.pointerHandler.originalCalendar.index);e=e||c.block.component.pid;(t=c.block.component.blocks[0].userState)&&l.addClass("sg-event--"+t);l.addClass("bg-folder"+e)}),a=r.$on("calendar:drag",function(){var e,t,n,i,a,o,r,s;if(e=!1,g.$view&&g.$view.type==u.type){if(t="multiday-allday"===u.type,n=c.block.component.c_isallday,i=c.block.pointerHandler.currentEventCoordinates.dayNumber,a=c.block.pointerHandler.currentEventCoordinates.start,r=c.block.pointerHandler.currentEventCoordinates.duration,s=f.EventDragDayLength-a,angular.isUndefined(r))return;for(s<(o=r)&&(o=s),-1<i&&(h<0&&i==d.dayNumber||i==h&&(p==h||!c.block.component.isException))&&(e=!0,t||(n||(c.block.startHour=m(a)),g.$view.quarterHeight?(l.css("top",a*g.$view.quarterHeight+"px"),l.css("height",o*g.$view.quarterHeight+"px")):l.css("top",g.$view.topOffset+"px")),l.removeClass("fg-folder"+c.block.component.pid),l.removeClass("sg-event--ghost--last"),l.addClass("sg-event--ghost--first"),c.block.isFirst=!0),r-=o,i++;!e&&r&&i<=d.dayNumber;)(o=r)>f.EventDragDayLength&&(o=f.EventDragDayLength),-1<i&&i==d.dayNumber&&(e=!0,t||(l.css("top",g.$view.topOffset+"px"),g.$view.quarterHeight&&l.css("height",o*g.$view.quarterHeight+"px")),l.removeClass("sg-event--ghost--first"),l.removeClass("sg-event--ghost--last"),l.addClass("fg-folder"+c.block.component.pid)),r-=o,i++,a=0;r||(t?l.addClass("sg-event--ghost--last"):n||(c.block.endHour=function(e,t){return m((e+t)%f.EventDragDayLength)}(a,o)))}e?l.removeClass("ng-hide"):l.addClass("ng-hide")}),o=r.$on("calendar:dragend",function(){_.forEachRight(n.classList,function(e){/^bg-folder/.test(e)&&l.removeClass(e)}),l.addClass("ng-hide")});function m(e){var t=15*e,e=Math.floor(t/60);return(e=e<10?"0"+e:e)+":"+(t=(t=t%60)<10?"0"+t:t)}c.$on("$destroy",function(){i(),a(),o()})}}}e.$inject=["$rootScope","$timeout","CalendarSettings","Calendar","Component"],angular.module("SOGo.SchedulerUI").directive("sgCalendarGhost",e)}(),function(){"use strict";function e(e){return{restrict:"E",scope:{component:"=sgComponent",clickComponent:"&sgClick"},replace:!0,template:function(e,t){return['<div class="sg-event"',' ng-click="clickComponent({clickEvent: $event, clickComponent: component})">',' <div class="text">',' <span ng-show="::component.c_priority" class="sg-priority" ng-bind="::component.c_priority"></span>',' <div class="sg-category-dot-container">',' <div class="sg-category-dot" ng-repeat="category in ::component.categories"'," ng-class=\"::('bg-category' + category)\"></div>"," </div>"," {{ ::component.c_title }}",' <span class="sg-icons">',' <md-icon ng-if="::component.occurrenceId">repeat</md-icon>',' <md-icon ng-if="::component.c_nextalarm">alarm</md-icon>',' <md-icon ng-if="::component.c_classification == 2">visibility_off</md-icon>',' <md-icon ng-if="::component.c_classification == 1">vpn_key</md-icon>'," </span>",' <div class="secondary" ng-if="::!component.c_isallday">',' <md-icon>access_time</md-icon> <span ng-bind="::component.starthour"></span>'," </div>",' <div class="secondary" ng-if="::component.c_location">',' <md-icon>place</md-icon> <span ng-bind="::component.c_location"></span>'," </div>"," </div>","</div>"].join("")},link:function(e,t,n){e.component.viewable&&t.addClass("md-clickable");e.component.userstate&&t.addClass("sg-event--"+e.component.userstate);t.addClass("bg-folder"+e.component.pid),t.addClass("contrast-bdr-folder"+e.component.pid),0===e.component.c_isopaque&&t.addClass("sg-event--transparent");0===e.component.c_status&&t.addClass("sg-event--cancelled")}}}e.$inject=["CalendarSettings"],angular.module("SOGo.SchedulerUI").directive("sgCalendarListEvent",e)}(),function(){function e(r,e,t,n,s,i,a,o,c,d,u){var h=this;this.$onInit=function(){this.editMode=!1},this.$postLink=function(){this.clickableElement=t.find("p")[0],this.nameElements=this.clickableElement.getElementsByClassName("sg-calendar-name"),this.inputContainer=t.find("md-input-container")[0],this.inputElement=t.find("input")[0],this.moreOptionsButton=_.last(t.find("md-icon")),this.updateCalendarName()},this.updateCalendarName=function(){_.forEach(this.nameElements,function(e){e.innerHTML=h.calendar.name})},this.editFolder=function(e){e.stopPropagation(),e.preventDefault(),this.editMode=!0,this.inputElement.value=this.calendar.name,this.clickableElement.classList.add("ng-hide"),this.inputContainer.classList.remove("ng-hide"),e.srcEvent&&"touchend"==e.srcEvent.type?n(function(){h.inputElement.focus(),h.inputElement.select()},200):(this.inputElement.select(),this.inputElement.focus()),this.panel&&this.panel.close()},this.saveFolder=function(e){this.inputElement.disabled||(0===this.inputElement.value.length&&this.revertEditing(),this.calendar.name=this.inputElement.value,this.inputElement.disabled=!0,this.calendar.$rename().then(function(e){h.editMode=!1,h.inputContainer.classList.add("ng-hide"),h.clickableElement.classList.remove("ng-hide"),h.updateCalendarName()},function(){h.editMode=!0,h.inputElement.value=h.calendar.name,n(function(){h.inputElement.focus(),h.inputElement.select()},200)}).finally(function(){h.inputElement.disabled=!1}))},this.revertEditing=function(){this.editMode=!1,this.clickableElement.classList.remove("ng-hide"),this.inputContainer.classList.add("ng-hide"),this.inputElement.value=this.calendar.name},this.confirmDelete=function(){this.calendar.isSubscription?this.calendar.$delete().catch(function(e,t){d.alert(l('An error occured while deleting the calendar "%{0}".',h.calendar.name),l(e.error))}):d.confirm(l("Warning"),l('Are you sure you want to delete the calendar "%{0}"?',this.calendar.name),{ok:l("Delete")}).then(function(){h.calendar.$delete().catch(function(e,t){d.alert(l('An error occured while deleting the calendar "%{0}".',h.calendar.name),l(e.error))})})},this.showMenu=function(o){var e=i.newPanelPosition().relativeTo(this.moreOptionsButton).addPanelPosition(i.xPosition.ALIGN_START,i.yPosition.ALIGN_TOPS),t=i.newPanelAnimation().openFrom(this.moreOptionsButton).duration(100).withAnimation(i.animation.FADE),t={attachTo:angular.element(document.body),locals:{itemCtrl:this,calendar:this.calendar,editFolder:angular.bind(this,this.editFolder),confirmDelete:angular.bind(this,this.confirmDelete)},bindToController:!0,controller:n,controllerAs:"$menuCtrl",position:e,animation:t,targetEvent:o,templateUrl:"UIxCalendarMenu",trapFocus:!0,clickOutsideToClose:!0,escapeToClose:!0,focusOnOpen:!0};function n(e,n,i,t){var a=this;this.showOnly=function(){_.forEach(u.$findAll(),function(e){a.calendar.id==e.id?e.active=1:e.active=0})},this.showAll=function(){_.forEach(u.$findAll(),function(e){e.active=1})},this.showProperties=function(){var e=this.calendar.color;function t(e,t,n){var i=this;i.calendar=new u(n.$omit()),i.saveProperties=function(e){e.$valid&&i.calendar.$save().then(function(){n.init(i.calendar.$omit()),t.hide()},function(){e.$setPristine()})},i.close=function(){t.cancel()},e.$watch(function(){return i.calendar.color},function(){n.color=i.calendar.color})}n.show({templateUrl:this.calendar.id+"/properties",controller:t,controllerAs:"properties",clickOutsideToClose:!0,escapeToClose:!0,locals:{srcCalendar:this.calendar}}).catch(function(){a.calendar.color=e}),t.$inject=["$scope","$mdDialog","srcCalendar"]},this.showLinks=function(){function e(e,t){this.calendar=t,this.close=function(){e.hide()}}n.show({parent:angular.element(document.body),clickOutsideToClose:!0,escapeToClose:!0,templateUrl:this.calendar.id+"/links",controller:e,controllerAs:"links",locals:{calendar:this.calendar}}),e.$inject=["$mdDialog","calendar"]},this.importCalendar=function(){function e(e,o,t){function n(e){e=0===e.type.indexOf("text")||/\.(ics)$/.test(e.name);return e||s.show({template:["<md-toast>",' <div class="md-toast-content">',' <md-icon class="md-warn md-hue-1">error_outline</md-icon>'," <span>"+l("Select an iCalendar file (.ics).")+"</span>"," </div>","</md-toast>"].join(""),position:"top right",hideDelay:3e3}),e}this.uploader=new i({url:ApplicationBaseURL+[t.id,"import"].join("/"),autoUpload:!0,queueLimit:1,filters:[{name:n,fn:n}],onSuccessItem:function(e,t,n,i){var a;o.hide(),0===t.imported?a=l("No event was imported."):(a=l("A total of %{0} events were imported in the calendar.",t.imported),r.$emit("calendars:list")),s.show(s.simple().textContent(a).position("top right").hideDelay(3e3))},onErrorItem:function(e,t,n,i){s.show({template:["<md-toast>",' <div class="md-toast-content">',' <md-icon class="md-warn md-hue-1">error_outline</md-icon>'," <span>"+l("An error occurred while importing calendar.")+"</span>"," </div>","</md-toast>"].join(""),position:"top right",hideDelay:3e3})}}),this.close=function(){o.hide()}}n.show({parent:angular.element(document.body),targetEvent:o,clickOutsideToClose:!0,escapeToClose:!0,templateUrl:"UIxCalendarImportDialog",controller:e,controllerAs:"$CalendarImportDialogController",locals:{folder:this.calendar}}),e.$inject=["scope","$mdDialog","folder"]},this.share=function(){this.calendar.$acl.$users().then(function(){n.show({templateUrl:a.calendar.id+"/UIxAclEditor",controller:"AclController",controllerAs:"acl",clickOutsideToClose:!0,escapeToClose:!0,locals:{usersWithACL:a.calendar.$acl.users,User:t,folder:a.calendar}})})}}i.open(t).then(function(e){(h.panel=e).panelEl.one("click",function(){e.close()})}),n.$inject=["mdPanelRef","$mdDialog","FileUploader","User"]}}e.$inject=["$rootScope","$scope","$element","$timeout","$mdToast","$mdPanel","$mdMedia","$mdSidenav","sgConstant","Dialog","Calendar"],angular.module("SOGo.SchedulerUI").controller("sgCalendarListItemController",e).directive("sgCalendarListItem",function(){return{restrict:"C",scope:{},bindToController:{calendar:"=sgCalendar"},template:['<md-switch ng-model="$ctrl.calendar.active"'," ng-class=\"$ctrl.calendar.getClassName('md-switch')\"",' ng-true-value="1"',' ng-false-value="0"',' aria-label="'+l("Enable")+'"></md-switch>','<p class="sg-item-name"',' ng-dblclick="$ctrl.editFolder($event)">',' <span ng-bind="$ctrl.calendar.name"></span>',' <md-icon ng-if="$ctrl.calendar.$error" class="md-warn">error</md-icon>',' <md-tooltip md-delay="1000"',' md-autohide="true"',' ng-bind="$ctrl.calendar.name"></md-tooltip>',' <span class="sg-counter-badge ng-hide"',' ng-show="calendar.activeTasks"',' ng-bind="calendar.activeTasks"></span>',"</p>",'<md-input-container class="md-flex ng-hide">',' <input class="sg-item-name" type="text"',' aria-label="'+l("Name of the Calendar")+'"',' ng-blur="$ctrl.saveFolder($event)"',' sg-enter="$ctrl.saveFolder($event)"',' sg-escape="$ctrl.revertEditing()" />',"</md-input-container>",'<md-icon class="md-menu md-secondary-container"',' as-sortable-item-handle="as-sortable-item-handle"'," md-colors=\"::{color: 'accent-400'}\">drag_handle</md-icon>",'<md-icon class="md-menu md-secondary-container sg-list-sortable-hide"',' ng-click="$ctrl.showMenu($event)"',' aria-label="'+l("Options")+'">more_vert</md-icon>'].join(""),controller:"sgCalendarListItemController",controllerAs:"$ctrl"}})}(),function(){"use strict";angular.module("SOGo.SchedulerUI").directive("sgCalendarMonthDay",function(){return{restrict:"E",scope:{blocks:"=sgBlocks",day:"@sgDay",clickBlock:"&sgClick"},template:["<sg-calendar-month-event",' class="sg-draggable-calendar-block"',' ng-repeat="block in blocks[day]"',' sg-block="block"',' sg-click="clickBlock({event: clickEvent, component: clickComponent})"/>'].join("")}})}(),function(){"use strict";angular.module("SOGo.SchedulerUI").directive("sgCalendarMonthEvent",function(){return{restrict:"E",scope:{block:"=sgBlock",clickBlock:"&sgClick"},replace:!0,template:function(e,t){t=_.has(t,"sgCalendarGhost")?"":"::";return['<div class="sg-event"'," ng-class=\"{'sg-event--dragging': block.dragging}\"",' ng-click="clickBlock({clickEvent: $event, clickComponent: block.component})">',' <div class="sg-category" ng-repeat="category in '+t+'block.component.categories"',' ng-class="'+t+"('bg-category' + category)\"",' ng-style="'+t+"{ right: ($index * 10) + '%' }\"></div>",' <div class="text">',' <span class="secondary" ng-if="'+t+'(!block.component.c_isallday && block.isFirst)">{{ '+t+"block.component.startHour }}</span>",' <span ng-show="'+t+'block.component.c_priority" class="sg-priority">{{'+t+"block.component.c_priority}}</span>"," {{ "+t+"block.component.summary }}",' <span class="sg-icons">',' <md-icon ng-if="'+t+'block.component.occurrenceId">repeat</md-icon>',' <md-icon ng-if="'+t+'block.component.c_nextalarm">alarm</md-icon>',' <md-icon ng-if="'+t+'block.component.c_classification == 2">visibility_off</md-icon>',' <md-icon ng-if="'+t+'block.component.c_classification == 1">vpn_key</md-icon>'," </span>"," </div>","</div>"].join("")},link:function(e,t,n){_.has(n,"sgCalendarGhost")||(e.block.userState&&t.addClass("sg-event--"+e.block.userState),e.block.component&&(t.addClass("bg-folder"+e.block.component.pid),0===e.block.component.c_isopaque&&t.addClass("sg-event--transparent"),0===e.block.component.c_status&&t.addClass("sg-event--cancelled")))}}})}(),function(){"use strict";function e(e,n){var t=this,i={portrait:{letter:[8.5,11,"in"],legal:[8.5,14,"in"],a4:[210,297,"mm"]},landscape:{letter:[11,8.5,"in"],legal:[14,8.5,"in"],a4:[297,210,"mm"]}},a={letter:[.4,2.1],legal:[.4,2.1],a4:[10,30]};this.$onInit=function(){e.$watchGroup([function(){return t.pageSize},function(){return t.workingHoursOnly}],angular.bind(this,function(){var e,t=i[this.orientation][this.pageSize];this.units=t[2],this.pageMargin=a[this.pageSize][0]+this.units,this.viewportHeight=(t[1]-2*a[this.pageSize][0]).toString()+this.units,this.hideHoursStart=0,this.hideHoursEnd=24,this.totalHours=24,this.clipTop=0,"month"===this.calendarView?this.viewHeight=(t[1]-3*a[this.pageSize][0]).toString()+this.units:(this.workingHoursOnly&&(n.defaults.SOGoDayEndTime&&(e=n.defaults.SOGoDayEndTime.split(":"),this.hideHoursEnd=parseInt(e[0]),this.totalHours=this.hideHoursEnd),n.defaults.SOGoDayStartTime&&(e=n.defaults.SOGoDayStartTime.split(":"),this.hideHoursStart=parseInt(e[0]),this.totalHours-=this.hideHoursStart)),this.hourHeight=(t[1]-2*a[this.pageSize][0]-a[this.pageSize][1])/this.totalHours,this.clipTop=(this.hourHeight*this.hideHoursStart).toString()+this.units,this.viewHeight=(this.hideHoursEnd*this.hourHeight).toString()+this.units)}))},this.eventsPositions=function(){var e,t=0,n=[];if("month"===this.calendarView)n.push("[ui-view=calendars] .monthView md-grid-list { min-height: "+this.viewHeight+"; }");else for(;t<=96;)t<=4*this.hideHoursStart&&(e=4*this.hideHoursStart-t,n.push("[ui-view=calendars] .sg-event.starts"+t+" .text { margin-top: "+this.hourHeight/4*e+this.units+"; }")),n.push("[ui-view=calendars] .sg-event.starts"+t+" { top: "+this.hourHeight/4*t+this.units+"; }"),n.push("[ui-view=calendars] .sg-event.lasts"+t+" { height: "+this.hourHeight/4*t+this.units+"; }"),t++;return n.join("\n")}}e.$inject=["$scope","Preferences"],angular.module("SOGo.SchedulerUI").directive("sgCalendarPrintStylesheet",function(){return{restrict:"E",scope:{calendarView:"<sgCalendarView",pageSize:"<sgPageSize",orientation:"<sgOrientation",workingHoursOnly:"<sgWorkingHoursOnly"},replace:!0,bindToController:!0,controller:e,controllerAs:"$ctrl",template:['<style type="text/css">'," @page {"," size: {{ $ctrl.pageSize }} {{ $ctrl.orientation }};"," margin: 0;"," }"," @media print {"," body {"," padding: {{ $ctrl.pageMargin }};"," }"," [ui-view=calendars] .view-list {"," height: {{ $ctrl.viewportHeight }};"," overflow: hidden;"," }"," [ui-view=calendars] .calendarView {"," transform: translateY(-{{ $ctrl.clipTop }});"," height: {{ $ctrl.viewHeight }};"," position: relative;"," overflow: hidden;"," }"," [ui-view=calendars] .allDaysView {"," max-height: {{ $ctrl.hourHeight }}{{ $ctrl.units }} !important;"," }"," [ui-view=calendars] .hours .hour,"," [ui-view=calendars] .days .day .clickableHourCell {"," min-height: {{ $ctrl.hourHeight }}{{ $ctrl.units }};"," max-height: {{ $ctrl.hourHeight }}{{ $ctrl.units }};"," }"," {{ $ctrl.eventsPositions() }}"," }","</style>"].join("\n")}})}(),function(){"use strict";function e(c,l,e,t,d,n,u,h,p){return{restrict:"A",scope:{type:"@sgCalendarScrollView"},controller:i,link:function(e,n,t,i){var a,o,r;function s(e,t){this.$element=e,this.element=e[0],this.type=t,this.quarterHeight=this.getQuarterHeight(),this.scrollStep=6*this.quarterHeight,this.dayNumbers=this.getDayNumbers(),this.maxX=this.getMaxColumns(),this.deregisterDragStart=c.$on("calendar:dragstart",angular.bind(this,this.onDragStart)),this.deregisterDragStop=c.$on("calendar:dragend",angular.bind(this,this.onDragEnd)),this.bindedUpdateCoordinates=angular.bind(this,this.updateCoordinates),this.bindedUpdateFromPointerHandler=angular.bind(this,this.updateFromPointerHandler),this.updateCoordinates(),angular.element(l).on("resize",this.bindedUpdateCoordinates)}a=null,o=e.type,r="multicolumndayview"==n.attr("sg-view"),i.isMultiColumn=r,d(function(){var e,t;a=new s(n,o),"monthly"==o||p.defaults.SOGoDayStartTime&&(t=p.defaults.SOGoDayStartTime.split(":"),e=document.getElementById("hour"+parseInt(t[0])),t=parseInt(t[1])*a.quarterHeight,a.element.scrollTop=e.offsetTop+t);i.quarterHeight=a.quarterHeight}),e.$on("$destroy",function(){a&&a.$destroy()}),s.prototype={$destroy:function(){this.deregisterDragStart(),this.deregisterDragStop(),this.$element.off("mousemove",this.bindedUpdateFromPointerHandler),angular.element(l).off("resize",this.bindedUpdateCoordinates)},onDragStart:function(){this.$element.on("mousemove",this.bindedUpdateFromPointerHandler),this.updateCoordinates(),this.updateFromPointerHandler()},onDragEnd:function(){this.$element.off("mousemove",this.bindedUpdateFromPointerHandler),u.$view=null},getQuarterHeight:function(){var e=null,t=document.getElementById("hour0"),n=document.getElementById("hour23");return e=t&&n?(n.offsetTop-t.offsetTop)/92:e},getDayDimensions:function(e){var t,n,i,a,o=t=n=i=0,r=this.element.getElementsByClassName("day");return 0<r.length&&(o=(a=r[0].getBoundingClientRect()).height,t=a.width,n=a.left-e,0<(r=r[0].getElementsByClassName("sg-calendar-tile-header")).length&&(i=r[0].clientHeight)),{height:o,width:t,offset:{left:n,top:i}}},getDayNumbers:function(){var e=this.element.getElementsByTagName("sg-calendar-day");return _.map(e,function(e,t){return r?t:parseInt(e.attributes["sg-day-number"].value)})},getMaxColumns:function(){var e;return"monthly"==this.type?(e=this.element.getElementsByTagName("md-grid-list")[0],parseInt(e.attributes["md-cols"].value)-1):this.element.getElementsByClassName("day").length-1},updateCoordinates:function(){var e=this.element.getBoundingClientRect(),t=this.getDayDimensions(e.left);angular.extend(this,{coordinates:{x:e.left,y:e.top},dayHeight:t.height,dayWidth:t.width,daysOffset:t.offset.left,topOffset:t.offset.top})},updateFromPointerHandler:function(){var e,t,n=h.$ghost.pointerHandler;this.coordinates&&n&&(e=n.getContainerBasedCoordinates(this))&&(u.$view=this,t=(new Date).getTime(),(!this.lastScroll||t>this.lastScroll+100)&&(this.lastScroll=t,(n=e.y-this.scrollStep)<0?(t=-this.element.scrollTop,this.element.scrollTop+=n=n<t?t:n):0<(n=(n=e.y+this.scrollStep)-this.element.clientHeight)&&(this.element.scrollTop+=n)))}}}}}function i(e){this.type=e.type}e.$inject=["$rootScope","$window","$document","$q","$timeout","$mdGesture","Calendar","Component","Preferences"],i.$inject=["$scope"],angular.module("SOGo.SchedulerUI").directive("sgCalendarScrollView",e)}(),function(){"use strict";angular.module("SOGo.SchedulerUI").directive("sgCategoryStylesheet",function(){return{restrict:"E",require:"ngModel",scope:{ngModel:"="},replace:!0,template:['<style type="text/css">'," .bg-category{{ ngModel.id }} {"," background-color: {{ ngModel.color }} !important;"," }"," .bdr-category{{ ngModel.id }} {"," border-color: {{ ngModel.color }} !important;"," }","</style>"].join("")}})}(),function(){"use strict";function e(u,h,p,m,f,g,y){return{restrict:"CA",require:"^sgCalendarDay",link:function(o,r,e,s){if(o.block){if(!o.block.component.editable||o.block.userState)return void r.removeClass("sg-draggable-calendar-block");!function(){var e,t,n,i,a;o.block.length<3||(e=o.block.component,t=o.block.dayIndex,a=_.findIndex(e.blocks,["dayIndex",t]),i=0===a,t=a===e.blocks.length-1,(a=angular.element('<div class="dragGrip"></div>')).addClass("bdr-folder"+e.pid),e.c_isallday||"SG-CALENDAR-MONTH-DAY"===r[0].parentNode.tagName?(i&&(n=angular.element('<div class="dragGrip-left"></div>').append(a),r.append(n)),t&&(n=angular.element('<div class="dragGrip-right"></div>').append(a.clone()),r.append(n))):(i&&(i=angular.element('<div class="dragGrip-top"></div>').append(a),r.append(i)),t&&(a=angular.element('<div class="dragGrip-bottom"></div>').append(a.clone()),r.append(a))))}()}function t(e){var t;e.stopPropagation(),e.target.scrollHeight>e.target.clientHeight+1&&(t=(t=e.target.getBoundingClientRect()).left+t.width-18,e.pageX>t)||(t="move-event",o.block&&o.block.component?"dragGrip-top"==e.target.className||"dragGrip-left"==e.target.className?t="change-start":"dragGrip-bottom"!=e.target.className&&"dragGrip-right"!=e.target.className||(t="change-end"):t="change-end",(t=new d(t)).initFromEvent(e),y.$ghost.pointerHandler=t,angular.element(document).one("mouseup",n),angular.element(document).on("mousemove",i))}function i(e){var t=y.$ghost.pointerHandler;h(function(){t.updateFromEvent(e)})}function n(e){var t=o.block,n=y.$ghost.pointerHandler;angular.element(document).off("mousemove",i),n.dragHasStarted&&(u.$emit("calendar:dragend"),n.dragHasStarted=!1),t&&t.component&&_.forEach(t.component.blocks,function(e){e.dragging=!1})}function c(){}function a(e){this.setEventType(e)}function d(e){this.dragMode=e}r.on("mousedown",t),o.$on("$destroy",function(){r.off("mousedown",t),r.off("mousemove",i)}),c.prototype={x:-1,y:-1,getDelta:function(e){var t=new c;return t.x=this.x-e.x,t.y=this.y-e.y,f.$view&&(t.days=f.$view.dayNumbers[this.x]-f.$view.dayNumbers[e.x]),t},getDistance:function(e){e=this.getDelta(e);return Math.sqrt(e.x*e.x+e.y*e.y)},clone:function(){var e=new c;return e.x=this.x,e.y=this.y,e}},a.prototype={dayNumber:-1,weekDay:-1,start:-1,duration:-1,eventType:null,setEventType:function(e){this.eventType=e},initFromBlock:function(e){var i=-1;"monthly"===this.eventType?(this.start=0,this.duration=e.component.blocks.length*g.EventDragDayLength):(this.start=e.component.blocks[0].start,this.duration=_.sumBy(e.component.blocks,function(e){var t=e.dayNumber,n=i<0?0:t-i-1;return i=t,e.length+n*g.EventDragDayLength}))},initFromCalendar:function(e){this.dayNumber=e},getDelta:function(e){var t=new a;return t.dayNumber=this.dayNumber-e.dayNumber,t.start=this.start-e.start,t.duration=this.duration-e.duration,t},_quartersToHM:function(e){var t=15*e,e=Math.floor(t/60),t=t%60;return(e=e<10?"0"+e:e)+":"+(t=t<10?"0"+t:t)},getStartTime:function(){return this._quartersToHM(this.start)},getEndTime:function(){var e=(this.start+this.duration)%g.EventDragDayLength;return this._quartersToHM(e)},clone:function(){var e=new a;return e.dayNumber=this.dayNumber,e.start=this.start,e.duration=this.duration,e}},d.prototype={originalCoordinates:null,currentCoordinates:null,originalViewCoordinates:null,currentViewCoordinates:null,originalEventCoordinates:null,currentEventCoordinates:null,originalCalendar:null,dragHasStarted:!1,getEventViewCoordinates:null,initFromBlock:function(e){this.currentEventCoordinates=new a(this.eventType),this.originalEventCoordinates=new a(this.eventType),this.originalEventCoordinates.initFromBlock(e)},initFromEvent:function(e){this.currentCoordinates=new c,this.updateFromEvent(e),this.originalCoordinates=this.currentCoordinates.clone()},initFromCalendar:function(e){this.originalCalendar=e,this.currentEventCoordinates.initFromCalendar(e.index),this.originalEventCoordinates.initFromCalendar(e.index)},updateFromEvent:function(e){var t,n,i,a;this.currentCoordinates.x=e.pageX,this.currentCoordinates.y=e.pageY,this.dragHasStarted&&f.$view?(a=this.getEventViewCoordinates(f.$view),this.originalViewCoordinates||(this.originalViewCoordinates=this.getEventViewCoordinates(f.$view,this.originalCoordinates),y.$ghost.component.isNew&&(this.setTimeFromQuarters(y.$ghost.component.start,this.originalViewCoordinates.y),p.debug("new event start date "+y.$ghost.component.start))),this.currentViewCoordinates&&a&&a.x==this.currentViewCoordinates.x&&a.y==this.currentViewCoordinates.y||(this.currentViewCoordinates=a,this.originalViewCoordinates&&(a||(this.currentViewCoordinates=this.originalViewCoordinates.clone()),this.updateEventCoordinates()))):this.originalCoordinates&&this.currentCoordinates&&!this.dragHasStarted&&3<this.getDistance()&&(this.dragHasStarted=!0,i=r.hasClass("clickableHourCell"),e="SG-CALENDAR-MONTH-DAY"==r[0].parentNode.tagName||r.hasClass("clickableDayCell"),a=s.calendarData(),o.block&&o.block.component?t=o.block:(n=s.dayString.parseDate(m.$mdDateLocaleProvider,"%Y-%m-%e"),n={type:"appointment",pid:a?a.pid:f.$defaultCalendar(),summary:l("New Event"),startDate:n,isAllDay:i?0:1},(t={component:new y(n),dayNumber:s.dayNumber,length:0}).component.blocks=[t]),n="multiday",e?n="monthly":t.component.c_isallday&&(n="multiday-allday"),_.forEach(t.component.blocks,function(e){e.dragging=!0}),(e=y.$ghost.pointerHandler).prepareWithEventType(n),e.initFromBlock(t),a&&e.initFromCalendar(a),y.$ghost.component=t.component,p.debug("emit calendar:dragstart "+n),u.$emit("calendar:dragstart"))},updateEventCoordinates:function(){var e,t,n=this.currentViewCoordinates.getDelta(this.originalViewCoordinates),n=n.days*g.EventDragDayLength+n.y;p.debug("quarters delta "+n),angular.isUndefined(this.originalEventCoordinates.start)?(this.originalEventCoordinates.dayNumber=f.$view.dayNumbers[this.originalViewCoordinates.x],this.originalEventCoordinates.start=this.originalViewCoordinates.y):this.originalEventCoordinates.dayNumber<0&&(this.originalEventCoordinates.dayNumber=f.$view.dayNumbers[o.block.component.blocks[0].dayIndex]),this.currentEventCoordinates.dayNumber=this.originalEventCoordinates.dayNumber,"move-event"==this.dragMode?(this.currentEventCoordinates.start=this.originalEventCoordinates.start+n,this.currentEventCoordinates.duration=this.originalEventCoordinates.duration):"change-start"==this.dragMode?0<(e=this.originalEventCoordinates.duration-n)?(this.currentEventCoordinates.start=this.originalEventCoordinates.start+n,this.currentEventCoordinates.duration=e):e<0&&(this.currentEventCoordinates.start=this.originalEventCoordinates.start+this.originalEventCoordinates.duration,this.currentEventCoordinates.duration=-e):"change-end"==this.dragMode&&(0<(e=this.originalEventCoordinates.duration+n)?(this.currentEventCoordinates.start=this.originalEventCoordinates.start,this.currentEventCoordinates.duration=e):e<0&&(this.currentEventCoordinates.start=this.originalEventCoordinates.start+e,this.currentEventCoordinates.duration=-e)),this.currentEventCoordinates.start<0?(t=Math.ceil(-this.currentEventCoordinates.start/g.EventDragDayLength),this.currentEventCoordinates.start+=t*g.EventDragDayLength,this.currentEventCoordinates.dayNumber-=t):this.currentEventCoordinates.start>=g.EventDragDayLength&&(t=Math.floor(this.currentEventCoordinates.start/g.EventDragDayLength),this.currentEventCoordinates.start-=t*g.EventDragDayLength,this.currentEventCoordinates.dayNumber+=t),p.debug("event coordinates "+JSON.stringify(this.currentEventCoordinates)),u.$emit("calendar:drag")},getContainerBasedCoordinates:function(e,t){var n=(t||this.currentCoordinates).getDelta(e.coordinates),t=e.element;return n=n.x<e.daysOffset||n.x>t.clientWidth||n.y<0||n.y>t.clientHeight?null:n},prepareWithEventType:function(e){var t={multiday:this.getEventMultiDayViewCoordinates,"multiday-allday":this.getEventMultiDayAllDayViewCoordinates,monthly:this.getEventMonthlyViewCoordinates,unknown:null}[e];this.eventType=e,this.getEventViewCoordinates=t},getEventMultiDayViewCoordinates:function(e,t){var n,i=this.getEventMultiDayAllDayViewCoordinates(e,t);return i&&(n=e.quarterHeight,(t=this.getContainerBasedCoordinates(e,t)).y+=e.element.scrollTop,i.y=Math.floor((t.y-g.EventDragHorizontalOffset)/n),n=g.EventDragDayLength-1,i.y<0?i.y=0:i.y>n&&(i.y=n)),i},getEventMultiDayAllDayViewCoordinates:function(e,t){var n,i=this.getContainerBasedCoordinates(e,t);return i?(n=new c,t=e.dayWidth,e=e.daysOffset,n.x=Math.floor((i.x-e)/t),i=0,e=f.$view.maxX,"move-event"==this.dragMode||(t=s.calendarData())&&(i=e=t.index),n.x<i?n.x=i:n.x>e&&(n.x=e),n.y=0):n=null,n},getEventMonthlyViewCoordinates:function(e,t){var n,i,a,o=this.getContainerBasedCoordinates(e,t);return o?(n=new c,i=e.maxX,a=e.dayWidth,t=e.daysOffset,e=e.dayHeight,(e=Math.floor(+o.y/e))<0&&(e=0),n.x=Math.floor((o.x-t)/a),n.x<0?n.x=0:n.x>i&&(n.x=i),n.x+=(i+1)*e,n.y=0):n=null,n},getDistance:function(){return this.currentCoordinates.getDistance(this.originalCoordinates)},setTimeFromQuarters:function(e,t){var n=Math.floor(t/4);e.setHours(n,t%4*15)}}}}}e.$inject=["$rootScope","$timeout","$log","Preferences","Calendar","CalendarSettings","Component"],angular.module("SOGo.SchedulerUI").directive("sgDraggableCalendarBlock",e)}(),function(){function e(e,t,n){var i=this;this.$onInit=function(){e.$watch(function(){return i.component?{start:i.component.start,end:i.component.end,attendees:_.keys(i.component.$attendees.$futureFreebusyData)}:null},function(e,t){e&&e.attendees&&e.attendees.length&&n.all(_.values(i.component.$attendees.$futureFreebusyData)).then(function(){i.onUpdate()})},!0)},this.onUpdate=function(){}}e.$inject=["$scope","$element","$q"],angular.module("SOGo.SchedulerUI").directive("sgFreebusy",function(){return{restrict:"C",scope:{},bindToController:{component:"=sgComponent"},controller:e}})}(),function(){function e(e,t){var c=this;this.$postLink=function(){var a,o=[],r=[],s=[];this.parentController=e.parentController,a=this.parentController.onUpdate,_.forEach(t.find("div"),function(e){e.className.startsWith("hour")?o.push(e):e.className.startsWith("quarter")?r.push(e):e.className.startsWith("busy")&&s.push(e)}),this.parentController.onUpdate=function(){var e=c.attendee.uid?c.attendee.freebusy[c.day]:null;c.attendee.uid||_.forEach(o,function(e){e.classList.add("sg-no-freebusy")});for(var t=0;t<24;t++)for(var n=0;n<4;n++){var i=4*t+n;c.coversFreebusy(t,n)?r[i].classList.add("event"):r[i].classList.remove("event"),e&&e[t][n]?s[i].classList.remove("ng-hide"):s[i].classList.add("ng-hide")}angular.bind(c.parentController,a)()}},this.coversFreebusy=function(e,t){return c.attendees.coversFreeBusy(c.day,e,t)}}e.$inject=["$scope","$element"],angular.module("SOGo.SchedulerUI").directive("sgFreebusyDay",function(){return{restrict:"E",require:"^^sgFreebusy",bindToController:{day:"=sgDay",attendees:"=sgAttendees",attendee:"=sgAttendee"},replace:!0,template:function(e,t){for(var n=["<md-list-item>"],i=0;i<24;i++){n.push(' <div class="hour">');for(var a=0;a<4;a++)n.push(' <div class="quarter">'),n.push(' <div class="busy ng-hide"></div>'),n.push(" </div>");n.push(" </div>")}return n.push(" <md-divider>\x3c!-- divider --\x3e</md-divider>"),n.push("</md-list-item>"),n.join("")},link:function(e,t,n,i){e.parentController=i},controller:e,controllerAs:"$ctrl"}})}(),function(){"use strict";function e(r,s,c){var l,d=this,u=s.controller("sgCalendarScrollView");r.nowDay=null,r.lineElement=null,r.updateLine=function(e){var t=new Date,n=t.getDayString(),i=t.getHours(),a=4*r.quarterHeight,o=t.getMinutes(),t=r.quarterHeight/15,t=parseInt(i*a+o*t-1);!e&&n==r.nowDay||(r.lineElement&&r.lineElement.remove(),r.lineElement=function(t,e){var n=angular.element("<sg-now-line>");u.isMultiColumn?e&&e[0].attributes["sg-day"].value==t&&s.append(n):_.forEach(e,function(e){e.attributes["sg-day"].value==t&&angular.element(e).find("div").eq(0).append(n)});return n}(n,r.days),r.nowDay=n);r.lineElement&&(r.lineElement.css("top",t+"px"),l=c(angular.bind(d,r.updateLine),6e4))},r.$on("$destroy",function(){l&&c.cancel(l)})}e.$inject=["$scope","$element","$timeout"],angular.module("SOGo.SchedulerUI").directive("sgNowLine",function(){return{restrict:"C",require:"^^sgCalendarScrollView",link:function(n,e,t,i){function a(){return e.find("sg-calendar-day")}var o=n.$watch(function(){return i.quarterHeight},function(e){var t;e&&(o(),n.quarterHeight=e,t=n.$watch(a,function(e){e.length&&(t(),n.days=e,n.updateLine())}))})},controller:e}})}();
//# sourceMappingURL=Scheduler.services.js.map