sogo/UI/WebServerResources/js/Common.js.map

1 line
216 KiB
Plaintext

{"version":3,"sources":["Common/utils.js","Common/Common.app.js","Common/mdColors.app.js","Common/decodeUri.filter.js","Common/encodeUri.filter.js","Common/ensureTarget.filter.js","Common/loc.filter.js","Common/range.filter.js","Common/AclController.js","Common/navController.js","Common/Acl.service.js","Common/Alarm.service.js","Common/Authentication.service.js","Common/Dialog.service.js","Common/Gravatar.service.js","Common/Resource.service.js","Common/sgFocus.service.js","Common/User.service.js","Common/sgAvatarImage.directive.js","Common/sgCheckmark.directive.js","Common/sgColorPicker.directive.js","Common/sgCompile.directive.js","Common/sgEnter.directive.js","Common/sgEscape.directive.js","Common/sgFocus.directive.js","Common/sgFolderStylesheet.directive.js","Common/sgPlaceholder.directive.js","Common/sgSearch.directive.js","Common/sgSelectOnly.directive.js","Common/sgSubscribe.directive.js","Common/sgTimepicker.directive.js","Common/sgToggleGrid.directive.js","Common/sgTransformOnBlur.directive.js"],"names":["l","i","j","key","arguments","value","args","labels","clabels","length","replace","m","val","parseFloat","isNaN","hexToRgb","hex","result","exec","r","parseInt","g","b","contrast","color","c","Math","pow","guid","S4","random","toString","substring","substr","toLowerCase","configure","$logProvider","$compileProvider","$httpProvider","$mdThemingProvider","definePalette","50","100","200","300","400","500","600","700","800","900","A100","A200","A400","A700","contrastDefaultColor","contrastLightColors","contrastDarkColors","1000","theme","primaryPalette","default","hue-1","hue-2","hue-3","accentPalette","backgroundPalette","DebugEnabled","debugEnabled","debugInfoEnabled","interceptors","push","AuthInterceptor","$window","$q","response","test","config","headers","Accept","data","location","reload","reject","ErrorInterceptor","$rootScope","responseError","rejection","$broadcast","angular","module","isPopup","document","body","classList","contains","baseURL","ApplicationBaseURL","activeUser","param","settings","login","UserLogin","identification","UserIdentification","email","UserEmail","language","UserLanguage","folderURL","UserFolderURL","isSuperUser","IsSuperUser","path","calendar","UserCalendarPath","contacts","UserContactsPath","mail","UserMailPath","preferences","UserPreferencesPath","administration","UserAdministrationPath","help","HelpURL","logoff","UserLogoffPath","constant","selection","xs","gt-xs","sm","gt-sm","md","gt-md","lg","gt-lg","xl","print","factory","$inject","_$mdThemingProvider","runBlock","$interpolate","$document","$log","buildCssSelectors","selectors","join","addRule","fgInterpolate","bgInterpolate","themeName","paletteName","colorArray","hueName","colorValue","colorContrast","context","palette","hue","customSheet","insertRule","index","addBorderRule","bdrInterpolate","getStyleSheet","style","head","querySelector","createElement","title","appendChild","createTextNode","sheet","fgDefault","bgDefault","bdrDefault","fgDefaultHue","bgDefaultHue","fgColor","bgColor","bdrColor","fgHue","bgHue","cssRules","deleteRule","forEach","_THEMES","_PALETTES","colors","primary","name","hues","run","decodeUri","decodeURIComponent","filter","encodeUri","encodeURIComponent","ensureTarget","$sce","element","tree","find","attr","trustAs","html","loc","range","n","res","AclController","$mdDialog","Dialog","usersWithACL","User","folder","userFilter","$query","$filter","$acl","users","closeModal","$resetUsersRights","hide","saveModal","$saveUsersRights","then","status","alert","confirmChange","user","confirmation","$confirmRights","vm","showing","message","removeUser","$removeUser","uid","addUser","$addUser","userToAdd","searchText","selectedUid","selectUser","error","selectedUser","$rights","this","controller","navController","$scope","$timeout","$interval","$http","$mdSidenav","$mdToast","$mdMedia","sgConstant","sgSettings","Alarm","leftIsClose","isOpen","onHttpError","event","isString","statusText","show","template","hideDelay","position","debug","currentDay","window","get","secondsBeforeTomorrow","toggleLeft","isGtMedium","triggerHandler","toggle","toggleRight","$watch","newVal","$on","getAlarms","Acl","folderId","Settings","Resource","extend","$$resource","$User","prototype","$users","owner","_this","deferred","defer","acls","isDefined","userResource","fetch","canSubscribeUser","isSubscribed","wasSubscribed","bind","resolve","promise","_","indexOf","map","userClass","isGroup","splice","$resetRights","deferredSave","deferredSubscribe","action","$rightsAreDirty","$omit","save","$shadowRights","copy","rights","uids","all","currentAlarm","AlarmService","$toast","now","Date","browserTime","floor","getTime","alarms","sort","a","x","y","next","pop","utc","url","alarmTime","delay","f","showAlarm","cancel","AlarmController","scope","reminder","ok","summary","locals","Authentication","redirectUrl","username","domain","userName","address","baseAddress","altBaseAddress","parts","hostpart","protocol","newAddress","href","split","startsWith","endsWith","getService","$cookies","passwordPolicyConfig","readLoginCookie","loginValues","cookie","base64decode","service","d","password","rememberLogin","loginSuffix","method","loginCookie","expire","grace","msg","perr","LDAPPasswordPolicyError","PolicyNoError","PolicyAccountLocked","changePassword","newPassword","xsrfCookie","remove","X-XSRF-TOKEN","PolicyPasswordModNotAllowed","PolicyInsufficientPasswordQuality","PolicyPasswordTooShort","PolicyPasswordTooYoung","PolicyPasswordInHistory","formatted","PolicyPasswordUnknown","PolicyPasswordSystemUnknown","put","$get","PolicyPasswordChangeUnsupported","PolicyPasswordExpired","PolicyChangeAfterReset","PolicyMustSupplyOldPassword","provider","DialogService","$modal","content","htmlContent","confirm","options","prompt","label","PromptDialogController","o","parent","clickOutsideToClose","escapeToClose","inputType","Gravatar","size","alternate_avatar","hash","s","md5","no_404","_http","_q","_path","_activeUser","$factory","compact","escape","params","flatten","newguid","create","post","id","newValue","download","getFileNameFromHeader","header","trim","type","accept","responseType","cache","transformResponse","fileName","blob","Blob","saveAs","Error","sgFocus","userData","init","$gravatar","search","excludedUsers","dry","when","results","compareUids","isUndefined","$$shortFormat","$shortFormat","$$image","image","c_email","$alternateAvatar","empty","fullname","cn","no_email","$isAnonymous","$isSpecial","$confirmation","some","values","constructor","isEqual","zero","keys","$folders","$$folders","folders","sgAvatarImage","restrict","bindToController","src","link","controllerAs","attrs","imgElement","mdIconElement","css","img","genericImg","sgAvatarImageController","$element","Preferences","getGravatar","defaults","SOGoAlternateAvatar","urlEmail","hideGenericAvatar","showGenericAvatar","addClass","removeClass","ready","old","SOGoGravatarEnabled","attributes","directive","sgCheckmarkDirective","$parse","$mdAria","$mdTheming","$mdUtil","compile","tElement","tAttrs","on","hasAttribute","stopImmediatePropagation","ngModelCtrl","parseConstantExpr","expression","fallback","parseFn","listener","ev","$apply","viewValue","$viewValue","trueValue","falseValue","$setViewValue","$render","render","CHECKED_CSS","sgTrueValue","sgFalseValue","fakeNgModel","expectWithText","transclude","require","sgColorPicker","iElement","iAttr","ngModelController","sgColor","sgIconColor","sgColorPickerController","sgColors","setColor","sgCompile","$compile","sgCompileLink","ensureCompileRunsOnce","$eval","contents","sgEnter","ENTER_KEY","which","preventDefault","sgEscape","ESCAPE_KEY","elem","keyCode","sgFocusOn","e","focus","select","sgFolderStylesheet","sgFolderStylesheetController","ngModel","sgPlaceholder","placeholder","sgSearchPreTransclude","tAttr","inputEl","selectEl","buttonEl","removeAttr","compiledButtonEl","formName","inputName","allowDot","doSearch","cancelSearch","priority","sgSearch","clone","append","sgSearchController","minLength","isNumber","minimumSearchLength","searchTextOptions","updateOn","debounce","blur","onChange","form","input","rawSearchText","$valid","$setValidity","searchField","sgSelectOnly","postLink","autoComplete","getInput","eq","selectedItem","$applyAsync","sgSubscribe","folderType","onFolderSelect","sgSubscribeDialogController","showDialog","templateUrl","sgSubscribeController","$setTouched","selectFolder","folderData","close","timePaneDirective","TimePaneCtrl","controllers","sgTimePaneCtrl","mdInputContainer","timePaneElement","configureNgModel","$attrs","$animate","$mdConstant","$$mdDateUtil","$mdDateLocale","$mdInkRipple","KEY_CODE","dateUtil","nextTimePaneUniqueId","selectedTime","displayTime","isInitialized","hours","displayName","selected","min5","min1","ii","show5min","getToggleBtnLbl","is5min","toggleManual5min","manual5min","tabindex","self","hourClickHandler","displayVal","updated","setHours","Number","setNgModelValue","minuteClickHandler","setMinutes","attachTimePaneEventListeners","SELECTED_TIME_CLASS","FOCUSED_TIME_CLASS","changeSelectedTime","date","previousSelectedTime","changeDisplayTime","prevH","getHours","prevHCell","getElementById","setAttribute","prevM","getMinutes","prevMCell","prevM5Cell","mCell","newH","hCell","add","newM","isValidDate","buildInitialTimePaneDisplay","today","handleKeyEvent","ESCAPE","TAB","$emit","ENTER","mode","changed","opt_date","previousFocus","timePickerDirective","TimePickerCtrl","mdTimePickerCtrl","$$rAF","dateLocale","inputElement","inputContainer","ngInputElement","timePane","timeButton","inputMask","isFocused","isDisabled","setDisabled","disabled","isTimeOpen","timePaneOpenedFrom","nextUid","bodyClickHandler","handleBodyClick","windowResizeHandler","closeTimePane","installPropertyInterceptors","attachChangeListeners","attachInteractionListeners","detachTimePane","EXTRA_INPUT_SIZE","INVALID_CLASS","DEFAULT_DEBOUNCE_INTERVAL","TIME_PANE_HEIGHT","MIN5","GTXS","XS","MIN1","TIME_PANE_WIDTH","time","formatTime","resizeInputElement","updateErrorState","handleInputEvent","keyCodes","altKey","DOWN_ARROW","openTimePane","$digest","ngDisabled","$parent","Object","defineProperty","set","clearErrorState","field","inputString","arr","h","isDate","attachTimePane","elementRect","getBoundingClientRect","bodyRect","paneTop","top","paneLeft","left","viewportTop","scrollTop","viewportLeft","scrollLeft","viewportBottom","innerHeight","viewportRight","innerWidth","paneWidth","scale","transform","min","paneHeight","width","enableScrolling","parentNode","removeChild","target","disableScrollAround","nextTick","addEventListener","removeEventListener","getTimePaneCtrl","focusTime","ctrl","setFocused","isInTime","getClosest","sgToggleGrid","flattenedDays","modelDays","sgToggleGridAttr","modelAttr","tiles","tile","includes","day","findIndex","$setDirty","toggleClass","sgTransformOnBlur","mdChipsCtrl","mouseUpActions","onInputBlur","appendFcn","inputHasFocus","chipBuffer","getChipBuffer","hasAutocomplete","requireMatch","appendChip","resetChipBuffer","String","suffix","pattern","lastIndexOf","_base64_keyStr","base64encode","chr1","chr2","chr3","enc1","enc2","enc3","enc4","output","utf8encode","charCodeAt","charAt","fromCharCode","L","k","K","G","I","F","H","q","p","u","aa","Z","D","t","Array","B","J","P","E","v","Y","X","W","V","C","S","Q","N","M","A","z","w","U","T","R","O","capitalize","toUpperCase","slice","asDate","newDate","newString","isValidEmail","emailRE","asCSSIdentifier","characters","escapeds","re","RegExp","timeInterval","interval","parseDate","localeProvider","format","string","formattingTokens","tokens","token","regexes","parsedInput","matchesCount","year","month","%d","%e","%m","%b","shortMonths","%B","months","%y","nearFuture","getFullYear","%Y","match","NaN","daysUpTo","otherDate","days","day1","day2","tmp","nbrDays","round","setTime","minutesTo","delta","dstOffset","valueOf","getTimezoneOffset","stringWithSeparator","separator","getMonth","getDate","getYear","str","addDays","initialDate","milliSeconds","addHours","nbrHours","addMinutes","nbrMinutes","beginOfDay","setSeconds","setMilliseconds","beginOfWeek","firstDayOfWeek","offset","getDay","endOfWeek","getDayString","getHourString","separators","max","validParts","%a","shortDays","%A","%H","%M","shift"],"mappings":"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","file":"Common.js","sourcesContent":["/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\nString.prototype.endsWith = function(suffix) {\n return this.indexOf(suffix, this.length - suffix.length) !== -1;\n};\n\nString.prototype.startsWith = function(pattern, position) {\n position = angular.isNumber(position) ? position : 0;\n return this.lastIndexOf(pattern, position) === position;\n};\n\nString.prototype._base64_keyStr = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\nString.prototype.base64encode = function () {\n var output = \"\";\n var chr1, chr2, chr3, enc1, enc2, enc3, enc4;\n var i = 0;\n \n var input = this.utf8encode();\n\n while (i < input.length) {\n chr1 = input.charCodeAt(i++);\n chr2 = input.charCodeAt(i++);\n chr3 = input.charCodeAt(i++);\n \n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n \n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n \n output = output +\n this._base64_keyStr.charAt(enc1) + this._base64_keyStr.charAt(enc2) +\n this._base64_keyStr.charAt(enc3) + this._base64_keyStr.charAt(enc4);\n }\n \n return output;\n};\n\nString.prototype.base64decode = function() { \n var output = \"\";\n var chr1, chr2, chr3;\n var enc1, enc2, enc3, enc4;\n var i = 0;\n \n var input = \"\" + this; // .replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\")\n while (i < input.length) {\n enc1 = this._base64_keyStr.indexOf(input.charAt(i++));\n enc2 = this._base64_keyStr.indexOf(input.charAt(i++));\n enc3 = this._base64_keyStr.indexOf(input.charAt(i++));\n enc4 = this._base64_keyStr.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n \n output = output + String.fromCharCode(chr1);\n \n if (enc3 != 64) {\n output = output + String.fromCharCode(chr2);\n }\n if (enc4 != 64) {\n output = output + String.fromCharCode(chr3);\n }\n }\n\n return output;\n};\n\nString.prototype.md5 = function() {\n if (!this.length) { return; }\n // MD5 (Message-Digest Algorithm) by WebToolkit\n var md5 = function(s){function L(k,d){return(k<<d)|(k>>>(32-d));}function K(G,k){var I,d,F,H,x;F=(G&2147483648);H=(k&2147483648);I=(G&1073741824);d=(k&1073741824);x=(G&1073741823)+(k&1073741823);if(I&d){return(x^2147483648^F^H);}if(I|d){if(x&1073741824){return(x^3221225472^F^H);}else{return(x^1073741824^F^H);}}else{return(x^F^H);}}function r(d,F,k){return(d&F)|((~d)&k);}function q(d,F,k){return(d&k)|(F&(~k));}function p(d,F,k){return(d^F^k);}function n(d,F,k){return(F^(d|(~k)));}function u(G,F,aa,Z,k,H,I){G=K(G,K(K(r(F,aa,Z),k),I));return K(L(G,H),F);}function f(G,F,aa,Z,k,H,I){G=K(G,K(K(q(F,aa,Z),k),I));return K(L(G,H),F);}function D(G,F,aa,Z,k,H,I){G=K(G,K(K(p(F,aa,Z),k),I));return K(L(G,H),F);}function t(G,F,aa,Z,k,H,I){G=K(G,K(K(n(F,aa,Z),k),I));return K(L(G,H),F);}function e(G){var Z;var F=G.length;var x=F+8;var k=(x-(x%64))/64;var I=(k+1)*16;var aa=Array(I-1);var d=0;var H=0;while(H<F){Z=(H-(H%4))/4;d=(H%4)*8;aa[Z]=(aa[Z]|(G.charCodeAt(H)<<d));H++;}Z=(H-(H%4))/4;d=(H%4)*8;aa[Z]=aa[Z]|(128<<d);aa[I-2]=F<<3;aa[I-1]=F>>>29;return aa;}function B(x){var k=\"\",F=\"\",G,d;for(d=0;d<=3;d++){G=(x>>>(d*8))&255;F=\"0\"+G.toString(16);k=k+F.substr(F.length-2,2);}return k;}function J(k){k=k.replace(/rn/g,\"n\");var d=\"\";for(var F=0;F<k.length;F++){var x=k.charCodeAt(F);if(x<128){d+=String.fromCharCode(x);}else{if((x>127)&&(x<2048)){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128);}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128);}}}return d;}var C=Array();var P,h,E,v,g,Y,X,W,V;var S=7,Q=12,N=17,M=22;var A=5,z=9,y=14,w=20;var o=4,m=11,l=16,j=23;var U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P<C.length;P+=16){h=Y;E=X;v=W;g=V;Y=u(Y,X,W,V,C[P+0],S,3614090360);V=u(V,Y,X,W,C[P+1],Q,3905402710);W=u(W,V,Y,X,C[P+2],N,606105819);X=u(X,W,V,Y,C[P+3],M,3250441966);Y=u(Y,X,W,V,C[P+4],S,4118548399);V=u(V,Y,X,W,C[P+5],Q,1200080426);W=u(W,V,Y,X,C[P+6],N,2821735955);X=u(X,W,V,Y,C[P+7],M,4249261313);Y=u(Y,X,W,V,C[P+8],S,1770035416);V=u(V,Y,X,W,C[P+9],Q,2336552879);W=u(W,V,Y,X,C[P+10],N,4294925233);X=u(X,W,V,Y,C[P+11],M,2304563134);Y=u(Y,X,W,V,C[P+12],S,1804603682);V=u(V,Y,X,W,C[P+13],Q,4254626195);W=u(W,V,Y,X,C[P+14],N,2792965006);X=u(X,W,V,Y,C[P+15],M,1236535329);Y=f(Y,X,W,V,C[P+1],A,4129170786);V=f(V,Y,X,W,C[P+6],z,3225465664);W=f(W,V,Y,X,C[P+11],y,643717713);X=f(X,W,V,Y,C[P+0],w,3921069994);Y=f(Y,X,W,V,C[P+5],A,3593408605);V=f(V,Y,X,W,C[P+10],z,38016083);W=f(W,V,Y,X,C[P+15],y,3634488961);X=f(X,W,V,Y,C[P+4],w,3889429448);Y=f(Y,X,W,V,C[P+9],A,568446438);V=f(V,Y,X,W,C[P+14],z,3275163606);W=f(W,V,Y,X,C[P+3],y,4107603335);X=f(X,W,V,Y,C[P+8],w,1163531501);Y=f(Y,X,W,V,C[P+13],A,2850285829);V=f(V,Y,X,W,C[P+2],z,4243563512);W=f(W,V,Y,X,C[P+7],y,1735328473);X=f(X,W,V,Y,C[P+12],w,2368359562);Y=D(Y,X,W,V,C[P+5],o,4294588738);V=D(V,Y,X,W,C[P+8],m,2272392833);W=D(W,V,Y,X,C[P+11],l,1839030562);X=D(X,W,V,Y,C[P+14],j,4259657740);Y=D(Y,X,W,V,C[P+1],o,2763975236);V=D(V,Y,X,W,C[P+4],m,1272893353);W=D(W,V,Y,X,C[P+7],l,4139469664);X=D(X,W,V,Y,C[P+10],j,3200236656);Y=D(Y,X,W,V,C[P+13],o,681279174);V=D(V,Y,X,W,C[P+0],m,3936430074);W=D(W,V,Y,X,C[P+3],l,3572445317);X=D(X,W,V,Y,C[P+6],j,76029189);Y=D(Y,X,W,V,C[P+9],o,3654602809);V=D(V,Y,X,W,C[P+12],m,3873151461);W=D(W,V,Y,X,C[P+15],l,530742520);X=D(X,W,V,Y,C[P+2],j,3299628645);Y=t(Y,X,W,V,C[P+0],U,4096336452);V=t(V,Y,X,W,C[P+7],T,1126891415);W=t(W,V,Y,X,C[P+14],R,2878612391);X=t(X,W,V,Y,C[P+5],O,4237533241);Y=t(Y,X,W,V,C[P+12],U,1700485571);V=t(V,Y,X,W,C[P+3],T,2399980690);W=t(W,V,Y,X,C[P+10],R,4293915773);X=t(X,W,V,Y,C[P+1],O,2240044497);Y=t(Y,X,W,V,C[P+8],U,1873313359);V=t(V,Y,X,W,C[P+15],T,4264355552);W=t(W,V,Y,X,C[P+6],R,2734768916);X=t(X,W,V,Y,C[P+13],O,1309151649);Y=t(Y,X,W,V,C[P+4],U,4149444226);V=t(V,Y,X,W,C[P+11],T,3174756917);W=t(W,V,Y,X,C[P+2],R,718787259);X=t(X,W,V,Y,C[P+9],O,3951481745);Y=K(Y,h);X=K(X,E);W=K(W,v);V=K(V,g);}var i=B(Y)+B(X)+B(W)+B(V);return i.toLowerCase();};\n return md5(this.toLowerCase());\n};\n\nString.prototype.capitalize = function() {\n return this.charAt(0).toUpperCase() + this.slice(1);\n};\n\nString.prototype.asDate = function () {\n var newDate;\n var date = this.split(\"/\");\n if (date.length == 3)\n newDate = new Date(date[2], date[1] - 1, date[0]); // dd/mm/yyyy\n else {\n date = this.split(\"-\");\n if (date.length == 3)\n newDate = new Date(date[0], date[1] - 1, date[2]); // yyyy-mm-dd\n else {\n if (this.length == 8) {\n newDate = new Date(this.substring(0, 4),\n this.substring(4, 6) - 1,\n this.substring(6, 8)); // yyyymmdd\n }\n }\n }\n\n return newDate;\n};\n\nString.prototype.formatted = function() {\n var newString = this;\n\n for (var i = 0; i < arguments.length; i++) {\n newString = newString.replace(\"%{\" + i + \"}\", arguments[i], \"g\");\n }\n\n return newString;\n};\n\nString.prototype.isValidEmail = function() {\n var emailRE = /^([\\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;\n return emailRE.test(this);\n};\n\nString.prototype.asCSSIdentifier = function() {\n var characters = [ '_' , '\\\\.', '#' , '@' , '\\\\*', ':' , ',' , ' ', \"'\", '&', '\\\\+' ];\n var escapeds = [ '_U_', '_D_', '_H_', '_A_', '_S_', '_C_', '_CO_', '_SP_', '_SQ_', '_AM_', '_P_' ];\n\n var newString = this;\n for (var i = 0; i < characters.length; i++) {\n var re = new RegExp(characters[i], 'g');\n newString = newString.replace(re, escapeds[i]);\n }\n\n if (/^\\d+/.test(newString)) {\n newString = '_' + newString;\n }\n\n return newString;\n};\n\nString.prototype.timeInterval = function () {\n var interval;\n if (this == \"once_per_hour\")\n interval = 3600;\n else if (this == \"every_minute\")\n interval = 60;\n else {\n interval = parseInt(this.substr(6)) * 60;\n }\n\n return interval;\n};\n\nString.prototype.parseDate = function(localeProvider, format) {\n var string, formattingTokens, tokens, token, now, date, regexes, i, parsedInput, matchesCount;\n\n string = '' + this;\n formattingTokens = /%[dembByY]/g;\n now = new Date();\n date = {\n year: -1,\n month: -1,\n day: -1\n };\n regexes = {\n '%d': [/\\d\\d/, function(input) {\n date.day = parseInt(input);\n return (date.day < 32);\n }],\n '%e': [/ ?\\d?\\d/, function(input) {\n date.day = parseInt(input);\n return (date.day < 32);\n }],\n '%m': [/\\d\\d/, function(input) {\n date.month = parseInt(input) - 1;\n return (date.month < 12);\n }],\n '%b': [/[^\\d\\s\\.\\/\\-]{2,}/, function(input) {\n var i = _.indexOf(localeProvider.shortMonths, input);\n if (i >= 0)\n date.month = i;\n return (i >= 0);\n }],\n '%B': [/[^\\d\\s\\.\\/\\-]{2,}/, function(input) {\n var i = _.indexOf(localeProvider.months, input);\n if (i >= 0)\n date.month = i;\n return (i >= 0);\n }],\n '%y': [/\\d\\d/, function(input) {\n var nearFuture = parseInt(now.getFullYear().toString().substring(2)) + 5;\n date.year = parseInt(input);\n if (date.year < nearFuture) date.year += 2000;\n else date.year += 1900;\n return true;\n }],\n '%Y': [/[12]\\d\\d\\d/, function(input) {\n date.year = parseInt(input);\n return true;\n }]\n };\n tokens = format.match(formattingTokens) || [];\n matchesCount = 0;\n\n for (i = 0; i < tokens.length; i++) {\n token = tokens[i];\n parsedInput = (string.match(regexes[token][0]) || [])[0];\n if (parsedInput) {\n string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n if (regexes[token][1](parsedInput))\n matchesCount++;\n }\n }\n\n if (tokens.length === matchesCount) {\n // console.debug(this + ' + ' + format + ' = ' + JSON.stringify(date));\n return new Date(date.year, date.month, date.day);\n }\n else\n return new Date(NaN);\n};\n\nDate.prototype.daysUpTo = function(otherDate) {\n var days = [];\n\n var day1 = this.getTime();\n var day2 = otherDate.getTime();\n if (day1 > day2) {\n var tmp = day1;\n day1 = day2;\n day2 = tmp;\n }\n\n var nbrDays = Math.round((day2 - day1) / 86400000) + 1;\n for (var i = 0; i < nbrDays; i++) {\n var newDate = new Date();\n newDate.setTime(day1 + (i * 86400000));\n days.push(newDate);\n }\n\n return days;\n};\n\nDate.prototype.minutesTo = function(otherDate) {\n var delta, dstOffset;\n\n delta = Math.floor(otherDate.valueOf() - this.valueOf())/1000/60;\n dstOffset = otherDate.getTimezoneOffset() - this.getTimezoneOffset();\n\n return delta - dstOffset;\n};\n\nDate.prototype.stringWithSeparator = function(separator) {\n var month = '' + (this.getMonth() + 1);\n var day = '' + this.getDate();\n var year = this.getYear();\n if (year < 1000)\n year = '' + (year + 1900);\n if (month.length == 1)\n month = '0' + month;\n if (day.length == 1)\n day = '0' + day;\n\n if (separator == '-')\n str = year + '-' + month + '-' + day;\n else\n str = day + '/' + month + '/' + year;\n\n return str;\n};\n\nDate.prototype.addDays = function(nbrDays) {\n var initialDate, milliSeconds, dstOffset;\n\n milliSeconds = this.getTime();\n initialDate = new Date(milliSeconds);\n milliSeconds += 86400000 * nbrDays;\n this.setTime(milliSeconds);\n\n dstOffset = this.getTimezoneOffset() - initialDate.getTimezoneOffset();\n if (dstOffset !== 0) {\n milliSeconds = this.getTime() + dstOffset*60*1000;\n this.setTime(milliSeconds);\n }\n};\n\nDate.prototype.addHours = function(nbrHours) {\n var milliSeconds = this.getTime();\n milliSeconds += 3600000 * nbrHours;\n this.setTime(milliSeconds);\n};\n\nDate.prototype.addMinutes = function(nbrMinutes) {\n var milliSeconds = this.getTime();\n milliSeconds += 60000 * nbrMinutes;\n this.setTime(milliSeconds);\n};\n\nDate.prototype.beginOfDay = function() {\n var beginOfDay = new Date(this.getTime());\n beginOfDay.setHours(0);\n beginOfDay.setMinutes(0);\n beginOfDay.setSeconds(0);\n beginOfDay.setMilliseconds(0);\n\n return beginOfDay;\n};\n\nDate.prototype.beginOfWeek = function(firstDayOfWeek) {\n var offset = firstDayOfWeek - this.getDay();\n if (offset > 0)\n offset -= 7;\n\n var beginOfWeek = this.beginOfDay();\n beginOfWeek.setHours(12);\n beginOfWeek.addDays(offset);\n\n return beginOfWeek;\n};\n\nDate.prototype.endOfWeek = function(firstDayOfWeek) {\n var endOfWeek = this.beginOfWeek(firstDayOfWeek);\n endOfWeek.addDays(6);\n\n endOfWeek.setHours(23);\n endOfWeek.setMinutes(59);\n endOfWeek.setSeconds(59);\n endOfWeek.setMilliseconds(999);\n\n return endOfWeek;\n};\n\n// YYYYMMDD\nDate.prototype.getDayString = function() {\n var newString = this.getYear();\n if (newString < 1000) newString += 1900;\n var month = '' + (this.getMonth() + 1);\n if (month.length == 1)\n month = '0' + month;\n newString += month;\n var day = '' + this.getDate();\n if (day.length == 1)\n day = '0' + day;\n newString += day;\n\n return newString;\n};\n\n// MMHH\nDate.prototype.getHourString = function() {\n var newString = this.getHours() + '00';\n if (newString.length == 3)\n newString = '0' + newString;\n\n return newString;\n};\n\nDate.prototype.format = function(localeProvider, format) {\n var separators, parts, i, max,\n date = [],\n validParts = /%[deaAmbByYHIMp]/g,\n val = {\n '%d': this.getDate(), // day of month (e.g., 01)\n '%e': this.getDate(), // day of month, space padded\n '%a': localeProvider.shortDays[this.getDay()], // locale's abbreviated weekday name (e.g., Sun)\n '%A': localeProvider.days[this.getDay()], // locale's full weekday name (e.g., Sunday)\n '%m': this.getMonth() + 1, // month (01..12)\n '%b': localeProvider.shortMonths[this.getMonth()], // locale's abbreviated month name (e.g., Jan)\n '%B': localeProvider.months[this.getMonth()], // locale's full month name (e.g., January)\n '%y': this.getFullYear().toString().substring(2), // last two digits of year (00..99)\n '%Y': this.getFullYear(), // year\n '%H': this.getHours(), // hour (00..23)\n '%M': this.getMinutes() }; // minute (00..59)\n val['%I'] = val['%H'] > 12 ? val['%H'] % 12 : val['%H']; // hour (01..12)\n val['%p'] = val['%H'] < 12 ? l('AM') : l('PM'); // locale's equivalent of either AM or PM\n\n val['%d'] = (val['%d'] < 10 ? '0' : '') + val['%d'];\n val['%e'] = (val['%e'] < 10 ? ' ' : '') + val['%e'];\n val['%m'] = (val['%m'] < 10 ? '0' : '') + val['%m'];\n val['%H'] = (val['%H'] < 10 ? '0' : '') + val['%H'];\n val['%I'] = (val['%I'] < 10 ? '0' : '') + val['%I'];\n val['%M'] = (val['%M'] < 10 ? '0' : '') + val['%M'];\n\n separators = format.replace(validParts, '\\0').split('\\0');\n parts = format.match(validParts);\n for (i = 0, max = parts.length; i <= max; i++){\n if (separators.length)\n date.push(separators.shift());\n date.push(val[parts[i]]);\n }\n\n return date.join('');\n};\n\n/* Functions */\n\nfunction l() {\n var key = arguments[0], value = key, args = arguments, i, j;\n\n // Retrieve translation\n if (labels[key]) {\n value = labels[key];\n }\n else if (clabels[key]) {\n value = clabels[key];\n }\n\n // Format placeholders %{0}, %{1], %{2}, ...\n for (i = 1, j = 0; i < args.length; i++, j++) {\n value = value.replace('%{' + j + '}', args[i]);\n }\n\n // Format placeholders %d and %s\n i = 1;\n if (args.length > 1) {\n value = value.replace(/%((%)|s|d)/g, function(m) {\n // m is the matched format, e.g. %s, %d\n var val = null;\n if (m[2]) {\n val = m[2];\n }\n else {\n val = args[i];\n // A switch statement so that the formatter can be extended. Default is %s\n switch (m) {\n case '%d':\n val = parseFloat(val);\n if (isNaN(val))\n val = 0;\n break;\n }\n i++;\n }\n return val;\n });\n }\n\n return value;\n}\n\nfunction hexToRgb(hex) {\n var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n}\n\n// Respect contrast ratio recommendation from W3C:\n// http://www.w3.org/TR/WCAG20/#contrast-ratiodef\nfunction contrast(hex) {\n var color, c, l = 1;\n\n color = hexToRgb(hex);\n if (color) {\n c = [color.r / 255, color.g / 255, color.b / 255];\n\n for (var i = 0; i < c.length; ++i) {\n if (c[i] <= 0.03928) {\n\tc[i] = c[i] / 12.92;\n }\n else {\n\tc[i] = Math.pow((c[i] + 0.055) / 1.055, 2.4);\n }\n }\n\n l = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];\n }\n\n if (l > 0.179) {\n return 'black';\n }\n else {\n return 'white';\n }\n}\n\nfunction guid() {\n function S4() {\n return (((1+Math.random())*0x10000)|0).toString(16).substring(1); \n }\n \n return (S4() + S4() + \"-\" + S4() + \"-4\" + S4().substr(0,3) + \"-\" + S4() + \"-\" + S4() + S4() + S4()).toLowerCase();\n}\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n angular.module('SOGo.Common', ['ngAnimate', 'ngMessages', 'ngSanitize', 'ngMaterial', 'mdColors'])\n .value('sgSettings', {\n isPopup: document.body.classList.contains('popup'),\n baseURL: function() {\n return ApplicationBaseURL || null;\n },\n activeUser: function(param) {\n var settings = {\n login: UserLogin || null,\n identification: UserIdentification || null,\n email: UserEmail || null,\n language: UserLanguage || null,\n folderURL: UserFolderURL || null,\n isSuperUser: IsSuperUser || null,\n path: {\n calendar: UserCalendarPath || null,\n contacts: UserContactsPath || null,\n mail: UserMailPath || null,\n preferences: UserPreferencesPath || null,\n administration: (IsSuperUser ? UserAdministrationPath : null),\n help: HelpURL || null,\n logoff: UserLogoffPath || null\n }\n };\n if (param)\n return settings[param];\n else\n return settings;\n }\n })\n\n .constant('sgColors', {\n selection: [\n '#FFFFFF',\n '#330033',\n '#C0C0C0',\n '#999999',\n '#666666',\n '#333333',\n '#000000',\n '#FFCCCC',\n '#FF6666',\n '#FF0000',\n '#CC0000',\n '#990000',\n '#660000',\n '#330000',\n '#FFCC99',\n '#FF9966',\n '#FF9900',\n '#FF6600',\n '#CC6600',\n '#993300',\n '#663300',\n '#FFFF99',\n '#FFFF66',\n '#FFCC66',\n '#FFCC33',\n '#CC9933',\n '#996633',\n '#663333',\n '#FFFFCC',\n '#FFFF33',\n '#FFFF00',\n '#FFCC00',\n '#999900',\n '#666600',\n '#333300',\n '#CCCCCC',\n '#66FF99',\n '#33FF33',\n '#33CC00',\n '#009900',\n '#006600',\n '#003300',\n '#99FFFF',\n '#33FFFF',\n '#66CCCC',\n '#00CCCC',\n '#339999',\n '#336666',\n '#003333',\n '#CCFFFF',\n '#66FFFF',\n '#33CCFF',\n '#3366FF',\n '#3333FF',\n '#000099',\n '#000066',\n '#CCCCFF',\n '#9999FF',\n '#6666CC',\n '#6633FF',\n '#6600CC',\n '#333399',\n '#330099',\n '#FFCCFF',\n '#FF99FF',\n '#CC66CC',\n '#CC33CC',\n '#993399',\n '#663366',\n '#99FF99'\n ]\n })\n\n // md break-points values are hard-coded in angular-material/src/core/util/constant.js\n // $mdMedia has a built-in support for those values but can also evaluate others.\n // The following breakpoints match our CSS breakpoints in scss/core/variables.scss\n .constant('sgConstant', {\n 'xs' : '(max-width: 599px)' ,\n 'gt-xs' : '(min-width: 600px)' ,\n 'sm' : '(min-width: 600px) and (max-width: 959px)' ,\n 'gt-sm' : '(min-width: 960px)' ,\n 'md' : '(min-width: 960px) and (max-width: 1023px)' ,\n 'gt-md' : '(min-width: 1024px)' ,\n 'lg' : '(min-width: 1024px) and (max-width: 1279px)',\n 'gt-lg' : '(min-width: 1280px)' ,\n 'xl' : '(min-width: 1920px)' ,\n 'print' : 'print'\n })\n\n .config(configure)\n\n .factory('AuthInterceptor', AuthInterceptor)\n .factory('ErrorInterceptor', ErrorInterceptor);\n\n /**\n * @ngInject\n */\n configure.$inject = ['$logProvider', '$compileProvider', '$httpProvider', '$mdThemingProvider'];\n function configure($logProvider, $compileProvider, $httpProvider, $mdThemingProvider) {\n // Accent palette\n $mdThemingProvider.definePalette('sogo-green', {\n '50': 'eaf5e9',\n '100': 'cbe5c8',\n '200': 'aad6a5',\n '300': '88c781',\n '400': '66b86a',\n '500': '56b04c',\n '600': '4da143',\n '700': '388e3c',\n '800': '367d2e',\n '900': '225e1b',\n // 'A100': 'b9f6ca',\n 'A100': 'fafafa', // assigned to md-hue-1\n 'A200': '69f0ae',\n 'A400': '00e676',\n 'A700': '00c853',\n 'contrastDefaultColor': 'dark',\n // 'contrastDarkColors': ['50', '100', '200', 'A100'],\n 'contrastLightColors': ['300', '400', '500', '600', '700', '800', '900']\n });\n // Primary palette\n $mdThemingProvider.definePalette('sogo-blue', {\n '50': 'f0faf9',\n '100': 'e1f5f3',\n '200': 'ceebe8',\n '300': 'bfe0dd',\n '400': 'b2d6d3',\n '500': 'a1ccc8',\n '600': '8ebfbb',\n '700': '7db3b0',\n '800': '639997',\n '900': '4d8080',\n 'A100': 'd4f7fa',\n 'A200': 'c3f5fa',\n 'A400': '53e3f0',\n 'A700': '00b0c0',\n 'contrastDefaultColor': 'light',\n 'contrastDarkColors': ['50', '100', '200'],\n // 'contrastLightColors': ['300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700']\n });\n // Background palette\n $mdThemingProvider.definePalette('sogo-paper', {\n '50': 'fcf7f8',\n '100': 'f7f1dc',\n '200': 'ede5ca',\n '300': 'e6d8ba',\n '400': 'e2d2a3',\n '500': 'd6c48d',\n '600': 'baa870',\n '700': '857545',\n '800': '524517',\n '900': '433809',\n '1000': '000000',\n 'A100': 'ffffff',\n 'A200': 'eeeeee',\n 'A400': 'bdbdbd',\n 'A700': '616161',\n 'contrastDefaultColor': 'dark',\n 'contrastLightColors': ['800', '900']\n });\n // Default theme definition\n $mdThemingProvider.theme('default')\n .primaryPalette('sogo-blue', {\n 'default': '900',\n 'hue-1': '400',\n 'hue-2': '800',\n 'hue-3': 'A700'\n })\n .accentPalette('sogo-green', {\n 'default': '500',\n // 'hue-1': '200',\n 'hue-1': 'A100', // background-50\n 'hue-2': '300',\n 'hue-3': 'A700'\n })\n .backgroundPalette('grey', {\n 'default': '50',\n 'hue-1': '200',\n 'hue-2': '300',\n 'hue-3': '500'\n });\n\n if (!DebugEnabled) {\n // Disable debug data\n $logProvider.debugEnabled(false);\n $compileProvider.debugInfoEnabled(false);\n }\n\n $httpProvider.interceptors.push('AuthInterceptor');\n $httpProvider.interceptors.push('ErrorInterceptor');\n }\n\n AuthInterceptor.$inject = ['$window', '$q'];\n function AuthInterceptor($window, $q) {\n return {\n response: function(response) {\n // When expecting JSON but receiving HTML, assume session has expired and reload page\n if (response && /^application\\/json/.test(response.config.headers.Accept) &&\n /^<!DOCTYPE html>/.test(response.data)) {\n $window.location.reload(true);\n return $q.reject();\n }\n return response;\n }\n };\n }\n\n /**\n * @ngInject\n */\n ErrorInterceptor.$inject = ['$rootScope', '$q'];\n function ErrorInterceptor($rootScope, $q) {\n return {\n responseError: function(rejection) {\n if (/^application\\/json/.test(rejection.config.headers.Accept)) {\n // Broadcast the response error\n $rootScope.$broadcast('http:Error', rejection);\n }\n return $q.reject(rejection);\n }\n };\n }\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/*\n * https://github.com/angular/material/issues/1269\n * https://gist.github.com/senthilprabhut/dd2147ebabc89bf223e7\n */\n\n(function() {\n 'use strict';\n\n var _$mdThemingProvider;\n\n angular\n .module('mdColors', ['ngMaterial'])\n .config(configure)\n .run(runBlock);\n\n /**\n * @ngInject\n */\n configure.$inject = ['$mdThemingProvider'];\n function configure($mdThemingProvider) {\n _$mdThemingProvider = $mdThemingProvider;\n }\n \n /**\n * @ngInject\n */\n runBlock.$inject = ['$interpolate', '$document', '$log'];\n function runBlock($interpolate, $document, $log) {\n\n function buildCssSelectors(selectors) {\n var result = selectors.join('');\n return result;\n }\n\n var fgDefault = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-fg']) + ' { color:{{value}};}'),\n bgDefault = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-bg']) + ' { background-color:{{value}};}'),\n bdrDefault = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-bdr']) + ' { border-color:{{value}};}'),\n fgDefaultHue = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{hue}}','.md-fg']) + ' { color:{{value}};}'),\n bgDefaultHue = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{hue}}','.md-bg']) + ' { background-color:{{value}};}'),\n fgColor = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{palette}}','.md-fg']) + ' { color:{{value}};}'),\n bgColor = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{palette}}','.md-bg']) + ' { background-color:{{value}}; color:{{contrast}}; }'),\n bdrColor = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{palette}}','.md-bdr']) + ' { border-color:{{value}};}'),\n fgHue = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{palette}}.md-{{hue}}','.md-fg']) + ' { color:{{value}};}'),\n bgHue = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{palette}}.md-{{hue}}','.md-bg']) + ' { background-color:{{value}};}'),\n customSheet = getStyleSheet(),\n index = 0;\n\n // Clear out old rules from stylesheet\n while (customSheet.cssRules.length > 0 ) {\n customSheet.deleteRule(0);\n }\n angular.forEach(_$mdThemingProvider._THEMES, function(theme, themeName){\n // Add default selectors - primary is the default palette\n addRule(fgDefault, bgDefault, themeName, 'primary',\n _$mdThemingProvider._PALETTES[theme.colors.primary.name][theme.colors.primary.hues.default]);\n addRule(fgDefaultHue, bgDefaultHue, themeName, 'primary',\n _$mdThemingProvider._PALETTES[theme.colors.primary.name][theme.colors.primary.hues['hue-2'] ], 'hue-2');\n addRule(fgDefaultHue, bgDefaultHue, themeName, 'primary',\n _$mdThemingProvider._PALETTES[theme.colors.primary.name][theme.colors.primary.hues['hue-3'] ], 'hue-3');\n addRule(fgDefaultHue, bgDefaultHue, themeName, 'primary',\n _$mdThemingProvider._PALETTES[theme.colors.primary.name][theme.colors.primary.hues['hue-1'] ], 'hue-1');\n addBorderRule(bdrDefault, themeName, 'primary',\n _$mdThemingProvider._PALETTES[theme.colors.primary.name][theme.colors.primary.hues.default]);\n\n // Add selectors for palettes - accent, background, primary and warn\n angular.forEach(theme.colors, function(color, paletteName){\n addRule(fgColor, bgColor, themeName, paletteName, _$mdThemingProvider._PALETTES[color.name][color.hues.default]);\n addBorderRule(bdrColor, themeName, paletteName, _$mdThemingProvider._PALETTES[color.name][color.hues.default]);\n addRule(fgHue, bgHue, themeName, paletteName, _$mdThemingProvider._PALETTES[color.name][color.hues['hue-2'] ], 'hue-2');\n addRule(fgHue, bgHue, themeName, paletteName, _$mdThemingProvider._PALETTES[color.name][color.hues['hue-3'] ], 'hue-3');\n addRule(fgHue, bgHue, themeName, paletteName, _$mdThemingProvider._PALETTES[color.name][color.hues['hue-1'] ], 'hue-1');\n });\n\n //$log.debug(_.map(customSheet.cssRules, 'cssText').join(\"\\n\"));\n });\n\n function addRule(fgInterpolate, bgInterpolate, themeName, paletteName, colorArray, hueName){\n // Set up interpolation functions to build css rules.\n if (!colorArray) return;\n var colorValue = 'rgb(' + colorArray.value[0] + ',' + colorArray.value[1] + ',' + colorArray.value[2] + ')',\n colorContrast = 'rgb(' + colorArray.contrast[0] + ',' + colorArray.contrast[1] + ',' + colorArray.contrast[2] + ')',\n context = {\n theme: themeName,\n palette: paletteName,\n value: colorValue,\n contrast: colorContrast,\n hue: hueName\n };\n\n // Insert foreground color rule\n customSheet.insertRule(fgInterpolate(context), index);\n index += 1;\n\n // Insert background color rule\n customSheet.insertRule(bgInterpolate(context), index);\n index += 1;\n }\n\n function addBorderRule(bdrInterpolate, themeName, paletteName, colorArray, hueName){\n // Set up interpolation functions to build css rule for border color.\n if (!colorArray) return;\n var colorValue = 'rgb(' + colorArray.value[0] + ',' + colorArray.value[1] + ',' + colorArray.value[2] + ')';\n\n customSheet.insertRule(bdrInterpolate({\n theme: themeName,\n palette: paletteName,\n value: colorValue,\n hue: hueName\n }), index);\n index += 1;\n }\n\n function getStyleSheet() {\n // function to add a dynamic style-sheet to the document\n var style = $document[0].head.querySelector('style[title=\"Dynamic-Generated-by-mdColors\"]');\n if (style === null) {\n style = $document[0].createElement('style');\n style.title = 'Dynamic-Generated-by-mdColors';\n // WebKit hack... (not sure if still needed)\n style.appendChild($document[0].createTextNode(''));\n $document[0].head.appendChild(style);\n }\n return style.sheet;\n }\n }\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/**\n * @type {angular.Module}\n */\n(function () {\n 'use strict';\n\n /**\n * @ngInject\n */\n decodeUri.$inject = ['$window'];\n function decodeUri($window) {\n return $window.decodeURIComponent;\n }\n\n angular.module('SOGo.Common')\n .filter('decodeUri', decodeUri);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/**\n * @type {angular.Module}\n */\n(function () {\n 'use strict';\n\n /**\n * @ngInject\n */\n encodeUri.$inject = ['$window'];\n function encodeUri($window) {\n return $window.encodeURIComponent;\n }\n\n angular.module('SOGo.Common')\n .filter('encodeUri', encodeUri);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function () {\n 'use strict';\n\n /**\n * ensureTarget - A filter to set a blank target to all links.\n * @memberof SOGo.Common\n * @ngInject\n * @example:\n\n <div ng-bind-html=\"part.content | ensureTarget\"><!-- msg --></div>\n */\n ensureTarget.$inject = ['$sce'];\n function ensureTarget($sce) {\n return function(element) {\n var tree = angular.element('<div>' + element + '</div>');\n tree.find('a').attr('target', '_blank');\n return $sce.trustAs('html', tree.html());\n };\n }\n\n angular.module('SOGo.Common')\n .filter('ensureTarget', ensureTarget);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/**\n * loc - A simple filter to return the localized version of a string.\n * @memberof SOGo.Common\n */\n(function () {\n 'use strict';\n\n /**\n * @ngInject\n */\n function loc() {\n return l;\n }\n\n angular.module('SOGo.Common')\n .filter('loc', loc);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/**\n * range - A simple filter that will return an array of the size of its argument.\n * @memberof SOGo.Common\n */\n(function () {\n 'use strict';\n\n function range() {\n return function(n) {\n var res = [];\n for (var i = 0; i < parseInt(n); i++) {\n res.push(i);\n }\n return res;\n };\n }\n\n angular.module('SOGo.Common')\n .filter('range', range);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @ngInject\n */\n AclController.$inject = ['$mdDialog', 'Dialog', 'usersWithACL', 'User', 'folder'];\n function AclController($mdDialog, Dialog, usersWithACL, User, folder) {\n var vm = this;\n\n vm.users = usersWithACL; // ACL users\n vm.folder = folder;\n vm.selectedUser = null;\n vm.selectedUid = null;\n vm.userToAdd = '';\n vm.searchText = '';\n vm.userFilter = userFilter;\n vm.closeModal = closeModal;\n vm.saveModal = saveModal;\n vm.confirmChange = confirmChange;\n vm.removeUser = removeUser;\n vm.addUser = addUser;\n vm.selectUser = selectUser;\n vm.confirmation = { showing: false,\n message: ''};\n\n function userFilter($query) {\n return User.$filter($query, folder.$acl.users);\n }\n\n function closeModal() {\n folder.$acl.$resetUsersRights(); // cancel changes\n $mdDialog.hide();\n }\n\n function saveModal() {\n folder.$acl.$saveUsersRights().then(function() {\n $mdDialog.hide();\n }, function(data, status) {\n Dialog.alert(l('Warning'), l('An error occured please try again.'));\n });\n }\n\n function confirmChange(user) {\n var confirmation = user.$confirmRights(vm.folder);\n if (confirmation) {\n vm.confirmation.showing = true;\n vm.confirmation.message = confirmation;\n }\n }\n\n function removeUser(user) {\n folder.$acl.$removeUser(user.uid);\n }\n\n function addUser(data) {\n if (data) {\n folder.$acl.$addUser(data).then(function(user) {\n vm.userToAdd = '';\n vm.searchText = '';\n vm.selectedUid = null;\n if (user)\n selectUser(user);\n }, function(error) {\n Dialog.alert(l('Warning'), error);\n });\n }\n }\n\n function selectUser(user) {\n if (vm.selectedUid == user.uid) {\n vm.selectedUid = null;\n }\n else {\n vm.selectedUid = user.uid;\n vm.selectedUser = user;\n vm.selectedUser.$rights();\n }\n }\n }\n\n angular\n .module('SOGo.Common')\n .controller('AclController', AclController);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/**\n * @type {angular.Module}\n */\n(function () {\n 'use strict';\n\n /**\n * @ngInject\n */\n navController.$inject = ['$rootScope', '$scope', '$timeout', '$interval', '$http', '$window', '$mdSidenav', '$mdToast', '$mdMedia', '$log', 'sgConstant', 'sgSettings', 'Alarm'];\n function navController($rootScope, $scope, $timeout, $interval, $http, $window, $mdSidenav, $mdToast, $mdMedia, $log, sgConstant, sgSettings, Alarm) {\n\n $scope.isPopup = sgSettings.isPopup;\n $scope.activeUser = sgSettings.activeUser();\n $scope.baseURL = sgSettings.baseURL();\n $scope.leftIsClose = !$mdMedia(sgConstant['gt-md']);\n\n // Show current day in top bar\n $scope.currentDay = window.currentDay;\n $timeout(function() {\n // Update date when day ends\n $interval(function() {\n $http.get('../date').then(function(data) {\n $scope.currentDay = data;\n });\n }, 24 * 3600 * 1000);\n }, window.currentDay.secondsBeforeTomorrow * 1000);\n\n $scope.toggleLeft = function() {\n if ($scope.isGtMedium) {\n // Left sidenav is toggled while sidenav is locked open; bypass $mdSidenav\n $scope.leftIsClose = !$scope.leftIsClose;\n }\n else {\n $scope.leftIsClose = leftIsClose();\n // Fire a window resize when opening the sidenav on a small device.\n // This is a fix until the following issue is officially resolved:\n // https://github.com/angular/material/issues/7309\n if ($scope.leftIsClose)\n angular.element($window).triggerHandler('resize');\n $mdSidenav('left').toggle()\n .then(function () {\n $log.debug(\"toggle left is done\");\n });\n }\n };\n $scope.toggleRight = function() {\n $mdSidenav('right').toggle()\n .then(function () {\n $log.debug(\"toggle right is done\");\n });\n };\n // $scope.openBottomSheet = function() {\n // $mdBottomSheet.show({\n // parent: angular.element(document.getElementById('left-sidenav')),\n // templateUrl: 'bottomSheetTemplate.html'\n // });\n // };\n // $scope.toggleDetailView = function() {\n // var detail = angular.element(document.getElementById('detailView'));\n // detail.toggleClass('sg-close');\n // };\n $scope.$watch(function() {\n return $mdMedia(sgConstant['gt-md']);\n }, function(newVal) {\n $scope.isGtMedium = newVal;\n if (newVal) {\n $scope.leftIsClose = false;\n }\n });\n\n function leftIsClose() {\n return !$mdSidenav('left').isOpen();\n }\n\n function onHttpError(event, response) {\n var message;\n if (response.data && response.data.message && angular.isString(response.data.message))\n message = response.data.message;\n else if (response.status)\n message = response.statusText;\n\n if (message)\n $mdToast.show({\n template: [\n '<md-toast>',\n ' <div class=\"md-toast-content\">',\n ' <md-icon class=\"md-warn md-hue-1\">error_outline</md-icon>',\n ' <span flex>' + l(message) + '</span>',\n ' </div>',\n '</md-toast>'\n ].join(''),\n hideDelay: 5000,\n position: 'top right'\n });\n else\n $log.debug('untrap error');\n }\n\n // Listen to HTTP errors broadcasted from HTTP interceptor\n $rootScope.$on('http:Error', onHttpError);\n\n Alarm.getAlarms();\n }\n\n angular.module('SOGo.Common')\n .controller('navController', navController);\n})();\n","(function() {\n 'use strict';\n\n /**\n * @name Acl\n * @constructor\n * @param {String} folderId - the folder ID associated to the ACLs\n */\n function Acl(folderId) {\n this.folderId = folderId;\n }\n\n /**\n * @memberof Acl\n * @desc The factory we'll use to register with Angular.\n * @return the Acl constructor\n */\n Acl.factory = ['$q', '$timeout', 'sgSettings', 'Resource', 'User', function($q, $timeout, Settings, Resource, User) {\n angular.extend(Acl, {\n $q: $q,\n $timeout: $timeout,\n $$resource: new Resource(Settings.activeUser('folderURL'), Settings.activeUser()),\n $User: User\n });\n\n return Acl;\n }];\n\n /**\n * @module SOGo.Common\n * @desc Factory registration of User in Angular module.\n */\n angular.module('SOGo.Common').factory('Acl', Acl.factory);\n\n /**\n * @function $users\n * @memberof Acl.prototype\n * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser\n * @desc Fetch the list of users that have specific rights for the current folder.\n * @return a promise of an array of User objects\n */\n Acl.prototype.$users = function(owner) {\n var _this = this,\n deferred = Acl.$q.defer(),\n user;\n if (this.users) {\n deferred.resolve(this.users);\n }\n else {\n var acls;\n if (angular.isDefined(owner))\n acls = Acl.$$resource.userResource(owner).fetch(this.folderId, 'acls');\n else\n acls = Acl.$$resource.fetch(this.folderId, 'acls');\n\n return acls.then(function(response) {\n _this.users = [];\n //console.debug(JSON.stringify(users, undefined, 2));\n angular.forEach(response.users, function(data) {\n user = new Acl.$User(data);\n user.canSubscribeUser = user.isSubscribed;\n user.wasSubscribed = user.isSubscribed;\n user.$rights = angular.bind(user, user.$acl, _this.folderId, owner);\n _this.users.push(user);\n });\n deferred.resolve(_this.users);\n return _this.users;\n });\n }\n return deferred.promise;\n };\n\n /**\n * @function $addUser\n * @memberof Acl.prototype\n * @param {Object} user - a User object with minimal set of attributes (uid, isGroup, cn, c_email)\n * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser\n * @see {@link User.$filter}\n */\n Acl.prototype.$addUser = function(user, owner) {\n var _this = this,\n deferred = Acl.$q.defer(),\n param = {uid: user.uid};\n if (!user.uid || _.indexOf(_.map(this.users, 'uid'), user.uid) > -1) {\n // No UID specified or user already in ACLs\n deferred.resolve();\n }\n else {\n var acls;\n\n if (angular.isDefined(owner))\n acls = Acl.$$resource.userResource(owner).fetch(this.folderId, 'addUserInAcls', param);\n else\n acls = Acl.$$resource.fetch(this.folderId, 'addUserInAcls', param);\n\n acls.then(function() {\n user.wasSubscribed = false;\n user.userClass = user.isGroup ? 'normal-group' : 'normal-user';\n user.$rights = angular.bind(user, user.$acl, _this.folderId);\n _this.users.push(user);\n deferred.resolve(user);\n }, function(data, status) {\n deferred.reject(l('An error occured please try again.'));\n });\n }\n return deferred.promise;\n };\n\n /**\n * @function $removeUser\n * @memberof Acl.prototype\n * @desc Remove a user from the folder's ACL\n * @return a promise of the server call to remove the user from the folder's ACL\n */\n Acl.prototype.$removeUser = function(uid, owner) {\n var _this = this,\n param = {uid: uid},\n acls;\n\n if (angular.isDefined(owner))\n acls = Acl.$$resource.userResource(owner).fetch(this.folderId, 'removeUserFromAcls', param);\n else\n acls = Acl.$$resource.fetch(this.folderId, 'removeUserFromAcls', param);\n\n return acls.then(function() {\n var i = _.indexOf(_.map(_this.users, 'uid'), uid);\n if (i >= 0) {\n _this.users.splice(i, 1);\n }\n });\n };\n\n /**\n * @function $resetUsersRights\n * @memberof Acl.prototype\n * @desc Restore initial rights of all users.\n */\n Acl.prototype.$resetUsersRights = function() {\n angular.forEach(this.users, function(user) {\n user.$resetRights();\n });\n };\n\n /**\n * @function $saveUsersRights\n * @memberof Acl.prototype\n * @desc Save user rights that have changed and subscribe users that have been selected.\n * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser\n * @return a promise that resolved only if the modifications and subscriptions were successful\n */\n Acl.prototype.$saveUsersRights = function(owner) {\n var _this = this,\n deferredSave = Acl.$q.defer(),\n deferredSubscribe = Acl.$q.defer(),\n param = {action: 'saveUserRights'},\n users = [];\n\n // Save user rights\n angular.forEach(this.users, function(user) {\n if (user.$rightsAreDirty()) {\n users.push(user.$omit());\n // console.debug('save ' + JSON.stringify(user.$omit(), undefined, 2));\n }\n });\n if (users.length) {\n var acls;\n\n if (angular.isDefined(owner))\n acls = Acl.$$resource.userResource(owner).save(this.folderId, users, param);\n else\n acls = Acl.$$resource.save(this.folderId, users, param);\n\n acls.then(function() {\n // Save was successful; copy rights to shadow rights\n angular.forEach(_this.users, function(user) {\n if (user.$rightsAreDirty()) {\n user.$shadowRights = angular.copy(user.rights);\n }\n });\n deferredSave.resolve();\n }, deferredSave.reject);\n }\n else {\n deferredSave.resolve();\n }\n\n // Subscribe users\n users = [];\n angular.forEach(this.users, function(user) {\n if (!user.wasSubscribed && user.isSubscribed) {\n users.push(user.uid);\n // console.debug('subscribe ' + user.uid);\n }\n });\n if (users.length) {\n param = {uids: users.join(',')};\n Acl.$$resource.fetch(this.folderId, 'subscribeUsers', param)\n .then(function() {\n // Subscribe was successful; reset \"wasSubscribed\" attribute\n angular.forEach(_this.users, function(user) {\n user.wasSubscribed = user.isSubscribed;\n });\n deferredSubscribe.resolve();\n }, deferredSubscribe.reject);\n }\n else {\n deferredSubscribe.resolve();\n }\n return Acl.$q.all([deferredSave.promise, deferredSubscribe.promise]);\n };\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Alarm\n * @constructor\n */\n function Alarm() {\n this.currentAlarm = null;\n }\n\n /**\n * @name getAlarms\n * @desc Fetch the list of alarms from the server and use the last one\n */\n Alarm.getAlarms = function() {\n var _this = this;\n var now = new Date();\n var browserTime = Math.floor(now.getTime()/1000);\n\n this.$$resource.fetch('', 'alarmslist?browserTime=' + browserTime).then(function(data) {\n \n var alarms = data.alarms.sort(function reverseSortByAlarmTime(a, b) {\n var x = parseInt(a[2]);\n var y = parseInt(b[2]);\n return (y - x);\n });\n\n if (alarms.length > 0) {\n var next = alarms.pop();\n var now = new Date();\n var utc = Math.floor(now.getTime()/1000);\n var url = next[0] + '/' + next[1];\n var alarmTime = parseInt(next[2]);\n var delay = alarmTime;\n if (alarmTime > 0) delay -= utc;\n var d = new Date(alarmTime*1000);\n //console.log (\"now = \" + now.toUTCString());\n //console.log (\"next event \" + url + \" in \" + delay + \" seconds (on \" + d.toUTCString() + \")\");\n\n var f = angular.bind(_this, Alarm.showAlarm, url);\n\n if (_this.currentAlarm)\n _this.$timeout.cancel(_this.currentAlarm);\n\n _this.currentAlarm = _this.$timeout(f, delay*1000);\n }\n });\n };\n \n /**\n * @name showAlarm\n * @desc Show the latest alarm using a toast\n * @param url The URL of the calendar component for snoozing\n */\n Alarm.showAlarm = function(url) {\n var _this = this;\n\n this.$$resource.fetch(url, '?resetAlarm=yes').then(function(data) {\n _this.$toast.show({\n position: 'top right',\n hideDelay: 0,\n template: [\n '<md-toast>',\n ' <div class=\"md-toast-content\">',\n ' <md-input-container>',\n ' <label style=\"color: white;\">' + data.summary + '</label>',\n ' <md-select ng-model=\"reminder\">',\n ' <md-option value=5>',\n l('5 minutes'),\n ' </md-option>',\n ' <md-option value=10>',\n l('10 minutes'),\n ' </md-option>',\n ' <md-option value=15>',\n l('15 minutes'),\n ' </md-option>',\n ' <md-option value=30>',\n l('30 minutes'),\n ' </md-option>',\n ' <md-option value=45>',\n l('45 minutes'),\n ' </md-option>',\n ' <md-option value=60>',\n l('1 hour'),\n ' </md-option>',\n ' <md-option value=1440>',\n l('1 day'),\n ' </md-option>',\n ' </md-select>',\n ' </md-input-container>',\n ' <md-button ng-click=\"cancel()\">',\n l('Cancel'),\n ' </md-button>',\n ' <md-button ng-click=\"ok()\">',\n l('Ok'),\n ' </md-button>',\n ' </div>',\n '</md-toast>'\n ].join(''),\n locals: {\n url: url\n },\n controller: AlarmController\n });\n\n /**\n * @ngInject\n */\n AlarmController.$inject = ['scope', '$mdToast', 'url'];\n function AlarmController(scope, $mdToast, url) {\n scope.reminder = '10';\n scope.cancel = function() {\n $mdToast.hide();\n };\n scope.ok = function() {\n _this.$$resource.fetch(url, 'view?snoozeAlarm=' + scope.reminder);\n $mdToast.hide();\n };\n }\n });\n };\n\n /**\n * @memberof Alarm\n * @desc The factory we'll register as Alarm in the Angular module SOGo.Common\n * @ngInject\n */\n AlarmService.$inject = ['$timeout', 'sgSettings', 'Resource', '$mdToast'];\n function AlarmService($timeout, Settings, Resource, $mdToast) {\n angular.extend(Alarm, {\n $timeout: $timeout,\n $$resource: new Resource(Settings.activeUser('folderURL') + 'Calendar', Settings.activeUser()),\n $toast: $mdToast\n });\n\n return Alarm; // return constructor\n }\n\n /* Factory registration in Angular module */\n angular\n .module('SOGo.Common')\n .factory('Alarm', AlarmService);\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n/* JavaScript for Authentication */\n\n(function() {\n /* jshint validthis: true */\n 'use strict';\n\n angular.module('SOGo.Authentication', ['ngCookies'])\n\n .constant('passwordPolicyConfig', {\n PolicyPasswordChangeUnsupported: -3,\n PolicyPasswordSystemUnknown: -2,\n PolicyPasswordUnknown: -1,\n PolicyPasswordExpired: 0,\n PolicyAccountLocked: 1,\n PolicyChangeAfterReset: 2,\n PolicyPasswordModNotAllowed: 3,\n PolicyMustSupplyOldPassword: 4,\n PolicyInsufficientPasswordQuality: 5,\n PolicyPasswordTooShort: 6,\n PolicyPasswordTooYoung: 7,\n PolicyPasswordInHistory: 8,\n PolicyNoError: 65535\n })\n\n .provider('Authentication', Authentication);\n\n function Authentication() {\n function redirectUrl(username, domain) {\n var userName, address, baseAddress, altBaseAddress, parts, hostpart, protocol, newAddress;\n\n userName = username;\n if (domain)\n userName += '@' + domain.value;\n address = '' + window.location.href;\n baseAddress = ApplicationBaseURL + '/' + encodeURIComponent(userName);\n if (baseAddress[0] == '/') {\n parts = address.split('/');\n hostpart = parts[2];\n protocol = parts[0];\n baseAddress = protocol + '//' + hostpart + baseAddress;\n }\n parts = baseAddress.split('/');\n parts.splice(0, 3);\n altBaseAddress = parts.join('/');\n if ((address.startsWith(baseAddress) || address.startsWith(altBaseAddress)) &&\n !address.endsWith('/logoff')) {\n newAddress = address;\n }\n else {\n newAddress = baseAddress;\n }\n\n return newAddress;\n }\n\n this.$get = getService;\n\n /**\n * @ngInject\n */\n getService.$inject = ['$q', '$http', '$cookies', 'passwordPolicyConfig'];\n function getService($q, $http, $cookies, passwordPolicyConfig) {\n var service;\n\n function readLoginCookie() {\n var loginValues = null,\n cookie = $cookies.get('0xHIGHFLYxSOGo'),\n value;\n if (cookie && cookie.length > 8) {\n value = decodeURIComponent(cookie.substr(8));\n loginValues = value.base64decode().split(':');\n }\n\n return loginValues;\n }\n\n service = {\n login: function(data) {\n var d = $q.defer(),\n username = data.username,\n password = data.password,\n domain = data.domain,\n language,\n rememberLogin = data.rememberLogin ? 1 : 0;\n\n if (data.loginSuffix && !username.endsWith(data.loginSuffix)) {\n username += loginSuffix;\n domain = false;\n }\n if (data.language && data.language != 'WONoSelectionString') {\n language = data.language;\n }\n\n $http({\n method: 'POST',\n url: '/SOGo/connect',\n data: {\n userName: username,\n password: password,\n domain: domain,\n language: language,\n rememberLogin: rememberLogin\n }\n }).then(function(response) {\n var data = response.data;\n // Make sure browser's cookies are enabled\n var loginCookie = readLoginCookie();\n if (!loginCookie) {\n d.reject(l('cookiesNotEnabled'));\n }\n else {\n // Check password policy\n if (typeof data.expire != 'undefined' && typeof data.grace != 'undefined') {\n if (data.expire < 0 && data.grace > 0) {\n d.reject({grace: data.grace});\n //showPasswordDialog('grace', createPasswordGraceDialog, data['grace']);\n } else if (data.expire > 0 && data.grace == -1) {\n d.reject({expire: data.expire});\n //showPasswordDialog('expiration', createPasswordExpirationDialog, data['expire']);\n }\n else {\n d.resolve(redirectUrl(username, domain));\n }\n }\n else {\n d.resolve(redirectUrl(username, domain));\n }\n }\n }, function(response) {\n var msg, perr, data = response.data;\n if (data && data.LDAPPasswordPolicyError) {\n perr = data.LDAPPasswordPolicyError;\n if (perr == passwordPolicyConfig.PolicyNoError) {\n msg = l('Wrong username or password.');\n }\n else if (perr == passwordPolicyConfig.PolicyAccountLocked) {\n msg = l('Your account was locked due to too many failed attempts.');\n }\n else {\n msg = l('Login failed due to unhandled error case: ') + perr;\n }\n }\n else {\n msg = l('Unhandled error response');\n }\n d.reject({error: msg});\n });\n return d.promise;\n }, // login: function(data) { ...\n\n changePassword: function(newPassword) {\n var d = $q.defer(),\n loginCookie = readLoginCookie(),\n xsrfCookie = $cookies.get('XSRF-TOKEN');\n\n $cookies.remove('XSRF-TOKEN', {path: '/SOGo/'});\n\n $http({\n method: 'POST',\n url: '/SOGo/so/changePassword',\n headers: {\n 'X-XSRF-TOKEN' : xsrfCookie\n },\n data: {\n userName: loginCookie[0],\n password: loginCookie[1],\n newPassword: newPassword }\n }).then(d.resolve, function(response) {\n var error,\n data = response.data,\n perr = data.LDAPPasswordPolicyError;\n\n if (!perr) {\n perr = passwordPolicyConfig.PolicyPasswordSystemUnknown;\n error = _(\"Unhandled error response\");\n }\n else if (perr == passwordPolicyConfig.PolicyNoError) {\n error = l(\"Password change failed\");\n } else if (perr == passwordPolicyConfig.PolicyPasswordModNotAllowed) {\n error = l(\"Password change failed - Permission denied\");\n } else if (perr == passwordPolicyConfig.PolicyInsufficientPasswordQuality) {\n error = l(\"Password change failed - Insufficient password quality\");\n } else if (perr == passwordPolicyConfig.PolicyPasswordTooShort) {\n error = l(\"Password change failed - Password is too short\");\n } else if (perr == passwordPolicyConfig.PolicyPasswordTooYoung) {\n error = l(\"Password change failed - Password is too young\");\n } else if (perr == passwordPolicyConfig.PolicyPasswordInHistory) {\n error = l(\"Password change failed - Password is in history\");\n } else {\n error = l(\"Unhandled policy error: %{0}\").formatted(perr);\n perr = passwordPolicyConfig.PolicyPasswordUnknown;\n }\n\n // Restore the cookie\n $cookies.put('XSRF-TOKEN', xsrfCookie, {path: '/SOGo/'});\n d.reject(error);\n });\n return d.promise;\n }\n };\n return service;\n }\n }\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Dialog\n * @constructor\n */\n function Dialog() {\n }\n\n /**\n * @name alert\n * @desc Show an alert dialog box with a single \"OK\" button\n * @param {string} title\n * @param {string} content\n */\n Dialog.alert = function(title, content) {\n var alert = this.$modal.alert()\n .title(title)\n .htmlContent(content)\n .ok(l('OK'));\n this.$modal.show(alert);\n };\n\n /**\n * @name confirm\n * @desc Show a confirmation dialog box with buttons 'Cancel' and 'OK'\n * @param {string} title\n * @param {string} content\n * @returns a promise that resolves if the user has clicked on the 'OK' button\n */\n Dialog.confirm = function(title, content, options) {\n var confirm = this.$modal.confirm()\n .title(title)\n .htmlContent(content)\n .ok((options && options.ok)? options.ok : l('OK'))\n .cancel((options && options.cancel)? options.cancel : l('Cancel'));\n return this.$modal.show(confirm);\n };\n\n /**\n * @name prompt\n * @desc Show a primpt dialog box with a input text field and the 'Cancel' and 'OK' buttons\n * @param {string} title\n * @param {string} label\n * @param {object} [options] - use a different input type by setting 'inputType'\n * @returns a promise that resolves with the input field value\n */\n Dialog.prompt = function(title, label, options) {\n var o = options || {},\n d = this.$q.defer();\n\n this.$modal.show({\n parent: angular.element(document.body),\n clickOutsideToClose: true,\n escapeToClose: true,\n template: [\n '<md-dialog flex=\"50\" flex-xs=\"90\">',\n ' <md-dialog-content class=\"md-dialog-content\" layout=\"column\">',\n ' <h2 class=\"md-title\" ng-bind=\"title\"></h2>',\n ' <md-input-container>',\n ' <label>' + label + '</label>',\n ' <input type=\"' + (o.inputType || 'text') + '\"',\n ' aria-label=\"' + title + '\"',\n ' ng-model=\"name\" md-autofocus=\"true\" required />',\n ' </md-input-container>',\n ' </md-dialog-content>',\n ' <md-dialog-actions>',\n ' <md-button ng-click=\"cancel()\">',\n ' ' + l('Cancel'),\n ' </md-button>',\n ' <md-button class=\"md-primary\" ng-click=\"ok()\" ng-disabled=\"!name.length\">',\n ' ' + l('OK'),\n ' </md-button>',\n ' </md-dialog-actions>',\n '</md-dialog>'\n ].join(''),\n controller: PromptDialogController\n });\n\n /**\n * @ngInject\n */\n PromptDialogController.$inject = ['scope', '$mdDialog'];\n function PromptDialogController(scope, $mdDialog) {\n scope.title = title;\n scope.name = \"\";\n scope.cancel = function() {\n d.reject();\n $mdDialog.hide();\n };\n scope.ok = function() {\n d.resolve(scope.name);\n $mdDialog.hide();\n };\n }\n\n return d.promise;\n };\n\n /**\n * @memberof Dialog\n * @desc The factory we'll register as Dialog in the Angular module SOGo.Common\n * @ngInject\n */\n DialogService.$inject = ['$q', '$mdDialog'];\n function DialogService($q, $mdDialog) {\n angular.extend(Dialog, { $q: $q , $modal: $mdDialog });\n\n return Dialog; // return constructor\n }\n\n /* Factory registration in Angular module */\n angular\n .module('SOGo.Common')\n .factory('Dialog', DialogService);\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * Gravatar - A service to build the Gravatar URL for an email address\n * @memberof SOGo.Common\n * @param {string} email\n * @param {number} [size] - the size of the image\n * @param {string} alternate avatar to use (none, identicon, monsterid, wavatar, retro)\n * @ngInject\n */\n function Gravatar() {\n return function(email, size, alternate_avatar, options) {\n var x, y, hash, s = size, a = alternate_avatar;\n if (!email) {\n return '';\n }\n x = email.indexOf('<');\n if (x >= 0) {\n y = email.indexOf('>', x);\n if (y > x)\n email = email.substring(x+1,y);\n }\n if (!size) {\n s = 48; // default to 48 pixels\n }\n hash = email.md5();\n\n if (!a || a == \"none\") {\n if (options && options.no_404)\n alternate_avatar = \"mm\"; // mystery man alternative\n else\n alternate_avatar = \"404\";\n }\n\n return 'https://www.gravatar.com/avatar/' + hash + '?s=' + s + '&d=' + alternate_avatar;\n };\n }\n\n angular\n .module('SOGo.Common')\n .factory('Gravatar', Gravatar);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Resource\n * @constructor\n * @param {Object} $http - the Angular HTTP service\n * @param {Object} $q - the Angular promise/deferred service\n * @param {String} path - the base path of the external resource\n * @param {Object} options - extra attributes to be associated to the object\n */\n function Resource($http, $q, path, activeUser, options) {\n angular.extend(this, {\n _http: $http,\n _q: $q,\n _path: path,\n _activeUser: activeUser\n });\n angular.extend(this, options);\n // Trim trailing slash\n this._path = this._path.replace(/\\/$/, '');\n }\n\n /**\n * @memberof Resource\n * @desc The factory we'll use to register with Angular.\n * @return a new Resource object\n */\n Resource.$factory = ['$http', '$q', function($http, $q) {\n return function(path, activeUser, options) {\n return new Resource($http, $q, path, activeUser, options);\n };\n }];\n\n /**\n * @module SOGo.Common\n * @desc Factory registration of Resource in Angular module.\n */\n angular.module('SOGo.Common').factory('Resource', Resource.$factory);\n\n /**\n * @function userResource\n * @memberof Resource.prototype\n * @desc Create a new Resource object associated to a username different than the active user.\n * @param {String} uid - the user UID\n * @return a new Resource object\n */\n Resource.prototype.userResource = function(uid) {\n var path = _.compact(this._activeUser.folderURL.split('/'));\n path.splice(path.length - 1, 1, escape(uid));\n\n return new Resource(this._http, this._q, '/' + path.join('/'), this._activeUser);\n };\n\n /**\n * @function fetch\n * @memberof Resource.prototype\n * @desc Fetch resource using a specific folder, action and/or parameters.\n * @param {string} folderId - the folder on which the action will be applied (ex: addressbook, calendar)\n * @param {string} action - the action to be used in the URL\n * @param {Object} params - Object parameters injected through the $http service\n * @return a promise\n */\n Resource.prototype.fetch = function(folderId, action, params) {\n var deferred = this._q.defer(),\n path = [this._path];\n if (folderId) path.push(folderId.split('/'));\n if (action) path.push(action);\n path = _.compact(_.flatten(path)).join('/');\n\n this._http({\n method: 'GET',\n url: path,\n params: params\n })\n .then(function(response) {\n return deferred.resolve(response.data);\n }, deferred.reject);\n\n return deferred.promise;\n };\n\n /**\n * @function newguid\n * @memberof Resource.prototype\n * @desc Fetch a new GUID on the specified folder ID.\n * @return a promise of the new data structure\n */\n Resource.prototype.newguid = function(folderId) {\n var deferred = this._q.defer(),\n path = this._path + '/' + folderId + '/newguid';\n\n this._http\n .get(path)\n .then(function(response) {\n return deferred.resolve(response.data);\n }, deferred.reject);\n\n return deferred.promise;\n };\n\n /**\n * @function create\n * @memberof Resource.prototype\n * @desc Create a new resource using a specific action (post).\n * @param {string} action - the action to be used in the URL\n * @param {string} name - the new resource's name\n * @return a promise\n */\n Resource.prototype.create = function(action, name) {\n var deferred = this._q.defer(),\n path = this._path + '/' + action;\n\n this._http\n .post(path, { name: name })\n .then(function(response) {\n return deferred.resolve(response.data);\n }, deferred.reject);\n\n return deferred.promise;\n };\n\n /**\n * @function post\n * @memberof Resource.prototype\n * @desc Post a resource attributes on the server.\n * @return a promise\n */\n Resource.prototype.post = function(id, action, data) {\n var deferred = this._q.defer(),\n path = [this._path];\n if (id) path.push(id);\n if (action) path.push(action);\n path = _.compact(_.flatten(path)).join('/');\n\n this._http\n .post(path, data)\n .then(function(response) {\n return deferred.resolve(response.data);\n }, deferred.reject);\n\n return deferred.promise;\n };\n\n /**\n * @function save\n * @memberof Resource.prototype\n * @desc Save a resource attributes on the server (post /save).\n * @return a promise\n */\n Resource.prototype.save = function(id, newValue, options) {\n var action = (options && options.action)? options.action : 'save';\n\n return this.post(id, action, newValue);\n };\n\n /**\n * @function download\n * @memberof Resource.prototype\n * @desc Download a file from the server. Requires FileSaver.js.\n * @see {@link http://blog.davidjs.com/2015/07/download-files-via-post-request-in-angularjs/|Download files via POST request in AngularJs}\n * @see {@link https://github.com/eligrey/FileSaver.js|FileSaver.js}\n * @return a promise\n */\n Resource.prototype.download = function(id, action, data, options) {\n var deferred = this._q.defer(),\n type = (options && options.type)? options.type : 'application/zip',\n path = [this._path];\n if (id) path.push(id);\n if (action) path.push(action);\n path = _.compact(_.flatten(path)).join('/');\n\n function getFileNameFromHeader(header) {\n var result;\n\n if (!header) return null;\n result = header.split(\";\")[1].trim().split(\"=\")[1];\n\n return result.replace(/\"/g, '');\n }\n\n return this._http({\n method: 'POST',\n url: path,\n data: data,\n headers: {\n accept: type\n },\n responseType: 'arraybuffer',\n cache: false,\n transformResponse: function (data, headers) {\n var fileName, result, blob = null;\n\n if (data) {\n blob = new Blob([data], { type: type });\n }\n fileName = getFileNameFromHeader(headers('content-disposition'));\n\n if (!saveAs) {\n throw new Error('To use Resource.download, FileSaver.js must be loaded.');\n }\n else {\n saveAs(blob, fileName);\n }\n }\n });\n };\n\n /**\n * @function remove\n * @memberof Resource.prototype\n * @desc Delete a resource (get /delete).\n * @return a promise\n */\n Resource.prototype.remove = function(uid) {\n var deferred = this._q.defer(),\n path = this._path + '/' + uid + '/delete';\n\n this._http\n .get(path)\n .then(function(response) {\n return deferred.resolve(response.data);\n }, deferred.reject);\n\n return deferred.promise;\n };\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n \n /**\n * sgFocus - A service to set the focus on the element associated to a specific string\n * @memberof SOGo.Common\n * @param {string} name - the string identifier of the element\n * @see {@link SOGo.Common.sgFocusOn}\n * @ngInject\n */\n sgFocus.$inject = ['$rootScope', '$timeout'];\n function sgFocus($rootScope, $timeout) {\n return function(name) {\n $timeout(function() {\n $rootScope.$broadcast('sgFocusOn', name);\n });\n };\n }\n\n angular\n .module('SOGo.Common')\n .factory('sgFocus', sgFocus);\n})();\n","(function() {\n 'use strict';\n\n /**\n * @name User\n * @constructor\n * @param {object} [userData] - some default values for the user\n */\n function User(userData) {\n if (userData) {\n this.init(userData);\n }\n }\n\n /**\n * @memberof User\n * @desc The factory we'll use to register with Angular.\n * @return the User constructor\n */\n User.factory = ['$q', '$log', 'sgSettings', 'Resource', 'Gravatar', function($q, $log, Settings, Resource, Gravatar) {\n angular.extend(User, {\n $q: $q,\n $log: $log,\n $$resource: new Resource(Settings.activeUser('folderURL'), Settings.activeUser()),\n $gravatar: Gravatar,\n $query: '',\n $users: []\n });\n\n return User;\n }];\n\n /**\n * @module SOGo.Common\n * @desc Factory registration of User in Angular module.\n */\n angular.module('SOGo.Common').factory('User', User.factory);\n\n /**\n * @memberof User\n * @desc Search for users that match a string.\n * @param {string} search - a string used to performed the search\n * @param {object[]} excludedUsers - a list of User objects that must be excluded from the results\n * @return a promise of an array of matching User objects\n */\n User.$filter = function(search, excludedUsers, options) {\n var _this = this, param = {search: search};\n\n if (!options || !options.dry) {\n if (!search) {\n // No query specified\n User.$users.splice(0, User.$users.length);\n return User.$q.when(User.$users);\n }\n if (User.$query == search) {\n // Query hasn't changed\n return User.$q.when(User.$users);\n }\n User.$query = search;\n }\n\n return User.$$resource.fetch(null, 'usersSearch', param).then(function(response) {\n var results, index, user, users,\n compareUids = function(data) {\n return this.uid == data.uid;\n };\n\n if (options) {\n if (options.dry)\n users = [];\n else if (options.results)\n users = options.results;\n }\n else\n users = User.$users;\n\n if (excludedUsers) {\n // Remove excluded users from response\n results = _.filter(response.users, function(user) {\n return !_.find(excludedUsers, _.bind(compareUids, user));\n });\n }\n else {\n results = response.users;\n }\n\n // Remove users that no longer match the search query\n for (index = users.length - 1; index >= 0; index--) {\n user = users[index];\n if (!_.find(results, _.bind(compareUids, user))) {\n users.splice(index, 1);\n }\n }\n // Add new users matching the search query\n _.forEach(results, function(data, index) {\n if (_.isUndefined(_.find(users, _.bind(compareUids, data)))) {\n var user = new User(data);\n users.splice(index, 0, user);\n }\n });\n User.$log.debug(users);\n return users;\n });\n };\n\n /**\n * @function init\n * @memberof User.prototype\n * @desc Extend instance with required attributes and new data.\n * @param {object} data - attributes of user\n */\n User.prototype.init = function(data) {\n angular.extend(this, data);\n if (!this.$$shortFormat)\n this.$$shortFormat = this.$shortFormat();\n if (!this.$$image)\n this.$$image = this.image || User.$gravatar(this.c_email, 32, User.$alternateAvatar, {no_404: true});\n\n // An empty attribute to trick md-autocomplete when adding users from the ACLs editor\n this.empty = ' ';\n };\n\n /**\n * @function $shortFormat\n * @memberof User.prototype\n * @return the fullname along with the email address\n */\n User.prototype.$shortFormat = function(options) {\n var fullname = this.cn || this.c_email;\n var email = this.c_email;\n var no_email = options && options.email === false;\n if (!no_email && email && fullname != email) {\n fullname += ' <' + email + '>';\n }\n return fullname;\n };\n\n /**\n * @function $acl\n * @memberof User.prototype\n * @desc Fetch the user rights associated to a specific folder and populate the 'rights' attribute.\n * @param {string} the folder ID\n * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser\n * @return a promise\n */\n User.prototype.$acl = function(folderId, owner) {\n var _this = this,\n deferred = User.$q.defer(),\n param = {uid: this.uid};\n if (this.$shadowRights) {\n deferred.resolve(this.rights);\n }\n else {\n var rights;\n\n if (angular.isDefined(owner))\n rights = User.$$resource.userResource(owner).fetch(folderId, 'userRights', param);\n else\n rights = User.$$resource.fetch(folderId, 'userRights', param);\n\n rights.then(function(data) {\n _this.rights = data;\n // Convert numbers (0|1) to boolean values\n //angular.forEach(_.keys(_this.rights), function(key) {\n // _this.rights[key] = _this.rights[key] ? true : false;\n //});\n // console.debug('rights ' + _this.uid + ' => ' + JSON.stringify(data, undefined, 2));\n // Keep a copy of the server's version\n _this.$shadowRights = angular.copy(data);\n deferred.resolve(data);\n return data;\n });\n }\n return deferred.promise;\n };\n\n /**\n * @function $isAnonymous\n * @memberof User.prototype\n * @return true if it's the special anonymous user\n */\n User.prototype.$isAnonymous = function() {\n return this.uid == 'anonymous';\n };\n\n /**\n * @function $isSpecial\n * @memberof User.prototype\n * @desc Only accurate from the ACL editor.\n * @return true if the user is not a regular system user\n */\n User.prototype.$isSpecial = function() {\n return this.userClass && this.userClass == 'public-user';\n };\n\n /**\n * @function $confirmRights\n * @memberof User.prototype\n * @desc Check if a confirmation is required before giving some rights.\n * @return the confirmation message or false if no confirmation is required\n */\n User.prototype.$confirmRights = function(folder) {\n var confirmation = false;\n\n if (this.$confirmation) {\n // Don't bother the user more than once\n return false;\n }\n\n if (_.some(_.values(this.rights))) {\n if (this.uid == 'anonymous') {\n if (folder.constructor.name == 'AddressBook')\n confirmation = l('Potentially anyone on the Internet will be able to access your address book \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?', folder.name);\n else if (folder.constructor.name == 'Calendar')\n confirmation = l('Potentially anyone on the Internet will be able to access your calendar \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?', folder.name);\n }\n else if (this.uid == 'anyone' || this.uid == '<default>') {\n if (folder.constructor.name == 'AddressBook')\n confirmation = l('Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?', folder.name);\n else if (folder.constructor.name == 'Calendar')\n confirmation = l('Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?', folder.name);\n else if (folder.constructor.name == 'Mailbox')\n confirmation = l('Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?', folder.name);\n }\n }\n\n this.$confirmation = confirmation;\n\n return confirmation;\n };\n\n /**\n * @function $rightsAreDirty\n * @memberof User.prototype\n * @return whether or not the rights have changed from their initial values\n */\n User.prototype.$rightsAreDirty = function() {\n return this.rights && !_.isEqual(this.rights, this.$shadowRights);\n };\n\n /**\n * @function $resetRights\n * @memberof User.prototype\n * @desc Restore initial rights or disable all rights\n * @param {boolean} [zero] - reset all rights to zero when true\n */\n User.prototype.$resetRights = function(zero) {\n var _this = this;\n if (zero) {\n // Disable all rights\n _.map(_.keys(this.rights), function(key) {\n if (angular.isString(_this.rights[key]))\n _this.rights[key] = 'None';\n else\n _this.rights[key] = 0;\n });\n }\n else {\n // Restore initial rights\n this.rights = angular.copy(this.$shadowRights);\n }\n };\n\n /**\n * @function $folders\n * @memberof User.prototype\n * @desc Retrieve the list of folders of a specific type\n * @param {string} type - either 'contact' or 'calendar'\n * @return a promise of the HTTP query result or the cached result\n */\n User.prototype.$folders = function(type) {\n var _this = this,\n deferred = User.$q.defer(),\n param = {type: type};\n if (this.$$folders) {\n deferred.resolve(this.$$folders);\n }\n else {\n User.$$resource.userResource(this.uid).fetch(null, 'foldersSearch', param).then(function(response) {\n _this.$$folders = response.folders;\n deferred.resolve(response.folders);\n });\n }\n return deferred.promise;\n };\n\n /**\n * @function $omit\n * @memberof User.prototype\n * @desc Return a sanitized object used to send to the server.\n * @return an object literal copy of the User instance\n */\n User.prototype.$omit = function() {\n var user = {};\n angular.forEach(this, function(value, key) {\n if (key != 'constructor' && key[0] != '$') {\n user[key] = value;\n }\n });\n return user;\n };\n\n User.prototype.toString = function() {\n return '[User ' + this.c_email + ']';\n };\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint validthis: true, newcap: false */\n 'use strict';\n\n /**\n * sgAvatarImage - An avatar directive that returns un img element with either a local URL (if sg-src is specified)\n * or a Gravatar URL built from the Gravatar factory (using sg-email).\n * Based on http://blog.lingohub.com/2014/08/better-ux-with-angularjs-directives/.\n * @memberof SOGo.Common\n * @example:\n <sg-avatar-image sg-email=\"test@email.com\" size=\"50\"></sg-avatar-image>\n */\n function sgAvatarImage() {\n return {\n restrict: 'AE',\n scope: {},\n bindToController: {\n size: '@',\n email: '=sgEmail',\n src: '=sgSrc'\n },\n template: [\n '<md-icon>person</md-icon>', // the generic icon\n '<img class=\"ng-hide\" ng-src=\"{{vm.url}}\" />' // the gravatar or local image\n ].join(''),\n link: link,\n controller: 'sgAvatarImageController',\n controllerAs: 'vm'\n };\n }\n\n function link(scope, element, attrs, controller) {\n var imgElement = element.find('img'),\n mdIconElement = element.find('md-icon');\n\n if (attrs.size) {\n imgElement.attr('width', attrs.size);\n imgElement.attr('height', attrs.size);\n mdIconElement.css('font-size', attrs.size + 'px');\n }\n\n controller.img = imgElement;\n controller.genericImg = mdIconElement;\n }\n\n /**\n * @ngInject\n */\n sgAvatarImageController.$inject = ['$scope', '$element', '$http', '$q', 'Preferences', 'Gravatar'];\n function sgAvatarImageController($scope, $element, $http, $q, Preferences, Gravatar) {\n var vm;\n\n vm = this;\n\n // Wait on user's defaults\n Preferences.ready().then(function() {\n $scope.$watch(function() { return vm.email; }, function(email, old) {\n if (email && vm.urlEmail != email) {\n // Email has changed or doesn't match the current URL (this happens when using md-virtual-repeat)\n showGenericAvatar();\n if (Preferences.defaults.SOGoGravatarEnabled)\n getGravatar(email);\n }\n else if (!email)\n showGenericAvatar();\n });\n });\n\n // If sg-src is defined, watch the expression for the URL of a local image\n if ('sg-src' in $element[0].attributes) {\n $scope.$watch(function() { return vm.src; }, function(src) {\n if (src) {\n // Set image URL and save the associated email address\n vm.url = src;\n vm.urlEmail = '' + vm.email;\n hideGenericAvatar();\n }\n });\n }\n\n function getGravatar(email) {\n var url = Gravatar(email, vm.size, Preferences.defaults.SOGoAlternateAvatar);\n $http({\n method: 'GET',\n url: url,\n cache: true,\n headers: { Accept: 'image/*' }\n }).then(function successCallback() {\n if (!vm.url) {\n // Set image URL and save the associated email address\n vm.url = url;\n vm.urlEmail = email;\n hideGenericAvatar();\n }\n }, function errorCallback() {\n showGenericAvatar();\n });\n }\n\n function showGenericAvatar() {\n vm.url = null;\n vm.urlEmail = null;\n vm.img.addClass('ng-hide');\n vm.genericImg.removeClass('ng-hide');\n }\n\n function hideGenericAvatar() {\n vm.genericImg.addClass('ng-hide');\n vm.img.removeClass('ng-hide');\n }\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgAvatarImage', sgAvatarImage)\n .controller('sgAvatarImageController', sgAvatarImageController);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n angular\n .module('SOGo.Common')\n .directive('sgCheckmark', sgCheckmarkDirective);\n\n /*\n * sgCheckmark - A checkmark to be used in a mdMenuItem\n * @memberof SOGo.Common\n * @restrict element\n *\n * @example:\n\n <md-menu>\n <md-button class=\"md-icon-button\" aria-label=\"Sort\"\n ng-click=\"$mdOpenMenu()\">\n <md-icon>sort</md-icon>\n </md-button>\n <md-menu-content>\n <md-menu-item>\n <sg-checkmark\n aria-label=\"Descending Order\"\n ng-model=\"ctrl.asc\"\n ng-click=\"ctrl.filter()\"\n sg-true-value=\"0\"\n sg-false-value=\"1\">Descending Order</sg-checkmark>\n </md-menu-item> \n </md-menu-content>\n </md-menu>\n */\n sgCheckmarkDirective.$inject = ['$parse', '$mdAria', '$mdTheming', '$mdUtil'];\n function sgCheckmarkDirective($parse, $mdAria, $mdTheming, $mdUtil) {\n var CHECKED_CSS = 'sg-checked';\n\n return {\n restrict: 'E',\n replace: true,\n transclude: true,\n require: '?ngModel',\n //priority: 210, // Run before ngAria\n template: [\n '<button class=\"md-button sg-checkmark\" type=\"button\">',\n ' <md-icon>check</md-icon>',\n ' <span ng-transclude></span',\n '</button>'\n ].join(''),\n compile: compile\n };\n\n function compile(tElement, tAttrs) {\n\n // Attach a click handler in compile in order to immediately stop propagation\n // (especially for ng-click) when the checkmark is disabled.\n tElement.on('click', function(event) {\n if (this.hasAttribute('disabled')) {\n event.stopImmediatePropagation();\n }\n });\n\n return function postLink(scope, element, attr, ngModelCtrl) {\n // See https://github.com/angular/angular.js/commit/c90cefe16142d973a123e945fc9058e8a874c357\n var trueValue = parseConstantExpr($parse, scope, 'sgTrueValue', attr.sgTrueValue, true),\n falseValue = parseConstantExpr($parse, scope, 'sgFalseValue', attr.sgFalseValue, false);\n \n ngModelCtrl = ngModelCtrl || $mdUtil.fakeNgModel();\n $mdTheming(element);\n\n $mdAria.expectWithText(element, 'aria-label');\n\n element.on('click', listener);\n\n ngModelCtrl.$render = render;\n\n function parseConstantExpr($parse, context, name, expression, fallback) {\n var parseFn;\n if (angular.isDefined(expression)) {\n parseFn = $parse(expression);\n if (!parseFn.constant) {\n throw Error('Expected constant expression for `' + name + '`, but saw `' + expression + '`.');\n }\n return parseFn(context);\n }\n return fallback;\n }\n\n function listener(ev) {\n if (element[0].hasAttribute('disabled')) {\n return;\n }\n\n scope.$apply(function() {\n // Toggle the checkmark value\n var viewValue = ngModelCtrl.$viewValue == trueValue? falseValue : trueValue;\n\n ngModelCtrl.$setViewValue( viewValue, ev && ev.type);\n ngModelCtrl.$render();\n });\n }\n\n function render() {\n if (ngModelCtrl.$viewValue == trueValue)\n element.addClass(CHECKED_CSS);\n else\n element.removeClass(CHECKED_CSS);\n }\n };\n }\n }\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint validthis: true */\n 'use strict';\n\n /*\n * sgColorPicker - Color picker widget\n * @restrict element\n * @param {function} sgOnSelect - the function to call when clicking on a color.\n * One variable is available: color.\n * @ngInject\n * @example:\n\n <sg-color-picker sg-on-select=\"properties.calendar.color = color\"></sg-color-picker>\n */\n function sgColorPicker() {\n return {\n restrict: 'E',\n require: 'ngModel',\n template: [\n '<md-menu>',\n ' <md-button class=\"md-icon-button\"',\n ' label:aria-label=\"Options\"',\n ' ng-style=\"{ \\'background-color\\': sgColor }\"',\n ' ng-click=\"$mdOpenMenu()\"',\n ' md-menu-origin=\"md-menu-origin\">',\n ' <md-icon ng-style=\"{ color: sgIconColor }\">color_lens</md-icon>',\n ' </md-button>',\n ' <md-menu-content width=\"3\">',\n ' <md-content class=\"md-padding\">',\n ' <md-grid-list class=\"sg-color-picker\" md-cols=\"7\" md-row-height=\"1:1\" md-gutter=\"0.5em\">',\n ' <md-grid-tile ng-repeat=\"color in ::sgColors track by $index\"',\n ' ng-style=\"{ \\'background-color\\': color }\"',\n ' ng-class=\"{ selected: color == sgColor }\"',\n ' ng-click=\"setColor(color)\"><md-icon ng-style=\"{ color: color }\">check_box</md-icon></md-grid-tile>',\n ' </md-grid-list>',\n ' </md-content>',\n ' </md-menu-content>',\n '</md-menu>'\n ].join(''),\n replace: true,\n controller: sgColorPickerController,\n link: link\n };\n\n function link(scope, iElement, iAttr, ngModelController) {\n // Expose ng-model value to scope\n ngModelController.$render = function() {\n scope.sgColor = ngModelController.$viewValue;\n scope.sgIconColor = contrast(ngModelController.$viewValue);\n };\n }\n }\n \n /**\n * @ngInject\n */\n sgColorPickerController.$inject = ['$scope', '$element', 'sgColors'];\n function sgColorPickerController($scope, $element, sgColors) {\n var ngModelController = $element.controller('ngModel');\n\n $scope.sgColors = sgColors.selection;\n $scope.setColor = function(color) {\n // Update scope value and ng-model\n $scope.sgColor = color;\n $scope.sgIconColor = contrast(color);\n ngModelController.$setViewValue(color);\n };\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgColorPicker', sgColorPicker);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /*\n * sgCompile - Assign an expression to a DOM element and compile it.\n * @memberof SOGo.Common\n * @restrict attribute\n * @param {object} sgCompile - the expression to compile\n * @ngInject\n * @example:\n\n <div sg-compile=\"part.content\"><!-- msg --></div>\n */\n sgCompile.$inject = ['$compile'];\n function sgCompile($compile) {\n return {\n restrict: 'A',\n link: sgCompileLink\n };\n\n function sgCompileLink(scope, element, attrs) {\n var ensureCompileRunsOnce = scope.$watch(\n function(scope) {\n // Watch the sg-compile expression for changes\n return scope.$eval(attrs.sgCompile);\n },\n function(value) {\n // When the sg-compile expression changes, assign it into the current DOM\n element.html(value);\n \n // Compile the new DOM and link it to the current scope.\n // NOTE: we only compile .childNodes so that we don't get into infinite loop compiling ourselves\n $compile(element.contents())(scope);\n \n // Use un-watch feature to ensure compilation happens only once.\n ensureCompileRunsOnce();\n }\n );\n }\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgCompile', sgCompile);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * sgEnter - A directive evaluated when the enter key is pressed\n * @memberof SOGo.Common\n * @ngInject\n * @example:\n\n <input type=\"text\"\n sg-enter=\"save($index)\" />\n */\n function sgEnter() {\n var ENTER_KEY = 13;\n return function(scope, element, attrs) {\n element.bind(\"keydown keypress\", function(event) {\n if (event.which === ENTER_KEY) {\n scope.$apply(attrs.sgEnter);\n event.preventDefault();\n }\n });\n };\n }\n \n angular\n .module('SOGo.Common')\n .directive('sgEnter', sgEnter);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * sgEscape - A directive evaluated when the escape key is pressed\n * @memberof SOGo.Common\n * @ngInject\n * @example:\n\n <input type=\"text\"\n sg-escape=\"revertEditing($index)\" />\n */\n function sgEscape() {\n var ESCAPE_KEY = 27;\n return function(scope, elem, attrs) {\n elem.bind('keydown', function(event) {\n if (event.keyCode === ESCAPE_KEY) {\n scope.$apply(attrs.sgEscape);\n }\n });\n };\n }\n \n angular\n .module('SOGo.Common')\n .directive('sgEscape', sgEscape);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * sgFocusOn - A directive that sets the focus on its element when the specified string is broadcasted\n * @memberof SOGo.Common\n * @see {@link SOGo.Common.sgFocus}\n * @ngInject\n * @example:\n\n <input type=\"text\"\n sg-focus-on=\"username\" />\n */\n function sgFocusOn() {\n return function(scope, elem, attr) {\n scope.$on('sgFocusOn', function(e, name) {\n if (name === attr.sgFocusOn) {\n elem[0].focus();\n elem[0].select();\n }\n });\n };\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgFocusOn', sgFocusOn);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint validthis: true */\n 'use strict';\n\n /*\n * sgFolderStylesheet - Add CSS stylesheet for a folder's color (addressbook or calendar)\n * @memberof SOGo.Common\n * @restrict attribute\n * @param {object} ngModel - the object literal describing the folder (an Addressbook or Calendar instance)\n * @example:\n\n <sg-folder-stylesheet\n ng-repeat=\"calendar in calendars.list\"\n ng-model=\"calendar\" />\n */\n function sgFolderStylesheet() {\n return {\n restrict: 'E',\n require: 'ngModel',\n scope: {\n ngModel: '='\n },\n replace: true,\n bindToController: true,\n controller: sgFolderStylesheetController,\n controllerAs: 'cssCtrl',\n template: [\n '<style type=\"text/css\">',\n /* Background color */\n ' .bg-folder{{ cssCtrl.ngModel.id }} {',\n ' background-color: {{ cssCtrl.ngModel.color }} !important;',\n ' color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' }',\n ' .sg-event.bg-folder{{ cssCtrl.ngModel.id }} md-icon {',\n ' color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' }',\n // Set the contrast color of toolbar icons except the one of the background\n ' md-toolbar.bg-folder{{ cssCtrl.ngModel.id }} md-icon:not(.sg-icon-toolbar-bg) {',\n ' color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' }',\n // Set the contrast color of input labels\n ' .bg-folder{{ cssCtrl.ngModel.id }} label,',\n ' .bg-folder{{ cssCtrl.ngModel.id }} .md-input {',\n ' color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' opacity: 0.8;',\n ' }',\n /* Foreground color */\n ' .fg-folder{{ cssCtrl.ngModel.id }},',\n ' .sg-event.fg-folder{{ cssCtrl.ngModel.id }} md-icon {',\n ' color: {{ cssCtrl.ngModel.color }} !important;',\n ' }',\n /* Border color */\n ' .bdr-folder{{ cssCtrl.ngModel.id }} {',\n ' border-color: {{ cssCtrl.ngModel.color }} !important;',\n ' }',\n ' .contrast-bdr-folder{{ cssCtrl.ngModel.id }} {',\n ' border-color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' }',\n /* Checkbox color */\n ' .checkbox-folder{{ cssCtrl.ngModel.id }} ._md-icon {',\n ' background-color: {{ cssCtrl.ngModel.color }} !important;',\n ' }',\n ' .checkbox-folder{{ cssCtrl.ngModel.id }}.md-checked ._md-icon:after {',\n ' border-color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' }',\n '</style>'\n ].join('')\n };\n\n function sgFolderStylesheetController() {\n var vm = this;\n\n vm.contrast = contrast; // defined in Common/utils.js\n }\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgFolderStylesheet', sgFolderStylesheet);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * sgPlaceholder - A directive for dynamic placeholder\n * @memberof SOGo.Common\n * @ngInject\n * @example:\n\n <input type=\"text\"\n sg-placeholder=\"this_is_a_variable\" />\n */\n function sgPlaceholder() {\n return {\n restrict: 'A',\n scope: {\n placeholder: '=sgPlaceholder'\n },\n link: function(scope, elem, attr) {\n scope.$watch('placeholder',function() {\n elem[0].placeholder = scope.placeholder;\n });\n }\n };\n }\n \n angular\n .module('SOGo.Common')\n .directive('sgPlaceholder', sgPlaceholder);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint validthis: true */\n 'use strict';\n\n /*\n * sgSearch - Search within a list of items\n * @memberof SOGo.Common\n * @restrict attribute\n * @param {function} sgSearch - the function to call when performing a search.\n * Two variables are available: searchField and searchText.\n * @example:\n\n <div sg-search=\"mailbox.$filter({ sort: 'date', asc: false }, [{ searchBy: searchField, searchInput: searchText }])\">\n <md-button class=\"sg-icon-button\"\n sg-search-cancel=\"ctrl.cancelSearch()\">\n <md-icon>arrow_back</md-icon>\n </md-button>\n <md-input-container>\n <input name=\"search\" type=\"search\"/>\n </md-input-container>\n <md-select class=\"sg-toolbar-sort md-contrast-light\">\n <md-option value=\"subject\">Subject</md-option>\n <md-option value=\"sender\">sender</md-option>\n </md-select>\n </div>\n */\n sgSearchPreTransclude.$inject = ['$parse'];\n function sgSearchPreTransclude($parse) {\n return {\n restrict: 'A',\n controller: 'sgSearchController',\n controllerAs: '$sgSearchController',\n priority: 1001,\n compile: compile\n };\n\n function compile(tElement, tAttr) {\n var mdInputEl = tElement.find('md-input-container'),\n inputEl = tElement.find('input'),\n selectEl = tElement.find('md-select'),\n buttonEl = tElement.find('md-button');\n\n inputEl.attr('ng-model', '$sgSearchController.searchText');\n inputEl.attr('ng-model-options', '$sgSearchController.searchTextOptions');\n inputEl.attr('ng-change', '$sgSearchController.onChange()');\n if (selectEl) {\n selectEl.attr('ng-model', '$sgSearchController.searchField');\n selectEl.attr('ng-change', '$sgSearchController.onChange()');\n }\n if (buttonEl && buttonEl.attr('sg-search-cancel')) {\n buttonEl.attr('ng-click', buttonEl.attr('sg-search-cancel'));\n buttonEl.removeAttr('sg-search-cancel');\n }\n else {\n buttonEl = null;\n }\n\n return function postLink(scope, iElement, iAttr, controller) {\n var compiledButtonEl = iElement.find('button');\n\n // Retrive the form and input names to check the form's validity in the controller\n controller.formName = iElement.attr('name');\n controller.inputName = inputEl.attr('name');\n\n // Associate the sg-allow-dot parameter (boolean) to the controller\n controller.allowDot = $parse(iElement.attr('sg-allow-dot'))(scope);\n\n // Associate callback to controller\n controller.doSearch = $parse(iElement.attr('sg-search'));\n\n // Reset the input field when cancelling the search\n if (buttonEl && compiledButtonEl) {\n compiledButtonEl.on('click', controller.cancelSearch);\n }\n };\n }\n }\n\n function sgSearch() {\n return {\n restrict: 'A',\n priority: 1000,\n transclude: true,\n compile: compile\n };\n\n function compile(tElement, tAttr) {\n return function postLink(scope, iElement, iAttr, controller, transclude) {\n transclude(function(clone) {\n iElement.append(clone);\n });\n };\n }\n }\n\n /**\n * @ngInject\n */\n sgSearchController.$inject = ['$window', '$scope', '$element'];\n function sgSearchController($window, $scope, $element) {\n var vm = this, minLength;\n\n // Domain's defaults\n minLength = angular.isNumber($window.minimumSearchLength)? $window.minimumSearchLength : 2;\n\n // Controller variables\n vm.searchText = null;\n\n // Model options\n vm.searchTextOptions = {\n updateOn: 'default blur',\n debounce: {\n default: 300,\n blur: 0\n }\n };\n\n // Method to call on data changes\n vm.onChange = function() {\n var form = $scope[vm.formName],\n input = form[vm.inputName],\n rawSearchText = input.$viewValue;\n\n if (vm.allowDot && rawSearchText == '.' || form.$valid && rawSearchText) {\n if (rawSearchText == '.')\n // Ignore the minlength constraint when using the dot operator\n input.$setValidity('minlength', true);\n\n // doSearch is the compiled expression of the sg-search attribute\n vm.doSearch($scope, { searchText: rawSearchText, searchField: vm.searchField });\n }\n };\n\n // Reset input field when cancelling the search\n vm.cancelSearch = function() {\n vm.searchText = null;\n };\n }\n\n angular\n .module('SOGo.Common')\n .controller('sgSearchController', sgSearchController)\n .directive('sgSearch', sgSearchPreTransclude)\n .directive('sgSearch', sgSearch);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * sgSelectOnly - A directive that restricts an autocomplete field to its selectable values.\n * @memberof SOGo.Common\n * @ngInject\n * @example:\n\n <md-autocomplete\n md-items=\"timezone in timeZones\"\n ng-required=\"true\"\n sg-select-only>\n */\n function sgSelectOnly() {\n return {\n link: postLink,\n require: 'mdAutocomplete',\n restrict: 'A'\n };\n\n function postLink(scope, element, attrs, autoComplete) {\n function getInput() {\n return element.find('input').eq(0);\n }\n\n // We need to wait for the autocomplete directive to be compiled\n var listener = scope.$watch(getInput, function (input) {\n var ngModel;\n\n if (input.length) {\n listener(); // self release\n ngModel = input.controller('ngModel');\n input.on('blur', function () {\n if (!autoComplete.scope.selectedItem) {\n scope.$applyAsync(ngModel.$setValidity('required', false));\n }\n });\n }\n });\n }\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgSelectOnly', sgSelectOnly);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint validthis: true */\n 'use strict';\n\n /*\n * sgSubscribe - Common subscription widget\n * @restrict attribute\n * @param {string} sgSubscribe - the folder type\n * @param {function} sgSubscribeOnSelect - the function to call when subscribing to a folder.\n * One variable is available: folderData.\n * @ngInject\n * @example:\n\n <md-button sg-subscribe=\"contact\" sg-subscribe-on-select=\"subscribeToFolder\">Subscribe ..</md-button>\n */\n sgSubscribe.$inject = ['User'];\n function sgSubscribe(User) {\n return {\n restrict: 'A',\n scope: {\n folderType: '@sgSubscribe',\n onFolderSelect: '&sgSubscribeOnSelect'\n },\n replace: false,\n bindToController: true,\n controller: sgSubscribeDialogController,\n controllerAs: '$sgSubscribeDialogController',\n link: link\n };\n }\n\n function link(scope, element, attrs, controller) {\n var inputEl = element.find('input');\n element.on('click', controller.showDialog);\n }\n\n /**\n * @ngInject\n */\n sgSubscribeDialogController.$inject = ['$mdDialog'];\n function sgSubscribeDialogController($mdDialog) {\n var vm = this;\n vm.showDialog = function() {\n $mdDialog.show({\n templateUrl: '../Contacts/UIxContactsUserFolders',\n clickOutsideToClose: true,\n locals: {\n folderType: vm.folderType,\n onFolderSelect: vm.onFolderSelect\n },\n controller: sgSubscribeController,\n controllerAs: 'subscribe'\n });\n };\n }\n\n /**\n * @ngInject\n */\n sgSubscribeController.$inject = ['$mdDialog', 'folderType', 'onFolderSelect', 'User'];\n function sgSubscribeController($mdDialog, folderType, onFolderSelect, User) {\n var vm = this;\n\n vm.selectedUser = null;\n vm.users = [];\n\n vm.searchTextOptions = {\n updateOn: 'default blur',\n debounce: {\n default: 300,\n blur: 0\n }\n };\n\n vm.onChange = function(input) {\n User.$filter(vm.searchText, null, { results: vm.users }).then(function(users) {\n input.$setValidity('matches', users.length > 0);\n input.$setTouched();\n if (vm.selectedUser) {\n // If selected user is no longer part of the matching users, unselect it\n if (_.isUndefined(_.find(users, function(user) {\n return user.uid == vm.selectedUser.uid;\n }))) {\n vm.selectedUser = null;\n }\n }\n });\n };\n\n vm.selectUser = function(i) {\n if (vm.selectedUser == vm.users[i]) {\n vm.selectedUser = null;\n }\n else {\n // Fetch folders of specific type for selected user\n vm.users[i].$folders(folderType).then(function() {\n vm.selectedUser = vm.users[i];\n });\n }\n };\n\n // Callback upon subscription to a folder\n vm.selectFolder = function(folder) {\n onFolderSelect({folderData: folder});\n };\n\n vm.close = function() {\n $mdDialog.hide();\n };\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgSubscribe', sgSubscribe);\n})();\n","(function() {\n 'use strict';\n\n angular\n .module('SOGo.Common')\n .directive('sgTimePane', timePaneDirective);\n \n function timePaneDirective() {\n return {\n template: [\n '<div class=\"sg-time-pane\">',\n ' <div class=\"hours-pane\">',\n ' <div ng-repeat=\"hoursBigLine in hours\" layout=\"row\" layout-xs=\"column\">',\n ' <div ng-repeat=\"hoursLine in hoursBigLine\" layout=\"row\" class=\"hours\">',\n ' <md-button class=\"hourBtn sg-time-selection-indicator\" id=\"{{hour.id}}\"',\n ' md-no-ink',\n ' ng-repeat=\"hour in hoursLine\"',\n ' ng-click=\"hourClickHandler(hour.displayName)\">{{hour.displayName}}</md-button>',\n ' </div>',\n ' </div>',\n ' </div>',\n ' <div class=\"min5\" ng-show=\"is5min()\">',\n ' <div layout=\"row\" layout-xs=\"column\">',\n ' <div ng-repeat=\"minutesLine in min5\" layout=\"row\">',\n ' <md-button class=\"minuteBtn sg-time-selection-indicator\" id=\"{{minute.id}}\"',\n ' md-no-ink',\n ' ng-repeat=\"minute in minutesLine\"',\n ' ng-click=\"minuteClickHandler(minute.displayName)\">{{minute.displayName}}</md-button>',\n ' </div>',\n ' </div>',\n ' </div>',\n ' <div class=\"sg-time-scroll-mask\" ng-hide=\"is5min()\">',\n ' <div class=\"min1\" layout=\"row\" layout-xs=\"column\" layout-wrap>',\n ' <div ng-repeat=\"minutesLine in min1\" layout=\"row\" layout-align=\"space-around center\">',\n ' <md-button class=\"minuteBtn sg-time-selection-indicator\" id=\"{{minute.id}}\"',\n ' md-no-ink',\n ' ng-repeat=\"minute in minutesLine\"',\n ' ng-click=\"minuteClickHandler(minute.displayName)\">{{minute.displayName}}</md-button>',\n ' </div>',\n ' </div>',\n ' </div>',\n ' <div flex layout=\"row\" layout-align=\"center center\" md-colors=\"::{background: \\'default-background-200\\'}\">',\n ' <md-button class=\"toggleBtn md-fab md-mini\" ng-bind=\"getToggleBtnLbl()\" ng-click=\"toggleManual5min()\"></md-button>',\n ' </div>',\n '</div>'\n ].join(''),\n scope: {},\n require: ['ngModel', 'sgTimePane', '?^mdInputContainer'],\n controller: TimePaneCtrl,\n controllerAs: 'ctrl',\n bindToController: true,\n link: function(scope, element, attrs, controllers) {\n var ngModelCtrl = controllers[0];\n var sgTimePaneCtrl = controllers[1];\n\n var mdInputContainer = controllers[2];\n if (mdInputContainer) {\n throw Error('sg-timepicker should not be placed inside md-input-container.');\n }\n\n var timePaneElement = element;\n sgTimePaneCtrl.configureNgModel(ngModelCtrl, sgTimePaneCtrl, timePaneElement);\n }\n };\n }\n\n /** Class applied to the selected hour or minute cell/. */\n var SELECTED_TIME_CLASS = 'sg-time-selected';\n\n /** Class applied to the focused hour or minute cell/. */\n var FOCUSED_TIME_CLASS = 'md-focus';\n\n /** Next identifier for calendar instance. */\n var nextTimePaneUniqueId = 0;\n\n function TimePaneCtrl($element, $attrs, $scope, $animate, $q, $mdConstant,\n $mdTheming, $$mdDateUtil, $mdDateLocale, $mdInkRipple, $mdUtil) {\n var m;\n this.$scope = $scope;\n this.$element = $element;\n this.timePaneElement = $element[0].querySelector('.sg-time-pane');\n this.$animate = $animate;\n this.$q = $q;\n this.$mdInkRipple = $mdInkRipple;\n this.$mdUtil = $mdUtil;\n this.keyCode = $mdConstant.KEY_CODE;\n this.dateUtil = $$mdDateUtil;\n this.id = nextTimePaneUniqueId++;\n this.ngModelCtrl = null;\n this.selectedTime = null;\n this.displayTime = null;\n this.isInitialized = false;\n\n $scope.hours=[];\n $scope.hours[0]=[];\n $scope.hours[0][0]=[];\n $scope.hours[0][1]=[];\n $scope.hours[1]=[];\n $scope.hours[1][0]=[];\n $scope.hours[1][1]=[];\n for(var i=0; i<6; i++){\n $scope.hours[0][0][i] = {id:'tp-'+this.id+'-hour-'+i, displayName:i<10?\"0\"+i:\"\"+i, selected:false};\n $scope.hours[0][1][i] = {id:'tp-'+this.id+'-hour-'+(i+6),displayName:(i+6)<10?\"0\"+(i+6):\"\"+(i+6), selected:false};\n $scope.hours[1][0][i] = {id:'tp-'+this.id+'-hour-'+(i+12), displayName:\"\"+(i+12), selected:false};\n $scope.hours[1][1][i] = {id:'tp-'+this.id+'-hour-'+(i+18), displayName:\"\"+(i+18), selected:false};\n }\n\n $scope.min5=[];\n $scope.min5[0]=[];\n $scope.min5[1]=[];\n for(i=0; i<6; i++){\n m=i*5;\n $scope.min5[0][i] = {id:'tp-'+this.id+'-minute5-'+m, displayName:m<10?\":0\"+m:\":\"+m, selected:true};\n $scope.min5[1][i] = {id:'tp-'+this.id+'-minute5-'+(m+30), displayName:\":\"+(m+30), selected:false};\n }\n\n $scope.min1=[];\n for(i=0; i<12; i++){\n $scope.min1[i]=[];\n for(var ii=0; ii<5; ii++){\n m=i*5 + ii;\n $scope.min1[i][ii] = {id:'tp-'+this.id+'-minute-'+m, displayName:m<10?\":0\"+m:\":\"+m, selected:true};\n }\n }\n\n $scope.show5min = true;\n $scope.getToggleBtnLbl = function() {\n return ($scope.is5min()) ? '>>' : '<<';\n };\n $scope.toggleManual5min = function() {\n $scope.manual5min = !$scope.is5min();\n };\n $scope.is5min = function() {\n if ($scope.manual5min === true || $scope.manual5min === false) {\n return $scope.manual5min;\n }\n else {\n return $scope.show5min;\n }\n };\n\n if (!$attrs.tabindex) {\n $element.attr('tabindex', '-1');\n }\n\n var self = this;\n\n this.hourClickHandler = function(displayVal) {\n var updated = new Date(self.displayTime);\n updated.setHours(Number(displayVal));\n self.setNgModelValue(updated, 'hours');\n };\n $scope.hourClickHandler = this.hourClickHandler;\n\n this.minuteClickHandler = function(displayVal) {\n //remove leading ':'\n var val = displayVal.substr(1);\n var updated = new Date(self.displayTime);\n updated.setMinutes(Number(val));\n self.setNgModelValue(updated, 'minutes');\n };\n $scope.minuteClickHandler = this.minuteClickHandler;\n\n this.attachTimePaneEventListeners();\n }\n TimePaneCtrl.$inject = [\"$element\", \"$attrs\", \"$scope\", \"$animate\", \"$q\", \"$mdConstant\", \"$mdTheming\", \"$$mdDateUtil\", \"$mdDateLocale\", \"$mdInkRipple\", \"$mdUtil\"];\n\n TimePaneCtrl.prototype.configureNgModel = function(ngModelCtrl, sgTimePaneCtrl, timePaneElement) {\n this.ngModelCtrl = ngModelCtrl;\n\n var self = this;\n ngModelCtrl.$render = function() {\n self.changeSelectedTime(self.ngModelCtrl.$viewValue, sgTimePaneCtrl, timePaneElement);\n };\n };\n\n /**\n * Change the selected date in the time (ngModel value has already been changed).\n */\n TimePaneCtrl.prototype.changeSelectedTime = function(date, sgTimePaneCtrl, timePaneElement) {\n var self = this;\n var previousSelectedTime = this.selectedTime;\n this.selectedTime = date;\n this.changeDisplayTime(date).then(function() {\n\n // Remove the selected class from the previously selected date, if any.\n if (previousSelectedTime) {\n var prevH = previousSelectedTime.getHours();\n var prevHCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-hour-'+prevH);\n if (prevHCell) {\n prevHCell.classList.remove(SELECTED_TIME_CLASS);\n prevHCell.setAttribute('aria-selected', 'false');\n }\n var prevM = previousSelectedTime.getMinutes();\n var prevMCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute-'+prevM);\n if (prevMCell) {\n prevMCell.classList.remove(SELECTED_TIME_CLASS);\n prevMCell.setAttribute('aria-selected', 'false');\n }\n var prevM5Cell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute5-'+prevM);\n if (prevM5Cell) {\n prevM5Cell.classList.remove(SELECTED_TIME_CLASS);\n prevM5Cell.setAttribute('aria-selected', 'false');\n }\n }\n\n // Apply the select class to the new selected date if it is set.\n if (date) {\n var newH = date.getHours();\n var mCell, hCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-hour-'+newH);\n if (hCell) {\n hCell.classList.add(SELECTED_TIME_CLASS);\n hCell.setAttribute('aria-selected', 'true');\n }\n var newM = date.getMinutes();\n if (newM % 5 === 0) {\n sgTimePaneCtrl.$scope.show5min = true;\n mCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute5-'+newM);\n if (mCell) {\n mCell.classList.add(SELECTED_TIME_CLASS);\n mCell.setAttribute('aria-selected', 'true');\n }\n }\n else {\n sgTimePaneCtrl.$scope.show5min = false;\n }\n mCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute-'+newM);\n if (mCell) {\n mCell.classList.add(SELECTED_TIME_CLASS);\n mCell.setAttribute('aria-selected', 'true');\n }\n\n }\n });\n };\n\n TimePaneCtrl.prototype.changeDisplayTime = function(date) {\n var d = new Date(date);\n if (!this.isInitialized) {\n this.buildInitialTimePaneDisplay();\n return this.$q.when();\n }\n if (!this.dateUtil.isValidDate(d)) {\n return this.$q.when();\n }\n\n this.displayTime = d;\n\n return this.$q.when();\n };\n TimePaneCtrl.prototype.buildInitialTimePaneDisplay = function() {\n this.displayTime = this.selectedTime || this.today;\n this.isInitialized = true;\n };\n\n TimePaneCtrl.prototype.attachTimePaneEventListeners = function() {\n // Keyboard interaction.\n this.$element.on('keydown', angular.bind(this, this.handleKeyEvent));\n };\n\n /*** User input handling ***/\n\n /**\n * Handles a key event in the calendar with the appropriate action. The action will either\n * be to select the focused date or to navigate to focus a new date.\n * @param {KeyboardEvent} event\n */\n TimePaneCtrl.prototype.handleKeyEvent = function(event) {\n var self = this;\n this.$scope.$apply(function() {\n // Capture escape and emit back up so that a wrapping component\n // (such as a time-picker) can decide to close.\n if (event.which == self.keyCode.ESCAPE || event.which == self.keyCode.TAB) {\n self.$scope.$emit('md-time-pane-close');\n\n if (event.which == self.keyCode.TAB) {\n event.preventDefault();\n }\n\n return;\n }\n\n // Remaining key events fall into two categories: selection and navigation.\n // Start by checking if this is a selection event.\n if (event.which === self.keyCode.ENTER) {\n self.setNgModelValue(self.displayTime, 'enter');\n event.preventDefault();\n return;\n }\n\n // Selection isn't occuring, so the key event is either navigation or nothing.\n /*var date = self.getFocusDateFromKeyEvent(event);\n if (date) {\n event.preventDefault();\n event.stopPropagation();\n\n // Since this is a keyboard interaction, actually give the newly focused date keyboard\n // focus after the been brought into view.\n self.changeDisplayTime(date).then(function () {\n self.focus(date);\n });\n }*/\n });\n };\n\n /**\n * Sets the ng-model value for the time pane and emits a change event.\n * @param {Date} date\n */\n TimePaneCtrl.prototype.setNgModelValue = function(date, mode) {\n this.$scope.$emit('sg-time-pane-change', {date:date, changed:mode});\n this.ngModelCtrl.$setViewValue(date);\n this.ngModelCtrl.$render();\n };\n\n /**\n * Focus the cell corresponding to the given date.\n * @param {Date=} opt_date\n */\n TimePaneCtrl.prototype.focus = function(opt_date, sgTimePaneCtrl) {\n var date = opt_date || this.selectedTime || this.today;\n\n var previousFocus = this.timePaneElement.querySelector('.md-focus');\n if (previousFocus) {\n previousFocus.classList.remove(FOCUSED_TIME_CLASS);\n }\n\n if (date) {\n var newH = date.getHours();\n var hCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-hour-'+newH);\n if (hCell) {\n hCell.classList.add(FOCUSED_TIME_CLASS);\n hCell.focus();\n }\n }\n };\n})();\n\n(function() {\n 'use strict';\n \n angular.module('SOGo.Common')\n .directive('sgTimepicker', timePickerDirective);\n\n /**\n * @ngdoc directive\n * @name mdTimepicker\n * @module material.components.timepicker\n *\n * @param {Date} ng-model The component's model. Expects a JavaScript Date object.\n * @param {expression=} ng-change Expression evaluated when the model value changes.\n * @param {boolean=} disabled Whether the timepicker is disabled.\n *\n * @description\n * `<sg-timepicker>` is a component used to select a single time.\n * For information on how to configure internationalization for the time picker,\n * see `$mdTimeLocaleProvider`.\n *\n * @usage\n * <hljs lang=\"html\">\n * <sg-timepicker ng-model=\"birthday\"></sg-timepicker>\n * </hljs>\n *\n */\n function timePickerDirective() {\n return {\n template: [\n // Buttons are not in the tab order because users can open the hours pane via keyboard\n // interaction on the text input, and multiple tab stops for one component (picker)\n // may be confusing.\n '<md-button class=\"sg-timepicker-button md-icon-button\" type=\"button\" ',\n ' tabindex=\"-1\" aria-hidden=\"true\" ',\n ' ng-click=\"ctrl.openTimePane($event)\">',\n ' <md-icon class=\"sg-timepicker-icon\">access_time</md-icon>',\n '</md-button>',\n '<div class=\"md-default-theme sg-timepicker-input-container\" ',\n ' ng-class=\"{\\'sg-timepicker-focused\\': ctrl.isFocused}\">',\n ' <input class=\"sg-timepicker-input\" aria-haspopup=\"true\" ',\n ' ng-focus=\"ctrl.setFocused(true)\" ng-blur=\"ctrl.setFocused(false)\">',\n ' <md-button type=\"button\" md-no-ink ',\n ' class=\"sg-timepicker-triangle-button md-icon-button\" ',\n ' ng-click=\"ctrl.openTimePane($event)\" ',\n ' aria-label=\"{{::ctrl.dateLocale.msgOpenCalendar}}\">',\n ' <div class=\"sg-timepicker-expand-triangle\"></div>',\n ' </md-button>',\n '</div>',\n // This pane will be detached from here and re-attached to the document body.\n '<div class=\"sg-timepicker-time-pane md-whiteframe-z1\">',\n ' <div class=\"sg-timepicker-input-mask\">',\n ' <div class=\"sg-timepicker-input-mask-opaque\"',\n ' md-colors=\"::{background: \\'default-background-A100\\'}\"></div>', // using mdColors\n ' </div>',\n ' <div class=\"sg-timepicker-time\" md-colors=\"::{background: \\'default-background-A100\\'}\">',\n ' <sg-time-pane role=\"dialog\" aria-label=\"{{::ctrl.dateLocale.msgCalendar}}\" ',\n ' ng-model=\"ctrl.time\" ng-if=\"ctrl.isTimeOpen\"></sg-time-pane>',\n ' </div>',\n '</div>'\n ].join(''),\n require: ['ngModel', 'sgTimepicker'],\n scope: {\n placeholder: '@mdPlaceholder'\n },\n controller: TimePickerCtrl,\n controllerAs: 'ctrl',\n bindToController: true,\n link: function(scope, element, attr, controllers) {\n var ngModelCtrl = controllers[0];\n var mdTimePickerCtrl = controllers[1];\n\n mdTimePickerCtrl.configureNgModel(ngModelCtrl);\n }\n };\n }\n\n /** Additional offset for the input's `size` attribute, which is updated based on its content. */\n var EXTRA_INPUT_SIZE = 3;\n\n /** Class applied to the container if the date is invalid. */\n var INVALID_CLASS = 'sg-timepicker-invalid';\n\n /** Default time in ms to debounce input event by. */\n var DEFAULT_DEBOUNCE_INTERVAL = 500;\n\n /**\n * Height of the calendar pane used to check if the pane is going outside the boundary of\n * the viewport. See calendar.scss for how $md-calendar-height is computed; an extra 20px is\n * also added to space the pane away from the exact edge of the screen.\n *\n * This is computed statically now, but can be changed to be measured if the circumstances\n * of calendar sizing are changed.\n */\n var TIME_PANE_HEIGHT = { MIN5: { GTXS: 172 + 20, XS: 291 + 20 },\n MIN1: { GTXS: 364 + 20, XS: 454 + 20 } };\n\n /**\n * Width of the calendar pane used to check if the pane is going outside the boundary of\n * the viewport. See calendar.scss for how $md-calendar-width is computed; an extra 20px is\n * also added to space the pane away from the exact edge of the screen.\n *\n * This is computed statically now, but can be changed to be measured if the circumstances\n * of calendar sizing are changed.\n */\n var TIME_PANE_WIDTH = { GTXS: 510 + 20, XS: 274 + 20 };\n\n /**\n * Controller for sg-timepicker.\n *\n * ngInject @constructor\n */\n TimePickerCtrl.$inject = [\"$scope\", \"$element\", \"$attrs\", \"$compile\", \"$timeout\", \"$window\",\n \"$mdConstant\", \"$mdMedia\", \"$mdTheming\", \"$mdUtil\", \"$mdDateLocale\", \"$$mdDateUtil\", \"$$rAF\"];\n function TimePickerCtrl($scope, $element, $attrs, $compile, $timeout, $window,\n $mdConstant, $mdMedia, $mdTheming, $mdUtil, $mdDateLocale, $$mdDateUtil, $$rAF) {\n /** @final */\n this.$compile = $compile;\n\n /** @final */\n this.$timeout = $timeout;\n\n /** @final */\n this.$window = $window;\n\n /** @final */\n this.dateLocale = $mdDateLocale;\n\n /** @final */\n this.dateUtil = $$mdDateUtil;\n\n /** @final */\n this.$mdConstant = $mdConstant;\n\n /** @final */\n this.$mdMedia = $mdMedia;\n\n /* @final */\n this.$mdUtil = $mdUtil;\n\n /** @final */\n this.$$rAF = $$rAF;\n\n /** @type {!angular.NgModelController} */\n this.ngModelCtrl = null;\n\n /** @type {HTMLInputElement} */\n this.inputElement = $element[0].querySelector('input');\n\n /** @type {HTMLElement} */\n this.inputContainer = $element[0].querySelector('.sg-timepicker-input-container');\n\n /** @final {!angular.JQLite} */\n this.ngInputElement = angular.element(this.inputElement);\n\n /** @type {HTMLElement} Floating time pane. */\n this.timePane = $element[0].querySelector('.sg-timepicker-time-pane');\n\n /** @type {HTMLElement} Time icon button. */\n this.timeButton = $element[0].querySelector('.sg-timepicker-button');\n\n /**\n * Element covering everything but the input in the top of the floating calendar pane.\n * @type {HTMLElement}\n */\n this.inputMask = $element[0].querySelector('.sg-timepicker-input-mask-opaque');\n\n /** @final {!angular.JQLite} */\n this.$element = $element;\n\n /** @final {!angular.Attributes} */\n this.$attrs = $attrs;\n\n /** @final {!angular.Scope} */\n this.$scope = $scope;\n\n /** @type {Date} */\n this.date = null;\n\n /** @type {boolean} */\n this.isFocused = false;\n\n /** @type {boolean} */\n this.isDisabled = false;\n this.setDisabled($element[0].disabled || angular.isString($attrs.disabled));\n\n /** @type {boolean} Whether the date-picker's calendar pane is open. */\n this.isTimeOpen = false;\n\n /**\n * Element from which the calendar pane was opened. Keep track of this so that we can return\n * focus to it when the pane is closed.\n * @type {HTMLElement}\n */\n this.timePaneOpenedFrom = null;\n\n this.timePane.id = 'sg-time-pane' + $mdUtil.nextUid();\n\n $mdTheming($element);\n\n /** Pre-bound click handler is saved so that the event listener can be removed. */\n this.bodyClickHandler = angular.bind(this, this.handleBodyClick);\n\n /** Pre-bound resize handler so that the event listener can be removed. */\n this.windowResizeHandler = $mdUtil.debounce(angular.bind(this, this.closeTimePane), 100);\n\n // Unless the user specifies so, the datepicker should not be a tab stop.\n // This is necessary because ngAria might add a tabindex to anything with an ng-model\n // (based on whether or not the user has turned that particular feature on/off).\n if (!$attrs.tabindex) {\n $element.attr('tabindex', '-1');\n }\n\n this.installPropertyInterceptors();\n this.attachChangeListeners();\n this.attachInteractionListeners();\n\n var self = this;\n $scope.$on('$destroy', function() {\n self.detachTimePane();\n });\n }\n\n /**\n * Sets up the controller's reference to ngModelController.\n * @param {!angular.NgModelController} ngModelCtrl\n */\n TimePickerCtrl.prototype.configureNgModel = function(ngModelCtrl) {\n this.ngModelCtrl = ngModelCtrl;\n\n var self = this;\n ngModelCtrl.$render = function() {\n var value = self.ngModelCtrl.$viewValue;\n\n if (value && !(value instanceof Date)) {\n throw Error('The ng-model for sg-timepicker must be a Date instance. ' +\n 'Currently the model is a: ' + (typeof value));\n }\n\n self.time = value;\n self.inputElement.value = self.dateLocale.formatTime(value);\n self.resizeInputElement();\n self.updateErrorState();\n };\n };\n\n /**\n * Attach event listeners for both the text input and the md-time.\n * Events are used instead of ng-model so that updates don't infinitely update the other\n * on a change. This should also be more performant than using a $watch.\n */\n TimePickerCtrl.prototype.attachChangeListeners = function() {\n var self = this;\n\n self.$scope.$on('sg-time-pane-change', function(event, data) {\n var time = new Date(data.date);\n self.ngModelCtrl.$setViewValue(time);\n self.time = time;\n self.inputElement.value = self.dateLocale.formatTime(time);\n if (data.changed == 'minutes') {\n self.closeTimePane();\n }\n self.resizeInputElement();\n self.inputContainer.classList.remove(INVALID_CLASS);\n });\n\n self.ngInputElement.on('input', angular.bind(self, self.resizeInputElement));\n self.ngInputElement.on('input', self.$mdUtil.debounce(self.handleInputEvent,\n DEFAULT_DEBOUNCE_INTERVAL, self));\n };\n\n /** Attach event listeners for user interaction. */\n TimePickerCtrl.prototype.attachInteractionListeners = function() {\n var self = this;\n var $scope = this.$scope;\n var keyCodes = this.$mdConstant.KEY_CODE;\n\n // Add event listener through angular so that we can triggerHandler in unit tests.\n self.ngInputElement.on('keydown', function(event) {\n if (event.altKey && event.keyCode == keyCodes.DOWN_ARROW) {\n self.openTimePane(event);\n $scope.$digest();\n }\n });\n\n $scope.$on('md-time-close', function() {\n self.closeTimePane();\n });\n };\n\n /**\n * Capture properties set to the time-picker and imperitively handle internal changes.\n * This is done to avoid setting up additional $watches.\n */\n TimePickerCtrl.prototype.installPropertyInterceptors = function() {\n var self = this;\n\n if (this.$attrs.ngDisabled) {\n // The expression is to be evaluated against the directive element's scope and not\n // the directive's isolate scope.\n var scope = this.$scope.$parent;\n if (scope) {\n scope.$watch(this.$attrs.ngDisabled, function(isDisabled) {\n self.setDisabled(isDisabled);\n });\n }\n }\n\n Object.defineProperty(this, 'placeholder', {\n get: function() { return self.inputElement.placeholder; },\n set: function(value) { self.inputElement.placeholder = value || ''; }\n });\n };\n\n /**\n * Sets whether the date-picker is disabled.\n * @param {boolean} isDisabled\n */\n TimePickerCtrl.prototype.setDisabled = function(isDisabled) {\n this.isDisabled = isDisabled;\n this.inputElement.disabled = isDisabled;\n this.timeButton.disabled = isDisabled;\n };\n\n /**\n * Sets the custom ngModel.$error flags to be consumed by ngMessages. Flags are:\n * - mindate: whether the selected date is before the minimum date.\n * - maxdate: whether the selected flag is after the maximum date.\n * - filtered: whether the selected date is allowed by the custom filtering function.\n * - valid: whether the entered text input is a valid date\n *\n * The 'required' flag is handled automatically by ngModel.\n *\n * @param {Date=} opt_date Date to check. If not given, defaults to the datepicker's model value.\n */\n TimePickerCtrl.prototype.updateErrorState = function(opt_date) {\n var date = opt_date || this.date;\n\n // Clear any existing errors to get rid of anything that's no longer relevant.\n this.clearErrorState();\n\n if (!this.dateUtil.isValidDate(date)) {\n // The date is seen as \"not a valid date\" if there is *something* set\n // (i.e.., not null or undefined), but that something isn't a valid date.\n this.ngModelCtrl.$setValidity('valid', date === null);\n }\n\n // TODO(jelbourn): Change this to classList.toggle when we stop using PhantomJS in unit tests\n // because it doesn't conform to the DOMTokenList spec.\n // See https://github.com/ariya/phantomjs/issues/12782.\n if (!this.ngModelCtrl.$valid) {\n this.inputContainer.classList.add(INVALID_CLASS);\n }\n };\n\n /** Clears any error flags set by `updateErrorState`. */\n TimePickerCtrl.prototype.clearErrorState = function() {\n this.inputContainer.classList.remove(INVALID_CLASS);\n ['valid'].forEach(function(field) {\n this.ngModelCtrl.$setValidity(field, true);\n }, this);\n };\n\n /**\n * Resizes the input element based on the size of its content.\n */\n TimePickerCtrl.prototype.resizeInputElement = function() {\n this.inputElement.size = this.inputElement.value.length + EXTRA_INPUT_SIZE;\n };\n\n /**\n * Sets the model value if the user input is a valid time.\n * Adds an invalid class to the input element if not.\n */\n TimePickerCtrl.prototype.handleInputEvent = function(self) {\n var inputString = this.inputElement.value;\n var arr = inputString.split(/[\\.:]/);\n\n if (inputString === '') {\n this.ngModelCtrl.$setViewValue(null);\n this.time = null;\n this.inputContainer.classList.remove(INVALID_CLASS);\n }\n else if (arr.length < 2) {\n arr = /(\\d{1,2})(\\d{2})/i.exec(inputString);\n if (arr)\n arr.splice(0, 1); // only keep text captured by parenthesis\n }\n\n if (!arr || arr.length < 2) {\n this.inputContainer.classList.toggle(INVALID_CLASS, inputString);\n }\n else {\n var h = Number(arr[0]);\n var m = Number(arr[1]);\n var newVal = new Date(this.time);\n if (h && h >= 0 && h <= 23 && m && m >= 0 && m <= 59 && angular.isDate(newVal)) {\n newVal.setHours(h);\n newVal.setMinutes(m);\n this.ngModelCtrl.$setViewValue(newVal);\n this.time = newVal;\n this.inputElement.value = this.dateLocale.formatTime(newVal);\n this.inputContainer.classList.remove(INVALID_CLASS);\n }\n else {\n this.inputContainer.classList.toggle(INVALID_CLASS, inputString);\n }\n }\n };\n\n /** Position and attach the floating calendar to the document. */\n TimePickerCtrl.prototype.attachTimePane = function() {\n var timePane = this.timePane;\n this.$element.addClass('sg-timepicker-open');\n\n var elementRect = this.inputContainer.getBoundingClientRect();\n var bodyRect = document.body.getBoundingClientRect();\n\n // Check to see if the calendar pane would go off the screen. If so, adjust position\n // accordingly to keep it within the viewport.\n var paneTop = elementRect.top - bodyRect.top;\n var paneLeft = elementRect.left - bodyRect.left;\n\n // If ng-material has disabled body scrolling (for example, if a dialog is open),\n // then it's possible that the already-scrolled body has a negative top/left. In this case,\n // we want to treat the \"real\" top as (0 - bodyRect.top). In a normal scrolling situation,\n // though, the top of the viewport should just be the body's scroll position.\n var viewportTop = (bodyRect.top < 0 && document.body.scrollTop === 0) ?\n -bodyRect.top :\n document.body.scrollTop;\n\n var viewportLeft = (bodyRect.left < 0 && document.body.scrollLeft === 0) ?\n -bodyRect.left :\n document.body.scrollLeft;\n\n var viewportBottom = viewportTop + this.$window.innerHeight;\n var viewportRight = viewportLeft + this.$window.innerWidth;\n\n // If the right edge of the pane would be off the screen and shifting it left by the\n // difference would not go past the left edge of the screen. If the time pane is too\n // big to fit on the screen at all, move it to the left of the screen and scale the entire\n // element down to fit.\n var paneWidth = this.$mdMedia('xs')? TIME_PANE_WIDTH.XS : TIME_PANE_WIDTH.GTXS;\n if (paneLeft + paneWidth > viewportRight) {\n if (viewportRight - paneWidth > 0) {\n paneLeft = viewportRight - paneWidth;\n } else {\n paneLeft = viewportLeft;\n var scale = this.$window.innerWidth / paneWidth;\n timePane.style.transform = 'scale(' + scale + ')';\n }\n timePane.classList.add('sg-timepicker-pos-adjusted');\n }\n\n // If the bottom edge of the pane would be off the screen and shifting it up by the\n // difference would not go past the top edge of the screen.\n var min = (typeof this.time == 'object' && this.time.getMinutes() % 5 === 0)? 'MIN5' : 'MIN1';\n var paneHeight = this.$mdMedia('xs')? TIME_PANE_HEIGHT[min].XS : TIME_PANE_HEIGHT[min].GTXS;\n if (paneTop + paneHeight > viewportBottom &&\n viewportBottom - paneHeight > viewportTop) {\n paneTop = viewportBottom - paneHeight;\n timePane.classList.add('sg-timepicker-pos-adjusted');\n }\n\n timePane.style.left = paneLeft + 'px';\n timePane.style.top = paneTop + 'px';\n document.body.appendChild(timePane);\n\n // The top of the calendar pane is a transparent box that shows the text input underneath.\n // Since the pane is floating, though, the page underneath the pane *adjacent* to the input is\n // also shown unless we cover it up. The inputMask does this by filling up the remaining space\n // based on the width of the input.\n this.inputMask.style.left = elementRect.width + 'px';\n\n // Add CSS class after one frame to trigger open animation.\n this.$$rAF(function() {\n timePane.classList.add('md-pane-open');\n });\n };\n\n /** Detach the floating time pane from the document. */\n TimePickerCtrl.prototype.detachTimePane = function() {\n this.$element.removeClass('sg-timepicker-open');\n this.timePane.classList.remove('md-pane-open');\n this.timePane.classList.remove('md-timepicker-pos-adjusted');\n\n if (this.isTimeOpen) {\n this.$mdUtil.enableScrolling();\n }\n\n if (this.timePane.parentNode) {\n // Use native DOM removal because we do not want any of the angular state of this element\n // to be disposed.\n this.timePane.parentNode.removeChild(this.timePane);\n }\n };\n\n /**\n * Open the floating time pane.\n * @param {Event} event\n */\n TimePickerCtrl.prototype.openTimePane = function(event) {\n if (!this.isTimeOpen && !this.isDisabled) {\n this.isTimeOpen = true;\n this.timePaneOpenedFrom = event.target;\n this.attachTimePane();\n //this.focusTime();\n\n // Because the time pane is attached directly to the body, it is possible that the\n // rest of the component (input, etc) is in a different scrolling container, such as\n // an md-content. This means that, if the container is scrolled, the pane would remain\n // stationary. To remedy this, we disable scrolling while the time pane is open, which\n // also matches the native behavior for things like `<select>` on Mac and Windows.\n this.$mdUtil.disableScrollAround(this.timePane);\n\n // Attach click listener inside of a timeout because, if this open call was triggered by a\n // click, we don't want it to be immediately propogated up to the body and handled.\n var self = this;\n this.$mdUtil.nextTick(function() {\n document.body.addEventListener('click', self.bodyClickHandler);\n }, false);\n\n window.addEventListener('resize', this.windowResizeHandler);\n }\n };\n\n /** Close the floating time pane. */\n TimePickerCtrl.prototype.closeTimePane = function() {\n if (this.isTimeOpen) {\n this.detachTimePane();\n this.isTimeOpen = false;\n this.timePaneOpenedFrom.focus();\n this.timePaneOpenedFrom = null;\n\n this.ngModelCtrl.$setTouched();\n\n document.body.removeEventListener('click', this.bodyClickHandler);\n window.removeEventListener('resize', this.windowResizeHandler);\n }\n };\n\n /** Gets the controller instance for the time in the floating pane. */\n TimePickerCtrl.prototype.getTimePaneCtrl = function() {\n return angular.element(this.timePane.querySelector('sg-time-pane')).controller('sgTimePane');\n };\n\n /** Focus the time in the floating pane. */\n TimePickerCtrl.prototype.focusTime = function() {\n // Use a timeout in order to allow the time to be rendered, as it is gated behind an ng-if.\n var self = this;\n this.$mdUtil.nextTick(function() {\n var ctrl = self.getTimePaneCtrl();\n self.getTimePaneCtrl().focus(null, ctrl);\n }, false);\n };\n\n /**\n * Sets whether the input is currently focused.\n * @param {boolean} isFocused\n */\n TimePickerCtrl.prototype.setFocused = function(isFocused) {\n if (!isFocused) {\n this.ngModelCtrl.$setTouched();\n }\n this.isFocused = isFocused;\n };\n\n /**\n * Handles a click on the document body when the floating time pane is open.\n * Closes the floating time pane if the click is not inside of it.\n * @param {MouseEvent} event\n */\n TimePickerCtrl.prototype.handleBodyClick = function(event) {\n if (this.isTimeOpen) {\n // TODO(jelbourn): way want to also include the md-datepicker itself in this check.\n var isInTime = this.$mdUtil.getClosest(event.target, 'sg-time-pane');\n if (!isInTime) {\n this.closeTimePane();\n }\n\n this.$scope.$digest();\n }\n };\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /*\n * sgToggleGrid - Convert the tiles of a grid to toggle buttons\n * @memberof SOGo.Common\n * @restrict attribute\n * @param {string} [sgToggleGridAttr] - the attribute that specifies if an object is enabled (toggled)\n * @ngInject\n * @example:\n\n <md-grid-list md-cols=\"7\" md-row-height=\"1:1\"\n ng-model=\"editor.event.repeat.days\"\n sg-toggle-grid sg-toggle-grid-attr=\"day\">..</md-grid-list>\n */\n sgToggleGrid.$inject = ['$parse', '$mdUtil'];\n function sgToggleGrid($parse, $mdUtil) {\n return {\n restrict: 'A',\n require: '?ngModel',\n compile: compile\n };\n\n function compile(tElement, tAttrs) {\n return function postLink(scope, element, attr, ngModelCtrl) {\n var tiles = tElement.find('md-grid-tile'),\n tile,\n i,\n modelDays,\n modelAttr,\n toggleClass;\n\n ngModelCtrl = ngModelCtrl || $mdUtil.fakeNgModel();\n ngModelCtrl.$render = render;\n\n toggleClass = function() {\n // Toggle class on click event and call toggle function\n var tile = angular.element(this),\n day = tile.attr('value');\n tile.toggleClass('sg-active');\n toggle(day);\n };\n\n for (i = 0; i < tiles.length; i++) {\n tile = angular.element(tiles[i]);\n tile.addClass('sg-icon-button');\n tile.find('figure').addClass('md-icon');\n tile.on('click', toggleClass);\n }\n\n function render() {\n var flattenedDays = ngModelCtrl.$viewValue;\n modelDays = ngModelCtrl.$viewValue;\n if (tAttrs.sgToggleGridAttr) {\n modelAttr = tAttrs.sgToggleGridAttr;\n flattenedDays = _.map(ngModelCtrl.$viewValue, tAttrs.sgToggleGridAttr);\n }\n _.forEach(tiles, function(o) {\n var tile = angular.element(o);\n if (_.includes(flattenedDays, tile.attr('value'))) {\n tile.addClass('sg-active');\n }\n });\n }\n\n function toggle(day) {\n var i = _.findIndex(modelDays, function(o) {\n if (modelAttr)\n return o[modelAttr] == day;\n else\n return o == day;\n });\n if (i < 0) {\n if (modelAttr) {\n var o = {};\n o[modelAttr] = day;\n modelDays.push(o);\n }\n else\n modelDays.push(day);\n }\n else\n modelDays.splice(i, 1);\n\n scope.$apply(function() {\n ngModelCtrl.$setViewValue(modelDays);\n ngModelCtrl.$setDirty();\n });\n }\n };\n }\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgToggleGrid', sgToggleGrid);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint loopfunc: true */\n 'use strict';\n\n /**\n * sgTransformOnBlur - A directive to extend md-chips so the text of the input\n * field is converted to a chip when the field is loosing focus.\n *\n * See issue on github:\n *\n * https://github.com/angular/material/issues/3364\n *\n * Code is extracted from \"MdChipsCtrl.prototype.onInputBlur\" in controller:\n *\n * angular-material/src/components/chips/js/chipsController.js\n *\n * @memberof SOGo.Common\n * @ngInject\n * @example:\n\n <md-chips ng-model=\"editor.message.editable.to\"\n md-separator-keys=\"editor.recipientSeparatorKeys\"\n md-transform-chip=\"editor.addRecipient($chip, 'to')\"\n sg-transform-on-blur>\n */\n sgTransformOnBlur.$inject = ['$window', '$timeout'];\n function sgTransformOnBlur($window, $timeout) {\n return {\n link: link,\n require: 'mdChips', // Extends the original mdChips directive\n restrict: 'A'\n };\n\n function link(scope, element, attributes, mdChipsCtrl) {\n var mouseUpActions = [];\n\n mdChipsCtrl.onInputBlur = function() {\n var appendFcn;\n\n this.inputHasFocus = false;\n appendFcn = (function() {\n var chipBuffer = this.getChipBuffer();\n if ((this.hasAutocomplete && this.requireMatch) || !chipBuffer || chipBuffer === \"\") return;\n this.appendChip(chipBuffer);\n this.resetChipBuffer();\n }).bind(this);\n\n if (this.hasAutocomplete) {\n mouseUpActions.push(appendFcn);\n $window.addEventListener('click', function(event){\n while (mouseUpActions.length > 0) {\n // Trigger actions after some delay to give time to md-autocomple to clear the input field\n var action = mouseUpActions.splice(0,1)[0];\n $timeout(function(){\n $timeout(action);\n });\n }\n }, false);\n }\n else\n appendFcn();\n };\n }\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgTransformOnBlur', sgTransformOnBlur);\n})();\n"]}