From 8b5cca765fc4a2c1a629df77dd3d499f4fc59577 Mon Sep 17 00:00:00 2001 From: maxmg Date: Mon, 24 Feb 2020 17:57:54 +0100 Subject: [PATCH] MAJ 4.1.2 --- demo/libs/lucca-ui.js | 3092 ++++++++++++++++++++--------------------- dist/lucca-ui.d.ts | 2 + dist/lucca-ui.js | 3092 ++++++++++++++++++++--------------------- dist/lucca-ui.min.js | 4 +- package.json | 2 +- 5 files changed, 3097 insertions(+), 3095 deletions(-) diff --git a/demo/libs/lucca-ui.js b/demo/libs/lucca-ui.js index de95733e..e55c7fd6 100644 --- a/demo/libs/lucca-ui.js +++ b/demo/libs/lucca-ui.js @@ -3043,9 +3043,9 @@ var lui; var translate; (function (translate) { "use strict"; - translate.AVAILABLE_LANGUAGES = ["en", "fr", "de", "es", "it", "nl"]; - translate.LANGUAGES_TO_CODE = { en: 1033, de: 1031, es: 1034, fr: 1036, it: 1040, nl: 2067 }; - translate.CODES_TO_LANGUAGES = { 1033: "en", 1031: "de", 1034: "es", 1036: "fr", 1040: "it", 2067: "nl" }; + translate.AVAILABLE_LANGUAGES = ["en", "fr", "de", "es", "it", "nl", "pt"]; + translate.LANGUAGES_TO_CODE = { en: 1033, de: 1031, es: 1034, fr: 1036, it: 1040, nl: 2067, pt: 2070 }; + translate.CODES_TO_LANGUAGES = { 1033: "en", 1031: "de", 1034: "es", 1036: "fr", 1040: "it", 2067: "nl", 2070: "pt" }; var CulturedList = (function () { function CulturedList(culture) { this.culture = culture; @@ -4338,1546 +4338,1546 @@ var lui; ); }]); -;/* global angular */ -(function(){ - 'use strict'; - var DayBlockDirective = function () { - return { - template : - '
'+ - - '
{{controller.date | luifMoment: \'dddd\'}}'+ - '
'+ - - '
{{controller.date | luifMoment:\'DD\'}}'+ - '
'+ - - '
{{controller.date | luifMoment: \'MMM\'}}'+ - '
'+ - - '
{{controller.date | luifMoment: \'YYYY\'}}'+ - '
'+ - - '
', - - scope : { - date: '=', - showDay: '=', - primaryColor: '=', - secondaryColor: '=' - }, - - restrict : 'E', - bindToController : true, - controllerAs : 'controller', - controller : 'luidDayBlockController' - }; - }; - - - angular - .module('lui') - .directive('luidDayBlock', DayBlockDirective) - .controller('luidDayBlockController', function(){ - var controller = this; - - controller.weekdayStyleOverride = function() { - return { - color: controller.primaryColor, - }; - }; - controller.dayStyleOverride = function() { - return { - "background-color": controller.primaryColor, - "border-color": controller.primaryColor, - "color": controller.secondaryColor, - }; - }; - controller.monthStyleOverride = function() { - return { - "background-color": controller.secondaryColor, - "border-color": controller.primaryColor, - "color": controller.primaryColor, - }; - }; - controller.yearStyleOverride = function() { - return { - "background-color": controller.secondaryColor, - "border-color": controller.primaryColor, - "color": controller.primaryColor, - }; - }; - - - }); - -})(); - - -;(function(){ - 'use strict'; - /** - ** DEPENDENCIES - ** - none - **/ - angular.module('lui') - .directive('luidKeydown', function () { - return { - restrict: 'A', - scope:{ - mappings: '=' - }, - link: function (scope, element, attrs) { - element.on('keydown', function (e) { - if ( !!scope.mappings && !!scope.mappings[e.which] ){ - scope.mappings[e.which](e); - // e.preventDefault(); - } - }); - } - }; - }); - angular.module('lui') - .directive('luidSelectOnClick', function () { - return { - restrict: 'A', - link: function (scope, element, attrs) { - element.on('click', function () { - this.select(); - }); - element.on('focus', function () { - this.select(); - }); - } - }; - }); - angular.module('lui') - .directive('luidFocusOn', function() { - return function(scope, elem, attr) { - scope.$on(attr.luidFocusOn, function(e) { - setTimeout( function() { elem[0].focus(); scope.$apply(); }, 1); - }); - }; - }); -})(); -;(function () { - "use strict"; - - /** - ** DEPENDENCIES - ** - angular translate - ** - underscore - **/ - - angular.module("lui.translate") - .directive("luidTranslations", ["$translate", "_", "$filter", "$timeout", function ($translate, _, $filter, $timeout) { - function link(scope, element, attrs, ctrls) { - var ngModelCtrl = ctrls[1]; - var translateCtrl = ctrls[0]; - - /** Associations language/code */ - var languagesToCodes = { en: 1033, de: 1031, es: 1034, fr: 1036, it: 1040, nl: 2067 }; - - /** List of all the available languages labels */ - var cultures = _.keys(languagesToCodes); - scope.cultures = cultures; - - scope.currentCulture = $translate.preferredLanguage() || "en"; - - var mode = !!attrs.mode ? attrs.mode : "dictionary"; - if (mode === "dictionary" && ngModelCtrl.$viewValue !== undefined) { - _.each(cultures, function (culture) { - scope.$watch( - function () { return !!ngModelCtrl.$viewValue ? ngModelCtrl.$viewValue[culture] : ngModelCtrl.$viewValue; }, - function () { ngModelCtrl.$render(); } - ); - }); - } - - ngModelCtrl.$render = function () { - scope.internal = parse(ngModelCtrl.$viewValue); - translateCtrl.updateTooltip(); - }; - - translateCtrl.updateViewValue = function () { - switch (mode) { - case "dictionary": - return updateDictionary(scope.internal); - case "|": - case "pipe": - return updatePipe(scope.internal); - case "lucca": - return updateLucca(scope.internal); - } - }; - - translateCtrl.updateTooltip = function () { - var tooltipText = ""; - if(!!!scope.internal) { - scope.tooltipText = undefined; - return; - } - for(var i = 0; i < scope.cultures.length; i++) { - if(!!scope.internal[scope.cultures[i]]) { - tooltipText += "["+scope.cultures[i].toUpperCase()+"] : "+ scope.internal[scope.cultures[i]] + "\n"; - } - } - scope.tooltipText = tooltipText; - }; - - var parse = function (value) { - if (value === undefined) { return undefined; } - switch (mode) { - case "dictionary": - return parseDictionary(value); - case "|": - case "pipe": - return parsePipe(value); - case "lucca": - return parseLucca(value); - default: - return undefined; - } - }; - - // Mode lucca - var parseLucca = function (value) { - return _.reduce(cultures, function (memo, culture) { - var targetLabel = _.findWhere(value, { cultureCode: languagesToCodes[culture] }); - memo[culture] = !!targetLabel ? targetLabel.value : undefined; - // We need to keep the original id - memo[culture + "_id"] = !!targetLabel ? targetLabel.id : undefined; - return memo; - }, {}); - }; - var updateLucca = function (value) { - var allEmpty = true; - var viewValue = []; - _.each(cultures, function (culture) { - if (!!value[culture] && value[culture] !== "") { - viewValue.push({ id: value[culture + "_id"], cultureCode: languagesToCodes[culture], value: value[culture] }); - allEmpty = false; - } - }); - ngModelCtrl.$setViewValue(allEmpty ? undefined : viewValue); - scope.$parent.$eval(attrs.ngChange); - }; - - // Mode dictionary - var parseDictionary = function (value) { - return _.reduce(cultures, function (memo, culture) { - memo[culture] = value[culture]; - return memo; - }, {}); - }; - var updateDictionary = function (value) { - var allEmpty = true; - var viewValue = {}; - _.each(cultures, function (culture) { - viewValue[culture] = value[culture]; - allEmpty &= value[culture] === undefined || value[culture] === ""; - }); - ngModelCtrl.$setViewValue(allEmpty ? undefined : viewValue); - scope.$parent.$eval(attrs.ngChange); // needs to be called manually cuz the object ref of the $viewValue didn't change - }; - - // Mode pipe - var parsePipe = function (value) { - // value looks like this "en:some stuff|de:|nl:|fr:des bidules|it:|es:" - var translations = value.split("|"); - var result = {}; - _.each(translations, function (t) { - var key = t.substring(0, 2); - var val = t.substring(3); - result[key] = val; - }); - return _.pick(result, cultures); - }; - var updatePipe = function (value) { - if (!_.find(cultures, function (culture) { return value[culture] !== undefined && value[culture] !== ""; })) { - ngModelCtrl.$setViewValue(undefined); - } else { - var newVal = _.map(cultures, function (c) { - if (!!value[c]) { - return c + ":" + value[c]; - } - return c + ":"; - }).join("|"); - ngModelCtrl.$setViewValue(newVal); - } - }; - } - return { - require: ['luidTranslations', '^ngModel'], - controller: 'luidTranslationsController', - scope: { - mode: '@', // allowed values: "pipe" (or "|"), "dictionary", "lucca" (lucca proprietary format) - size: "@", // the size of the input (short, long, x-long, fitting) - isDisabled: "=ngDisabled" - }, - templateUrl: "lui/directives/luidTranslations.html", - restrict: 'EA', - link: link - }; - }]) - .controller('luidTranslationsController', ['$scope', '$translate', '$timeout', function ($scope, $filter, $timeout) { - var ctrl = this; - /****************** - * UPDATE * - ******************/ - $scope.update = function () { ctrl.updateViewValue(); ctrl.updateTooltip(); }; - - /****************** - * FOCUS & BLUR * - ******************/ - - $scope.focusInput = function () { - $scope.focused = true; - }; - $scope.blurInput = function () { - $scope.focused = false; - }; - - $scope.blurOnEnter = function($event) { - $event.target.blur(); - $event.preventDefault(); - }; - }]); - - /**************************/ - /***** TEMPLATES *****/ - /**************************/ - angular.module("lui").run(["$templateCache", function ($templateCache) { - $templateCache.put("lui/directives/luidTranslations.html", - "
" + - "
" + - " " + - " {{currentCulture}}" + - "
" + - "
" + - "
" + - "
" + - " " + - " {{culture}}" + - "
" + - "
" + - "
" + - "
" + - ""); - }]); -})(); -;(function(){ - 'use strict'; - /** - ** DEPENDENCIES - ** - moment - **/ - var MAGIC_DELAY_BEFORE_WHEEL = 200; - - angular.module('lui') - .directive('luidMoment', ['moment', function(moment){ - function link(scope, element, attrs, ctrls){ - var ngModelCtrl = ctrls[1]; - var mpCtrl = ctrls[0]; - - // display the value i on two chars - if(!!attrs.format){ // allows to have a ng-model of type string, not moment - var format = scope.$eval(attrs.format); - - ngModelCtrl.getValue = function() { - var vv = ngModelCtrl.$viewValue; - if (!vv) { - return undefined; - } - var momentVv = moment(vv, format); - if (!momentVv.isValid()) { - return undefined; - } - return momentVv; - }; - - ngModelCtrl.$render = function() { - var momentValue = ngModelCtrl.getValue(); - scope.hours = !!momentValue ? momentValue.format('HH') : undefined; - scope.mins = !!momentValue ? momentValue.format('mm') : undefined; - ngModelCtrl.$validate(); - }; - - ngModelCtrl.setValue = function(newMomentValue) { - ngModelCtrl.$setViewValue(!newMomentValue ? undefined : newMomentValue.format(format)); - }; - ngModelCtrl.$validators.min = function (modelValue,viewValue) { - return !viewValue || mpCtrl.checkMin(moment(modelValue, format)); - }; - ngModelCtrl.$validators.max = function (modelValue,viewValue) { - return !viewValue || mpCtrl.checkMax(moment(modelValue, format)); - }; - } else { - ngModelCtrl.getValue = function() { - var vv = ngModelCtrl.$viewValue; - if (!vv) { - return undefined; - } - var momentVv = moment(vv); - if (!vv.isValid()) { - return undefined; - } - return momentVv; - }; - ngModelCtrl.$render = function() { - var vv = ngModelCtrl.getValue(); - var condition = !!vv && vv.isValid(); - scope.hours = condition ? vv.format('HH') : undefined; - scope.mins = condition ? vv.format('mm') : undefined; - ngModelCtrl.$validate(); - }; - ngModelCtrl.setValue = function(newMomentValue) { - ngModelCtrl.$setViewValue(newMomentValue); - }; - ngModelCtrl.$validators.min = function (modelValue,viewValue) { - return !viewValue || mpCtrl.checkMin(modelValue); - }; - ngModelCtrl.$validators.max = function (modelValue,viewValue) { - return !viewValue || mpCtrl.checkMax(modelValue); - }; - } - - scope.ngModelCtrl = ngModelCtrl; - - ngModelCtrl.$validators.hours = function (modelValue,viewValue) { - return scope.hours !== undefined && scope.hours !== "" && !isNaN(parseInt(scope.hours)); - }; - ngModelCtrl.$validators.minutes = function (modelValue,viewValue) { - return scope.mins !== undefined && scope.mins !== "" && parseInt(scope.mins) < 60; - }; - - var inputs = element.querySelectorAll('.input'); - mpCtrl.setupEvents(element, angular.element(inputs[0]), angular.element(inputs[1])); - - // reexecute validators if min or max change - // will not be reexecuted if min is a moment and something like `min.add(3, 'h')` is called - scope.$watch('min', function(){ - ngModelCtrl.$validate(); - }); - scope.$watch('max', function(){ - ngModelCtrl.$validate(); - }); - - } - - return { - require:['luidMoment','^ngModel'], - controller:'luidMomentController', - scope: { - min:'=', // a moment or a str to specify the min for this input - max:'=', // idem for max - step:'=', // the number of minutes to add/subtract when clicking the addMins button or scrolling on the add in input - referenceDate:'=', // when entering a time, the date to set it, also used to count the number of days between the ngModel and this date, if unavailable, will use min then max then today - isDisabled:'=', - showButtons:'=', // forces the buttons to be displayed even if neither inputs is focused - enforceValid:'=', // prevents entering an ng-invalid input by correcting the value when losing focus - - format:'=', // alows ng-model to be a string with the right format - - // hacks - minOffset:'=', // to avoid having to say min=val1+val2 because it causes an other digest cycle, we give the offset and the - maxOffset:'=' - }, - templateUrl:"lui/directives/luidMoment.html", - restrict:'EA', - link: link, - }; - }]) - .controller('luidMomentController', ['$scope', '$timeout', 'moment', '$element', function($scope, $timeout, moment, $element) { - function incr(step) { - function calculateNewValue() { - function contains(array, value) { return array.indexOf(value) !== -1; } - - var curr = moment(currentValue()); - if (!curr || !curr.isValid()) { curr = getRefDate().startOf('day'); } - if (contains(specialSteps, Math.abs(step)) && curr.minutes() % step !== 0) { - step = step < 0 ? - (curr.minutes() % step) : -curr.minutes() % step + step; - } - - var newValue = curr.add(step,'m'); - newValue.seconds(0); - return newValue; - } - - if ($scope.isDisabled) { return; } - // $scope.ngModelCtrl.$setValidity('pattern', true); - - update(calculateNewValue(), true); - } - - function update(newValue, autoCorrect) { - updateWithoutRender(newValue, autoCorrect); - $scope.ngModelCtrl.$render(); - } - - function updateWithoutRender(newValue, autoCorrect) { - function correctedValue(newValue, min, max) { - switch(true){ - case (!newValue) : return newValue; - case (min && min.diff(newValue) > 0) : return min; - case (max && max.diff(newValue) < 0) : return max; - default : return newValue; - } - } - var min = getMin(); - var max = getMax(); - - if (autoCorrect) { - var newCorrectedValue = correctedValue(newValue, min, max); - if (newCorrectedValue.format("HH:mm") !== newValue.format("HH:mm")) { - newValue = newCorrectedValue; - - $element.addClass('autocorrect'); - setTimeout(function() { - $element.removeClass('autocorrect'); - }, 200); - } - } - $scope.maxed = newValue && max && max.diff(newValue) <= 0; - $scope.mined = newValue && min && min.diff(newValue) >= 0; - - $scope.ngModelCtrl.setValue(newValue); - } - - // translate between string values and viewvalue - function undefinedHoursOrMinutes() { - return $scope.hours === undefined || $scope.hours === "" || $scope.mins === undefined || $scope.mins === ""; - } - - function getInputedTime() { - if (undefinedHoursOrMinutes()) { - return undefined; - } - - var intHours = parseInt($scope.hours); - var intMinutes = parseInt($scope.mins); - // if (intHours != intHours) { intHours = 0; } // intHour isNaN - // if (intMinutes != intMinutes) { intMinutes = 0; } // intMins isNaN - if (intMinutes > 60) { intMinutes = 59; $scope.mins = "59"; } - - var initialTime = getRefDate().hours(intHours).minutes(intMinutes).seconds(0); - - // try to put time between min and max by adding some days while time < min and time !> max - var time = betweenMinAndMax(initialTime); - - return time; - } - - function betweenMinAndMax(refTime) { - var time = moment(refTime); - var minTime = moment(time), maxTime = moment(time); - var min = getMin(), max = getMax(); - var dayCnt; - // time < min, add enough day to have it after min - if(!!min && time.isBefore(min)) { - // number of days between min and time, rounded to next integer - dayCnt = Math.ceil(min.diff(time, 'day', true)); - minTime.add(dayCnt, 'day'); - } - // time > max - if (!!max && time.isAfter(max)) { - // number of days between max and time, rounded to previous integer - dayCnt = Math.floor(max.diff(time, 'day', true)); - maxTime.add(dayCnt, 'days'); - } - - if (!!max && (minTime.isBefore(max) || minTime.isSame(max))) { - return minTime; - } - if (!!min && (maxTime.isAfter(min) || maxTime.isSame(min))) { - return maxTime; - } - return time; - } - - function cancelTimeouts() { - function cancel(timeout){ - if (!!timeout) { - $timeout.cancel(timeout); - timeout = undefined; - } - } - cancel(hoursFocusTimeout); - cancel(minsFocusTimeout); - } - - function correctValue() { - update(currentValue(), $scope.enforceValid); - } - - function getStep() { return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step); } - - function getRefDate() { - function toMoment(value) { return (!!value && moment(value).isValid()) ? moment(value) : undefined; } - - return toMoment($scope.referenceDate) || toMoment($scope.min) || toMoment($scope.max) || moment(); - } - - function getExtremum(extremum, offset, checkMidnight) { - function rawExtremum(){ - switch(true){ - // check if min/max is a valid moment - case (!!extremum.isValid && !!extremum.isValid()) : return moment(extremum); - // check if min/max is parsable by moment - case (moment(extremum,'YYYY-MM-DD HH:mm').isValid()) : return moment(extremum,'YYYY-MM-DD HH:mm'); - // check if min/max is like '23:15' - case (moment(extremum, 'HH:mm').isValid()) : - var refDate = getRefDate(); - var extrem = moment(extremum, 'HH:mm').year(refDate.year()).month(refDate.month()).date(refDate.date()); - // a min/max time of '00:00' means midnight tomorrow - if (checkMidnight && extrem.hours() + extrem.minutes() === 0) { extrem.add(1,'d');} - return extrem; - } - } - - // min/max attr not specified - if (!extremum) { return undefined; } - var extrem = rawExtremum(); - extrem.add(moment.duration(offset)); - return extrem; - } - - function getMin() { return getExtremum($scope.min, $scope.minOffset, false); } - function getMax() { return getExtremum($scope.max, $scope.maxOffset, true); } - - function currentValue() { return !$scope.format ? $scope.ngModelCtrl.$viewValue : moment($scope.ngModelCtrl.$viewValue, $scope.format); } - - function incrementEvent(eventName, value) { - cancelTimeouts(); - incr(value); - $scope.$broadcast(eventName); - } - - function focusEvent(isMinute) { - cancelTimeouts(); - $scope.minsFocused = !!isMinute; - $scope.hoursFocused = !isMinute; - } - - function blurEvent(timeout, isFocused){ - var model = $scope.ngModelCtrl.$modelValue; - updateWithoutRender(model); - timeout = $timeout(function(){ - timeout = false; - correctValue(); - }, 200); - } - - var hoursFocusTimeout, minsFocusTimeout; - var specialSteps = [5, 10, 15, 20, 30]; - var mpCtrl = this; - $scope.pattern = /^([0-9]{0,2})?$/; - - // stuff to control the focus of the different elements and the clicky bits on the + - buttons - // what we want is show the + - buttons if one of the inputs is displayed - // and we want to be able to click on said buttons without loosing focus (obv) - $scope.incrHours = function() { incrementEvent('focusHours', 60); }; - $scope.decrHours = function() { incrementEvent('focusHours', -60); }; - $scope.incrMins = function() { incrementEvent('focusMinutes', getStep()); }; - $scope.decrMins = function() { incrementEvent('focusMinutes', -getStep()); }; - - function isUndefinedOrEmpty(val) { - return val === undefined || val === ""; - } - - // string value changed - $scope.changeHours = function(){ - if(isUndefinedOrEmpty($scope.hours)){ - return updateWithoutRender(undefined); - } - - if(isUndefinedOrEmpty($scope.mins)){ - $scope.mins = "00"; - } - - if ($scope.hours.length == 2) { - if (parseInt($scope.hours) > 23) { $scope.hours = '23'; } - $scope.$broadcast('focusMinutes'); - } else if ($scope.hours.length == 1 && parseInt($scope.hours) > 2) { - $scope.hours = 0 + $scope.hours; - $scope.$broadcast('focusMinutes'); - } - updateWithoutRender(getInputedTime()); - }; - - $scope.changeMins = function() { - if (!$scope.mins || $scope.mins.length < 2) { - $scope.ngModelCtrl.$setValidity("minutes", false); - } else { - updateWithoutRender(getInputedTime()); - } - }; - - // display stuff - $scope.formatInputValue = function() { $scope.ngModelCtrl.$render(); }; - - $scope.getDayGap = function(){ - var refDate = getRefDate().startOf('day'); - return moment.duration(moment(currentValue()).startOf('d').diff(refDate)).asDays(); - }; - - $scope.blurHours = function() { blurEvent(hoursFocusTimeout, $scope.hoursFocused); }; - $scope.blurMins = function() { - if(!$scope.mins) { - if($scope.hours === "" || $scope.hours === undefined){ - $scope.mins = undefined; - } else { - $scope.mins = "00"; - } - } else if ($scope.mins.length < 2) { - $scope.mins = "0" + $scope.mins; - } - blurEvent(minsFocusTimeout, $scope.minsFocused); - }; - - $scope.focusHours = function() { focusEvent(false); }; - $scope.focusMins = function() { focusEvent(true); }; - - this.checkMin = function(newValue) { - var min = getMin(); - return !min || min.diff(newValue) <= 0; - }; - - this.checkMax = function(newValue) { - var max = getMax(); - return !max || max.diff(newValue) >= 0; - }; - - // events - mousewheel and arrowkeys - this.setupEvents = function(elt, hoursField, minsField){ - var hoursInput = angular.element(hoursField.find('input')[0]), - minsInput = angular.element(minsField.find('input')[0]); - - function setupArrowkeyEvents(hoursInput, minsInput) { - function subscription(e, step){ - switch(e.which){ - case 38:// up - e.preventDefault(); - incr(step); - $scope.$apply(); - break; - case 40:// down - e.preventDefault(); - incr(-step); - $scope.$apply(); - break; - case 13:// enter - e.preventDefault(); - $scope.formatInputValue(); - $scope.$apply(); - break; - } - } - var step = getStep(); - hoursInput.bind('keydown', function(e) { subscription(e, 60); }); - minsInput.bind('keydown', function(e) { subscription(e, step); }); - } - - function setupMousewheelEvents(elt, hoursField, minsField) { - function isScrollingUp(e) { - e = e.originalEvent ? e.originalEvent : e; - //pick correct delta variable depending on event - var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; - return (e.detail || delta > 0); - } - var enableMouseWheel = false; - var enableWheelTimeout; - elt.bind('mouseenter', function(e) { - enableWheelTimeout = setTimeout(function() { - enableMouseWheel = true; - }, MAGIC_DELAY_BEFORE_WHEEL); - }); - elt.bind('mouseleave', function(e) { - if (!!enableWheelTimeout) { - clearTimeout(enableWheelTimeout); - } - enableMouseWheel = false; - }); - function subscription(e, incrStep){ - if(!$scope.isDisabled && enableMouseWheel){ - $scope.$apply(incr((isScrollingUp(e)) ? incrStep : -incrStep )); - e.preventDefault(); - } - } - var step = getStep(); - - hoursField.bind('mousewheel wheel', function(e) { subscription(e, 60); }); - minsField.bind('mousewheel wheel', function(e) { subscription(e, step); }); - } - - setupArrowkeyEvents( hoursInput, minsInput); - setupMousewheelEvents(elt, hoursField, minsField); - }; - - }]); - - angular.module("lui").run(["$templateCache", function($templateCache) { - $templateCache.put("lui/directives/luidMoment.html", - "
" + - " " + - " " + - " " + - "
" + - ":" + - "
" + - " " + - " " + - " " + - "
" + - ""); - }]); -})(); -;(function () { - 'use strict'; - /** - ** DEPENDENCIES - ** - none - **/ - - angular.module('lui').directive('luidPercentage', function () { - function link(scope, element, attrs, ctrls) { - - var ngModelCtrl = ctrls[1]; - var luidPercentageCtrl = ctrls[0]; - scope.pattern = /^([0-9]+)(\.([0-9]*)?)?$/i; - if (!attrs.format) { - scope.format = "0.XX"; - }else if(attrs.format !== "0.XX" && attrs.format !== "1.XX" && attrs.format !== "XX"){ - ngModelCtrl.$render = function () { scope.intPct = "unsupported format"; }; - return; - } - - scope.ngModelCtrl = ngModelCtrl; - - ngModelCtrl.$render = function () { - if (this.$viewValue === undefined) { - scope.intPct = undefined; - return; - } - // must support the different formats here - scope.intPct = scope.parse(parseFloat(this.$viewValue)); - }; - - // call the ng-change - ngModelCtrl.$viewChangeListeners.push(function () { - scope.$eval(attrs.ngChange); - }); - - // bind to various events - here only keypress=enter - luidPercentageCtrl.setupEvents(element.find('input')); - } - - - return { - require: ['luidPercentage', '^ngModel'], - controller: 'luidPercentageController', - scope: { - step: '=', // default = 5 - format: '@', // 'XX', '0.XX' or '1.XX', default 0.XX - ngDisabled: '=', - placeholder: '@' - }, - restrict: 'EA', - link: link, - template: - "
" + - "" + - "%" + - "
" - }; - }) - .controller('luidPercentageController', ['$scope', function ($scope) { - - // private - updates of some kinds - // incr value by `step` minutes - function incr(step) { - update(parseFloat($scope.intPct) + step); - } - - // sets viewValue and renders - function update(duration) { - updateWithoutRender(duration); - $scope.ngModelCtrl.$render(); - } - - function updateWithoutRender(duration) { - function format(pct) { - switch($scope.format || "0.XX"){ - case "XX" : return pct; - case "0.XX" : return pct/100; - case "1.XX" : return (pct/100) + 1; - default : return 0; - } - } - - var newValue = duration === undefined ? undefined : format(duration); - $scope.ngModelCtrl.$setViewValue(newValue); - } - - // events - key 'enter' - this.setupEvents = function (elt) { - function getStep(){ return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step);} - function setupKeyEvents(elt) { - var step = getStep(); - elt.bind('keydown', function (e) { - switch(e.which){ - case 38:// up - e.preventDefault(); - incr(step); - $scope.$apply(); - break; - case 40:// down - e.preventDefault(); - incr(-step); - $scope.$apply(); - break; - case 13:// enter - e.preventDefault(); - $scope.formatInputValue(); - $scope.$apply(); - break; - } - }); - } - function setupMousewheelEvents(elt) { - function isScrollingUp(e) { - e = e.originalEvent ? e.originalEvent : e; - //pick correct delta variable depending on event - var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; - return (e.detail || delta > 0); - } - - var step = getStep(); - elt.bind('mousewheel wheel', function (e) { - if (this === document.activeElement) { - $scope.$apply(incr((isScrollingUp(e)) ? step : -step)); - e.preventDefault(); - } - }); - } - - setupKeyEvents(elt); - setupMousewheelEvents(elt); - }; - - // public methods for update - $scope.updateValue = function () { - updateWithoutRender($scope.intPct); - }; - - $scope.parse = function (intInput) { - switch($scope.format || "0.XX"){ - case "XX": return intInput; - case "0.XX": return Math.round(10000 * intInput) / 100; - case "1.XX": return Math.round((intInput-1) * 10000) / 100; - default : return 0; - } - }; - - // display stuff - $scope.formatInputValue = function () { - $scope.ngModelCtrl.$render(); - }; - }]); -})(); -;(function () { - 'use strict'; - /** - ** DEPENDENCIES - ** - moment - **/ - - angular.module('lui').directive('luidTimespan', ['moment', function (moment) { - - function link(scope, element, attrs, ctrls) { - var ngModelCtrl = ctrls[1]; - var luidTimespanCtrl = ctrls[0]; - scope.pattern = /^\-?([0-9]+)((h([0-9]{2})?)?(m(in)?)?)?$/i; - if (!!attrs.unit) { - var unit = scope.$eval(attrs.unit); - if (unit == 'h' || unit == 'hour' || unit == 'hours') { - scope.useHours = true; - } - } - - scope.ngModelCtrl = ngModelCtrl; - - ngModelCtrl.$render = function () { - scope.strDuration = ''; - if (!this.$viewValue) { - return; - } - var currentDuration = moment.duration(this.$viewValue); - if (currentDuration < 0) { - scope.strDuration += "-"; - currentDuration = moment.duration(-currentDuration); - } - var hours = Math.floor(currentDuration.asHours()); - var minutes = currentDuration.minutes(); - if (hours === 0) { - scope.strDuration += minutes + 'm'; - } else { - scope.strDuration += (hours < 10 ? '0' : '') + hours + 'h' + (minutes < 10 ? '0' : '') + minutes; - } - }; - - // bind to various events - here only keypress=enter - luidTimespanCtrl.setupEvents(element.find('input')); - - // set to given mode or to default mode - luidTimespanCtrl.mode = attrs.mode ? attrs.mode : "timespan"; - } - - - return { - require: ['luidTimespan', '^ngModel'], - controller: 'luidTimespanController', - scope: { - step: '=', // default = 5 - unit: '=', // 'hours', 'hour', 'h' or 'm', default='m' - ngDisabled: '=', - placeholder: '@', - mode: "=", // 'timespan', 'moment.duration', default='timespan' - min: '=', //min value - max: '=', //max value - }, - restrict: 'EA', - link: link, - template: - "
" + - "" + - "
" - }; - }]) - .controller('luidTimespanController', ['$scope', 'moment', function ($scope, moment) { - var ctrl = this; - - function parse(strInput) { - // parsing str to moment.duration - function parseHoursAndMinutes(strInput) { - var d = moment.duration(); - var splitted = strInput.split(/h/i); - var isPositive = parseInt(splitted[0]) >= 0; - d.add(parseInt(splitted[0]), 'hours'); - var strMin = splitted[1]; - if (!!strMin && strMin.length >= 2) { - if (isPositive){ - d.add(parseInt(strMin.substring(0, 2)), 'minutes'); - } else { - d.subtract(parseInt(strMin.substring(0, 2)), 'minutes'); - } - } - return d; - } - - function parseMinutes(strInput) { - var d = moment.duration(); - var splitted = strInput.split(/m/i); - d.add(parseInt(splitted[0]), 'minutes'); - return d; - } - - function parseHours(strInput) { - var d = moment.duration(); - var splitted = strInput.split(/h/i); - d.add(parseInt(splitted[0]), 'hours'); - return d; - } - - switch(true){ - case (/h/i.test(strInput)) : return parseHoursAndMinutes(strInput); - case (/m/i.test(strInput)) : return parseMinutes(strInput); - case ($scope.useHours) : return parseHours(strInput); - default : return parseMinutes(strInput); - } - } - - // updates of some kinds - // incr value by `step` minutes - function incr(step) { - var newDur = moment.duration(currentValue()).add(step, 'minutes'); - if (newDur.asMilliseconds() < 0) { - newDur = moment.duration(); - } - update(newDur); - } - - // sets viewValue and renders - function update(newDuration) { - updateWithoutRender(newDuration); - $scope.ngModelCtrl.$render(); - } - - function updateWithoutRender(newDuration) { - // Handle min/max values - function correctValue(newValue){ - function correctedMinValue(newValue) { - var min = !$scope.min ? undefined : moment.duration($scope.min); - return (!min || min <= newValue) ? newValue : min; - } - - function correctedMaxValue(newValue) { - var max = !$scope.max ? undefined : moment.duration($scope.max); - return (!max || max >= newValue) ? newValue : max; - } - - return correctedMaxValue(correctedMinValue(newValue)); - } - - function format(dur) { - if (ctrl.mode === 'timespan') { - var timespan = ""; - if (dur.asMilliseconds() < 0){ - timespan += "-"; - dur = moment.duration(-dur); - } - timespan += (dur.days() > 0 ? Math.floor(dur.asDays()) + '.' : '') + (dur.hours() < 10 ? '0' : '') + dur.hours() + ':' + (dur.minutes() < 10 ? '0' : '') + dur.minutes() + ':00'; - return timespan; - } - return dur; - } - - if (newDuration === undefined) { - return $scope.ngModelCtrl.$setViewValue(undefined); - } - - // Check min/max values - newDuration = correctValue(newDuration); - var formattedValue = format(newDuration); - - $scope.ngModelCtrl.$setViewValue(formattedValue); - } - - function currentValue() { - return $scope.ngModelCtrl.$viewValue; - } - - // events - key 'enter' - this.setupEvents = function (elt) { - function getStep(){ return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step);} - function setupKeyEvents(elt) { - var step = getStep(); - elt.bind('keydown', function (e) { - switch(e.which){ - case 38:// up - e.preventDefault(); - incr(step); - $scope.$apply(); - break; - case 40:// down - e.preventDefault(); - incr(-step); - $scope.$apply(); - break; - case 13:// enter - e.preventDefault(); - $scope.formatInputValue(); - $scope.$apply(); - break; - } - }); - } - - function setupMousewheelEvents(elt) { - function isScrollingUp(e) { - e = e.originalEvent ? e.originalEvent : e; - //pick correct delta variable depending on event - var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; - return (e.detail || delta > 0); - } - - var step = getStep(); - elt.bind('mousewheel wheel', function (e) { - if (this === document.activeElement) { - $scope.$apply(incr((isScrollingUp(e)) ? step : -step)); - e.preventDefault(); - } - }); - } - - setupKeyEvents(elt); - setupMousewheelEvents(elt); - }; - - // public methods for update - $scope.updateValue = function () { - - // is only fired when pattern is valid or when it goes from valid to invalid - // improvement possible - check the pattern and set the validity of the all directive via ngModelCtrl.$setValidity - // currently when pattern invalid, the viewValue is set to '00:00:00' - if (!$scope.strDuration) { return updateWithoutRender(undefined); } // empty input => 00:00:00 - - // parse the strDuration to build newDuration - // the duration of the parsed strDuration - var newDuration = parse($scope.strDuration); - - // update viewvalue - updateWithoutRender(newDuration); - }; - - // display stuff - $scope.formatInputValue = function () { - $scope.ngModelCtrl.$render(); - }; - }]); -})(); -;(function(){ - 'use strict'; - /** - ** DEPENDENCIES - ** - none, nothing, nada - **/ - function replaceAll(string, find, replace) { - // http://stackoverflow.com/questions/1144783/replacing-all-occurrences-of-a-string-in-javascript - // lets not reinvent the wheel - if(!string){ return ''; } - function escapeRegExp(string) { - return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); - } - return string.replace(new RegExp(escapeRegExp(find), 'g'), replace); - } - angular.module('lui') - .filter('luifPlaceholder', function () { - return function (_input, _placeholder) { - return !!_input ? _input : _placeholder; - }; - }) - .filter('luifDefaultCode', function () { - // uppercased and with '_' instead of ' ' - return function (_input) { - return replaceAll(_input, ' ', '_').toUpperCase(); - }; - }) - .filter('luifStartFrom', function () { - //pagination filter - return function (_input, start) { - start = +start; //parse to int - return _input.slice(start); - }; - }) - .filter('luifNumber', ['$sce', '$filter', function($sce, $filter) { - return function(_input, _precision, _placeholder) { - - function getRightSpan(decimalPart, separator) { - if (decimalPart === undefined) { return ""; } - if (parseInt(decimalPart) === 0) { return "" + separator + decimalPart + ""; } - return "" + separator + decimalPart + ""; - } - - var placeholder = _placeholder === undefined ? '' : _placeholder; - // alert(_input + " " + (!!_input.isNaN && _input.isNaN())); - var input = _input === undefined || _input === null || _input === "" || _input != _input ? placeholder : _input; // the last check is to check if _input is NaN - var separator = $filter("number")(1.1,1)[1]; - var precision = _precision === undefined || _precision === null || _precision != _precision ? 2 : _precision; - - var text = $filter("number")(input, precision); - var decimalPart = (text || $filter("number")(0, precision)).split(separator)[1]; - var rightSpan = getRightSpan(decimalPart, separator); - - if (input === '' || !text){ - // the _input or the _placeholder was not parsable by the number $filter, just return input but trusted as html - return $sce.trustAsHtml(input + rightSpan); - } - - var integerPart = text.split(separator)[0]; - return $sce.trustAsHtml(integerPart + rightSpan); - }; - }]); -})(); -;(function () { - 'use strict'; - /** - ** DEPENDENCIES - ** - moment - **/ - var formatMoment = function (_moment, _format) { //expects a moment - if (!_moment) { - return ""; - } - var m = moment(_moment); - return m.isValid() ? m.format(_format) : _moment; - }; - - angular.module('lui') - .filter('luifFriendlyRange', function () { - var translations = { - 'en': { - startOnly: 'date(dddd, LL) onwards', - startOnlyThisYear: 'date(dddd, MMMM Do) onwards', - endOnly: 'until date(dddd, LL)', - endOnlyThisYear: 'until date(dddd, MMMM Do)', - date: 'date(LL)', - sameDay: 'start(dddd, LL)', - sameDayThisYear: 'start(dddd, MMMM Do)', - sameMonth: 'start(MMMM Do) - end(Do\, YYYY)', - sameMonthThisYear: 'start(MMMM Do) - end(Do)', - sameYear: 'start(MMMM Do) - end(LL)', - sameYearThisYear: 'start(MMMM Do) - end(MMMM Do)', - other: 'start(LL) - end(LL)' - }, - 'fr': { - startOnly: 'à partir du date(dddd LL)', - startOnlyThisYear: 'à partir du date(dddd Do MMMM)', - endOnly: 'jusqu\'au date(dddd LL)', - endOnlyThisYear: 'jusqu\'au date(dddd Do MMMM)', - date: 'date(LL)', - sameDay: 'le start(dddd LL)', - sameDayThisYear: 'le start(dddd Do MMMM)', - sameMonth: 'du start(Do) au end(LL)', - sameMonthThisYear: 'du start(Do) au end(Do MMMM)', - sameYear: 'du start(Do MMMM) au end(LL)', - sameYearThisYear: 'du start(Do MMMM) au end(Do MMMM)', - other: 'du start(LL) au end(LL)' - }, - 'de': { - - startOnly: 'von date(Do MMMM)', - startOnlyThisYear: 'von date(LL)', - endOnly: 'bis date(Do MMMM)', - endOnlyThisYear: 'bis date(LL)', - date: 'date(LL)', - sameDay: 'der start(dddd LL)', - sameDayThisYear: 'der start(dddd Do MMMM)', - sameMonth: 'von start(Do) bis end(LL)', - sameMonthThisYear: 'von start(Do) bis end(Do MMMM)', - sameYear: 'von start(Do MMMM) bis end(LL)', - sameYearThisYear: 'von start(Do MMMM) bis end(Do MMMM)', - other: 'von start(LL) bis end(LL)' - } - }; - function getTrad(trads, locale, key, fallbackKey) { - if (!!trads && !!trads[locale] && !!trads[locale][key]) { - return trads[locale][key]; - } - if (!!trads && !!trads[locale] && !!trads[locale][fallbackKey]) { - return trads[locale][fallbackKey]; - } - // fallback on english in provided translations - var fallbackLocale = "en"; - if (!!trads && !!trads[fallbackLocale] && !!trads[fallbackLocale][key]) { - return trads[fallbackLocale][key]; - } - if (!!trads && !!trads[fallbackLocale] && !!trads[fallbackLocale][fallbackKey]) { - return trads[fallbackLocale][fallbackKey]; - } - - // fallback on standard translations if I couldnt find what I need in provided trads - var fallbackTrads = translations; - if (!!fallbackTrads && !!fallbackTrads[locale] && !!fallbackTrads[locale][key]) { - return fallbackTrads[locale][key]; - } - if (!!fallbackTrads && !!fallbackTrads[locale] && !!fallbackTrads[locale][fallbackKey]) { - return fallbackTrads[locale][fallbackKey]; - } - // fallback on english in provided translations - if (!!fallbackTrads && !!fallbackTrads[fallbackLocale] && !!fallbackTrads[fallbackLocale][key]) { - return fallbackTrads[fallbackLocale][key]; - } - if (!!fallbackTrads && !!fallbackTrads[fallbackLocale] && !!fallbackTrads[fallbackLocale][fallbackKey]) { - return fallbackTrads[fallbackLocale][fallbackKey]; - } - } - return function (_block, _excludeEnd, _translations) { - if(!_block){ return; } - var start = _block.start || _block.startsAt || _block.startsOn || _block.startDate; - var end = _block.end || _block.endsAt || _block.endsOn || _block.endDate; - if (!start && !end) { - return ""; - } - start = !!start ? moment(start) : undefined; - end = !!end ? moment(end) : undefined; - if(_excludeEnd){ - end.add(-1,'minutes'); - } - var trad; - var format; - var regex; - if (!!start && !!end) { - format = start.year() === end.year() ? start.month() === end.month() ? start.date() === end.date() ? 'sameDay' : 'sameMonth' : 'sameYear' : 'other'; - if(moment().year() === start.year() && moment().year() === end.year()){ - format += "ThisYear"; - } - trad = getTrad(_translations, moment.locale(), format, "other"); - regex = /(start\((.*?)\))(.*(end\((.*?)\))){0,1}/gi.exec(trad); - return trad.replace(regex[1], start.format(regex[2])).replace(regex[4], end.format(regex[5])); - } - format = !!start ? "startOnly" : "endOnly"; - var date = start || end; - if(moment().year() === date.year()){ - format += "ThisYear"; - } - trad = getTrad(_translations, moment.locale(), format, "date"); - regex = /(date\((.*?)\))/gi.exec(trad); - return trad.replace(regex[1], date.format(regex[2])); - }; - }) - .filter('luifMoment', function () { - return function (_moment, _format) { - if (!_format) { _format = 'LLL'; } // default format - return formatMoment(_moment, _format); - }; - }) - .filter('luifCalendar', function () { - return function (_moment, _refDate) { - var m = moment(_moment); - var refDate = (_refDate && moment(_refDate).isValid()) ? moment(_refDate) : moment(); - - return m.isValid() ? m.calendar(_refDate) : _moment; - }; - }) - .filter('luifDuration', ['$filter', function ($filter) { - //expects a duration, returns the duration in the given unit with the given precision - return function (_duration, _sign, _unit, _precision) { - function getConfigIndex(expectedUnit){ - switch(expectedUnit){ - case 'd': - case 'day': - case 'days': return 0; - case undefined: - case '': - case 'h': - case 'hour': - case 'hours': return 1;// default - case 'm': - case 'min': - case 'mins': - case 'minute': - case 'minutes': return 2; - case 's': - case 'sec': - case 'second': - case 'seconds': return 3; - case 'ms': - case 'millisec': - case 'millisecond': - case 'milliseconds': return 4; - } - } - - function getNextNotNull(array, startIndex){ - return startIndex === 4 ? 4 : array[startIndex] !== 0 ? startIndex : getNextNotNull(array, startIndex + 1); - } - - function getPrevNotNull(array, startIndex){ - return startIndex === 0 ? 0 : array[startIndex] !== 0 ? startIndex : getPrevNotNull(array, startIndex - 1); - } - - function getDecimalNumber(days){ - switch(true){ - case (Math.floor((days * 10) % 10) === 0 && Math.floor((days * 100) % 10) === 0): return 0; - case (Math.floor((days * 100) % 10) === 0): return 1; - default: return 2; - } - } - - function formatValue (value, u, expectedUnit){ - switch(u){ - case expectedUnit : return value; - case 2 : - case 3 : return (value < 10 ? '0' + value : value); - case 4 : return (value < 10 ? '00' + value : value < 100 ? '0' + value : value); - default : return value; - } - } - - function getPrefix(sign, duration){ - if (sign) { - if (duration.asMilliseconds() > 0) { return '+'; } - else if (duration.asMilliseconds() < 0) { return '-'; } - } - return ''; - } - - // some localisation shenanigans - function getUnitSymbols(unit, precision){ - var result = ['d ', 'h', 'm', 's', 'ms']; - switch(moment.locale()){ - case "fr": result[0] = 'j '; break; - } - - // if precision = ms and unit bigger than s we want to display 12.525s and not 12s525ms - if(unit <= 3 && precision === 4) { result[3] = '.'; result[4] = 's'; } - if(unit <= 1 && precision === 2) { result[2] = ''; } - if(unit === 2 && precision === 3) { result[3] = ''; } - - return result; - } - - var unitConfigs = [ - { - index: 0, - unit: 'd', - dateConversion : 'asDays', - expectedPrecision : 'h' - }, - { - index: 1, - unit: 'h', - dateConversion : 'asHours', - expectedPrecision :'m' - }, - { - index: 2, - unit: 'm', - dateConversion : 'asMinutes', - expectedPrecision : 's' - }, - { - index: 3, - unit: 's', - dateConversion : 'asSeconds', - expectedPrecision : 's' - }, - { - index: 4, - unit: 'ms', - dateConversion : 'asMilliseconds', - expectedPrecision : 'ms' - }, - ]; - - var d = moment.duration(_duration); - - if (d.asMilliseconds() === 0) { return ''; } - - var values = [Math.abs(d.days()), Math.abs(d.hours()), Math.abs(d.minutes()), Math.abs(d.seconds()), Math.abs(d.milliseconds())]; - var config = unitConfigs[getConfigIndex(_unit)]; - var minimumUnit = Math.max(config.index, getNextNotNull(values, 0)); - values[config.index] = Math.abs(d[config.dateConversion]() >= 0 ? Math.floor(d[config.dateConversion]()) : Math.ceil(d[config.dateConversion]())); - - if (config.index === 0 && getConfigIndex(_precision) === 0 && d.asDays() !== 0){ - var myDays = Math.abs(d.asDays()); - var decimalNumber = getDecimalNumber(myDays); - minimumUnit = 0; - values[0] = $filter("number")(myDays, decimalNumber); - } - - var precision = getPrevNotNull(values, getConfigIndex(_precision || config.expectedPrecision)); - var units = getUnitSymbols(minimumUnit, precision); - - var result = ''; - for(var i = minimumUnit; i <= precision; i++){ - result += formatValue(values[i], i, minimumUnit) + units[i]; - } - - var prefix = !!result ? getPrefix(_sign, d) : ''; - return prefix + result; - }; - }]) - .filter('luifHumanize', function () { - return function (_duration, suffix) { - suffix = !!suffix; - var d = moment.duration(_duration); - return d.humanize(suffix); - }; - }); -})(); +;/* global angular */ +(function(){ + 'use strict'; + var DayBlockDirective = function () { + return { + template : + '
'+ + + '
{{controller.date | luifMoment: \'dddd\'}}'+ + '
'+ + + '
{{controller.date | luifMoment:\'DD\'}}'+ + '
'+ + + '
{{controller.date | luifMoment: \'MMM\'}}'+ + '
'+ + + '
{{controller.date | luifMoment: \'YYYY\'}}'+ + '
'+ + + '
', + + scope : { + date: '=', + showDay: '=', + primaryColor: '=', + secondaryColor: '=' + }, + + restrict : 'E', + bindToController : true, + controllerAs : 'controller', + controller : 'luidDayBlockController' + }; + }; + + + angular + .module('lui') + .directive('luidDayBlock', DayBlockDirective) + .controller('luidDayBlockController', function(){ + var controller = this; + + controller.weekdayStyleOverride = function() { + return { + color: controller.primaryColor, + }; + }; + controller.dayStyleOverride = function() { + return { + "background-color": controller.primaryColor, + "border-color": controller.primaryColor, + "color": controller.secondaryColor, + }; + }; + controller.monthStyleOverride = function() { + return { + "background-color": controller.secondaryColor, + "border-color": controller.primaryColor, + "color": controller.primaryColor, + }; + }; + controller.yearStyleOverride = function() { + return { + "background-color": controller.secondaryColor, + "border-color": controller.primaryColor, + "color": controller.primaryColor, + }; + }; + + + }); + +})(); + + +;(function(){ + 'use strict'; + /** + ** DEPENDENCIES + ** - none + **/ + angular.module('lui') + .directive('luidKeydown', function () { + return { + restrict: 'A', + scope:{ + mappings: '=' + }, + link: function (scope, element, attrs) { + element.on('keydown', function (e) { + if ( !!scope.mappings && !!scope.mappings[e.which] ){ + scope.mappings[e.which](e); + // e.preventDefault(); + } + }); + } + }; + }); + angular.module('lui') + .directive('luidSelectOnClick', function () { + return { + restrict: 'A', + link: function (scope, element, attrs) { + element.on('click', function () { + this.select(); + }); + element.on('focus', function () { + this.select(); + }); + } + }; + }); + angular.module('lui') + .directive('luidFocusOn', function() { + return function(scope, elem, attr) { + scope.$on(attr.luidFocusOn, function(e) { + setTimeout( function() { elem[0].focus(); scope.$apply(); }, 1); + }); + }; + }); +})(); +;(function () { + "use strict"; + + /** + ** DEPENDENCIES + ** - angular translate + ** - underscore + **/ + + angular.module("lui.translate") + .directive("luidTranslations", ["$translate", "_", "$filter", "$timeout", function ($translate, _, $filter, $timeout) { + function link(scope, element, attrs, ctrls) { + var ngModelCtrl = ctrls[1]; + var translateCtrl = ctrls[0]; + + /** Associations language/code */ + var languagesToCodes = { en: 1033, de: 1031, es: 1034, fr: 1036, it: 1040, nl: 2067 }; + + /** List of all the available languages labels */ + var cultures = _.keys(languagesToCodes); + scope.cultures = cultures; + + scope.currentCulture = $translate.preferredLanguage() || "en"; + + var mode = !!attrs.mode ? attrs.mode : "dictionary"; + if (mode === "dictionary" && ngModelCtrl.$viewValue !== undefined) { + _.each(cultures, function (culture) { + scope.$watch( + function () { return !!ngModelCtrl.$viewValue ? ngModelCtrl.$viewValue[culture] : ngModelCtrl.$viewValue; }, + function () { ngModelCtrl.$render(); } + ); + }); + } + + ngModelCtrl.$render = function () { + scope.internal = parse(ngModelCtrl.$viewValue); + translateCtrl.updateTooltip(); + }; + + translateCtrl.updateViewValue = function () { + switch (mode) { + case "dictionary": + return updateDictionary(scope.internal); + case "|": + case "pipe": + return updatePipe(scope.internal); + case "lucca": + return updateLucca(scope.internal); + } + }; + + translateCtrl.updateTooltip = function () { + var tooltipText = ""; + if(!!!scope.internal) { + scope.tooltipText = undefined; + return; + } + for(var i = 0; i < scope.cultures.length; i++) { + if(!!scope.internal[scope.cultures[i]]) { + tooltipText += "["+scope.cultures[i].toUpperCase()+"] : "+ scope.internal[scope.cultures[i]] + "\n"; + } + } + scope.tooltipText = tooltipText; + }; + + var parse = function (value) { + if (value === undefined) { return undefined; } + switch (mode) { + case "dictionary": + return parseDictionary(value); + case "|": + case "pipe": + return parsePipe(value); + case "lucca": + return parseLucca(value); + default: + return undefined; + } + }; + + // Mode lucca + var parseLucca = function (value) { + return _.reduce(cultures, function (memo, culture) { + var targetLabel = _.findWhere(value, { cultureCode: languagesToCodes[culture] }); + memo[culture] = !!targetLabel ? targetLabel.value : undefined; + // We need to keep the original id + memo[culture + "_id"] = !!targetLabel ? targetLabel.id : undefined; + return memo; + }, {}); + }; + var updateLucca = function (value) { + var allEmpty = true; + var viewValue = []; + _.each(cultures, function (culture) { + if (!!value[culture] && value[culture] !== "") { + viewValue.push({ id: value[culture + "_id"], cultureCode: languagesToCodes[culture], value: value[culture] }); + allEmpty = false; + } + }); + ngModelCtrl.$setViewValue(allEmpty ? undefined : viewValue); + scope.$parent.$eval(attrs.ngChange); + }; + + // Mode dictionary + var parseDictionary = function (value) { + return _.reduce(cultures, function (memo, culture) { + memo[culture] = value[culture]; + return memo; + }, {}); + }; + var updateDictionary = function (value) { + var allEmpty = true; + var viewValue = {}; + _.each(cultures, function (culture) { + viewValue[culture] = value[culture]; + allEmpty &= value[culture] === undefined || value[culture] === ""; + }); + ngModelCtrl.$setViewValue(allEmpty ? undefined : viewValue); + scope.$parent.$eval(attrs.ngChange); // needs to be called manually cuz the object ref of the $viewValue didn't change + }; + + // Mode pipe + var parsePipe = function (value) { + // value looks like this "en:some stuff|de:|nl:|fr:des bidules|it:|es:" + var translations = value.split("|"); + var result = {}; + _.each(translations, function (t) { + var key = t.substring(0, 2); + var val = t.substring(3); + result[key] = val; + }); + return _.pick(result, cultures); + }; + var updatePipe = function (value) { + if (!_.find(cultures, function (culture) { return value[culture] !== undefined && value[culture] !== ""; })) { + ngModelCtrl.$setViewValue(undefined); + } else { + var newVal = _.map(cultures, function (c) { + if (!!value[c]) { + return c + ":" + value[c]; + } + return c + ":"; + }).join("|"); + ngModelCtrl.$setViewValue(newVal); + } + }; + } + return { + require: ['luidTranslations', '^ngModel'], + controller: 'luidTranslationsController', + scope: { + mode: '@', // allowed values: "pipe" (or "|"), "dictionary", "lucca" (lucca proprietary format) + size: "@", // the size of the input (short, long, x-long, fitting) + isDisabled: "=ngDisabled" + }, + templateUrl: "lui/directives/luidTranslations.html", + restrict: 'EA', + link: link + }; + }]) + .controller('luidTranslationsController', ['$scope', '$translate', '$timeout', function ($scope, $filter, $timeout) { + var ctrl = this; + /****************** + * UPDATE * + ******************/ + $scope.update = function () { ctrl.updateViewValue(); ctrl.updateTooltip(); }; + + /****************** + * FOCUS & BLUR * + ******************/ + + $scope.focusInput = function () { + $scope.focused = true; + }; + $scope.blurInput = function () { + $scope.focused = false; + }; + + $scope.blurOnEnter = function($event) { + $event.target.blur(); + $event.preventDefault(); + }; + }]); + + /**************************/ + /***** TEMPLATES *****/ + /**************************/ + angular.module("lui").run(["$templateCache", function ($templateCache) { + $templateCache.put("lui/directives/luidTranslations.html", + "
" + + "
" + + " " + + " {{currentCulture}}" + + "
" + + "
" + + "
" + + "
" + + " " + + " {{culture}}" + + "
" + + "
" + + "
" + + "
" + + ""); + }]); +})(); +;(function(){ + 'use strict'; + /** + ** DEPENDENCIES + ** - moment + **/ + var MAGIC_DELAY_BEFORE_WHEEL = 200; + + angular.module('lui') + .directive('luidMoment', ['moment', function(moment){ + function link(scope, element, attrs, ctrls){ + var ngModelCtrl = ctrls[1]; + var mpCtrl = ctrls[0]; + + // display the value i on two chars + if(!!attrs.format){ // allows to have a ng-model of type string, not moment + var format = scope.$eval(attrs.format); + + ngModelCtrl.getValue = function() { + var vv = ngModelCtrl.$viewValue; + if (!vv) { + return undefined; + } + var momentVv = moment(vv, format); + if (!momentVv.isValid()) { + return undefined; + } + return momentVv; + }; + + ngModelCtrl.$render = function() { + var momentValue = ngModelCtrl.getValue(); + scope.hours = !!momentValue ? momentValue.format('HH') : undefined; + scope.mins = !!momentValue ? momentValue.format('mm') : undefined; + ngModelCtrl.$validate(); + }; + + ngModelCtrl.setValue = function(newMomentValue) { + ngModelCtrl.$setViewValue(!newMomentValue ? undefined : newMomentValue.format(format)); + }; + ngModelCtrl.$validators.min = function (modelValue,viewValue) { + return !viewValue || mpCtrl.checkMin(moment(modelValue, format)); + }; + ngModelCtrl.$validators.max = function (modelValue,viewValue) { + return !viewValue || mpCtrl.checkMax(moment(modelValue, format)); + }; + } else { + ngModelCtrl.getValue = function() { + var vv = ngModelCtrl.$viewValue; + if (!vv) { + return undefined; + } + var momentVv = moment(vv); + if (!vv.isValid()) { + return undefined; + } + return momentVv; + }; + ngModelCtrl.$render = function() { + var vv = ngModelCtrl.getValue(); + var condition = !!vv && vv.isValid(); + scope.hours = condition ? vv.format('HH') : undefined; + scope.mins = condition ? vv.format('mm') : undefined; + ngModelCtrl.$validate(); + }; + ngModelCtrl.setValue = function(newMomentValue) { + ngModelCtrl.$setViewValue(newMomentValue); + }; + ngModelCtrl.$validators.min = function (modelValue,viewValue) { + return !viewValue || mpCtrl.checkMin(modelValue); + }; + ngModelCtrl.$validators.max = function (modelValue,viewValue) { + return !viewValue || mpCtrl.checkMax(modelValue); + }; + } + + scope.ngModelCtrl = ngModelCtrl; + + ngModelCtrl.$validators.hours = function (modelValue,viewValue) { + return scope.hours !== undefined && scope.hours !== "" && !isNaN(parseInt(scope.hours)); + }; + ngModelCtrl.$validators.minutes = function (modelValue,viewValue) { + return scope.mins !== undefined && scope.mins !== "" && parseInt(scope.mins) < 60; + }; + + var inputs = element.querySelectorAll('.input'); + mpCtrl.setupEvents(element, angular.element(inputs[0]), angular.element(inputs[1])); + + // reexecute validators if min or max change + // will not be reexecuted if min is a moment and something like `min.add(3, 'h')` is called + scope.$watch('min', function(){ + ngModelCtrl.$validate(); + }); + scope.$watch('max', function(){ + ngModelCtrl.$validate(); + }); + + } + + return { + require:['luidMoment','^ngModel'], + controller:'luidMomentController', + scope: { + min:'=', // a moment or a str to specify the min for this input + max:'=', // idem for max + step:'=', // the number of minutes to add/subtract when clicking the addMins button or scrolling on the add in input + referenceDate:'=', // when entering a time, the date to set it, also used to count the number of days between the ngModel and this date, if unavailable, will use min then max then today + isDisabled:'=', + showButtons:'=', // forces the buttons to be displayed even if neither inputs is focused + enforceValid:'=', // prevents entering an ng-invalid input by correcting the value when losing focus + + format:'=', // alows ng-model to be a string with the right format + + // hacks + minOffset:'=', // to avoid having to say min=val1+val2 because it causes an other digest cycle, we give the offset and the + maxOffset:'=' + }, + templateUrl:"lui/directives/luidMoment.html", + restrict:'EA', + link: link, + }; + }]) + .controller('luidMomentController', ['$scope', '$timeout', 'moment', '$element', function($scope, $timeout, moment, $element) { + function incr(step) { + function calculateNewValue() { + function contains(array, value) { return array.indexOf(value) !== -1; } + + var curr = moment(currentValue()); + if (!curr || !curr.isValid()) { curr = getRefDate().startOf('day'); } + if (contains(specialSteps, Math.abs(step)) && curr.minutes() % step !== 0) { + step = step < 0 ? - (curr.minutes() % step) : -curr.minutes() % step + step; + } + + var newValue = curr.add(step,'m'); + newValue.seconds(0); + return newValue; + } + + if ($scope.isDisabled) { return; } + // $scope.ngModelCtrl.$setValidity('pattern', true); + + update(calculateNewValue(), true); + } + + function update(newValue, autoCorrect) { + updateWithoutRender(newValue, autoCorrect); + $scope.ngModelCtrl.$render(); + } + + function updateWithoutRender(newValue, autoCorrect) { + function correctedValue(newValue, min, max) { + switch(true){ + case (!newValue) : return newValue; + case (min && min.diff(newValue) > 0) : return min; + case (max && max.diff(newValue) < 0) : return max; + default : return newValue; + } + } + var min = getMin(); + var max = getMax(); + + if (autoCorrect) { + var newCorrectedValue = correctedValue(newValue, min, max); + if (newCorrectedValue.format("HH:mm") !== newValue.format("HH:mm")) { + newValue = newCorrectedValue; + + $element.addClass('autocorrect'); + setTimeout(function() { + $element.removeClass('autocorrect'); + }, 200); + } + } + $scope.maxed = newValue && max && max.diff(newValue) <= 0; + $scope.mined = newValue && min && min.diff(newValue) >= 0; + + $scope.ngModelCtrl.setValue(newValue); + } + + // translate between string values and viewvalue + function undefinedHoursOrMinutes() { + return $scope.hours === undefined || $scope.hours === "" || $scope.mins === undefined || $scope.mins === ""; + } + + function getInputedTime() { + if (undefinedHoursOrMinutes()) { + return undefined; + } + + var intHours = parseInt($scope.hours); + var intMinutes = parseInt($scope.mins); + // if (intHours != intHours) { intHours = 0; } // intHour isNaN + // if (intMinutes != intMinutes) { intMinutes = 0; } // intMins isNaN + if (intMinutes > 60) { intMinutes = 59; $scope.mins = "59"; } + + var initialTime = getRefDate().hours(intHours).minutes(intMinutes).seconds(0); + + // try to put time between min and max by adding some days while time < min and time !> max + var time = betweenMinAndMax(initialTime); + + return time; + } + + function betweenMinAndMax(refTime) { + var time = moment(refTime); + var minTime = moment(time), maxTime = moment(time); + var min = getMin(), max = getMax(); + var dayCnt; + // time < min, add enough day to have it after min + if(!!min && time.isBefore(min)) { + // number of days between min and time, rounded to next integer + dayCnt = Math.ceil(min.diff(time, 'day', true)); + minTime.add(dayCnt, 'day'); + } + // time > max + if (!!max && time.isAfter(max)) { + // number of days between max and time, rounded to previous integer + dayCnt = Math.floor(max.diff(time, 'day', true)); + maxTime.add(dayCnt, 'days'); + } + + if (!!max && (minTime.isBefore(max) || minTime.isSame(max))) { + return minTime; + } + if (!!min && (maxTime.isAfter(min) || maxTime.isSame(min))) { + return maxTime; + } + return time; + } + + function cancelTimeouts() { + function cancel(timeout){ + if (!!timeout) { + $timeout.cancel(timeout); + timeout = undefined; + } + } + cancel(hoursFocusTimeout); + cancel(minsFocusTimeout); + } + + function correctValue() { + update(currentValue(), $scope.enforceValid); + } + + function getStep() { return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step); } + + function getRefDate() { + function toMoment(value) { return (!!value && moment(value).isValid()) ? moment(value) : undefined; } + + return toMoment($scope.referenceDate) || toMoment($scope.min) || toMoment($scope.max) || moment(); + } + + function getExtremum(extremum, offset, checkMidnight) { + function rawExtremum(){ + switch(true){ + // check if min/max is a valid moment + case (!!extremum.isValid && !!extremum.isValid()) : return moment(extremum); + // check if min/max is parsable by moment + case (moment(extremum,'YYYY-MM-DD HH:mm').isValid()) : return moment(extremum,'YYYY-MM-DD HH:mm'); + // check if min/max is like '23:15' + case (moment(extremum, 'HH:mm').isValid()) : + var refDate = getRefDate(); + var extrem = moment(extremum, 'HH:mm').year(refDate.year()).month(refDate.month()).date(refDate.date()); + // a min/max time of '00:00' means midnight tomorrow + if (checkMidnight && extrem.hours() + extrem.minutes() === 0) { extrem.add(1,'d');} + return extrem; + } + } + + // min/max attr not specified + if (!extremum) { return undefined; } + var extrem = rawExtremum(); + extrem.add(moment.duration(offset)); + return extrem; + } + + function getMin() { return getExtremum($scope.min, $scope.minOffset, false); } + function getMax() { return getExtremum($scope.max, $scope.maxOffset, true); } + + function currentValue() { return !$scope.format ? $scope.ngModelCtrl.$viewValue : moment($scope.ngModelCtrl.$viewValue, $scope.format); } + + function incrementEvent(eventName, value) { + cancelTimeouts(); + incr(value); + $scope.$broadcast(eventName); + } + + function focusEvent(isMinute) { + cancelTimeouts(); + $scope.minsFocused = !!isMinute; + $scope.hoursFocused = !isMinute; + } + + function blurEvent(timeout, isFocused){ + var model = $scope.ngModelCtrl.$modelValue; + updateWithoutRender(model); + timeout = $timeout(function(){ + timeout = false; + correctValue(); + }, 200); + } + + var hoursFocusTimeout, minsFocusTimeout; + var specialSteps = [5, 10, 15, 20, 30]; + var mpCtrl = this; + $scope.pattern = /^([0-9]{0,2})?$/; + + // stuff to control the focus of the different elements and the clicky bits on the + - buttons + // what we want is show the + - buttons if one of the inputs is displayed + // and we want to be able to click on said buttons without loosing focus (obv) + $scope.incrHours = function() { incrementEvent('focusHours', 60); }; + $scope.decrHours = function() { incrementEvent('focusHours', -60); }; + $scope.incrMins = function() { incrementEvent('focusMinutes', getStep()); }; + $scope.decrMins = function() { incrementEvent('focusMinutes', -getStep()); }; + + function isUndefinedOrEmpty(val) { + return val === undefined || val === ""; + } + + // string value changed + $scope.changeHours = function(){ + if(isUndefinedOrEmpty($scope.hours)){ + return updateWithoutRender(undefined); + } + + if(isUndefinedOrEmpty($scope.mins)){ + $scope.mins = "00"; + } + + if ($scope.hours.length == 2) { + if (parseInt($scope.hours) > 23) { $scope.hours = '23'; } + $scope.$broadcast('focusMinutes'); + } else if ($scope.hours.length == 1 && parseInt($scope.hours) > 2) { + $scope.hours = 0 + $scope.hours; + $scope.$broadcast('focusMinutes'); + } + updateWithoutRender(getInputedTime()); + }; + + $scope.changeMins = function() { + if (!$scope.mins || $scope.mins.length < 2) { + $scope.ngModelCtrl.$setValidity("minutes", false); + } else { + updateWithoutRender(getInputedTime()); + } + }; + + // display stuff + $scope.formatInputValue = function() { $scope.ngModelCtrl.$render(); }; + + $scope.getDayGap = function(){ + var refDate = getRefDate().startOf('day'); + return moment.duration(moment(currentValue()).startOf('d').diff(refDate)).asDays(); + }; + + $scope.blurHours = function() { blurEvent(hoursFocusTimeout, $scope.hoursFocused); }; + $scope.blurMins = function() { + if(!$scope.mins) { + if($scope.hours === "" || $scope.hours === undefined){ + $scope.mins = undefined; + } else { + $scope.mins = "00"; + } + } else if ($scope.mins.length < 2) { + $scope.mins = "0" + $scope.mins; + } + blurEvent(minsFocusTimeout, $scope.minsFocused); + }; + + $scope.focusHours = function() { focusEvent(false); }; + $scope.focusMins = function() { focusEvent(true); }; + + this.checkMin = function(newValue) { + var min = getMin(); + return !min || min.diff(newValue) <= 0; + }; + + this.checkMax = function(newValue) { + var max = getMax(); + return !max || max.diff(newValue) >= 0; + }; + + // events - mousewheel and arrowkeys + this.setupEvents = function(elt, hoursField, minsField){ + var hoursInput = angular.element(hoursField.find('input')[0]), + minsInput = angular.element(minsField.find('input')[0]); + + function setupArrowkeyEvents(hoursInput, minsInput) { + function subscription(e, step){ + switch(e.which){ + case 38:// up + e.preventDefault(); + incr(step); + $scope.$apply(); + break; + case 40:// down + e.preventDefault(); + incr(-step); + $scope.$apply(); + break; + case 13:// enter + e.preventDefault(); + $scope.formatInputValue(); + $scope.$apply(); + break; + } + } + var step = getStep(); + hoursInput.bind('keydown', function(e) { subscription(e, 60); }); + minsInput.bind('keydown', function(e) { subscription(e, step); }); + } + + function setupMousewheelEvents(elt, hoursField, minsField) { + function isScrollingUp(e) { + e = e.originalEvent ? e.originalEvent : e; + //pick correct delta variable depending on event + var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; + return (e.detail || delta > 0); + } + var enableMouseWheel = false; + var enableWheelTimeout; + elt.bind('mouseenter', function(e) { + enableWheelTimeout = setTimeout(function() { + enableMouseWheel = true; + }, MAGIC_DELAY_BEFORE_WHEEL); + }); + elt.bind('mouseleave', function(e) { + if (!!enableWheelTimeout) { + clearTimeout(enableWheelTimeout); + } + enableMouseWheel = false; + }); + function subscription(e, incrStep){ + if(!$scope.isDisabled && enableMouseWheel){ + $scope.$apply(incr((isScrollingUp(e)) ? incrStep : -incrStep )); + e.preventDefault(); + } + } + var step = getStep(); + + hoursField.bind('mousewheel wheel', function(e) { subscription(e, 60); }); + minsField.bind('mousewheel wheel', function(e) { subscription(e, step); }); + } + + setupArrowkeyEvents( hoursInput, minsInput); + setupMousewheelEvents(elt, hoursField, minsField); + }; + + }]); + + angular.module("lui").run(["$templateCache", function($templateCache) { + $templateCache.put("lui/directives/luidMoment.html", + "
" + + " " + + " " + + " " + + "
" + + ":" + + "
" + + " " + + " " + + " " + + "
" + + ""); + }]); +})(); +;(function () { + 'use strict'; + /** + ** DEPENDENCIES + ** - none + **/ + + angular.module('lui').directive('luidPercentage', function () { + function link(scope, element, attrs, ctrls) { + + var ngModelCtrl = ctrls[1]; + var luidPercentageCtrl = ctrls[0]; + scope.pattern = /^([0-9]+)(\.([0-9]*)?)?$/i; + if (!attrs.format) { + scope.format = "0.XX"; + }else if(attrs.format !== "0.XX" && attrs.format !== "1.XX" && attrs.format !== "XX"){ + ngModelCtrl.$render = function () { scope.intPct = "unsupported format"; }; + return; + } + + scope.ngModelCtrl = ngModelCtrl; + + ngModelCtrl.$render = function () { + if (this.$viewValue === undefined) { + scope.intPct = undefined; + return; + } + // must support the different formats here + scope.intPct = scope.parse(parseFloat(this.$viewValue)); + }; + + // call the ng-change + ngModelCtrl.$viewChangeListeners.push(function () { + scope.$eval(attrs.ngChange); + }); + + // bind to various events - here only keypress=enter + luidPercentageCtrl.setupEvents(element.find('input')); + } + + + return { + require: ['luidPercentage', '^ngModel'], + controller: 'luidPercentageController', + scope: { + step: '=', // default = 5 + format: '@', // 'XX', '0.XX' or '1.XX', default 0.XX + ngDisabled: '=', + placeholder: '@' + }, + restrict: 'EA', + link: link, + template: + "
" + + "" + + "%" + + "
" + }; + }) + .controller('luidPercentageController', ['$scope', function ($scope) { + + // private - updates of some kinds + // incr value by `step` minutes + function incr(step) { + update(parseFloat($scope.intPct) + step); + } + + // sets viewValue and renders + function update(duration) { + updateWithoutRender(duration); + $scope.ngModelCtrl.$render(); + } + + function updateWithoutRender(duration) { + function format(pct) { + switch($scope.format || "0.XX"){ + case "XX" : return pct; + case "0.XX" : return pct/100; + case "1.XX" : return (pct/100) + 1; + default : return 0; + } + } + + var newValue = duration === undefined ? undefined : format(duration); + $scope.ngModelCtrl.$setViewValue(newValue); + } + + // events - key 'enter' + this.setupEvents = function (elt) { + function getStep(){ return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step);} + function setupKeyEvents(elt) { + var step = getStep(); + elt.bind('keydown', function (e) { + switch(e.which){ + case 38:// up + e.preventDefault(); + incr(step); + $scope.$apply(); + break; + case 40:// down + e.preventDefault(); + incr(-step); + $scope.$apply(); + break; + case 13:// enter + e.preventDefault(); + $scope.formatInputValue(); + $scope.$apply(); + break; + } + }); + } + function setupMousewheelEvents(elt) { + function isScrollingUp(e) { + e = e.originalEvent ? e.originalEvent : e; + //pick correct delta variable depending on event + var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; + return (e.detail || delta > 0); + } + + var step = getStep(); + elt.bind('mousewheel wheel', function (e) { + if (this === document.activeElement) { + $scope.$apply(incr((isScrollingUp(e)) ? step : -step)); + e.preventDefault(); + } + }); + } + + setupKeyEvents(elt); + setupMousewheelEvents(elt); + }; + + // public methods for update + $scope.updateValue = function () { + updateWithoutRender($scope.intPct); + }; + + $scope.parse = function (intInput) { + switch($scope.format || "0.XX"){ + case "XX": return intInput; + case "0.XX": return Math.round(10000 * intInput) / 100; + case "1.XX": return Math.round((intInput-1) * 10000) / 100; + default : return 0; + } + }; + + // display stuff + $scope.formatInputValue = function () { + $scope.ngModelCtrl.$render(); + }; + }]); +})(); +;(function () { + 'use strict'; + /** + ** DEPENDENCIES + ** - moment + **/ + + angular.module('lui').directive('luidTimespan', ['moment', function (moment) { + + function link(scope, element, attrs, ctrls) { + var ngModelCtrl = ctrls[1]; + var luidTimespanCtrl = ctrls[0]; + scope.pattern = /^\-?([0-9]+)((h([0-9]{2})?)?(m(in)?)?)?$/i; + if (!!attrs.unit) { + var unit = scope.$eval(attrs.unit); + if (unit == 'h' || unit == 'hour' || unit == 'hours') { + scope.useHours = true; + } + } + + scope.ngModelCtrl = ngModelCtrl; + + ngModelCtrl.$render = function () { + scope.strDuration = ''; + if (!this.$viewValue) { + return; + } + var currentDuration = moment.duration(this.$viewValue); + if (currentDuration < 0) { + scope.strDuration += "-"; + currentDuration = moment.duration(-currentDuration); + } + var hours = Math.floor(currentDuration.asHours()); + var minutes = currentDuration.minutes(); + if (hours === 0) { + scope.strDuration += minutes + 'm'; + } else { + scope.strDuration += (hours < 10 ? '0' : '') + hours + 'h' + (minutes < 10 ? '0' : '') + minutes; + } + }; + + // bind to various events - here only keypress=enter + luidTimespanCtrl.setupEvents(element.find('input')); + + // set to given mode or to default mode + luidTimespanCtrl.mode = attrs.mode ? attrs.mode : "timespan"; + } + + + return { + require: ['luidTimespan', '^ngModel'], + controller: 'luidTimespanController', + scope: { + step: '=', // default = 5 + unit: '=', // 'hours', 'hour', 'h' or 'm', default='m' + ngDisabled: '=', + placeholder: '@', + mode: "=", // 'timespan', 'moment.duration', default='timespan' + min: '=', //min value + max: '=', //max value + }, + restrict: 'EA', + link: link, + template: + "
" + + "" + + "
" + }; + }]) + .controller('luidTimespanController', ['$scope', 'moment', function ($scope, moment) { + var ctrl = this; + + function parse(strInput) { + // parsing str to moment.duration + function parseHoursAndMinutes(strInput) { + var d = moment.duration(); + var splitted = strInput.split(/h/i); + var isPositive = parseInt(splitted[0]) >= 0; + d.add(parseInt(splitted[0]), 'hours'); + var strMin = splitted[1]; + if (!!strMin && strMin.length >= 2) { + if (isPositive){ + d.add(parseInt(strMin.substring(0, 2)), 'minutes'); + } else { + d.subtract(parseInt(strMin.substring(0, 2)), 'minutes'); + } + } + return d; + } + + function parseMinutes(strInput) { + var d = moment.duration(); + var splitted = strInput.split(/m/i); + d.add(parseInt(splitted[0]), 'minutes'); + return d; + } + + function parseHours(strInput) { + var d = moment.duration(); + var splitted = strInput.split(/h/i); + d.add(parseInt(splitted[0]), 'hours'); + return d; + } + + switch(true){ + case (/h/i.test(strInput)) : return parseHoursAndMinutes(strInput); + case (/m/i.test(strInput)) : return parseMinutes(strInput); + case ($scope.useHours) : return parseHours(strInput); + default : return parseMinutes(strInput); + } + } + + // updates of some kinds + // incr value by `step` minutes + function incr(step) { + var newDur = moment.duration(currentValue()).add(step, 'minutes'); + if (newDur.asMilliseconds() < 0) { + newDur = moment.duration(); + } + update(newDur); + } + + // sets viewValue and renders + function update(newDuration) { + updateWithoutRender(newDuration); + $scope.ngModelCtrl.$render(); + } + + function updateWithoutRender(newDuration) { + // Handle min/max values + function correctValue(newValue){ + function correctedMinValue(newValue) { + var min = !$scope.min ? undefined : moment.duration($scope.min); + return (!min || min <= newValue) ? newValue : min; + } + + function correctedMaxValue(newValue) { + var max = !$scope.max ? undefined : moment.duration($scope.max); + return (!max || max >= newValue) ? newValue : max; + } + + return correctedMaxValue(correctedMinValue(newValue)); + } + + function format(dur) { + if (ctrl.mode === 'timespan') { + var timespan = ""; + if (dur.asMilliseconds() < 0){ + timespan += "-"; + dur = moment.duration(-dur); + } + timespan += (dur.days() > 0 ? Math.floor(dur.asDays()) + '.' : '') + (dur.hours() < 10 ? '0' : '') + dur.hours() + ':' + (dur.minutes() < 10 ? '0' : '') + dur.minutes() + ':00'; + return timespan; + } + return dur; + } + + if (newDuration === undefined) { + return $scope.ngModelCtrl.$setViewValue(undefined); + } + + // Check min/max values + newDuration = correctValue(newDuration); + var formattedValue = format(newDuration); + + $scope.ngModelCtrl.$setViewValue(formattedValue); + } + + function currentValue() { + return $scope.ngModelCtrl.$viewValue; + } + + // events - key 'enter' + this.setupEvents = function (elt) { + function getStep(){ return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step);} + function setupKeyEvents(elt) { + var step = getStep(); + elt.bind('keydown', function (e) { + switch(e.which){ + case 38:// up + e.preventDefault(); + incr(step); + $scope.$apply(); + break; + case 40:// down + e.preventDefault(); + incr(-step); + $scope.$apply(); + break; + case 13:// enter + e.preventDefault(); + $scope.formatInputValue(); + $scope.$apply(); + break; + } + }); + } + + function setupMousewheelEvents(elt) { + function isScrollingUp(e) { + e = e.originalEvent ? e.originalEvent : e; + //pick correct delta variable depending on event + var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; + return (e.detail || delta > 0); + } + + var step = getStep(); + elt.bind('mousewheel wheel', function (e) { + if (this === document.activeElement) { + $scope.$apply(incr((isScrollingUp(e)) ? step : -step)); + e.preventDefault(); + } + }); + } + + setupKeyEvents(elt); + setupMousewheelEvents(elt); + }; + + // public methods for update + $scope.updateValue = function () { + + // is only fired when pattern is valid or when it goes from valid to invalid + // improvement possible - check the pattern and set the validity of the all directive via ngModelCtrl.$setValidity + // currently when pattern invalid, the viewValue is set to '00:00:00' + if (!$scope.strDuration) { return updateWithoutRender(undefined); } // empty input => 00:00:00 + + // parse the strDuration to build newDuration + // the duration of the parsed strDuration + var newDuration = parse($scope.strDuration); + + // update viewvalue + updateWithoutRender(newDuration); + }; + + // display stuff + $scope.formatInputValue = function () { + $scope.ngModelCtrl.$render(); + }; + }]); +})(); +;(function(){ + 'use strict'; + /** + ** DEPENDENCIES + ** - none, nothing, nada + **/ + function replaceAll(string, find, replace) { + // http://stackoverflow.com/questions/1144783/replacing-all-occurrences-of-a-string-in-javascript + // lets not reinvent the wheel + if(!string){ return ''; } + function escapeRegExp(string) { + return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); + } + return string.replace(new RegExp(escapeRegExp(find), 'g'), replace); + } + angular.module('lui') + .filter('luifPlaceholder', function () { + return function (_input, _placeholder) { + return !!_input ? _input : _placeholder; + }; + }) + .filter('luifDefaultCode', function () { + // uppercased and with '_' instead of ' ' + return function (_input) { + return replaceAll(_input, ' ', '_').toUpperCase(); + }; + }) + .filter('luifStartFrom', function () { + //pagination filter + return function (_input, start) { + start = +start; //parse to int + return _input.slice(start); + }; + }) + .filter('luifNumber', ['$sce', '$filter', function($sce, $filter) { + return function(_input, _precision, _placeholder) { + + function getRightSpan(decimalPart, separator) { + if (decimalPart === undefined) { return ""; } + if (parseInt(decimalPart) === 0) { return "" + separator + decimalPart + ""; } + return "" + separator + decimalPart + ""; + } + + var placeholder = _placeholder === undefined ? '' : _placeholder; + // alert(_input + " " + (!!_input.isNaN && _input.isNaN())); + var input = _input === undefined || _input === null || _input === "" || _input != _input ? placeholder : _input; // the last check is to check if _input is NaN + var separator = $filter("number")(1.1,1)[1]; + var precision = _precision === undefined || _precision === null || _precision != _precision ? 2 : _precision; + + var text = $filter("number")(input, precision); + var decimalPart = (text || $filter("number")(0, precision)).split(separator)[1]; + var rightSpan = getRightSpan(decimalPart, separator); + + if (input === '' || !text){ + // the _input or the _placeholder was not parsable by the number $filter, just return input but trusted as html + return $sce.trustAsHtml(input + rightSpan); + } + + var integerPart = text.split(separator)[0]; + return $sce.trustAsHtml(integerPart + rightSpan); + }; + }]); +})(); +;(function () { + 'use strict'; + /** + ** DEPENDENCIES + ** - moment + **/ + var formatMoment = function (_moment, _format) { //expects a moment + if (!_moment) { + return ""; + } + var m = moment(_moment); + return m.isValid() ? m.format(_format) : _moment; + }; + + angular.module('lui') + .filter('luifFriendlyRange', function () { + var translations = { + 'en': { + startOnly: 'date(dddd, LL) onwards', + startOnlyThisYear: 'date(dddd, MMMM Do) onwards', + endOnly: 'until date(dddd, LL)', + endOnlyThisYear: 'until date(dddd, MMMM Do)', + date: 'date(LL)', + sameDay: 'start(dddd, LL)', + sameDayThisYear: 'start(dddd, MMMM Do)', + sameMonth: 'start(MMMM Do) - end(Do\, YYYY)', + sameMonthThisYear: 'start(MMMM Do) - end(Do)', + sameYear: 'start(MMMM Do) - end(LL)', + sameYearThisYear: 'start(MMMM Do) - end(MMMM Do)', + other: 'start(LL) - end(LL)' + }, + 'fr': { + startOnly: 'à partir du date(dddd LL)', + startOnlyThisYear: 'à partir du date(dddd Do MMMM)', + endOnly: 'jusqu\'au date(dddd LL)', + endOnlyThisYear: 'jusqu\'au date(dddd Do MMMM)', + date: 'date(LL)', + sameDay: 'le start(dddd LL)', + sameDayThisYear: 'le start(dddd Do MMMM)', + sameMonth: 'du start(Do) au end(LL)', + sameMonthThisYear: 'du start(Do) au end(Do MMMM)', + sameYear: 'du start(Do MMMM) au end(LL)', + sameYearThisYear: 'du start(Do MMMM) au end(Do MMMM)', + other: 'du start(LL) au end(LL)' + }, + 'de': { + + startOnly: 'von date(Do MMMM)', + startOnlyThisYear: 'von date(LL)', + endOnly: 'bis date(Do MMMM)', + endOnlyThisYear: 'bis date(LL)', + date: 'date(LL)', + sameDay: 'der start(dddd LL)', + sameDayThisYear: 'der start(dddd Do MMMM)', + sameMonth: 'von start(Do) bis end(LL)', + sameMonthThisYear: 'von start(Do) bis end(Do MMMM)', + sameYear: 'von start(Do MMMM) bis end(LL)', + sameYearThisYear: 'von start(Do MMMM) bis end(Do MMMM)', + other: 'von start(LL) bis end(LL)' + } + }; + function getTrad(trads, locale, key, fallbackKey) { + if (!!trads && !!trads[locale] && !!trads[locale][key]) { + return trads[locale][key]; + } + if (!!trads && !!trads[locale] && !!trads[locale][fallbackKey]) { + return trads[locale][fallbackKey]; + } + // fallback on english in provided translations + var fallbackLocale = "en"; + if (!!trads && !!trads[fallbackLocale] && !!trads[fallbackLocale][key]) { + return trads[fallbackLocale][key]; + } + if (!!trads && !!trads[fallbackLocale] && !!trads[fallbackLocale][fallbackKey]) { + return trads[fallbackLocale][fallbackKey]; + } + + // fallback on standard translations if I couldnt find what I need in provided trads + var fallbackTrads = translations; + if (!!fallbackTrads && !!fallbackTrads[locale] && !!fallbackTrads[locale][key]) { + return fallbackTrads[locale][key]; + } + if (!!fallbackTrads && !!fallbackTrads[locale] && !!fallbackTrads[locale][fallbackKey]) { + return fallbackTrads[locale][fallbackKey]; + } + // fallback on english in provided translations + if (!!fallbackTrads && !!fallbackTrads[fallbackLocale] && !!fallbackTrads[fallbackLocale][key]) { + return fallbackTrads[fallbackLocale][key]; + } + if (!!fallbackTrads && !!fallbackTrads[fallbackLocale] && !!fallbackTrads[fallbackLocale][fallbackKey]) { + return fallbackTrads[fallbackLocale][fallbackKey]; + } + } + return function (_block, _excludeEnd, _translations) { + if(!_block){ return; } + var start = _block.start || _block.startsAt || _block.startsOn || _block.startDate; + var end = _block.end || _block.endsAt || _block.endsOn || _block.endDate; + if (!start && !end) { + return ""; + } + start = !!start ? moment(start) : undefined; + end = !!end ? moment(end) : undefined; + if(_excludeEnd){ + end.add(-1,'minutes'); + } + var trad; + var format; + var regex; + if (!!start && !!end) { + format = start.year() === end.year() ? start.month() === end.month() ? start.date() === end.date() ? 'sameDay' : 'sameMonth' : 'sameYear' : 'other'; + if(moment().year() === start.year() && moment().year() === end.year()){ + format += "ThisYear"; + } + trad = getTrad(_translations, moment.locale(), format, "other"); + regex = /(start\((.*?)\))(.*(end\((.*?)\))){0,1}/gi.exec(trad); + return trad.replace(regex[1], start.format(regex[2])).replace(regex[4], end.format(regex[5])); + } + format = !!start ? "startOnly" : "endOnly"; + var date = start || end; + if(moment().year() === date.year()){ + format += "ThisYear"; + } + trad = getTrad(_translations, moment.locale(), format, "date"); + regex = /(date\((.*?)\))/gi.exec(trad); + return trad.replace(regex[1], date.format(regex[2])); + }; + }) + .filter('luifMoment', function () { + return function (_moment, _format) { + if (!_format) { _format = 'LLL'; } // default format + return formatMoment(_moment, _format); + }; + }) + .filter('luifCalendar', function () { + return function (_moment, _refDate) { + var m = moment(_moment); + var refDate = (_refDate && moment(_refDate).isValid()) ? moment(_refDate) : moment(); + + return m.isValid() ? m.calendar(_refDate) : _moment; + }; + }) + .filter('luifDuration', ['$filter', function ($filter) { + //expects a duration, returns the duration in the given unit with the given precision + return function (_duration, _sign, _unit, _precision) { + function getConfigIndex(expectedUnit){ + switch(expectedUnit){ + case 'd': + case 'day': + case 'days': return 0; + case undefined: + case '': + case 'h': + case 'hour': + case 'hours': return 1;// default + case 'm': + case 'min': + case 'mins': + case 'minute': + case 'minutes': return 2; + case 's': + case 'sec': + case 'second': + case 'seconds': return 3; + case 'ms': + case 'millisec': + case 'millisecond': + case 'milliseconds': return 4; + } + } + + function getNextNotNull(array, startIndex){ + return startIndex === 4 ? 4 : array[startIndex] !== 0 ? startIndex : getNextNotNull(array, startIndex + 1); + } + + function getPrevNotNull(array, startIndex){ + return startIndex === 0 ? 0 : array[startIndex] !== 0 ? startIndex : getPrevNotNull(array, startIndex - 1); + } + + function getDecimalNumber(days){ + switch(true){ + case (Math.floor((days * 10) % 10) === 0 && Math.floor((days * 100) % 10) === 0): return 0; + case (Math.floor((days * 100) % 10) === 0): return 1; + default: return 2; + } + } + + function formatValue (value, u, expectedUnit){ + switch(u){ + case expectedUnit : return value; + case 2 : + case 3 : return (value < 10 ? '0' + value : value); + case 4 : return (value < 10 ? '00' + value : value < 100 ? '0' + value : value); + default : return value; + } + } + + function getPrefix(sign, duration){ + if (sign) { + if (duration.asMilliseconds() > 0) { return '+'; } + else if (duration.asMilliseconds() < 0) { return '-'; } + } + return ''; + } + + // some localisation shenanigans + function getUnitSymbols(unit, precision){ + var result = ['d ', 'h', 'm', 's', 'ms']; + switch(moment.locale()){ + case "fr": result[0] = 'j '; break; + } + + // if precision = ms and unit bigger than s we want to display 12.525s and not 12s525ms + if(unit <= 3 && precision === 4) { result[3] = '.'; result[4] = 's'; } + if(unit <= 1 && precision === 2) { result[2] = ''; } + if(unit === 2 && precision === 3) { result[3] = ''; } + + return result; + } + + var unitConfigs = [ + { + index: 0, + unit: 'd', + dateConversion : 'asDays', + expectedPrecision : 'h' + }, + { + index: 1, + unit: 'h', + dateConversion : 'asHours', + expectedPrecision :'m' + }, + { + index: 2, + unit: 'm', + dateConversion : 'asMinutes', + expectedPrecision : 's' + }, + { + index: 3, + unit: 's', + dateConversion : 'asSeconds', + expectedPrecision : 's' + }, + { + index: 4, + unit: 'ms', + dateConversion : 'asMilliseconds', + expectedPrecision : 'ms' + }, + ]; + + var d = moment.duration(_duration); + + if (d.asMilliseconds() === 0) { return ''; } + + var values = [Math.abs(d.days()), Math.abs(d.hours()), Math.abs(d.minutes()), Math.abs(d.seconds()), Math.abs(d.milliseconds())]; + var config = unitConfigs[getConfigIndex(_unit)]; + var minimumUnit = Math.max(config.index, getNextNotNull(values, 0)); + values[config.index] = Math.abs(d[config.dateConversion]() >= 0 ? Math.floor(d[config.dateConversion]()) : Math.ceil(d[config.dateConversion]())); + + if (config.index === 0 && getConfigIndex(_precision) === 0 && d.asDays() !== 0){ + var myDays = Math.abs(d.asDays()); + var decimalNumber = getDecimalNumber(myDays); + minimumUnit = 0; + values[0] = $filter("number")(myDays, decimalNumber); + } + + var precision = getPrevNotNull(values, getConfigIndex(_precision || config.expectedPrecision)); + var units = getUnitSymbols(minimumUnit, precision); + + var result = ''; + for(var i = minimumUnit; i <= precision; i++){ + result += formatValue(values[i], i, minimumUnit) + units[i]; + } + + var prefix = !!result ? getPrefix(_sign, d) : ''; + return prefix + result; + }; + }]) + .filter('luifHumanize', function () { + return function (_duration, suffix) { + suffix = !!suffix; + var d = moment.duration(_duration); + return d.humanize(suffix); + }; + }); +})(); diff --git a/dist/lucca-ui.d.ts b/dist/lucca-ui.d.ts index d61e3ff5..90a614f2 100644 --- a/dist/lucca-ui.d.ts +++ b/dist/lucca-ui.d.ts @@ -517,6 +517,7 @@ declare module lui.translate { fr: number; it: number; nl: number; + pt: number; }; const CODES_TO_LANGUAGES: { 1031: string; @@ -525,6 +526,7 @@ declare module lui.translate { 1036: string; 1040: string; 2067: string; + 2070: string; }; class CulturedList { culture: string; diff --git a/dist/lucca-ui.js b/dist/lucca-ui.js index de95733e..e55c7fd6 100644 --- a/dist/lucca-ui.js +++ b/dist/lucca-ui.js @@ -3043,9 +3043,9 @@ var lui; var translate; (function (translate) { "use strict"; - translate.AVAILABLE_LANGUAGES = ["en", "fr", "de", "es", "it", "nl"]; - translate.LANGUAGES_TO_CODE = { en: 1033, de: 1031, es: 1034, fr: 1036, it: 1040, nl: 2067 }; - translate.CODES_TO_LANGUAGES = { 1033: "en", 1031: "de", 1034: "es", 1036: "fr", 1040: "it", 2067: "nl" }; + translate.AVAILABLE_LANGUAGES = ["en", "fr", "de", "es", "it", "nl", "pt"]; + translate.LANGUAGES_TO_CODE = { en: 1033, de: 1031, es: 1034, fr: 1036, it: 1040, nl: 2067, pt: 2070 }; + translate.CODES_TO_LANGUAGES = { 1033: "en", 1031: "de", 1034: "es", 1036: "fr", 1040: "it", 2067: "nl", 2070: "pt" }; var CulturedList = (function () { function CulturedList(culture) { this.culture = culture; @@ -4338,1546 +4338,1546 @@ var lui; ); }]); -;/* global angular */ -(function(){ - 'use strict'; - var DayBlockDirective = function () { - return { - template : - '
'+ - - '
{{controller.date | luifMoment: \'dddd\'}}'+ - '
'+ - - '
{{controller.date | luifMoment:\'DD\'}}'+ - '
'+ - - '
{{controller.date | luifMoment: \'MMM\'}}'+ - '
'+ - - '
{{controller.date | luifMoment: \'YYYY\'}}'+ - '
'+ - - '
', - - scope : { - date: '=', - showDay: '=', - primaryColor: '=', - secondaryColor: '=' - }, - - restrict : 'E', - bindToController : true, - controllerAs : 'controller', - controller : 'luidDayBlockController' - }; - }; - - - angular - .module('lui') - .directive('luidDayBlock', DayBlockDirective) - .controller('luidDayBlockController', function(){ - var controller = this; - - controller.weekdayStyleOverride = function() { - return { - color: controller.primaryColor, - }; - }; - controller.dayStyleOverride = function() { - return { - "background-color": controller.primaryColor, - "border-color": controller.primaryColor, - "color": controller.secondaryColor, - }; - }; - controller.monthStyleOverride = function() { - return { - "background-color": controller.secondaryColor, - "border-color": controller.primaryColor, - "color": controller.primaryColor, - }; - }; - controller.yearStyleOverride = function() { - return { - "background-color": controller.secondaryColor, - "border-color": controller.primaryColor, - "color": controller.primaryColor, - }; - }; - - - }); - -})(); - - -;(function(){ - 'use strict'; - /** - ** DEPENDENCIES - ** - none - **/ - angular.module('lui') - .directive('luidKeydown', function () { - return { - restrict: 'A', - scope:{ - mappings: '=' - }, - link: function (scope, element, attrs) { - element.on('keydown', function (e) { - if ( !!scope.mappings && !!scope.mappings[e.which] ){ - scope.mappings[e.which](e); - // e.preventDefault(); - } - }); - } - }; - }); - angular.module('lui') - .directive('luidSelectOnClick', function () { - return { - restrict: 'A', - link: function (scope, element, attrs) { - element.on('click', function () { - this.select(); - }); - element.on('focus', function () { - this.select(); - }); - } - }; - }); - angular.module('lui') - .directive('luidFocusOn', function() { - return function(scope, elem, attr) { - scope.$on(attr.luidFocusOn, function(e) { - setTimeout( function() { elem[0].focus(); scope.$apply(); }, 1); - }); - }; - }); -})(); -;(function () { - "use strict"; - - /** - ** DEPENDENCIES - ** - angular translate - ** - underscore - **/ - - angular.module("lui.translate") - .directive("luidTranslations", ["$translate", "_", "$filter", "$timeout", function ($translate, _, $filter, $timeout) { - function link(scope, element, attrs, ctrls) { - var ngModelCtrl = ctrls[1]; - var translateCtrl = ctrls[0]; - - /** Associations language/code */ - var languagesToCodes = { en: 1033, de: 1031, es: 1034, fr: 1036, it: 1040, nl: 2067 }; - - /** List of all the available languages labels */ - var cultures = _.keys(languagesToCodes); - scope.cultures = cultures; - - scope.currentCulture = $translate.preferredLanguage() || "en"; - - var mode = !!attrs.mode ? attrs.mode : "dictionary"; - if (mode === "dictionary" && ngModelCtrl.$viewValue !== undefined) { - _.each(cultures, function (culture) { - scope.$watch( - function () { return !!ngModelCtrl.$viewValue ? ngModelCtrl.$viewValue[culture] : ngModelCtrl.$viewValue; }, - function () { ngModelCtrl.$render(); } - ); - }); - } - - ngModelCtrl.$render = function () { - scope.internal = parse(ngModelCtrl.$viewValue); - translateCtrl.updateTooltip(); - }; - - translateCtrl.updateViewValue = function () { - switch (mode) { - case "dictionary": - return updateDictionary(scope.internal); - case "|": - case "pipe": - return updatePipe(scope.internal); - case "lucca": - return updateLucca(scope.internal); - } - }; - - translateCtrl.updateTooltip = function () { - var tooltipText = ""; - if(!!!scope.internal) { - scope.tooltipText = undefined; - return; - } - for(var i = 0; i < scope.cultures.length; i++) { - if(!!scope.internal[scope.cultures[i]]) { - tooltipText += "["+scope.cultures[i].toUpperCase()+"] : "+ scope.internal[scope.cultures[i]] + "\n"; - } - } - scope.tooltipText = tooltipText; - }; - - var parse = function (value) { - if (value === undefined) { return undefined; } - switch (mode) { - case "dictionary": - return parseDictionary(value); - case "|": - case "pipe": - return parsePipe(value); - case "lucca": - return parseLucca(value); - default: - return undefined; - } - }; - - // Mode lucca - var parseLucca = function (value) { - return _.reduce(cultures, function (memo, culture) { - var targetLabel = _.findWhere(value, { cultureCode: languagesToCodes[culture] }); - memo[culture] = !!targetLabel ? targetLabel.value : undefined; - // We need to keep the original id - memo[culture + "_id"] = !!targetLabel ? targetLabel.id : undefined; - return memo; - }, {}); - }; - var updateLucca = function (value) { - var allEmpty = true; - var viewValue = []; - _.each(cultures, function (culture) { - if (!!value[culture] && value[culture] !== "") { - viewValue.push({ id: value[culture + "_id"], cultureCode: languagesToCodes[culture], value: value[culture] }); - allEmpty = false; - } - }); - ngModelCtrl.$setViewValue(allEmpty ? undefined : viewValue); - scope.$parent.$eval(attrs.ngChange); - }; - - // Mode dictionary - var parseDictionary = function (value) { - return _.reduce(cultures, function (memo, culture) { - memo[culture] = value[culture]; - return memo; - }, {}); - }; - var updateDictionary = function (value) { - var allEmpty = true; - var viewValue = {}; - _.each(cultures, function (culture) { - viewValue[culture] = value[culture]; - allEmpty &= value[culture] === undefined || value[culture] === ""; - }); - ngModelCtrl.$setViewValue(allEmpty ? undefined : viewValue); - scope.$parent.$eval(attrs.ngChange); // needs to be called manually cuz the object ref of the $viewValue didn't change - }; - - // Mode pipe - var parsePipe = function (value) { - // value looks like this "en:some stuff|de:|nl:|fr:des bidules|it:|es:" - var translations = value.split("|"); - var result = {}; - _.each(translations, function (t) { - var key = t.substring(0, 2); - var val = t.substring(3); - result[key] = val; - }); - return _.pick(result, cultures); - }; - var updatePipe = function (value) { - if (!_.find(cultures, function (culture) { return value[culture] !== undefined && value[culture] !== ""; })) { - ngModelCtrl.$setViewValue(undefined); - } else { - var newVal = _.map(cultures, function (c) { - if (!!value[c]) { - return c + ":" + value[c]; - } - return c + ":"; - }).join("|"); - ngModelCtrl.$setViewValue(newVal); - } - }; - } - return { - require: ['luidTranslations', '^ngModel'], - controller: 'luidTranslationsController', - scope: { - mode: '@', // allowed values: "pipe" (or "|"), "dictionary", "lucca" (lucca proprietary format) - size: "@", // the size of the input (short, long, x-long, fitting) - isDisabled: "=ngDisabled" - }, - templateUrl: "lui/directives/luidTranslations.html", - restrict: 'EA', - link: link - }; - }]) - .controller('luidTranslationsController', ['$scope', '$translate', '$timeout', function ($scope, $filter, $timeout) { - var ctrl = this; - /****************** - * UPDATE * - ******************/ - $scope.update = function () { ctrl.updateViewValue(); ctrl.updateTooltip(); }; - - /****************** - * FOCUS & BLUR * - ******************/ - - $scope.focusInput = function () { - $scope.focused = true; - }; - $scope.blurInput = function () { - $scope.focused = false; - }; - - $scope.blurOnEnter = function($event) { - $event.target.blur(); - $event.preventDefault(); - }; - }]); - - /**************************/ - /***** TEMPLATES *****/ - /**************************/ - angular.module("lui").run(["$templateCache", function ($templateCache) { - $templateCache.put("lui/directives/luidTranslations.html", - "
" + - "
" + - " " + - " {{currentCulture}}" + - "
" + - "
" + - "
" + - "
" + - " " + - " {{culture}}" + - "
" + - "
" + - "
" + - "
" + - ""); - }]); -})(); -;(function(){ - 'use strict'; - /** - ** DEPENDENCIES - ** - moment - **/ - var MAGIC_DELAY_BEFORE_WHEEL = 200; - - angular.module('lui') - .directive('luidMoment', ['moment', function(moment){ - function link(scope, element, attrs, ctrls){ - var ngModelCtrl = ctrls[1]; - var mpCtrl = ctrls[0]; - - // display the value i on two chars - if(!!attrs.format){ // allows to have a ng-model of type string, not moment - var format = scope.$eval(attrs.format); - - ngModelCtrl.getValue = function() { - var vv = ngModelCtrl.$viewValue; - if (!vv) { - return undefined; - } - var momentVv = moment(vv, format); - if (!momentVv.isValid()) { - return undefined; - } - return momentVv; - }; - - ngModelCtrl.$render = function() { - var momentValue = ngModelCtrl.getValue(); - scope.hours = !!momentValue ? momentValue.format('HH') : undefined; - scope.mins = !!momentValue ? momentValue.format('mm') : undefined; - ngModelCtrl.$validate(); - }; - - ngModelCtrl.setValue = function(newMomentValue) { - ngModelCtrl.$setViewValue(!newMomentValue ? undefined : newMomentValue.format(format)); - }; - ngModelCtrl.$validators.min = function (modelValue,viewValue) { - return !viewValue || mpCtrl.checkMin(moment(modelValue, format)); - }; - ngModelCtrl.$validators.max = function (modelValue,viewValue) { - return !viewValue || mpCtrl.checkMax(moment(modelValue, format)); - }; - } else { - ngModelCtrl.getValue = function() { - var vv = ngModelCtrl.$viewValue; - if (!vv) { - return undefined; - } - var momentVv = moment(vv); - if (!vv.isValid()) { - return undefined; - } - return momentVv; - }; - ngModelCtrl.$render = function() { - var vv = ngModelCtrl.getValue(); - var condition = !!vv && vv.isValid(); - scope.hours = condition ? vv.format('HH') : undefined; - scope.mins = condition ? vv.format('mm') : undefined; - ngModelCtrl.$validate(); - }; - ngModelCtrl.setValue = function(newMomentValue) { - ngModelCtrl.$setViewValue(newMomentValue); - }; - ngModelCtrl.$validators.min = function (modelValue,viewValue) { - return !viewValue || mpCtrl.checkMin(modelValue); - }; - ngModelCtrl.$validators.max = function (modelValue,viewValue) { - return !viewValue || mpCtrl.checkMax(modelValue); - }; - } - - scope.ngModelCtrl = ngModelCtrl; - - ngModelCtrl.$validators.hours = function (modelValue,viewValue) { - return scope.hours !== undefined && scope.hours !== "" && !isNaN(parseInt(scope.hours)); - }; - ngModelCtrl.$validators.minutes = function (modelValue,viewValue) { - return scope.mins !== undefined && scope.mins !== "" && parseInt(scope.mins) < 60; - }; - - var inputs = element.querySelectorAll('.input'); - mpCtrl.setupEvents(element, angular.element(inputs[0]), angular.element(inputs[1])); - - // reexecute validators if min or max change - // will not be reexecuted if min is a moment and something like `min.add(3, 'h')` is called - scope.$watch('min', function(){ - ngModelCtrl.$validate(); - }); - scope.$watch('max', function(){ - ngModelCtrl.$validate(); - }); - - } - - return { - require:['luidMoment','^ngModel'], - controller:'luidMomentController', - scope: { - min:'=', // a moment or a str to specify the min for this input - max:'=', // idem for max - step:'=', // the number of minutes to add/subtract when clicking the addMins button or scrolling on the add in input - referenceDate:'=', // when entering a time, the date to set it, also used to count the number of days between the ngModel and this date, if unavailable, will use min then max then today - isDisabled:'=', - showButtons:'=', // forces the buttons to be displayed even if neither inputs is focused - enforceValid:'=', // prevents entering an ng-invalid input by correcting the value when losing focus - - format:'=', // alows ng-model to be a string with the right format - - // hacks - minOffset:'=', // to avoid having to say min=val1+val2 because it causes an other digest cycle, we give the offset and the - maxOffset:'=' - }, - templateUrl:"lui/directives/luidMoment.html", - restrict:'EA', - link: link, - }; - }]) - .controller('luidMomentController', ['$scope', '$timeout', 'moment', '$element', function($scope, $timeout, moment, $element) { - function incr(step) { - function calculateNewValue() { - function contains(array, value) { return array.indexOf(value) !== -1; } - - var curr = moment(currentValue()); - if (!curr || !curr.isValid()) { curr = getRefDate().startOf('day'); } - if (contains(specialSteps, Math.abs(step)) && curr.minutes() % step !== 0) { - step = step < 0 ? - (curr.minutes() % step) : -curr.minutes() % step + step; - } - - var newValue = curr.add(step,'m'); - newValue.seconds(0); - return newValue; - } - - if ($scope.isDisabled) { return; } - // $scope.ngModelCtrl.$setValidity('pattern', true); - - update(calculateNewValue(), true); - } - - function update(newValue, autoCorrect) { - updateWithoutRender(newValue, autoCorrect); - $scope.ngModelCtrl.$render(); - } - - function updateWithoutRender(newValue, autoCorrect) { - function correctedValue(newValue, min, max) { - switch(true){ - case (!newValue) : return newValue; - case (min && min.diff(newValue) > 0) : return min; - case (max && max.diff(newValue) < 0) : return max; - default : return newValue; - } - } - var min = getMin(); - var max = getMax(); - - if (autoCorrect) { - var newCorrectedValue = correctedValue(newValue, min, max); - if (newCorrectedValue.format("HH:mm") !== newValue.format("HH:mm")) { - newValue = newCorrectedValue; - - $element.addClass('autocorrect'); - setTimeout(function() { - $element.removeClass('autocorrect'); - }, 200); - } - } - $scope.maxed = newValue && max && max.diff(newValue) <= 0; - $scope.mined = newValue && min && min.diff(newValue) >= 0; - - $scope.ngModelCtrl.setValue(newValue); - } - - // translate between string values and viewvalue - function undefinedHoursOrMinutes() { - return $scope.hours === undefined || $scope.hours === "" || $scope.mins === undefined || $scope.mins === ""; - } - - function getInputedTime() { - if (undefinedHoursOrMinutes()) { - return undefined; - } - - var intHours = parseInt($scope.hours); - var intMinutes = parseInt($scope.mins); - // if (intHours != intHours) { intHours = 0; } // intHour isNaN - // if (intMinutes != intMinutes) { intMinutes = 0; } // intMins isNaN - if (intMinutes > 60) { intMinutes = 59; $scope.mins = "59"; } - - var initialTime = getRefDate().hours(intHours).minutes(intMinutes).seconds(0); - - // try to put time between min and max by adding some days while time < min and time !> max - var time = betweenMinAndMax(initialTime); - - return time; - } - - function betweenMinAndMax(refTime) { - var time = moment(refTime); - var minTime = moment(time), maxTime = moment(time); - var min = getMin(), max = getMax(); - var dayCnt; - // time < min, add enough day to have it after min - if(!!min && time.isBefore(min)) { - // number of days between min and time, rounded to next integer - dayCnt = Math.ceil(min.diff(time, 'day', true)); - minTime.add(dayCnt, 'day'); - } - // time > max - if (!!max && time.isAfter(max)) { - // number of days between max and time, rounded to previous integer - dayCnt = Math.floor(max.diff(time, 'day', true)); - maxTime.add(dayCnt, 'days'); - } - - if (!!max && (minTime.isBefore(max) || minTime.isSame(max))) { - return minTime; - } - if (!!min && (maxTime.isAfter(min) || maxTime.isSame(min))) { - return maxTime; - } - return time; - } - - function cancelTimeouts() { - function cancel(timeout){ - if (!!timeout) { - $timeout.cancel(timeout); - timeout = undefined; - } - } - cancel(hoursFocusTimeout); - cancel(minsFocusTimeout); - } - - function correctValue() { - update(currentValue(), $scope.enforceValid); - } - - function getStep() { return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step); } - - function getRefDate() { - function toMoment(value) { return (!!value && moment(value).isValid()) ? moment(value) : undefined; } - - return toMoment($scope.referenceDate) || toMoment($scope.min) || toMoment($scope.max) || moment(); - } - - function getExtremum(extremum, offset, checkMidnight) { - function rawExtremum(){ - switch(true){ - // check if min/max is a valid moment - case (!!extremum.isValid && !!extremum.isValid()) : return moment(extremum); - // check if min/max is parsable by moment - case (moment(extremum,'YYYY-MM-DD HH:mm').isValid()) : return moment(extremum,'YYYY-MM-DD HH:mm'); - // check if min/max is like '23:15' - case (moment(extremum, 'HH:mm').isValid()) : - var refDate = getRefDate(); - var extrem = moment(extremum, 'HH:mm').year(refDate.year()).month(refDate.month()).date(refDate.date()); - // a min/max time of '00:00' means midnight tomorrow - if (checkMidnight && extrem.hours() + extrem.minutes() === 0) { extrem.add(1,'d');} - return extrem; - } - } - - // min/max attr not specified - if (!extremum) { return undefined; } - var extrem = rawExtremum(); - extrem.add(moment.duration(offset)); - return extrem; - } - - function getMin() { return getExtremum($scope.min, $scope.minOffset, false); } - function getMax() { return getExtremum($scope.max, $scope.maxOffset, true); } - - function currentValue() { return !$scope.format ? $scope.ngModelCtrl.$viewValue : moment($scope.ngModelCtrl.$viewValue, $scope.format); } - - function incrementEvent(eventName, value) { - cancelTimeouts(); - incr(value); - $scope.$broadcast(eventName); - } - - function focusEvent(isMinute) { - cancelTimeouts(); - $scope.minsFocused = !!isMinute; - $scope.hoursFocused = !isMinute; - } - - function blurEvent(timeout, isFocused){ - var model = $scope.ngModelCtrl.$modelValue; - updateWithoutRender(model); - timeout = $timeout(function(){ - timeout = false; - correctValue(); - }, 200); - } - - var hoursFocusTimeout, minsFocusTimeout; - var specialSteps = [5, 10, 15, 20, 30]; - var mpCtrl = this; - $scope.pattern = /^([0-9]{0,2})?$/; - - // stuff to control the focus of the different elements and the clicky bits on the + - buttons - // what we want is show the + - buttons if one of the inputs is displayed - // and we want to be able to click on said buttons without loosing focus (obv) - $scope.incrHours = function() { incrementEvent('focusHours', 60); }; - $scope.decrHours = function() { incrementEvent('focusHours', -60); }; - $scope.incrMins = function() { incrementEvent('focusMinutes', getStep()); }; - $scope.decrMins = function() { incrementEvent('focusMinutes', -getStep()); }; - - function isUndefinedOrEmpty(val) { - return val === undefined || val === ""; - } - - // string value changed - $scope.changeHours = function(){ - if(isUndefinedOrEmpty($scope.hours)){ - return updateWithoutRender(undefined); - } - - if(isUndefinedOrEmpty($scope.mins)){ - $scope.mins = "00"; - } - - if ($scope.hours.length == 2) { - if (parseInt($scope.hours) > 23) { $scope.hours = '23'; } - $scope.$broadcast('focusMinutes'); - } else if ($scope.hours.length == 1 && parseInt($scope.hours) > 2) { - $scope.hours = 0 + $scope.hours; - $scope.$broadcast('focusMinutes'); - } - updateWithoutRender(getInputedTime()); - }; - - $scope.changeMins = function() { - if (!$scope.mins || $scope.mins.length < 2) { - $scope.ngModelCtrl.$setValidity("minutes", false); - } else { - updateWithoutRender(getInputedTime()); - } - }; - - // display stuff - $scope.formatInputValue = function() { $scope.ngModelCtrl.$render(); }; - - $scope.getDayGap = function(){ - var refDate = getRefDate().startOf('day'); - return moment.duration(moment(currentValue()).startOf('d').diff(refDate)).asDays(); - }; - - $scope.blurHours = function() { blurEvent(hoursFocusTimeout, $scope.hoursFocused); }; - $scope.blurMins = function() { - if(!$scope.mins) { - if($scope.hours === "" || $scope.hours === undefined){ - $scope.mins = undefined; - } else { - $scope.mins = "00"; - } - } else if ($scope.mins.length < 2) { - $scope.mins = "0" + $scope.mins; - } - blurEvent(minsFocusTimeout, $scope.minsFocused); - }; - - $scope.focusHours = function() { focusEvent(false); }; - $scope.focusMins = function() { focusEvent(true); }; - - this.checkMin = function(newValue) { - var min = getMin(); - return !min || min.diff(newValue) <= 0; - }; - - this.checkMax = function(newValue) { - var max = getMax(); - return !max || max.diff(newValue) >= 0; - }; - - // events - mousewheel and arrowkeys - this.setupEvents = function(elt, hoursField, minsField){ - var hoursInput = angular.element(hoursField.find('input')[0]), - minsInput = angular.element(minsField.find('input')[0]); - - function setupArrowkeyEvents(hoursInput, minsInput) { - function subscription(e, step){ - switch(e.which){ - case 38:// up - e.preventDefault(); - incr(step); - $scope.$apply(); - break; - case 40:// down - e.preventDefault(); - incr(-step); - $scope.$apply(); - break; - case 13:// enter - e.preventDefault(); - $scope.formatInputValue(); - $scope.$apply(); - break; - } - } - var step = getStep(); - hoursInput.bind('keydown', function(e) { subscription(e, 60); }); - minsInput.bind('keydown', function(e) { subscription(e, step); }); - } - - function setupMousewheelEvents(elt, hoursField, minsField) { - function isScrollingUp(e) { - e = e.originalEvent ? e.originalEvent : e; - //pick correct delta variable depending on event - var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; - return (e.detail || delta > 0); - } - var enableMouseWheel = false; - var enableWheelTimeout; - elt.bind('mouseenter', function(e) { - enableWheelTimeout = setTimeout(function() { - enableMouseWheel = true; - }, MAGIC_DELAY_BEFORE_WHEEL); - }); - elt.bind('mouseleave', function(e) { - if (!!enableWheelTimeout) { - clearTimeout(enableWheelTimeout); - } - enableMouseWheel = false; - }); - function subscription(e, incrStep){ - if(!$scope.isDisabled && enableMouseWheel){ - $scope.$apply(incr((isScrollingUp(e)) ? incrStep : -incrStep )); - e.preventDefault(); - } - } - var step = getStep(); - - hoursField.bind('mousewheel wheel', function(e) { subscription(e, 60); }); - minsField.bind('mousewheel wheel', function(e) { subscription(e, step); }); - } - - setupArrowkeyEvents( hoursInput, minsInput); - setupMousewheelEvents(elt, hoursField, minsField); - }; - - }]); - - angular.module("lui").run(["$templateCache", function($templateCache) { - $templateCache.put("lui/directives/luidMoment.html", - "
" + - " " + - " " + - " " + - "
" + - ":" + - "
" + - " " + - " " + - " " + - "
" + - ""); - }]); -})(); -;(function () { - 'use strict'; - /** - ** DEPENDENCIES - ** - none - **/ - - angular.module('lui').directive('luidPercentage', function () { - function link(scope, element, attrs, ctrls) { - - var ngModelCtrl = ctrls[1]; - var luidPercentageCtrl = ctrls[0]; - scope.pattern = /^([0-9]+)(\.([0-9]*)?)?$/i; - if (!attrs.format) { - scope.format = "0.XX"; - }else if(attrs.format !== "0.XX" && attrs.format !== "1.XX" && attrs.format !== "XX"){ - ngModelCtrl.$render = function () { scope.intPct = "unsupported format"; }; - return; - } - - scope.ngModelCtrl = ngModelCtrl; - - ngModelCtrl.$render = function () { - if (this.$viewValue === undefined) { - scope.intPct = undefined; - return; - } - // must support the different formats here - scope.intPct = scope.parse(parseFloat(this.$viewValue)); - }; - - // call the ng-change - ngModelCtrl.$viewChangeListeners.push(function () { - scope.$eval(attrs.ngChange); - }); - - // bind to various events - here only keypress=enter - luidPercentageCtrl.setupEvents(element.find('input')); - } - - - return { - require: ['luidPercentage', '^ngModel'], - controller: 'luidPercentageController', - scope: { - step: '=', // default = 5 - format: '@', // 'XX', '0.XX' or '1.XX', default 0.XX - ngDisabled: '=', - placeholder: '@' - }, - restrict: 'EA', - link: link, - template: - "
" + - "" + - "%" + - "
" - }; - }) - .controller('luidPercentageController', ['$scope', function ($scope) { - - // private - updates of some kinds - // incr value by `step` minutes - function incr(step) { - update(parseFloat($scope.intPct) + step); - } - - // sets viewValue and renders - function update(duration) { - updateWithoutRender(duration); - $scope.ngModelCtrl.$render(); - } - - function updateWithoutRender(duration) { - function format(pct) { - switch($scope.format || "0.XX"){ - case "XX" : return pct; - case "0.XX" : return pct/100; - case "1.XX" : return (pct/100) + 1; - default : return 0; - } - } - - var newValue = duration === undefined ? undefined : format(duration); - $scope.ngModelCtrl.$setViewValue(newValue); - } - - // events - key 'enter' - this.setupEvents = function (elt) { - function getStep(){ return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step);} - function setupKeyEvents(elt) { - var step = getStep(); - elt.bind('keydown', function (e) { - switch(e.which){ - case 38:// up - e.preventDefault(); - incr(step); - $scope.$apply(); - break; - case 40:// down - e.preventDefault(); - incr(-step); - $scope.$apply(); - break; - case 13:// enter - e.preventDefault(); - $scope.formatInputValue(); - $scope.$apply(); - break; - } - }); - } - function setupMousewheelEvents(elt) { - function isScrollingUp(e) { - e = e.originalEvent ? e.originalEvent : e; - //pick correct delta variable depending on event - var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; - return (e.detail || delta > 0); - } - - var step = getStep(); - elt.bind('mousewheel wheel', function (e) { - if (this === document.activeElement) { - $scope.$apply(incr((isScrollingUp(e)) ? step : -step)); - e.preventDefault(); - } - }); - } - - setupKeyEvents(elt); - setupMousewheelEvents(elt); - }; - - // public methods for update - $scope.updateValue = function () { - updateWithoutRender($scope.intPct); - }; - - $scope.parse = function (intInput) { - switch($scope.format || "0.XX"){ - case "XX": return intInput; - case "0.XX": return Math.round(10000 * intInput) / 100; - case "1.XX": return Math.round((intInput-1) * 10000) / 100; - default : return 0; - } - }; - - // display stuff - $scope.formatInputValue = function () { - $scope.ngModelCtrl.$render(); - }; - }]); -})(); -;(function () { - 'use strict'; - /** - ** DEPENDENCIES - ** - moment - **/ - - angular.module('lui').directive('luidTimespan', ['moment', function (moment) { - - function link(scope, element, attrs, ctrls) { - var ngModelCtrl = ctrls[1]; - var luidTimespanCtrl = ctrls[0]; - scope.pattern = /^\-?([0-9]+)((h([0-9]{2})?)?(m(in)?)?)?$/i; - if (!!attrs.unit) { - var unit = scope.$eval(attrs.unit); - if (unit == 'h' || unit == 'hour' || unit == 'hours') { - scope.useHours = true; - } - } - - scope.ngModelCtrl = ngModelCtrl; - - ngModelCtrl.$render = function () { - scope.strDuration = ''; - if (!this.$viewValue) { - return; - } - var currentDuration = moment.duration(this.$viewValue); - if (currentDuration < 0) { - scope.strDuration += "-"; - currentDuration = moment.duration(-currentDuration); - } - var hours = Math.floor(currentDuration.asHours()); - var minutes = currentDuration.minutes(); - if (hours === 0) { - scope.strDuration += minutes + 'm'; - } else { - scope.strDuration += (hours < 10 ? '0' : '') + hours + 'h' + (minutes < 10 ? '0' : '') + minutes; - } - }; - - // bind to various events - here only keypress=enter - luidTimespanCtrl.setupEvents(element.find('input')); - - // set to given mode or to default mode - luidTimespanCtrl.mode = attrs.mode ? attrs.mode : "timespan"; - } - - - return { - require: ['luidTimespan', '^ngModel'], - controller: 'luidTimespanController', - scope: { - step: '=', // default = 5 - unit: '=', // 'hours', 'hour', 'h' or 'm', default='m' - ngDisabled: '=', - placeholder: '@', - mode: "=", // 'timespan', 'moment.duration', default='timespan' - min: '=', //min value - max: '=', //max value - }, - restrict: 'EA', - link: link, - template: - "
" + - "" + - "
" - }; - }]) - .controller('luidTimespanController', ['$scope', 'moment', function ($scope, moment) { - var ctrl = this; - - function parse(strInput) { - // parsing str to moment.duration - function parseHoursAndMinutes(strInput) { - var d = moment.duration(); - var splitted = strInput.split(/h/i); - var isPositive = parseInt(splitted[0]) >= 0; - d.add(parseInt(splitted[0]), 'hours'); - var strMin = splitted[1]; - if (!!strMin && strMin.length >= 2) { - if (isPositive){ - d.add(parseInt(strMin.substring(0, 2)), 'minutes'); - } else { - d.subtract(parseInt(strMin.substring(0, 2)), 'minutes'); - } - } - return d; - } - - function parseMinutes(strInput) { - var d = moment.duration(); - var splitted = strInput.split(/m/i); - d.add(parseInt(splitted[0]), 'minutes'); - return d; - } - - function parseHours(strInput) { - var d = moment.duration(); - var splitted = strInput.split(/h/i); - d.add(parseInt(splitted[0]), 'hours'); - return d; - } - - switch(true){ - case (/h/i.test(strInput)) : return parseHoursAndMinutes(strInput); - case (/m/i.test(strInput)) : return parseMinutes(strInput); - case ($scope.useHours) : return parseHours(strInput); - default : return parseMinutes(strInput); - } - } - - // updates of some kinds - // incr value by `step` minutes - function incr(step) { - var newDur = moment.duration(currentValue()).add(step, 'minutes'); - if (newDur.asMilliseconds() < 0) { - newDur = moment.duration(); - } - update(newDur); - } - - // sets viewValue and renders - function update(newDuration) { - updateWithoutRender(newDuration); - $scope.ngModelCtrl.$render(); - } - - function updateWithoutRender(newDuration) { - // Handle min/max values - function correctValue(newValue){ - function correctedMinValue(newValue) { - var min = !$scope.min ? undefined : moment.duration($scope.min); - return (!min || min <= newValue) ? newValue : min; - } - - function correctedMaxValue(newValue) { - var max = !$scope.max ? undefined : moment.duration($scope.max); - return (!max || max >= newValue) ? newValue : max; - } - - return correctedMaxValue(correctedMinValue(newValue)); - } - - function format(dur) { - if (ctrl.mode === 'timespan') { - var timespan = ""; - if (dur.asMilliseconds() < 0){ - timespan += "-"; - dur = moment.duration(-dur); - } - timespan += (dur.days() > 0 ? Math.floor(dur.asDays()) + '.' : '') + (dur.hours() < 10 ? '0' : '') + dur.hours() + ':' + (dur.minutes() < 10 ? '0' : '') + dur.minutes() + ':00'; - return timespan; - } - return dur; - } - - if (newDuration === undefined) { - return $scope.ngModelCtrl.$setViewValue(undefined); - } - - // Check min/max values - newDuration = correctValue(newDuration); - var formattedValue = format(newDuration); - - $scope.ngModelCtrl.$setViewValue(formattedValue); - } - - function currentValue() { - return $scope.ngModelCtrl.$viewValue; - } - - // events - key 'enter' - this.setupEvents = function (elt) { - function getStep(){ return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step);} - function setupKeyEvents(elt) { - var step = getStep(); - elt.bind('keydown', function (e) { - switch(e.which){ - case 38:// up - e.preventDefault(); - incr(step); - $scope.$apply(); - break; - case 40:// down - e.preventDefault(); - incr(-step); - $scope.$apply(); - break; - case 13:// enter - e.preventDefault(); - $scope.formatInputValue(); - $scope.$apply(); - break; - } - }); - } - - function setupMousewheelEvents(elt) { - function isScrollingUp(e) { - e = e.originalEvent ? e.originalEvent : e; - //pick correct delta variable depending on event - var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; - return (e.detail || delta > 0); - } - - var step = getStep(); - elt.bind('mousewheel wheel', function (e) { - if (this === document.activeElement) { - $scope.$apply(incr((isScrollingUp(e)) ? step : -step)); - e.preventDefault(); - } - }); - } - - setupKeyEvents(elt); - setupMousewheelEvents(elt); - }; - - // public methods for update - $scope.updateValue = function () { - - // is only fired when pattern is valid or when it goes from valid to invalid - // improvement possible - check the pattern and set the validity of the all directive via ngModelCtrl.$setValidity - // currently when pattern invalid, the viewValue is set to '00:00:00' - if (!$scope.strDuration) { return updateWithoutRender(undefined); } // empty input => 00:00:00 - - // parse the strDuration to build newDuration - // the duration of the parsed strDuration - var newDuration = parse($scope.strDuration); - - // update viewvalue - updateWithoutRender(newDuration); - }; - - // display stuff - $scope.formatInputValue = function () { - $scope.ngModelCtrl.$render(); - }; - }]); -})(); -;(function(){ - 'use strict'; - /** - ** DEPENDENCIES - ** - none, nothing, nada - **/ - function replaceAll(string, find, replace) { - // http://stackoverflow.com/questions/1144783/replacing-all-occurrences-of-a-string-in-javascript - // lets not reinvent the wheel - if(!string){ return ''; } - function escapeRegExp(string) { - return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); - } - return string.replace(new RegExp(escapeRegExp(find), 'g'), replace); - } - angular.module('lui') - .filter('luifPlaceholder', function () { - return function (_input, _placeholder) { - return !!_input ? _input : _placeholder; - }; - }) - .filter('luifDefaultCode', function () { - // uppercased and with '_' instead of ' ' - return function (_input) { - return replaceAll(_input, ' ', '_').toUpperCase(); - }; - }) - .filter('luifStartFrom', function () { - //pagination filter - return function (_input, start) { - start = +start; //parse to int - return _input.slice(start); - }; - }) - .filter('luifNumber', ['$sce', '$filter', function($sce, $filter) { - return function(_input, _precision, _placeholder) { - - function getRightSpan(decimalPart, separator) { - if (decimalPart === undefined) { return ""; } - if (parseInt(decimalPart) === 0) { return "" + separator + decimalPart + ""; } - return "" + separator + decimalPart + ""; - } - - var placeholder = _placeholder === undefined ? '' : _placeholder; - // alert(_input + " " + (!!_input.isNaN && _input.isNaN())); - var input = _input === undefined || _input === null || _input === "" || _input != _input ? placeholder : _input; // the last check is to check if _input is NaN - var separator = $filter("number")(1.1,1)[1]; - var precision = _precision === undefined || _precision === null || _precision != _precision ? 2 : _precision; - - var text = $filter("number")(input, precision); - var decimalPart = (text || $filter("number")(0, precision)).split(separator)[1]; - var rightSpan = getRightSpan(decimalPart, separator); - - if (input === '' || !text){ - // the _input or the _placeholder was not parsable by the number $filter, just return input but trusted as html - return $sce.trustAsHtml(input + rightSpan); - } - - var integerPart = text.split(separator)[0]; - return $sce.trustAsHtml(integerPart + rightSpan); - }; - }]); -})(); -;(function () { - 'use strict'; - /** - ** DEPENDENCIES - ** - moment - **/ - var formatMoment = function (_moment, _format) { //expects a moment - if (!_moment) { - return ""; - } - var m = moment(_moment); - return m.isValid() ? m.format(_format) : _moment; - }; - - angular.module('lui') - .filter('luifFriendlyRange', function () { - var translations = { - 'en': { - startOnly: 'date(dddd, LL) onwards', - startOnlyThisYear: 'date(dddd, MMMM Do) onwards', - endOnly: 'until date(dddd, LL)', - endOnlyThisYear: 'until date(dddd, MMMM Do)', - date: 'date(LL)', - sameDay: 'start(dddd, LL)', - sameDayThisYear: 'start(dddd, MMMM Do)', - sameMonth: 'start(MMMM Do) - end(Do\, YYYY)', - sameMonthThisYear: 'start(MMMM Do) - end(Do)', - sameYear: 'start(MMMM Do) - end(LL)', - sameYearThisYear: 'start(MMMM Do) - end(MMMM Do)', - other: 'start(LL) - end(LL)' - }, - 'fr': { - startOnly: 'à partir du date(dddd LL)', - startOnlyThisYear: 'à partir du date(dddd Do MMMM)', - endOnly: 'jusqu\'au date(dddd LL)', - endOnlyThisYear: 'jusqu\'au date(dddd Do MMMM)', - date: 'date(LL)', - sameDay: 'le start(dddd LL)', - sameDayThisYear: 'le start(dddd Do MMMM)', - sameMonth: 'du start(Do) au end(LL)', - sameMonthThisYear: 'du start(Do) au end(Do MMMM)', - sameYear: 'du start(Do MMMM) au end(LL)', - sameYearThisYear: 'du start(Do MMMM) au end(Do MMMM)', - other: 'du start(LL) au end(LL)' - }, - 'de': { - - startOnly: 'von date(Do MMMM)', - startOnlyThisYear: 'von date(LL)', - endOnly: 'bis date(Do MMMM)', - endOnlyThisYear: 'bis date(LL)', - date: 'date(LL)', - sameDay: 'der start(dddd LL)', - sameDayThisYear: 'der start(dddd Do MMMM)', - sameMonth: 'von start(Do) bis end(LL)', - sameMonthThisYear: 'von start(Do) bis end(Do MMMM)', - sameYear: 'von start(Do MMMM) bis end(LL)', - sameYearThisYear: 'von start(Do MMMM) bis end(Do MMMM)', - other: 'von start(LL) bis end(LL)' - } - }; - function getTrad(trads, locale, key, fallbackKey) { - if (!!trads && !!trads[locale] && !!trads[locale][key]) { - return trads[locale][key]; - } - if (!!trads && !!trads[locale] && !!trads[locale][fallbackKey]) { - return trads[locale][fallbackKey]; - } - // fallback on english in provided translations - var fallbackLocale = "en"; - if (!!trads && !!trads[fallbackLocale] && !!trads[fallbackLocale][key]) { - return trads[fallbackLocale][key]; - } - if (!!trads && !!trads[fallbackLocale] && !!trads[fallbackLocale][fallbackKey]) { - return trads[fallbackLocale][fallbackKey]; - } - - // fallback on standard translations if I couldnt find what I need in provided trads - var fallbackTrads = translations; - if (!!fallbackTrads && !!fallbackTrads[locale] && !!fallbackTrads[locale][key]) { - return fallbackTrads[locale][key]; - } - if (!!fallbackTrads && !!fallbackTrads[locale] && !!fallbackTrads[locale][fallbackKey]) { - return fallbackTrads[locale][fallbackKey]; - } - // fallback on english in provided translations - if (!!fallbackTrads && !!fallbackTrads[fallbackLocale] && !!fallbackTrads[fallbackLocale][key]) { - return fallbackTrads[fallbackLocale][key]; - } - if (!!fallbackTrads && !!fallbackTrads[fallbackLocale] && !!fallbackTrads[fallbackLocale][fallbackKey]) { - return fallbackTrads[fallbackLocale][fallbackKey]; - } - } - return function (_block, _excludeEnd, _translations) { - if(!_block){ return; } - var start = _block.start || _block.startsAt || _block.startsOn || _block.startDate; - var end = _block.end || _block.endsAt || _block.endsOn || _block.endDate; - if (!start && !end) { - return ""; - } - start = !!start ? moment(start) : undefined; - end = !!end ? moment(end) : undefined; - if(_excludeEnd){ - end.add(-1,'minutes'); - } - var trad; - var format; - var regex; - if (!!start && !!end) { - format = start.year() === end.year() ? start.month() === end.month() ? start.date() === end.date() ? 'sameDay' : 'sameMonth' : 'sameYear' : 'other'; - if(moment().year() === start.year() && moment().year() === end.year()){ - format += "ThisYear"; - } - trad = getTrad(_translations, moment.locale(), format, "other"); - regex = /(start\((.*?)\))(.*(end\((.*?)\))){0,1}/gi.exec(trad); - return trad.replace(regex[1], start.format(regex[2])).replace(regex[4], end.format(regex[5])); - } - format = !!start ? "startOnly" : "endOnly"; - var date = start || end; - if(moment().year() === date.year()){ - format += "ThisYear"; - } - trad = getTrad(_translations, moment.locale(), format, "date"); - regex = /(date\((.*?)\))/gi.exec(trad); - return trad.replace(regex[1], date.format(regex[2])); - }; - }) - .filter('luifMoment', function () { - return function (_moment, _format) { - if (!_format) { _format = 'LLL'; } // default format - return formatMoment(_moment, _format); - }; - }) - .filter('luifCalendar', function () { - return function (_moment, _refDate) { - var m = moment(_moment); - var refDate = (_refDate && moment(_refDate).isValid()) ? moment(_refDate) : moment(); - - return m.isValid() ? m.calendar(_refDate) : _moment; - }; - }) - .filter('luifDuration', ['$filter', function ($filter) { - //expects a duration, returns the duration in the given unit with the given precision - return function (_duration, _sign, _unit, _precision) { - function getConfigIndex(expectedUnit){ - switch(expectedUnit){ - case 'd': - case 'day': - case 'days': return 0; - case undefined: - case '': - case 'h': - case 'hour': - case 'hours': return 1;// default - case 'm': - case 'min': - case 'mins': - case 'minute': - case 'minutes': return 2; - case 's': - case 'sec': - case 'second': - case 'seconds': return 3; - case 'ms': - case 'millisec': - case 'millisecond': - case 'milliseconds': return 4; - } - } - - function getNextNotNull(array, startIndex){ - return startIndex === 4 ? 4 : array[startIndex] !== 0 ? startIndex : getNextNotNull(array, startIndex + 1); - } - - function getPrevNotNull(array, startIndex){ - return startIndex === 0 ? 0 : array[startIndex] !== 0 ? startIndex : getPrevNotNull(array, startIndex - 1); - } - - function getDecimalNumber(days){ - switch(true){ - case (Math.floor((days * 10) % 10) === 0 && Math.floor((days * 100) % 10) === 0): return 0; - case (Math.floor((days * 100) % 10) === 0): return 1; - default: return 2; - } - } - - function formatValue (value, u, expectedUnit){ - switch(u){ - case expectedUnit : return value; - case 2 : - case 3 : return (value < 10 ? '0' + value : value); - case 4 : return (value < 10 ? '00' + value : value < 100 ? '0' + value : value); - default : return value; - } - } - - function getPrefix(sign, duration){ - if (sign) { - if (duration.asMilliseconds() > 0) { return '+'; } - else if (duration.asMilliseconds() < 0) { return '-'; } - } - return ''; - } - - // some localisation shenanigans - function getUnitSymbols(unit, precision){ - var result = ['d ', 'h', 'm', 's', 'ms']; - switch(moment.locale()){ - case "fr": result[0] = 'j '; break; - } - - // if precision = ms and unit bigger than s we want to display 12.525s and not 12s525ms - if(unit <= 3 && precision === 4) { result[3] = '.'; result[4] = 's'; } - if(unit <= 1 && precision === 2) { result[2] = ''; } - if(unit === 2 && precision === 3) { result[3] = ''; } - - return result; - } - - var unitConfigs = [ - { - index: 0, - unit: 'd', - dateConversion : 'asDays', - expectedPrecision : 'h' - }, - { - index: 1, - unit: 'h', - dateConversion : 'asHours', - expectedPrecision :'m' - }, - { - index: 2, - unit: 'm', - dateConversion : 'asMinutes', - expectedPrecision : 's' - }, - { - index: 3, - unit: 's', - dateConversion : 'asSeconds', - expectedPrecision : 's' - }, - { - index: 4, - unit: 'ms', - dateConversion : 'asMilliseconds', - expectedPrecision : 'ms' - }, - ]; - - var d = moment.duration(_duration); - - if (d.asMilliseconds() === 0) { return ''; } - - var values = [Math.abs(d.days()), Math.abs(d.hours()), Math.abs(d.minutes()), Math.abs(d.seconds()), Math.abs(d.milliseconds())]; - var config = unitConfigs[getConfigIndex(_unit)]; - var minimumUnit = Math.max(config.index, getNextNotNull(values, 0)); - values[config.index] = Math.abs(d[config.dateConversion]() >= 0 ? Math.floor(d[config.dateConversion]()) : Math.ceil(d[config.dateConversion]())); - - if (config.index === 0 && getConfigIndex(_precision) === 0 && d.asDays() !== 0){ - var myDays = Math.abs(d.asDays()); - var decimalNumber = getDecimalNumber(myDays); - minimumUnit = 0; - values[0] = $filter("number")(myDays, decimalNumber); - } - - var precision = getPrevNotNull(values, getConfigIndex(_precision || config.expectedPrecision)); - var units = getUnitSymbols(minimumUnit, precision); - - var result = ''; - for(var i = minimumUnit; i <= precision; i++){ - result += formatValue(values[i], i, minimumUnit) + units[i]; - } - - var prefix = !!result ? getPrefix(_sign, d) : ''; - return prefix + result; - }; - }]) - .filter('luifHumanize', function () { - return function (_duration, suffix) { - suffix = !!suffix; - var d = moment.duration(_duration); - return d.humanize(suffix); - }; - }); -})(); +;/* global angular */ +(function(){ + 'use strict'; + var DayBlockDirective = function () { + return { + template : + '
'+ + + '
{{controller.date | luifMoment: \'dddd\'}}'+ + '
'+ + + '
{{controller.date | luifMoment:\'DD\'}}'+ + '
'+ + + '
{{controller.date | luifMoment: \'MMM\'}}'+ + '
'+ + + '
{{controller.date | luifMoment: \'YYYY\'}}'+ + '
'+ + + '
', + + scope : { + date: '=', + showDay: '=', + primaryColor: '=', + secondaryColor: '=' + }, + + restrict : 'E', + bindToController : true, + controllerAs : 'controller', + controller : 'luidDayBlockController' + }; + }; + + + angular + .module('lui') + .directive('luidDayBlock', DayBlockDirective) + .controller('luidDayBlockController', function(){ + var controller = this; + + controller.weekdayStyleOverride = function() { + return { + color: controller.primaryColor, + }; + }; + controller.dayStyleOverride = function() { + return { + "background-color": controller.primaryColor, + "border-color": controller.primaryColor, + "color": controller.secondaryColor, + }; + }; + controller.monthStyleOverride = function() { + return { + "background-color": controller.secondaryColor, + "border-color": controller.primaryColor, + "color": controller.primaryColor, + }; + }; + controller.yearStyleOverride = function() { + return { + "background-color": controller.secondaryColor, + "border-color": controller.primaryColor, + "color": controller.primaryColor, + }; + }; + + + }); + +})(); + + +;(function(){ + 'use strict'; + /** + ** DEPENDENCIES + ** - none + **/ + angular.module('lui') + .directive('luidKeydown', function () { + return { + restrict: 'A', + scope:{ + mappings: '=' + }, + link: function (scope, element, attrs) { + element.on('keydown', function (e) { + if ( !!scope.mappings && !!scope.mappings[e.which] ){ + scope.mappings[e.which](e); + // e.preventDefault(); + } + }); + } + }; + }); + angular.module('lui') + .directive('luidSelectOnClick', function () { + return { + restrict: 'A', + link: function (scope, element, attrs) { + element.on('click', function () { + this.select(); + }); + element.on('focus', function () { + this.select(); + }); + } + }; + }); + angular.module('lui') + .directive('luidFocusOn', function() { + return function(scope, elem, attr) { + scope.$on(attr.luidFocusOn, function(e) { + setTimeout( function() { elem[0].focus(); scope.$apply(); }, 1); + }); + }; + }); +})(); +;(function () { + "use strict"; + + /** + ** DEPENDENCIES + ** - angular translate + ** - underscore + **/ + + angular.module("lui.translate") + .directive("luidTranslations", ["$translate", "_", "$filter", "$timeout", function ($translate, _, $filter, $timeout) { + function link(scope, element, attrs, ctrls) { + var ngModelCtrl = ctrls[1]; + var translateCtrl = ctrls[0]; + + /** Associations language/code */ + var languagesToCodes = { en: 1033, de: 1031, es: 1034, fr: 1036, it: 1040, nl: 2067 }; + + /** List of all the available languages labels */ + var cultures = _.keys(languagesToCodes); + scope.cultures = cultures; + + scope.currentCulture = $translate.preferredLanguage() || "en"; + + var mode = !!attrs.mode ? attrs.mode : "dictionary"; + if (mode === "dictionary" && ngModelCtrl.$viewValue !== undefined) { + _.each(cultures, function (culture) { + scope.$watch( + function () { return !!ngModelCtrl.$viewValue ? ngModelCtrl.$viewValue[culture] : ngModelCtrl.$viewValue; }, + function () { ngModelCtrl.$render(); } + ); + }); + } + + ngModelCtrl.$render = function () { + scope.internal = parse(ngModelCtrl.$viewValue); + translateCtrl.updateTooltip(); + }; + + translateCtrl.updateViewValue = function () { + switch (mode) { + case "dictionary": + return updateDictionary(scope.internal); + case "|": + case "pipe": + return updatePipe(scope.internal); + case "lucca": + return updateLucca(scope.internal); + } + }; + + translateCtrl.updateTooltip = function () { + var tooltipText = ""; + if(!!!scope.internal) { + scope.tooltipText = undefined; + return; + } + for(var i = 0; i < scope.cultures.length; i++) { + if(!!scope.internal[scope.cultures[i]]) { + tooltipText += "["+scope.cultures[i].toUpperCase()+"] : "+ scope.internal[scope.cultures[i]] + "\n"; + } + } + scope.tooltipText = tooltipText; + }; + + var parse = function (value) { + if (value === undefined) { return undefined; } + switch (mode) { + case "dictionary": + return parseDictionary(value); + case "|": + case "pipe": + return parsePipe(value); + case "lucca": + return parseLucca(value); + default: + return undefined; + } + }; + + // Mode lucca + var parseLucca = function (value) { + return _.reduce(cultures, function (memo, culture) { + var targetLabel = _.findWhere(value, { cultureCode: languagesToCodes[culture] }); + memo[culture] = !!targetLabel ? targetLabel.value : undefined; + // We need to keep the original id + memo[culture + "_id"] = !!targetLabel ? targetLabel.id : undefined; + return memo; + }, {}); + }; + var updateLucca = function (value) { + var allEmpty = true; + var viewValue = []; + _.each(cultures, function (culture) { + if (!!value[culture] && value[culture] !== "") { + viewValue.push({ id: value[culture + "_id"], cultureCode: languagesToCodes[culture], value: value[culture] }); + allEmpty = false; + } + }); + ngModelCtrl.$setViewValue(allEmpty ? undefined : viewValue); + scope.$parent.$eval(attrs.ngChange); + }; + + // Mode dictionary + var parseDictionary = function (value) { + return _.reduce(cultures, function (memo, culture) { + memo[culture] = value[culture]; + return memo; + }, {}); + }; + var updateDictionary = function (value) { + var allEmpty = true; + var viewValue = {}; + _.each(cultures, function (culture) { + viewValue[culture] = value[culture]; + allEmpty &= value[culture] === undefined || value[culture] === ""; + }); + ngModelCtrl.$setViewValue(allEmpty ? undefined : viewValue); + scope.$parent.$eval(attrs.ngChange); // needs to be called manually cuz the object ref of the $viewValue didn't change + }; + + // Mode pipe + var parsePipe = function (value) { + // value looks like this "en:some stuff|de:|nl:|fr:des bidules|it:|es:" + var translations = value.split("|"); + var result = {}; + _.each(translations, function (t) { + var key = t.substring(0, 2); + var val = t.substring(3); + result[key] = val; + }); + return _.pick(result, cultures); + }; + var updatePipe = function (value) { + if (!_.find(cultures, function (culture) { return value[culture] !== undefined && value[culture] !== ""; })) { + ngModelCtrl.$setViewValue(undefined); + } else { + var newVal = _.map(cultures, function (c) { + if (!!value[c]) { + return c + ":" + value[c]; + } + return c + ":"; + }).join("|"); + ngModelCtrl.$setViewValue(newVal); + } + }; + } + return { + require: ['luidTranslations', '^ngModel'], + controller: 'luidTranslationsController', + scope: { + mode: '@', // allowed values: "pipe" (or "|"), "dictionary", "lucca" (lucca proprietary format) + size: "@", // the size of the input (short, long, x-long, fitting) + isDisabled: "=ngDisabled" + }, + templateUrl: "lui/directives/luidTranslations.html", + restrict: 'EA', + link: link + }; + }]) + .controller('luidTranslationsController', ['$scope', '$translate', '$timeout', function ($scope, $filter, $timeout) { + var ctrl = this; + /****************** + * UPDATE * + ******************/ + $scope.update = function () { ctrl.updateViewValue(); ctrl.updateTooltip(); }; + + /****************** + * FOCUS & BLUR * + ******************/ + + $scope.focusInput = function () { + $scope.focused = true; + }; + $scope.blurInput = function () { + $scope.focused = false; + }; + + $scope.blurOnEnter = function($event) { + $event.target.blur(); + $event.preventDefault(); + }; + }]); + + /**************************/ + /***** TEMPLATES *****/ + /**************************/ + angular.module("lui").run(["$templateCache", function ($templateCache) { + $templateCache.put("lui/directives/luidTranslations.html", + "
" + + "
" + + " " + + " {{currentCulture}}" + + "
" + + "
" + + "
" + + "
" + + " " + + " {{culture}}" + + "
" + + "
" + + "
" + + "
" + + ""); + }]); +})(); +;(function(){ + 'use strict'; + /** + ** DEPENDENCIES + ** - moment + **/ + var MAGIC_DELAY_BEFORE_WHEEL = 200; + + angular.module('lui') + .directive('luidMoment', ['moment', function(moment){ + function link(scope, element, attrs, ctrls){ + var ngModelCtrl = ctrls[1]; + var mpCtrl = ctrls[0]; + + // display the value i on two chars + if(!!attrs.format){ // allows to have a ng-model of type string, not moment + var format = scope.$eval(attrs.format); + + ngModelCtrl.getValue = function() { + var vv = ngModelCtrl.$viewValue; + if (!vv) { + return undefined; + } + var momentVv = moment(vv, format); + if (!momentVv.isValid()) { + return undefined; + } + return momentVv; + }; + + ngModelCtrl.$render = function() { + var momentValue = ngModelCtrl.getValue(); + scope.hours = !!momentValue ? momentValue.format('HH') : undefined; + scope.mins = !!momentValue ? momentValue.format('mm') : undefined; + ngModelCtrl.$validate(); + }; + + ngModelCtrl.setValue = function(newMomentValue) { + ngModelCtrl.$setViewValue(!newMomentValue ? undefined : newMomentValue.format(format)); + }; + ngModelCtrl.$validators.min = function (modelValue,viewValue) { + return !viewValue || mpCtrl.checkMin(moment(modelValue, format)); + }; + ngModelCtrl.$validators.max = function (modelValue,viewValue) { + return !viewValue || mpCtrl.checkMax(moment(modelValue, format)); + }; + } else { + ngModelCtrl.getValue = function() { + var vv = ngModelCtrl.$viewValue; + if (!vv) { + return undefined; + } + var momentVv = moment(vv); + if (!vv.isValid()) { + return undefined; + } + return momentVv; + }; + ngModelCtrl.$render = function() { + var vv = ngModelCtrl.getValue(); + var condition = !!vv && vv.isValid(); + scope.hours = condition ? vv.format('HH') : undefined; + scope.mins = condition ? vv.format('mm') : undefined; + ngModelCtrl.$validate(); + }; + ngModelCtrl.setValue = function(newMomentValue) { + ngModelCtrl.$setViewValue(newMomentValue); + }; + ngModelCtrl.$validators.min = function (modelValue,viewValue) { + return !viewValue || mpCtrl.checkMin(modelValue); + }; + ngModelCtrl.$validators.max = function (modelValue,viewValue) { + return !viewValue || mpCtrl.checkMax(modelValue); + }; + } + + scope.ngModelCtrl = ngModelCtrl; + + ngModelCtrl.$validators.hours = function (modelValue,viewValue) { + return scope.hours !== undefined && scope.hours !== "" && !isNaN(parseInt(scope.hours)); + }; + ngModelCtrl.$validators.minutes = function (modelValue,viewValue) { + return scope.mins !== undefined && scope.mins !== "" && parseInt(scope.mins) < 60; + }; + + var inputs = element.querySelectorAll('.input'); + mpCtrl.setupEvents(element, angular.element(inputs[0]), angular.element(inputs[1])); + + // reexecute validators if min or max change + // will not be reexecuted if min is a moment and something like `min.add(3, 'h')` is called + scope.$watch('min', function(){ + ngModelCtrl.$validate(); + }); + scope.$watch('max', function(){ + ngModelCtrl.$validate(); + }); + + } + + return { + require:['luidMoment','^ngModel'], + controller:'luidMomentController', + scope: { + min:'=', // a moment or a str to specify the min for this input + max:'=', // idem for max + step:'=', // the number of minutes to add/subtract when clicking the addMins button or scrolling on the add in input + referenceDate:'=', // when entering a time, the date to set it, also used to count the number of days between the ngModel and this date, if unavailable, will use min then max then today + isDisabled:'=', + showButtons:'=', // forces the buttons to be displayed even if neither inputs is focused + enforceValid:'=', // prevents entering an ng-invalid input by correcting the value when losing focus + + format:'=', // alows ng-model to be a string with the right format + + // hacks + minOffset:'=', // to avoid having to say min=val1+val2 because it causes an other digest cycle, we give the offset and the + maxOffset:'=' + }, + templateUrl:"lui/directives/luidMoment.html", + restrict:'EA', + link: link, + }; + }]) + .controller('luidMomentController', ['$scope', '$timeout', 'moment', '$element', function($scope, $timeout, moment, $element) { + function incr(step) { + function calculateNewValue() { + function contains(array, value) { return array.indexOf(value) !== -1; } + + var curr = moment(currentValue()); + if (!curr || !curr.isValid()) { curr = getRefDate().startOf('day'); } + if (contains(specialSteps, Math.abs(step)) && curr.minutes() % step !== 0) { + step = step < 0 ? - (curr.minutes() % step) : -curr.minutes() % step + step; + } + + var newValue = curr.add(step,'m'); + newValue.seconds(0); + return newValue; + } + + if ($scope.isDisabled) { return; } + // $scope.ngModelCtrl.$setValidity('pattern', true); + + update(calculateNewValue(), true); + } + + function update(newValue, autoCorrect) { + updateWithoutRender(newValue, autoCorrect); + $scope.ngModelCtrl.$render(); + } + + function updateWithoutRender(newValue, autoCorrect) { + function correctedValue(newValue, min, max) { + switch(true){ + case (!newValue) : return newValue; + case (min && min.diff(newValue) > 0) : return min; + case (max && max.diff(newValue) < 0) : return max; + default : return newValue; + } + } + var min = getMin(); + var max = getMax(); + + if (autoCorrect) { + var newCorrectedValue = correctedValue(newValue, min, max); + if (newCorrectedValue.format("HH:mm") !== newValue.format("HH:mm")) { + newValue = newCorrectedValue; + + $element.addClass('autocorrect'); + setTimeout(function() { + $element.removeClass('autocorrect'); + }, 200); + } + } + $scope.maxed = newValue && max && max.diff(newValue) <= 0; + $scope.mined = newValue && min && min.diff(newValue) >= 0; + + $scope.ngModelCtrl.setValue(newValue); + } + + // translate between string values and viewvalue + function undefinedHoursOrMinutes() { + return $scope.hours === undefined || $scope.hours === "" || $scope.mins === undefined || $scope.mins === ""; + } + + function getInputedTime() { + if (undefinedHoursOrMinutes()) { + return undefined; + } + + var intHours = parseInt($scope.hours); + var intMinutes = parseInt($scope.mins); + // if (intHours != intHours) { intHours = 0; } // intHour isNaN + // if (intMinutes != intMinutes) { intMinutes = 0; } // intMins isNaN + if (intMinutes > 60) { intMinutes = 59; $scope.mins = "59"; } + + var initialTime = getRefDate().hours(intHours).minutes(intMinutes).seconds(0); + + // try to put time between min and max by adding some days while time < min and time !> max + var time = betweenMinAndMax(initialTime); + + return time; + } + + function betweenMinAndMax(refTime) { + var time = moment(refTime); + var minTime = moment(time), maxTime = moment(time); + var min = getMin(), max = getMax(); + var dayCnt; + // time < min, add enough day to have it after min + if(!!min && time.isBefore(min)) { + // number of days between min and time, rounded to next integer + dayCnt = Math.ceil(min.diff(time, 'day', true)); + minTime.add(dayCnt, 'day'); + } + // time > max + if (!!max && time.isAfter(max)) { + // number of days between max and time, rounded to previous integer + dayCnt = Math.floor(max.diff(time, 'day', true)); + maxTime.add(dayCnt, 'days'); + } + + if (!!max && (minTime.isBefore(max) || minTime.isSame(max))) { + return minTime; + } + if (!!min && (maxTime.isAfter(min) || maxTime.isSame(min))) { + return maxTime; + } + return time; + } + + function cancelTimeouts() { + function cancel(timeout){ + if (!!timeout) { + $timeout.cancel(timeout); + timeout = undefined; + } + } + cancel(hoursFocusTimeout); + cancel(minsFocusTimeout); + } + + function correctValue() { + update(currentValue(), $scope.enforceValid); + } + + function getStep() { return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step); } + + function getRefDate() { + function toMoment(value) { return (!!value && moment(value).isValid()) ? moment(value) : undefined; } + + return toMoment($scope.referenceDate) || toMoment($scope.min) || toMoment($scope.max) || moment(); + } + + function getExtremum(extremum, offset, checkMidnight) { + function rawExtremum(){ + switch(true){ + // check if min/max is a valid moment + case (!!extremum.isValid && !!extremum.isValid()) : return moment(extremum); + // check if min/max is parsable by moment + case (moment(extremum,'YYYY-MM-DD HH:mm').isValid()) : return moment(extremum,'YYYY-MM-DD HH:mm'); + // check if min/max is like '23:15' + case (moment(extremum, 'HH:mm').isValid()) : + var refDate = getRefDate(); + var extrem = moment(extremum, 'HH:mm').year(refDate.year()).month(refDate.month()).date(refDate.date()); + // a min/max time of '00:00' means midnight tomorrow + if (checkMidnight && extrem.hours() + extrem.minutes() === 0) { extrem.add(1,'d');} + return extrem; + } + } + + // min/max attr not specified + if (!extremum) { return undefined; } + var extrem = rawExtremum(); + extrem.add(moment.duration(offset)); + return extrem; + } + + function getMin() { return getExtremum($scope.min, $scope.minOffset, false); } + function getMax() { return getExtremum($scope.max, $scope.maxOffset, true); } + + function currentValue() { return !$scope.format ? $scope.ngModelCtrl.$viewValue : moment($scope.ngModelCtrl.$viewValue, $scope.format); } + + function incrementEvent(eventName, value) { + cancelTimeouts(); + incr(value); + $scope.$broadcast(eventName); + } + + function focusEvent(isMinute) { + cancelTimeouts(); + $scope.minsFocused = !!isMinute; + $scope.hoursFocused = !isMinute; + } + + function blurEvent(timeout, isFocused){ + var model = $scope.ngModelCtrl.$modelValue; + updateWithoutRender(model); + timeout = $timeout(function(){ + timeout = false; + correctValue(); + }, 200); + } + + var hoursFocusTimeout, minsFocusTimeout; + var specialSteps = [5, 10, 15, 20, 30]; + var mpCtrl = this; + $scope.pattern = /^([0-9]{0,2})?$/; + + // stuff to control the focus of the different elements and the clicky bits on the + - buttons + // what we want is show the + - buttons if one of the inputs is displayed + // and we want to be able to click on said buttons without loosing focus (obv) + $scope.incrHours = function() { incrementEvent('focusHours', 60); }; + $scope.decrHours = function() { incrementEvent('focusHours', -60); }; + $scope.incrMins = function() { incrementEvent('focusMinutes', getStep()); }; + $scope.decrMins = function() { incrementEvent('focusMinutes', -getStep()); }; + + function isUndefinedOrEmpty(val) { + return val === undefined || val === ""; + } + + // string value changed + $scope.changeHours = function(){ + if(isUndefinedOrEmpty($scope.hours)){ + return updateWithoutRender(undefined); + } + + if(isUndefinedOrEmpty($scope.mins)){ + $scope.mins = "00"; + } + + if ($scope.hours.length == 2) { + if (parseInt($scope.hours) > 23) { $scope.hours = '23'; } + $scope.$broadcast('focusMinutes'); + } else if ($scope.hours.length == 1 && parseInt($scope.hours) > 2) { + $scope.hours = 0 + $scope.hours; + $scope.$broadcast('focusMinutes'); + } + updateWithoutRender(getInputedTime()); + }; + + $scope.changeMins = function() { + if (!$scope.mins || $scope.mins.length < 2) { + $scope.ngModelCtrl.$setValidity("minutes", false); + } else { + updateWithoutRender(getInputedTime()); + } + }; + + // display stuff + $scope.formatInputValue = function() { $scope.ngModelCtrl.$render(); }; + + $scope.getDayGap = function(){ + var refDate = getRefDate().startOf('day'); + return moment.duration(moment(currentValue()).startOf('d').diff(refDate)).asDays(); + }; + + $scope.blurHours = function() { blurEvent(hoursFocusTimeout, $scope.hoursFocused); }; + $scope.blurMins = function() { + if(!$scope.mins) { + if($scope.hours === "" || $scope.hours === undefined){ + $scope.mins = undefined; + } else { + $scope.mins = "00"; + } + } else if ($scope.mins.length < 2) { + $scope.mins = "0" + $scope.mins; + } + blurEvent(minsFocusTimeout, $scope.minsFocused); + }; + + $scope.focusHours = function() { focusEvent(false); }; + $scope.focusMins = function() { focusEvent(true); }; + + this.checkMin = function(newValue) { + var min = getMin(); + return !min || min.diff(newValue) <= 0; + }; + + this.checkMax = function(newValue) { + var max = getMax(); + return !max || max.diff(newValue) >= 0; + }; + + // events - mousewheel and arrowkeys + this.setupEvents = function(elt, hoursField, minsField){ + var hoursInput = angular.element(hoursField.find('input')[0]), + minsInput = angular.element(minsField.find('input')[0]); + + function setupArrowkeyEvents(hoursInput, minsInput) { + function subscription(e, step){ + switch(e.which){ + case 38:// up + e.preventDefault(); + incr(step); + $scope.$apply(); + break; + case 40:// down + e.preventDefault(); + incr(-step); + $scope.$apply(); + break; + case 13:// enter + e.preventDefault(); + $scope.formatInputValue(); + $scope.$apply(); + break; + } + } + var step = getStep(); + hoursInput.bind('keydown', function(e) { subscription(e, 60); }); + minsInput.bind('keydown', function(e) { subscription(e, step); }); + } + + function setupMousewheelEvents(elt, hoursField, minsField) { + function isScrollingUp(e) { + e = e.originalEvent ? e.originalEvent : e; + //pick correct delta variable depending on event + var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; + return (e.detail || delta > 0); + } + var enableMouseWheel = false; + var enableWheelTimeout; + elt.bind('mouseenter', function(e) { + enableWheelTimeout = setTimeout(function() { + enableMouseWheel = true; + }, MAGIC_DELAY_BEFORE_WHEEL); + }); + elt.bind('mouseleave', function(e) { + if (!!enableWheelTimeout) { + clearTimeout(enableWheelTimeout); + } + enableMouseWheel = false; + }); + function subscription(e, incrStep){ + if(!$scope.isDisabled && enableMouseWheel){ + $scope.$apply(incr((isScrollingUp(e)) ? incrStep : -incrStep )); + e.preventDefault(); + } + } + var step = getStep(); + + hoursField.bind('mousewheel wheel', function(e) { subscription(e, 60); }); + minsField.bind('mousewheel wheel', function(e) { subscription(e, step); }); + } + + setupArrowkeyEvents( hoursInput, minsInput); + setupMousewheelEvents(elt, hoursField, minsField); + }; + + }]); + + angular.module("lui").run(["$templateCache", function($templateCache) { + $templateCache.put("lui/directives/luidMoment.html", + "
" + + " " + + " " + + " " + + "
" + + ":" + + "
" + + " " + + " " + + " " + + "
" + + ""); + }]); +})(); +;(function () { + 'use strict'; + /** + ** DEPENDENCIES + ** - none + **/ + + angular.module('lui').directive('luidPercentage', function () { + function link(scope, element, attrs, ctrls) { + + var ngModelCtrl = ctrls[1]; + var luidPercentageCtrl = ctrls[0]; + scope.pattern = /^([0-9]+)(\.([0-9]*)?)?$/i; + if (!attrs.format) { + scope.format = "0.XX"; + }else if(attrs.format !== "0.XX" && attrs.format !== "1.XX" && attrs.format !== "XX"){ + ngModelCtrl.$render = function () { scope.intPct = "unsupported format"; }; + return; + } + + scope.ngModelCtrl = ngModelCtrl; + + ngModelCtrl.$render = function () { + if (this.$viewValue === undefined) { + scope.intPct = undefined; + return; + } + // must support the different formats here + scope.intPct = scope.parse(parseFloat(this.$viewValue)); + }; + + // call the ng-change + ngModelCtrl.$viewChangeListeners.push(function () { + scope.$eval(attrs.ngChange); + }); + + // bind to various events - here only keypress=enter + luidPercentageCtrl.setupEvents(element.find('input')); + } + + + return { + require: ['luidPercentage', '^ngModel'], + controller: 'luidPercentageController', + scope: { + step: '=', // default = 5 + format: '@', // 'XX', '0.XX' or '1.XX', default 0.XX + ngDisabled: '=', + placeholder: '@' + }, + restrict: 'EA', + link: link, + template: + "
" + + "" + + "%" + + "
" + }; + }) + .controller('luidPercentageController', ['$scope', function ($scope) { + + // private - updates of some kinds + // incr value by `step` minutes + function incr(step) { + update(parseFloat($scope.intPct) + step); + } + + // sets viewValue and renders + function update(duration) { + updateWithoutRender(duration); + $scope.ngModelCtrl.$render(); + } + + function updateWithoutRender(duration) { + function format(pct) { + switch($scope.format || "0.XX"){ + case "XX" : return pct; + case "0.XX" : return pct/100; + case "1.XX" : return (pct/100) + 1; + default : return 0; + } + } + + var newValue = duration === undefined ? undefined : format(duration); + $scope.ngModelCtrl.$setViewValue(newValue); + } + + // events - key 'enter' + this.setupEvents = function (elt) { + function getStep(){ return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step);} + function setupKeyEvents(elt) { + var step = getStep(); + elt.bind('keydown', function (e) { + switch(e.which){ + case 38:// up + e.preventDefault(); + incr(step); + $scope.$apply(); + break; + case 40:// down + e.preventDefault(); + incr(-step); + $scope.$apply(); + break; + case 13:// enter + e.preventDefault(); + $scope.formatInputValue(); + $scope.$apply(); + break; + } + }); + } + function setupMousewheelEvents(elt) { + function isScrollingUp(e) { + e = e.originalEvent ? e.originalEvent : e; + //pick correct delta variable depending on event + var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; + return (e.detail || delta > 0); + } + + var step = getStep(); + elt.bind('mousewheel wheel', function (e) { + if (this === document.activeElement) { + $scope.$apply(incr((isScrollingUp(e)) ? step : -step)); + e.preventDefault(); + } + }); + } + + setupKeyEvents(elt); + setupMousewheelEvents(elt); + }; + + // public methods for update + $scope.updateValue = function () { + updateWithoutRender($scope.intPct); + }; + + $scope.parse = function (intInput) { + switch($scope.format || "0.XX"){ + case "XX": return intInput; + case "0.XX": return Math.round(10000 * intInput) / 100; + case "1.XX": return Math.round((intInput-1) * 10000) / 100; + default : return 0; + } + }; + + // display stuff + $scope.formatInputValue = function () { + $scope.ngModelCtrl.$render(); + }; + }]); +})(); +;(function () { + 'use strict'; + /** + ** DEPENDENCIES + ** - moment + **/ + + angular.module('lui').directive('luidTimespan', ['moment', function (moment) { + + function link(scope, element, attrs, ctrls) { + var ngModelCtrl = ctrls[1]; + var luidTimespanCtrl = ctrls[0]; + scope.pattern = /^\-?([0-9]+)((h([0-9]{2})?)?(m(in)?)?)?$/i; + if (!!attrs.unit) { + var unit = scope.$eval(attrs.unit); + if (unit == 'h' || unit == 'hour' || unit == 'hours') { + scope.useHours = true; + } + } + + scope.ngModelCtrl = ngModelCtrl; + + ngModelCtrl.$render = function () { + scope.strDuration = ''; + if (!this.$viewValue) { + return; + } + var currentDuration = moment.duration(this.$viewValue); + if (currentDuration < 0) { + scope.strDuration += "-"; + currentDuration = moment.duration(-currentDuration); + } + var hours = Math.floor(currentDuration.asHours()); + var minutes = currentDuration.minutes(); + if (hours === 0) { + scope.strDuration += minutes + 'm'; + } else { + scope.strDuration += (hours < 10 ? '0' : '') + hours + 'h' + (minutes < 10 ? '0' : '') + minutes; + } + }; + + // bind to various events - here only keypress=enter + luidTimespanCtrl.setupEvents(element.find('input')); + + // set to given mode or to default mode + luidTimespanCtrl.mode = attrs.mode ? attrs.mode : "timespan"; + } + + + return { + require: ['luidTimespan', '^ngModel'], + controller: 'luidTimespanController', + scope: { + step: '=', // default = 5 + unit: '=', // 'hours', 'hour', 'h' or 'm', default='m' + ngDisabled: '=', + placeholder: '@', + mode: "=", // 'timespan', 'moment.duration', default='timespan' + min: '=', //min value + max: '=', //max value + }, + restrict: 'EA', + link: link, + template: + "
" + + "" + + "
" + }; + }]) + .controller('luidTimespanController', ['$scope', 'moment', function ($scope, moment) { + var ctrl = this; + + function parse(strInput) { + // parsing str to moment.duration + function parseHoursAndMinutes(strInput) { + var d = moment.duration(); + var splitted = strInput.split(/h/i); + var isPositive = parseInt(splitted[0]) >= 0; + d.add(parseInt(splitted[0]), 'hours'); + var strMin = splitted[1]; + if (!!strMin && strMin.length >= 2) { + if (isPositive){ + d.add(parseInt(strMin.substring(0, 2)), 'minutes'); + } else { + d.subtract(parseInt(strMin.substring(0, 2)), 'minutes'); + } + } + return d; + } + + function parseMinutes(strInput) { + var d = moment.duration(); + var splitted = strInput.split(/m/i); + d.add(parseInt(splitted[0]), 'minutes'); + return d; + } + + function parseHours(strInput) { + var d = moment.duration(); + var splitted = strInput.split(/h/i); + d.add(parseInt(splitted[0]), 'hours'); + return d; + } + + switch(true){ + case (/h/i.test(strInput)) : return parseHoursAndMinutes(strInput); + case (/m/i.test(strInput)) : return parseMinutes(strInput); + case ($scope.useHours) : return parseHours(strInput); + default : return parseMinutes(strInput); + } + } + + // updates of some kinds + // incr value by `step` minutes + function incr(step) { + var newDur = moment.duration(currentValue()).add(step, 'minutes'); + if (newDur.asMilliseconds() < 0) { + newDur = moment.duration(); + } + update(newDur); + } + + // sets viewValue and renders + function update(newDuration) { + updateWithoutRender(newDuration); + $scope.ngModelCtrl.$render(); + } + + function updateWithoutRender(newDuration) { + // Handle min/max values + function correctValue(newValue){ + function correctedMinValue(newValue) { + var min = !$scope.min ? undefined : moment.duration($scope.min); + return (!min || min <= newValue) ? newValue : min; + } + + function correctedMaxValue(newValue) { + var max = !$scope.max ? undefined : moment.duration($scope.max); + return (!max || max >= newValue) ? newValue : max; + } + + return correctedMaxValue(correctedMinValue(newValue)); + } + + function format(dur) { + if (ctrl.mode === 'timespan') { + var timespan = ""; + if (dur.asMilliseconds() < 0){ + timespan += "-"; + dur = moment.duration(-dur); + } + timespan += (dur.days() > 0 ? Math.floor(dur.asDays()) + '.' : '') + (dur.hours() < 10 ? '0' : '') + dur.hours() + ':' + (dur.minutes() < 10 ? '0' : '') + dur.minutes() + ':00'; + return timespan; + } + return dur; + } + + if (newDuration === undefined) { + return $scope.ngModelCtrl.$setViewValue(undefined); + } + + // Check min/max values + newDuration = correctValue(newDuration); + var formattedValue = format(newDuration); + + $scope.ngModelCtrl.$setViewValue(formattedValue); + } + + function currentValue() { + return $scope.ngModelCtrl.$viewValue; + } + + // events - key 'enter' + this.setupEvents = function (elt) { + function getStep(){ return isNaN(parseInt($scope.step)) ? 5 : parseInt($scope.step);} + function setupKeyEvents(elt) { + var step = getStep(); + elt.bind('keydown', function (e) { + switch(e.which){ + case 38:// up + e.preventDefault(); + incr(step); + $scope.$apply(); + break; + case 40:// down + e.preventDefault(); + incr(-step); + $scope.$apply(); + break; + case 13:// enter + e.preventDefault(); + $scope.formatInputValue(); + $scope.$apply(); + break; + } + }); + } + + function setupMousewheelEvents(elt) { + function isScrollingUp(e) { + e = e.originalEvent ? e.originalEvent : e; + //pick correct delta variable depending on event + var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; + return (e.detail || delta > 0); + } + + var step = getStep(); + elt.bind('mousewheel wheel', function (e) { + if (this === document.activeElement) { + $scope.$apply(incr((isScrollingUp(e)) ? step : -step)); + e.preventDefault(); + } + }); + } + + setupKeyEvents(elt); + setupMousewheelEvents(elt); + }; + + // public methods for update + $scope.updateValue = function () { + + // is only fired when pattern is valid or when it goes from valid to invalid + // improvement possible - check the pattern and set the validity of the all directive via ngModelCtrl.$setValidity + // currently when pattern invalid, the viewValue is set to '00:00:00' + if (!$scope.strDuration) { return updateWithoutRender(undefined); } // empty input => 00:00:00 + + // parse the strDuration to build newDuration + // the duration of the parsed strDuration + var newDuration = parse($scope.strDuration); + + // update viewvalue + updateWithoutRender(newDuration); + }; + + // display stuff + $scope.formatInputValue = function () { + $scope.ngModelCtrl.$render(); + }; + }]); +})(); +;(function(){ + 'use strict'; + /** + ** DEPENDENCIES + ** - none, nothing, nada + **/ + function replaceAll(string, find, replace) { + // http://stackoverflow.com/questions/1144783/replacing-all-occurrences-of-a-string-in-javascript + // lets not reinvent the wheel + if(!string){ return ''; } + function escapeRegExp(string) { + return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); + } + return string.replace(new RegExp(escapeRegExp(find), 'g'), replace); + } + angular.module('lui') + .filter('luifPlaceholder', function () { + return function (_input, _placeholder) { + return !!_input ? _input : _placeholder; + }; + }) + .filter('luifDefaultCode', function () { + // uppercased and with '_' instead of ' ' + return function (_input) { + return replaceAll(_input, ' ', '_').toUpperCase(); + }; + }) + .filter('luifStartFrom', function () { + //pagination filter + return function (_input, start) { + start = +start; //parse to int + return _input.slice(start); + }; + }) + .filter('luifNumber', ['$sce', '$filter', function($sce, $filter) { + return function(_input, _precision, _placeholder) { + + function getRightSpan(decimalPart, separator) { + if (decimalPart === undefined) { return ""; } + if (parseInt(decimalPart) === 0) { return "" + separator + decimalPart + ""; } + return "" + separator + decimalPart + ""; + } + + var placeholder = _placeholder === undefined ? '' : _placeholder; + // alert(_input + " " + (!!_input.isNaN && _input.isNaN())); + var input = _input === undefined || _input === null || _input === "" || _input != _input ? placeholder : _input; // the last check is to check if _input is NaN + var separator = $filter("number")(1.1,1)[1]; + var precision = _precision === undefined || _precision === null || _precision != _precision ? 2 : _precision; + + var text = $filter("number")(input, precision); + var decimalPart = (text || $filter("number")(0, precision)).split(separator)[1]; + var rightSpan = getRightSpan(decimalPart, separator); + + if (input === '' || !text){ + // the _input or the _placeholder was not parsable by the number $filter, just return input but trusted as html + return $sce.trustAsHtml(input + rightSpan); + } + + var integerPart = text.split(separator)[0]; + return $sce.trustAsHtml(integerPart + rightSpan); + }; + }]); +})(); +;(function () { + 'use strict'; + /** + ** DEPENDENCIES + ** - moment + **/ + var formatMoment = function (_moment, _format) { //expects a moment + if (!_moment) { + return ""; + } + var m = moment(_moment); + return m.isValid() ? m.format(_format) : _moment; + }; + + angular.module('lui') + .filter('luifFriendlyRange', function () { + var translations = { + 'en': { + startOnly: 'date(dddd, LL) onwards', + startOnlyThisYear: 'date(dddd, MMMM Do) onwards', + endOnly: 'until date(dddd, LL)', + endOnlyThisYear: 'until date(dddd, MMMM Do)', + date: 'date(LL)', + sameDay: 'start(dddd, LL)', + sameDayThisYear: 'start(dddd, MMMM Do)', + sameMonth: 'start(MMMM Do) - end(Do\, YYYY)', + sameMonthThisYear: 'start(MMMM Do) - end(Do)', + sameYear: 'start(MMMM Do) - end(LL)', + sameYearThisYear: 'start(MMMM Do) - end(MMMM Do)', + other: 'start(LL) - end(LL)' + }, + 'fr': { + startOnly: 'à partir du date(dddd LL)', + startOnlyThisYear: 'à partir du date(dddd Do MMMM)', + endOnly: 'jusqu\'au date(dddd LL)', + endOnlyThisYear: 'jusqu\'au date(dddd Do MMMM)', + date: 'date(LL)', + sameDay: 'le start(dddd LL)', + sameDayThisYear: 'le start(dddd Do MMMM)', + sameMonth: 'du start(Do) au end(LL)', + sameMonthThisYear: 'du start(Do) au end(Do MMMM)', + sameYear: 'du start(Do MMMM) au end(LL)', + sameYearThisYear: 'du start(Do MMMM) au end(Do MMMM)', + other: 'du start(LL) au end(LL)' + }, + 'de': { + + startOnly: 'von date(Do MMMM)', + startOnlyThisYear: 'von date(LL)', + endOnly: 'bis date(Do MMMM)', + endOnlyThisYear: 'bis date(LL)', + date: 'date(LL)', + sameDay: 'der start(dddd LL)', + sameDayThisYear: 'der start(dddd Do MMMM)', + sameMonth: 'von start(Do) bis end(LL)', + sameMonthThisYear: 'von start(Do) bis end(Do MMMM)', + sameYear: 'von start(Do MMMM) bis end(LL)', + sameYearThisYear: 'von start(Do MMMM) bis end(Do MMMM)', + other: 'von start(LL) bis end(LL)' + } + }; + function getTrad(trads, locale, key, fallbackKey) { + if (!!trads && !!trads[locale] && !!trads[locale][key]) { + return trads[locale][key]; + } + if (!!trads && !!trads[locale] && !!trads[locale][fallbackKey]) { + return trads[locale][fallbackKey]; + } + // fallback on english in provided translations + var fallbackLocale = "en"; + if (!!trads && !!trads[fallbackLocale] && !!trads[fallbackLocale][key]) { + return trads[fallbackLocale][key]; + } + if (!!trads && !!trads[fallbackLocale] && !!trads[fallbackLocale][fallbackKey]) { + return trads[fallbackLocale][fallbackKey]; + } + + // fallback on standard translations if I couldnt find what I need in provided trads + var fallbackTrads = translations; + if (!!fallbackTrads && !!fallbackTrads[locale] && !!fallbackTrads[locale][key]) { + return fallbackTrads[locale][key]; + } + if (!!fallbackTrads && !!fallbackTrads[locale] && !!fallbackTrads[locale][fallbackKey]) { + return fallbackTrads[locale][fallbackKey]; + } + // fallback on english in provided translations + if (!!fallbackTrads && !!fallbackTrads[fallbackLocale] && !!fallbackTrads[fallbackLocale][key]) { + return fallbackTrads[fallbackLocale][key]; + } + if (!!fallbackTrads && !!fallbackTrads[fallbackLocale] && !!fallbackTrads[fallbackLocale][fallbackKey]) { + return fallbackTrads[fallbackLocale][fallbackKey]; + } + } + return function (_block, _excludeEnd, _translations) { + if(!_block){ return; } + var start = _block.start || _block.startsAt || _block.startsOn || _block.startDate; + var end = _block.end || _block.endsAt || _block.endsOn || _block.endDate; + if (!start && !end) { + return ""; + } + start = !!start ? moment(start) : undefined; + end = !!end ? moment(end) : undefined; + if(_excludeEnd){ + end.add(-1,'minutes'); + } + var trad; + var format; + var regex; + if (!!start && !!end) { + format = start.year() === end.year() ? start.month() === end.month() ? start.date() === end.date() ? 'sameDay' : 'sameMonth' : 'sameYear' : 'other'; + if(moment().year() === start.year() && moment().year() === end.year()){ + format += "ThisYear"; + } + trad = getTrad(_translations, moment.locale(), format, "other"); + regex = /(start\((.*?)\))(.*(end\((.*?)\))){0,1}/gi.exec(trad); + return trad.replace(regex[1], start.format(regex[2])).replace(regex[4], end.format(regex[5])); + } + format = !!start ? "startOnly" : "endOnly"; + var date = start || end; + if(moment().year() === date.year()){ + format += "ThisYear"; + } + trad = getTrad(_translations, moment.locale(), format, "date"); + regex = /(date\((.*?)\))/gi.exec(trad); + return trad.replace(regex[1], date.format(regex[2])); + }; + }) + .filter('luifMoment', function () { + return function (_moment, _format) { + if (!_format) { _format = 'LLL'; } // default format + return formatMoment(_moment, _format); + }; + }) + .filter('luifCalendar', function () { + return function (_moment, _refDate) { + var m = moment(_moment); + var refDate = (_refDate && moment(_refDate).isValid()) ? moment(_refDate) : moment(); + + return m.isValid() ? m.calendar(_refDate) : _moment; + }; + }) + .filter('luifDuration', ['$filter', function ($filter) { + //expects a duration, returns the duration in the given unit with the given precision + return function (_duration, _sign, _unit, _precision) { + function getConfigIndex(expectedUnit){ + switch(expectedUnit){ + case 'd': + case 'day': + case 'days': return 0; + case undefined: + case '': + case 'h': + case 'hour': + case 'hours': return 1;// default + case 'm': + case 'min': + case 'mins': + case 'minute': + case 'minutes': return 2; + case 's': + case 'sec': + case 'second': + case 'seconds': return 3; + case 'ms': + case 'millisec': + case 'millisecond': + case 'milliseconds': return 4; + } + } + + function getNextNotNull(array, startIndex){ + return startIndex === 4 ? 4 : array[startIndex] !== 0 ? startIndex : getNextNotNull(array, startIndex + 1); + } + + function getPrevNotNull(array, startIndex){ + return startIndex === 0 ? 0 : array[startIndex] !== 0 ? startIndex : getPrevNotNull(array, startIndex - 1); + } + + function getDecimalNumber(days){ + switch(true){ + case (Math.floor((days * 10) % 10) === 0 && Math.floor((days * 100) % 10) === 0): return 0; + case (Math.floor((days * 100) % 10) === 0): return 1; + default: return 2; + } + } + + function formatValue (value, u, expectedUnit){ + switch(u){ + case expectedUnit : return value; + case 2 : + case 3 : return (value < 10 ? '0' + value : value); + case 4 : return (value < 10 ? '00' + value : value < 100 ? '0' + value : value); + default : return value; + } + } + + function getPrefix(sign, duration){ + if (sign) { + if (duration.asMilliseconds() > 0) { return '+'; } + else if (duration.asMilliseconds() < 0) { return '-'; } + } + return ''; + } + + // some localisation shenanigans + function getUnitSymbols(unit, precision){ + var result = ['d ', 'h', 'm', 's', 'ms']; + switch(moment.locale()){ + case "fr": result[0] = 'j '; break; + } + + // if precision = ms and unit bigger than s we want to display 12.525s and not 12s525ms + if(unit <= 3 && precision === 4) { result[3] = '.'; result[4] = 's'; } + if(unit <= 1 && precision === 2) { result[2] = ''; } + if(unit === 2 && precision === 3) { result[3] = ''; } + + return result; + } + + var unitConfigs = [ + { + index: 0, + unit: 'd', + dateConversion : 'asDays', + expectedPrecision : 'h' + }, + { + index: 1, + unit: 'h', + dateConversion : 'asHours', + expectedPrecision :'m' + }, + { + index: 2, + unit: 'm', + dateConversion : 'asMinutes', + expectedPrecision : 's' + }, + { + index: 3, + unit: 's', + dateConversion : 'asSeconds', + expectedPrecision : 's' + }, + { + index: 4, + unit: 'ms', + dateConversion : 'asMilliseconds', + expectedPrecision : 'ms' + }, + ]; + + var d = moment.duration(_duration); + + if (d.asMilliseconds() === 0) { return ''; } + + var values = [Math.abs(d.days()), Math.abs(d.hours()), Math.abs(d.minutes()), Math.abs(d.seconds()), Math.abs(d.milliseconds())]; + var config = unitConfigs[getConfigIndex(_unit)]; + var minimumUnit = Math.max(config.index, getNextNotNull(values, 0)); + values[config.index] = Math.abs(d[config.dateConversion]() >= 0 ? Math.floor(d[config.dateConversion]()) : Math.ceil(d[config.dateConversion]())); + + if (config.index === 0 && getConfigIndex(_precision) === 0 && d.asDays() !== 0){ + var myDays = Math.abs(d.asDays()); + var decimalNumber = getDecimalNumber(myDays); + minimumUnit = 0; + values[0] = $filter("number")(myDays, decimalNumber); + } + + var precision = getPrevNotNull(values, getConfigIndex(_precision || config.expectedPrecision)); + var units = getUnitSymbols(minimumUnit, precision); + + var result = ''; + for(var i = minimumUnit; i <= precision; i++){ + result += formatValue(values[i], i, minimumUnit) + units[i]; + } + + var prefix = !!result ? getPrefix(_sign, d) : ''; + return prefix + result; + }; + }]) + .filter('luifHumanize', function () { + return function (_duration, suffix) { + suffix = !!suffix; + var d = moment.duration(_duration); + return d.humanize(suffix); + }; + }); +})(); diff --git a/dist/lucca-ui.min.js b/dist/lucca-ui.min.js index 1a15eaf9..1a875c2d 100644 --- a/dist/lucca-ui.min.js +++ b/dist/lucca-ui.min.js @@ -1,6 +1,6 @@ -/*! lucca-ui 25-06-2018 */ +/*! lucca-ui 24-02-2020 */ var __extends=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)},lui;!function(a){"use strict";angular.module("moment",[]).factory("moment",function(){return moment}),angular.module("underscore",[]).factory("_",function(){return _}),angular.module("iban",[]).factory("iban",function(){return IBAN}),angular.module("lui",["ngSanitize","ui.bootstrap","ui.select","moment","underscore"]),angular.module("lui.translate",["lui","pascalprecht.translate"]),angular.module("lui.notify",["lui","cgNotify"]),angular.module("lui.formly",["lui","formly"]),angular.module("lui.crop",["lui","lui.translate","uiCropper"]),angular.module("lui.iban",["lui","iban"]),angular.module("lui.tablegrid",["lui","lui.translate"])}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";angular.module("lui").directive("luiCloak",["$timeout",function(a){return{restrict:"A",link:function(b,c,d){a(function(){d.$set("luiCloak",void 0),c.removeClass("lui-cloak")},0)}}}])}(b=a.cloak||(a.cloak={}))}(lui||(lui={}));var lui;!function(a){"use strict"}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a){var b=this;this.$get=["$log",function(a){return new c(b.config,a)}],this.config={},this.$uibModalProvider=a}return a.prototype.setConfig=function(a){this.config=a;var b=new c(this.config);this.configureNguibs(b)},a.prototype.configureNguibs=function(a){this.$uibModalProvider.options={windowClass:a.prefix,backdropClass:a.prefix,animation:!0,backdrop:!0,appendTo:a.parentElt,size:"large"}},a.$inject=["$uibModalProvider"],a}(),c=function(){function a(a,b){if(_.extend(this,a),!this.parentElt&&this.parentTagIdClass){var c=this.parentTagIdClass||"body",d=document.getElementsByTagName(c),e=document.getElementById(c),f=document.getElementsByClassName(c);d&&d.length?this.parentElt=angular.element(d[0]):e?this.parentElt=angular.element(e):f&&f.length?this.parentElt=angular.element(f[0]):b&&b.warn("luisConfig - could not find a suitable element for tag/id/class: "+c)}this.prefix=this.prefix||"lui",this.startTop=this.startTop||40,this.okLabel=this.okLabel||"Ok",this.cancelLabel=this.cancelLabel||"Cancel",this.canDismissConfirm=this.canDismissConfirm}return a}();angular.module("lui").provider("luisConfig",b)}(b=a.config||(a.config={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a){this.date=moment(a)}return a}();a.CalendarDate=b;var c=function(){function a(a){this.date=moment(a),this.weeks=[],this.months=[],this.years=[],this.currentYear=this.date.year()===moment().year()}return a}();a.Calendar=c;var d=function(){function a(){}return a}();a.CalendarWeek=d;var e=function(a){function b(b){a.call(this,b),this.dayNum=b.date()}return __extends(b,a),b}(b);a.CalendarDay=e;var f=function(){function a(){}return a}();a.Shortcut=f,function(a){a[a.Days=0]="Days",a[a.Months=1]="Months",a[a.Years=2]="Years"}(a.CalendarMode||(a.CalendarMode={}));a.CalendarMode}(b=a.datepicker||(a.datepicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function b(b,c){this.minMode=a.CalendarMode.Days,this.$scope=b,this.$log=c,this.initCalendarScopeMethods(b),this.setMinMode(b.minMode),this.$scope.mode=this.minMode,b.direction="init"}return b.prototype.setCalendarCnt=function(a,b){this.calendarCnt=parseInt(a,10)||1,b&&this.calendarCnt>2&&(this.calendarCnt=2,this.$log.warn("no more than 2 months displayed in a date-picker popover"))},b.prototype.constructCalendars=function(){var a=this;return _.map(_.range(this.calendarCnt),function(b){return a.constructCalendar(a.currentDate,b)})},b.prototype.constructDayLabels=function(){return _.map(_.range(7),function(a){return moment().startOf("week").add(a,"days").format("dd")})},b.prototype.assignClasses=function(){switch(this.$scope.mode){case a.CalendarMode.Days:return this.assignDayClasses();case a.CalendarMode.Months:return this.assignMonthClasses();case a.CalendarMode.Years:return this.assignYearClasses()}},b.prototype.setMinMode=function(b){switch((b||"").toLowerCase()){case"0":case"d":case"day":case"days":this.minMode=a.CalendarMode.Days;break;case"1":case"m":case"month":case"months":this.minMode=a.CalendarMode.Months;break;case"2":case"y":case"year":case"years":this.minMode=a.CalendarMode.Years;break;default:this.minMode=a.CalendarMode.Days}},b.prototype.assignDayClasses=function(){var b=this,c=this.extractDays();_.each(c,function(c){c.selected=!1,c.start=!1,c.end=!1,c.inBetween=!1,b.selected&&c.date.format("YYYYMMDD")===moment(b.selected).format("YYYYMMDD")&&(c.selected=!0),b.start&&c.date.format("YYYYMMDD")===moment(b.start).format("YYYYMMDD")&&(c.start=!0),b.end&&c.date.format("YYYYMMDD")===moment(b.end).format("YYYYMMDD")&&(c.end=!0),b.start&&b.end&&c.date.isSameOrAfter(b.start)&&c.date.isSameOrBefore(b.end)&&(c.inBetween=!0),b.min&&b.min.diff(c.date)>0&&(c.disabled=!0),b.max&&b.max.diff(c.date)<0&&(c.disabled=!0),b.$scope.customClass&&(c.customClass=b.$scope.customClass(c.date,a.CalendarMode.Days))})},b.prototype.assignMonthClasses=function(){var b=this,c=this.extractMonths();_.each(c,function(c){c.selected=!1,c.start=!1,c.end=!1,c.inBetween=!1,b.selected&&c.date.format("YYYYMM")===moment(b.selected).format("YYYYMM")&&(c.selected=!0),b.start&&c.date.format("YYYYMM")===moment(b.start).format("YYYYMM")&&(c.start=!0),b.end&&c.date.format("YYYYMM")===moment(b.end).format("YYYYMM")&&(c.end=!0),b.start&&b.end&&!c.start&&!c.end&&c.date.isSameOrAfter(b.start)&&c.date.isSameOrBefore(b.end)&&(c.inBetween=!0),b.min&&b.min.diff(moment(c.date).endOf("month"))>0&&(c.disabled=!0),b.max&&b.max.diff(c.date)<0&&(c.disabled=!0),b.$scope.customClass&&(c.customClass=b.$scope.customClass(c.date,a.CalendarMode.Months))})},b.prototype.assignYearClasses=function(){var b=this,c=this.extractYears();_.each(c,function(c){c.selected=!1,c.start=!1,c.end=!1,c.inBetween=!1,b.selected&&c.date.format("YYYY")===moment(b.selected).format("YYYY")&&(c.selected=!0),b.start&&c.date.format("YYYY")===moment(b.start).format("YYYY")&&(c.start=!0),b.end&&c.date.format("YYYY")===moment(b.end).format("YYYY")&&(c.end=!0),b.start&&b.end&&!c.start&&!c.end&&c.date.isSameOrAfter(b.start)&&c.date.isSameOrBefore(b.end)&&(c.inBetween=!0),b.min&&b.min.diff(moment(c.date).endOf("year"))>0&&(c.disabled=!0),b.max&&b.max.diff(c.date)<0&&(c.disabled=!0),b.$scope.customClass&&(c.customClass=b.$scope.customClass(c.date,a.CalendarMode.Years))})},b.prototype.initCalendarScopeMethods=function(b){var c=this;b.dayLabels=this.constructDayLabels(),b.next=function(){c.changeCurrentDate(1),b.calendars=c.constructCalendars(),b.direction="next",c.assignClasses()},b.previous=function(){c.changeCurrentDate(-1),b.calendars=c.constructCalendars(),b.direction="previous",c.assignClasses()},b.switchToMonthMode=function(){b.mode=a.CalendarMode.Months,b.direction="mode-change out",c.currentDate.startOf("year"),b.calendars=c.constructCalendars(),c.assignClasses()},b.switchToYearMode=function(){b.mode=a.CalendarMode.Years,b.direction="mode-change out",b.calendars=c.constructCalendars(),c.assignClasses()},b.selectDay=function(a){c.selectDate(a.date)},b.selectMonth=function(d){c.minMode===a.CalendarMode.Months?c.selectDate(d.date):(c.currentDate=d.date,b.mode=a.CalendarMode.Days,b.direction="mode-change in",b.calendars=c.constructCalendars(),c.assignClasses())},b.selectYear=function(d){c.minMode===a.CalendarMode.Years?c.selectDate(d.date):(c.currentDate=d.date,b.mode=a.CalendarMode.Months,b.direction="mode-change in",b.calendars=c.constructCalendars(),c.assignClasses())}},b.prototype.constructCalendar=function(b,c){var d;switch(this.$scope.mode){case a.CalendarMode.Days:return d=new a.Calendar(moment(b).startOf("month").add(c,"month")),d.weeks=this.constructWeeks(d.date),d;case a.CalendarMode.Months:return d=new a.Calendar(moment(b).startOf("year").add(c,"year")),d.months=this.constructDates(d.date,"months"),d;case a.CalendarMode.Years:return d=new a.Calendar(moment(b).startOf("year").add(12*c,"year")),d.years=this.constructDates(d.date,"years"),d}},b.prototype.constructDates=function(b,c){return _.map(_.range(12),function(d){return new a.CalendarDate(moment(b).add(d,c))})},b.prototype.constructWeeks=function(a){for(var b=[],c=moment(a).startOf("week");c.month()===a.month()||moment(c).endOf("week").month()===a.month();)b.push(this.constructWeek(c,a)),c.add(1,"week");return b},b.prototype.constructWeek=function(b,c){var d={days:[]};return d.days=_.map(_.range(7),function(d){var e=new a.CalendarDay(moment(b).add(d,"days"));return e.date.month()!==c.month()&&(e.empty=!0),e}),d},b.prototype.extractDays=function(){return _.chain(this.$scope.calendars).pluck("weeks").flatten().pluck("days").flatten().reject(function(a){return a.empty}).value()},b.prototype.extractMonths=function(){return _.chain(this.$scope.calendars).pluck("months").flatten().value()},b.prototype.extractYears=function(){return _.chain(this.$scope.calendars).pluck("years").flatten().value()},b.prototype.changeCurrentDate=function(b){switch(this.$scope.mode){case a.CalendarMode.Days:this.currentDate.add(b,"months");break;case a.CalendarMode.Months:this.currentDate.add(b,"years");break;case a.CalendarMode.Years:this.currentDate.add(12*b,"years")}},b}();a.CalendarController=b}(b=a.datepicker||(a.datepicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(b){"use strict";var c=function(){function a(){this.restrict="E",this.templateUrl="lui/templates/date-picker/datepicker-inline.html",this.require=["ngModel","luidDatePicker"],this.scope={format:"@",displayedCalendars:"@",minMode:"@",min:"=",max:"=",customClass:"="},this.controller=e.IID}return a.factory=function(){var b=function(){return new a};return b},a.prototype.link=function(a,b,c,d){var e=d[0],f=d[1];f.setFormat(a.format),f.setNgModelCtrl(e),f.setCalendarCnt(a.displayedCalendars)},a.IID="luidDatePicker",a}(),d=function(){function a(){this.restrict="E",this.templateUrl="lui/templates/date-picker/datepicker-popup.html",this.require=["ngModel","luidDatePickerPopup"],this.scope={format:"@",displayFormat:"@",displayedCalendars:"@",minMode:"@",min:"=",max:"=",customClass:"=",placeholder:"@",shortcuts:"=",groupedShortcuts:"=",disableKeyboardInput:"="},this.controller=e.IID}return a.factory=function(){var b=function(){return new a};return b},a.prototype.link=function(a,b,c,d){var e=d[0],f=d[1];f.setElement(b),f.setFormat(a.format,a.displayFormat),f.setNgModelCtrl(e),f.setCalendarCnt(a.displayedCalendars,!0),f.setPopoverTrigger(b,a)},a.IID="luidDatePickerPopup",a}(),e=function(c){function d(a,b,d){var e=this;c.call(this,a,b),this.$scope=a,a.togglePopover=function(a){e.togglePopover(a)},a.openPopover=function(a){e.openPopover(a)},a.closePopoverOnKeyPress={9:function(a){e.closePopover(),e.$scope.$apply()},13:function(a){e.closePopover(),e.$scope.$apply(),e.element.find("input")[0].blur()}},a.$watch("min",function(){e.min=e.formatter.parseValue(a.min),e.validate(),e.selected=e.getViewValue(),e.assignClasses()}),a.$watch("max",function(){e.max=e.formatter.parseValue(a.max),e.validate(),e.selected=e.getViewValue(),e.assignClasses()}),a.clear=function(a){e.setViewValue(void 0),e.$scope.displayStr="",e.closePopover(),e.selected=void 0,e.assignClasses(),a.stopPropagation()},a.selectShortcut=function(a){var b=e.formatter.parseValue(a.date);e.setViewValue(b),e.$scope.displayStr=e.getDisplayStr(b),e.closePopover(),e.selected=b,e.assignClasses()},a.onDisplayStrChanged=function(b){var c=a.displayStr,d=moment(c,a.displayFormat);d.isValid()?(e.setViewValue(d),e.render(),a.displayStr=c):(d=moment(c,a.format),d.isValid()&&(e.setViewValue(d),e.render(),a.displayStr=c)),e.validate()}}return __extends(d,c),d.prototype.setNgModelCtrl=function(a){var c=this;this.ngModelCtrl=a,a.$render=function(){c.render()},a.$validators.min=function(a,b){var d=c.min,e=c.getViewValue();return!e||!d||d.diff(e)<=0},a.$validators.max=function(a,b){var d=c.max,e=c.getViewValue();return!e||!d||d.diff(e)>=0},this.$scope.customClass&&(a.$validators.customClass=function(a,d){var e=c.getViewValue();if(c.$scope.customClass&&e){var f=c.$scope.customClass(e,b.CalendarMode.Days).toLowerCase();return f.indexOf("disabled")===-1&&f.indexOf("forbidden")===-1}return!0})},d.prototype.setFormat=function(b,c){this.formatter=new a.formatter.MomentFormatter(b),"moment"!==b&&"date"!==b?this.displayFormat=c||b||"L":this.displayFormat=c||"L"},d.prototype.selectDate=function(a){this.setViewValue(a),this.$scope.displayStr=this.getDisplayStr(a),this.selected=a,this.assignClasses(),this.closePopover()},d.prototype.setPopoverTrigger=function(b,c){var d=this,e=function(){d.ngModelCtrl.$setTouched(),d.closePopover()};this.popoverController=new a.popover.ClickoutsideTrigger(b,c,e),c.popover={isOpen:!1},c.togglePopover=function(a){d.togglePopover(a)}},d.prototype.setElement=function(a){this.element=a},d.prototype.setViewValue=function(a){this.ngModelCtrl.$setViewValue(this.formatter.formatValue(a)),this.ngModelCtrl.$setTouched()},d.prototype.getViewValue=function(){return this.formatter.parseValue(this.ngModelCtrl.$viewValue)},d.prototype.validate=function(){this.ngModelCtrl.$validate()},d.prototype.render=function(){var a=this.formatter.parseValue(this.ngModelCtrl.$viewValue);this.currentDate=moment(a).startOf("month"),this.$scope.mode=this.minMode,this.$scope.calendars=this.constructCalendars(),this.selected=a,this.min=this.formatter.parseValue(this.$scope.min),this.max=this.formatter.parseValue(this.$scope.max),this.assignClasses(),this.$scope.displayStr=this.getDisplayStr(a)},d.prototype.togglePopover=function(a){this.$scope.popover.isOpen?this.closePopover():this.openPopover(a)},d.prototype.closePopover=function(){this.$scope.displayStr=this.getDisplayStr(this.getViewValue()),this.$scope.direction="",this.element.removeClass("ng-open"),this.popoverController&&this.popoverController.close()},d.prototype.openPopover=function(a){if(this.element.addClass("ng-open"),this.$scope.direction="init",this.popoverController&&(this.render(),this.popoverController.open(a)),!this.$scope.disableKeyboardInput){var b=this.element.children().children()[0];b.select()}},d.prototype.getDisplayStr=function(a){return a?a.format(this.displayFormat||"L"):void 0},d.IID="luidDatePickerController",d.$inject=["$scope","$log","$timeout"],d}(b.CalendarController);angular.module("lui").controller(e.IID,e),angular.module("lui").directive(c.IID,c.factory()),angular.module("lui").directive(d.IID,d.factory())}(b=a.datepicker||(a.datepicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(b){"use strict";angular.module("lui").directive("autoFocus",function(){return{restrict:"A",link:function(a,b){b[0].focus()}}});var c=function(){function a(){this.restrict="E",this.templateUrl="lui/templates/date-picker/daterangepicker.html",this.require=["ngModel","luidDaterangePicker"],this.scope={format:"@",displayFormat:"@",rangeFormat:"@",minMode:"@",min:"=",max:"=",customClass:"=",excludeEnd:"@",startProperty:"@",endProperty:"@",placeholder:"@",shortcuts:"=",groupedShortcuts:"=",disableKeyboardInput:"="},this.controller=d.IID}return a.factory=function(){return function(){return new a}},a.prototype.link=function(a,b,c,d){var e=d[0],f=d[1];f.setNgModelCtrl(e),f.setFormat(a.format,a.displayFormat),f.setCalendarCnt("2",!0),f.setPopoverTrigger(b,a),f.setExcludeEnd(a.excludeEnd),f.setProperties(a.startProperty,a.endProperty),f.setElement(b)},a.IID="luidDaterangePicker",a}(),d=function(c){function d(a,b,d){var e=this;switch(c.call(this,a,d),this.$scope=a,this.$filter=b,a.internal={},moment.locale()){case"fr":a.fromLabel="Du",a.toLabel="Au";break;default:a.fromLabel="From",a.toLabel="To"}this.rangeFormatDictionary={en:{other:a.rangeFormat}},a.internal.startDisplayStr="",a.internal.endDisplayStr="",a.focusEndInputOnTab={9:function(a){e.$scope.editEnd(a)}},a.closePopoverOnTab={9:function(a){e.closePopover(),e.$scope.$apply()}},a.selectShortcut=function(b){a.period=e.toPeriod(b),a.displayStr=e.$filter("luifFriendlyRange")(e.$scope.period,!1,e.rangeFormatDictionary),e.setViewValue(a.period),e.closePopover()},a.onStartDisplayStrChanged=function(b){var c,d=a.internal.startDisplayStr,f=a.displayFormat||"L";if(moment(d,f).isValid())c=moment(d,f);else{if(!moment(d,a.format).isValid())return;c=moment(d,a.format)}e.selectDate(c,!1,!1),e.currentDate=e.$scope.period.start,e.start=e.$scope.period.start,a.calendars=e.constructCalendars(),e.assignClasses()},a.onEndDisplayStrChanged=function(b){var c,d=a.internal.endDisplayStr,f=a.displayFormat||"L";if(moment(d,f).isValid())c=moment(d,f);else{if(!moment(d,a.format).isValid())return;c=moment(d,a.format)}e.selectDate(c,!1,!1),e.currentDate=moment(e.$scope.period.end),e.end=e.currentDate,a.calendars=e.constructCalendars(),e.assignClasses()},a.editStart=function(b){b&&b.stopPropagation(),a.editingStart=!0,e.$scope.period.start&&moment(e.currentDate).diff(e.$scope.period.start)>0&&(e.currentDate=moment(e.$scope.period.start).startOf("month"),e.$scope.calendars=e.constructCalendars(),e.assignClasses())},a.editEnd=function(b){b&&b.stopPropagation(),a.editingStart=!1,e.$scope.period.end&&moment(e.currentDate).add(e.calendarCnt,"months").diff(e.$scope.period.end)<=0&&(e.currentDate=moment(e.$scope.period.end).add(-e.calendarCnt+1,"months").startOf("month"),e.$scope.calendars=e.constructCalendars(),e.assignClasses())},a.onMouseEnter=function(b,c){a.editingStart||e.$scope.period.end||(e.end=b.date,e.assignClasses())},a.onMouseLeave=function(b,c){a.editingStart||e.$scope.period.end||(e.end=void 0,e.assignClasses())},a.popover={isOpen:!1},a.clear=function(b){a.period.start=void 0,a.period.end=void 0,e.setViewValue(void 0),e.closePopover(),b.stopPropagation()}}return __extends(d,c),d.prototype.setElement=function(a){this.element=a},d.prototype.setNgModelCtrl=function(a){var c=this;this.ngModelCtrl=a,a.$render=function(){a.$viewValue?(c.$scope.period=c.getViewValue(),c.$scope.displayStr=c.$filter("luifFriendlyRange")(c.$scope.period,!1,c.rangeFormatDictionary),c.$scope.internal.startDisplayStr=c.$scope.period.start?c.$scope.period.start.format(c.$scope.displayFormat||"L"):"",c.$scope.internal.endDisplayStr=c.$scope.period.end?c.$scope.period.end.format(c.$scope.displayFormat||"L"):""):(c.$scope.period=void 0,c.$scope.displayStr=void 0,c.$scope.internal.startDisplayStr=void 0,c.$scope.internal.endDisplayStr=void 0)},a.$isEmpty=function(a){var b=c.toPeriod(a);return!b||!b.start&&!b.end},a.$validators.min=function(a,b){var d=c.getViewValue().start,e=c.formatter.parseValue(c.$scope.min);return!d||!e||e.diff(d)<=0},a.$validators.max=function(a,b){var d=c.getViewValue().end,e=c.formatter.parseValue(c.$scope.max);return!d||!e||e.diff(d)>=0},this.$scope.customClass&&(a.$validators.customClass=function(a,d){var e=c.getViewValue();if(c.$scope.customClass&&e){var f=!0,g=!0;if(e.start){var h=c.$scope.customClass(e.start,b.CalendarMode.Days).toLowerCase();f=h.indexOf("disabled")===-1&&h.indexOf("forbidden")===-1}if(e.end){var i=c.$scope.customClass(e.end,b.CalendarMode.Days).toLowerCase();g=i.indexOf("disabled")===-1&&i.indexOf("forbidden")===-1}return f&&g}return!0})},d.prototype.setProperties=function(a,b){this.startProperty=a||"start",this.endProperty=b||"end"},d.prototype.setExcludeEnd=function(a){this.excludeEnd="true"===a},d.prototype.setFormat=function(b,c){this.formatter=new a.formatter.MomentFormatter(b),"moment"!==b&&"date"!==b?this.$scope.momentFormat=c||b||"L":this.$scope.momentFormat=c||"L"},d.prototype.setPopoverTrigger=function(b,c){var d=this,e=function(){d.closePopover()};this.popoverController=new a.popover.ClickoutsideTrigger(b,c,e),c.togglePopover=function(a){d.togglePopover(a)}},d.prototype.selectDate=function(a,c,d){if(void 0===c&&(c=!0),void 0===d&&(d=!0),this.$scope.editingStart)this.$scope.period.start=a,this.start=a,d&&(this.$scope.internal.startDisplayStr=a.format(this.$scope.displayFormat||"L")),c&&this.$scope.editEnd(),this.$scope.period.end&&this.$scope.period.start.isAfter(this.$scope.period.end)&&(this.$scope.period.end=void 0,this.end=void 0),this.assignClasses();else{switch(this.minMode){case b.CalendarMode.Months:this.$scope.period.end=a.endOf("month").startOf("day");break;case b.CalendarMode.Years:this.$scope.period.end=a.endOf("year").startOf("day");break;default:this.$scope.period.end=a,d&&(this.$scope.internal.endDisplayStr=a.format(this.$scope.displayFormat))}this.$scope.period.start?c&&this.closePopover():this.$scope.editStart()}},d.prototype.setViewValue=function(a){var b=_.clone(this.ngModelCtrl.$viewValue);return a||b?(b=b||{},a?(b[this.startProperty]=a.start?this.formatter.formatValue(moment(a.start)):void 0,b[this.endProperty]=a.end?this.formatter.formatValue(this.excludeEnd?moment(a.end).add(1,"day"):moment(a.end)):void 0,this.$scope.internal.startDisplayStr=a.start?a.start.format(this.$scope.displayFormat||"L"):void 0,this.$scope.internal.endDisplayStr=a.end?a.end.format(this.$scope.displayFormat||"L"):void 0):(b[this.startProperty]=void 0,b[this.endProperty]=void 0,this.$scope.internal.startDisplayStr="",this.$scope.internal.endDisplayStr=""),void this.ngModelCtrl.$setViewValue(b)):(this.$scope.internal.startDisplayStr="",this.$scope.internal.endDisplayStr="",this.ngModelCtrl.$setViewValue(void 0))},d.prototype.getViewValue=function(){return this.toPeriod(this.ngModelCtrl.$viewValue)},d.prototype.toPeriod=function(b){if(!b)return{start:void 0,end:void 0};var c={};c.start=b[this.startProperty],c.end=b[this.endProperty];var d=new a.Period(c,this.formatter);return this.excludeEnd&&d.end&&d.end.add(-1,"day"),d},d.prototype.togglePopover=function(a){this.$scope.popover.isOpen?this.closePopover():this.openPopover(a)},d.prototype.closePopover=function(){if(this.$scope.period.start&&this.$scope.period.end&&this.$scope.period.start.isAfter(this.$scope.period.end)){var a=this.$scope.period.start;this.$scope.period.start=this.$scope.period.end,this.$scope.period.end=a}this.$scope.direction="",this.setViewValue(this.$scope.period),this.$scope.displayStr=this.$filter("luifFriendlyRange")(this.$scope.period,!1,this.rangeFormatDictionary),this.element.removeClass("ng-open"),this.popoverController.close()},d.prototype.openPopover=function(a){var b=this.getViewValue();this.$scope.period=b||{start:void 0,end:void 0},this.currentDate=(b?moment(b.start):moment()).startOf("month"),this.$scope.mode=this.minMode,this.$scope.direction="init",this.$scope.calendars=this.constructCalendars(),b&&(this.start=b.start,this.end=b.end),this.min=this.formatter.parseValue(this.$scope.min),this.max=this.formatter.parseValue(this.$scope.max),this.assignClasses(),this.$scope.editingStart=!0,this.element.addClass("ng-open"),this.popoverController.open(a)},d.IID="luidDaterangePickerController",d.$inject=["$scope","$filter","$log"],d}(b.CalendarController);angular.module("lui").controller(d.IID,d),angular.module("lui").directive(c.IID,c.factory())}(b=a.datepicker||(a.datepicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";function b(){return function(a,b){var c=b.toLowerCase(),d=_.filter(a,function(a){return 0===a.name.toLowerCase().indexOf(c)}),e=_.chain(a).difference(d).filter(function(a){return a.name.toLowerCase().indexOf(c)>-1}).value(),f=_.filter(a,function(a){return a.name.toLowerCase().indexOf(c)===-1&&!!a.ancestorsLabel&&a.ancestorsLabel.toLowerCase().indexOf(c)>-1});return _.union(d,e,f)}}a.DepartmentFilter=b,angular.module("lui").filter("departmentFilter",b)}(b=a.departmentpicker||(a.departmentpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict"}(b=a.departmentpicker||(a.departmentpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";a.MAGIC_PAGING=15;var b=function(){function b(a,b,c){this.$scope=a,this.$filter=b,this.departmentPickerService=c,this.initDepartments(),this.initScope()}return b.prototype.setNgModelCtrl=function(a){var b=this;this.ngModelCtrl=a,this.ngModelCtrl.$render=function(){b.ngModelCtrl.$modelValue&&(b.$scope.internal.selectedDepartment=b.ngModelCtrl.$modelValue)}},b.prototype.initScope=function(){var a=this;this.$scope.internal={selectedDepartment:void 0},this.$scope.selectDepartment=function(){a.setViewValue(a.$scope.internal.selectedDepartment)},this.$scope.loadMore=function(b){a.$scope.departmentsToDisplay.length0&&(a.hasChild=!0),_.each(b,function(b){b.node.ancestorsLabel?b.node.ancestorsLabel+=" > ":b.node.ancestorsLabel="",b.node.ancestorsLabel+=a.name,b.node.level=a.level+1,c.setAncestry(a,b.children)})},a.IID="departmentPickerService",a.$inject=["$http"],a}();angular.module("lui").service(b.IID,b)}(b=a.departmentpicker||(a.departmentpicker={}))}(lui||(lui={}));var lui;!function(a){"use strict";var b=function(){function a(a,b){var c=a.start||a.startsOn||a.startsAt,d=a.end||a.endsOn||a.endsAt;this.start=b.parseValue(c),this.end=b.parseValue(d)}return a}();a.Period=b}(lui||(lui={}));var Lui;!function(a){var b;!function(a){"use strict";function b(){return function(a){return null===a||void 0===a?"":(_.each(c,function(b){a=a.replace(b.letters,b.base)}),a)}}var c=[{base:"A",letters:/[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g},{base:"AA",letters:/[\uA732]/g},{base:"AE",letters:/[\u00C6\u01FC\u01E2]/g},{base:"AO",letters:/[\uA734]/g},{base:"AU",letters:/[\uA736]/g},{base:"AV",letters:/[\uA738\uA73A]/g},{base:"AY",letters:/[\uA73C]/g},{base:"B",letters:/[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g},{base:"C",letters:/[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g},{base:"D",letters:/[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g},{base:"DZ",letters:/[\u01F1\u01C4]/g},{base:"Dz",letters:/[\u01F2\u01C5]/g},{base:"E",letters:/[\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E]/g},{base:"F",letters:/[\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g},{base:"G",letters:/[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g},{base:"H",letters:/[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g},{base:"I",letters:/[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g},{base:"J",letters:/[\u004A\u24BF\uFF2A\u0134\u0248]/g},{base:"K",letters:/[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g},{base:"L",letters:/[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g},{base:"LJ",letters:/[\u01C7]/g},{base:"Lj",letters:/[\u01C8]/g},{base:"M",letters:/[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g},{base:"N",letters:/[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g},{base:"NJ",letters:/[\u01CA]/g},{base:"Nj",letters:/[\u01CB]/g},{base:"O",letters:/[\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C]/g},{base:"OI",letters:/[\u01A2]/g},{base:"OO",letters:/[\uA74E]/g},{base:"OU",letters:/[\u0222]/g},{base:"P",letters:/[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g},{base:"Q",letters:/[\u0051\u24C6\uFF31\uA756\uA758\u024A]/g},{base:"R",letters:/[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g},{base:"S",letters:/[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g},{base:"T",letters:/[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g},{base:"TZ",letters:/[\uA728]/g},{base:"U",letters:/[\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244]/g},{base:"V",letters:/[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g},{base:"VY",letters:/[\uA760]/g},{base:"W",letters:/[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g},{base:"X",letters:/[\u0058\u24CD\uFF38\u1E8A\u1E8C]/g},{base:"Y",letters:/[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g},{base:"Z",letters:/[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g},{base:"a",letters:/[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250]/g},{base:"aa",letters:/[\uA733]/g},{base:"ae",letters:/[\u00E6\u01FD\u01E3]/g},{base:"ao",letters:/[\uA735]/g},{base:"au",letters:/[\uA737]/g},{base:"av",letters:/[\uA739\uA73B]/g},{base:"ay",letters:/[\uA73D]/g},{base:"b",letters:/[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253]/g},{base:"c",letters:/[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184]/g},{base:"d",letters:/[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A]/g },{base:"dz",letters:/[\u01F3\u01C6]/g},{base:"e",letters:/[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD]/g},{base:"f",letters:/[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C]/g},{base:"g",letters:/[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F]/g},{base:"h",letters:/[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265]/g},{base:"hv",letters:/[\u0195]/g},{base:"i",letters:/[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131]/g},{base:"j",letters:/[\u006A\u24D9\uFF4A\u0135\u01F0\u0249]/g},{base:"k",letters:/[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3]/g},{base:"l",letters:/[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747]/g},{base:"lj",letters:/[\u01C9]/g},{base:"m",letters:/[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g},{base:"n",letters:/[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g},{base:"nj",letters:/[\u01CC]/g},{base:"o",letters:/[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275]/g},{base:"oi",letters:/[\u01A3]/g},{base:"ou",letters:/[\u0223]/g},{base:"oo",letters:/[\uA74F]/g},{base:"p",letters:/[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g},{base:"q",letters:/[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g},{base:"r",letters:/[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g},{base:"s",letters:/[\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g},{base:"t",letters:/[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g},{base:"tz",letters:/[\uA729]/g},{base:"u",letters:/[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289]/g},{base:"v",letters:/[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g},{base:"vy",letters:/[\uA761]/g},{base:"w",letters:/[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g},{base:"x",letters:/[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g},{base:"y",letters:/[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g},{base:"z",letters:/[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g}];angular.module("lui").filter("luifStripAccents",b)}(b=a.Filters||(a.Filters={}))}(Lui||(Lui={}));var Lui;!function(a){"use strict";angular.module("lui.formly").config(["formlyConfigProvider",function(a){a.setType({name:"text",templateUrl:"lui/templates/formly/fields/text.html"}),a.setType({name:"textarea",templateUrl:"lui/templates/formly/fields/textarea.html"}),a.setType({name:"number",templateUrl:"lui/templates/formly/fields/number.html"}),a.setType({name:"email",templateUrl:"lui/templates/formly/fields/email.html"}),a.setType({name:"date",templateUrl:"lui/templates/formly/fields/date.html"}),a.setType({name:"daterange",templateUrl:"lui/templates/formly/fields/daterange.html"}),a.setType({name:"select",templateUrl:"lui/templates/formly/fields/select.html"}),a.setType({name:"checkbox",templateUrl:"lui/templates/formly/fields/checkbox.html"}),a.setType({name:"radio",templateUrl:"lui/templates/formly/fields/radio.html"}),a.setType({name:"picture",templateUrl:"lui/templates/formly/fields/picture.html"}),a.setType({name:"portrait",templateUrl:"lui/templates/formly/fields/portrait.html"}),a.setType({name:"user",templateUrl:"lui/templates/formly/fields/user.html"}),a.setType({name:"user_multiple",templateUrl:"lui/templates/formly/fields/user-multiple.html"}),a.setType({name:"api_select",templateUrl:"lui/templates/formly/fields/api-select.html"}),a.setType({name:"api_select_multiple",templateUrl:"lui/templates/formly/fields/api-select-multiple.html"}),a.setType({name:"iban",templateUrl:"lui/templates/formly/fields/iban.html"}),a.setType({name:"department",templateUrl:"lui/templates/formly/fields/department.html"})}])}(Lui||(Lui={}));var lui;!function(a){"use strict"}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=25,c=function(){function a(){this.restrict="AE",this.templateUrl="lui/templates/formly/inputs/api-select.html",this.scope={api:"=",filter:"=",orderBy:"=",placeholder:"@",allowClear:"="},this.controller=e.IID}return a.factory=function(){var b=function(){return new a};return b},a.prototype.link=function(a,b){a.onDropdownToggle=function(a){a?b.addClass("ng-open"):b.removeClass("ng-open")}},a.IID="luidApiSelect",a}(),d=function(){function a(){this.restrict="AE",this.templateUrl="lui/templates/formly/inputs/api-select-multiple.html",this.scope={api:"=",filter:"=",orderBy:"=",placeholder:"@"},this.controller=e.IID}return a.factory=function(){var b=function(){return new a};return b},a.prototype.link=function(a,b){a.onDropdownToggle=function(a){a?b.addClass("ng-open"):b.removeClass("ng-open")}},a.IID="luidApiSelectMultiple",a}(),e=function(){function a(a,c,d){function e(){g&&c.cancel(g),g=c(function(){a.refresh(""),g=void 0},250)}var f=this;this.offset=0;var g;a.$watch("filter",function(){e()}),a.$watch("api",function(){e()}),a.$watch("order",function(){e()}),a.refresh=function(c){f.offset=0;var e="0,"+b;d.get(c,a.api,a.filter,e,a.orderBy).then(function(b){a.choices=b,f.offset=a.choices.length})};var h;a.loadMore=function(c){if(!h){var e=f.offset+","+(f.offset+b);a.choices.push({id:0,loading:!0,name:""}),h=d.get(c,a.api,a.filter,e,a.orderBy).then(function(b){a.choices=_.chain(a.choices).reject(function(a){return a.loading}).union(b).uniq(function(a){return a.id}).value(),f.offset=a.choices.length,h=void 0},function(){h=void 0})}}}return a.IID="luidApiSelectController",a.$inject=["$scope","$timeout","luisStandardApiService"],a}();angular.module("lui").controller(e.IID,e),angular.module("lui").directive(c.IID,c.factory()),angular.module("lui").directive(d.IID,d.factory())}(b=a.apiselect||(a.apiselect={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a){this.$http=a}return a.prototype.get=function(a,b,c,d,e){var f=a?"name=like,"+a:void 0,g=d?"paging="+d:void 0,h="fields=id,name",i=e?"orderBy="+e:void 0,j=_.reject([h,f,g,c,i],function(a){return!a}).join("&");return this.$http.get(b+"?"+j).then(function(a){return b.indexOf("/v3/")!==-1?a.data.data.items:a.data.data})},a.IID="luisStandardApiService",a.$inject=["$http"],a}();a.StandardApiService=b,angular.module("lui").service(b.IID,b)}(b=a.apiselect||(a.apiselect={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a,b){this.$scope=a,this.ibanChecker=b,this.initScope()}return a.prototype.setNgModelCtrl=function(a){var b=this;this.ngModelCtrl=a,this.ngModelCtrl.$render=function(){var a=b.getViewValue()?b.getViewValue().replace(" ",""):null;a?(b.$scope.countryCode=a.substring(0,2),b.$scope.controlKey=a.substring(2,4),b.$scope.bban=a.substring(4)):(b.$scope.countryCode="",b.$scope.controlKey="",b.$scope.bban="")},this.ngModelCtrl.$validators.iban=function(){return!b.ngModelCtrl.$viewValue||b.ibanChecker.isValid(a.$viewValue)},this.ngModelCtrl.$validators.maxlength=function(){return!b.ngModelCtrl.$viewValue||b.ngModelCtrl.$viewValue.length<=34}},a.prototype.setInputs=function(a){var b=a.find("input");this.countryInput=angular.element(b[0]),this.controlInput=angular.element(b[1]),this.bbanInput=angular.element(b[2])},a.prototype.initScope=function(){var a=this;this.$scope.updateValue=function(){a.setViewValue(a.$scope.countryCode.toUpperCase()+a.$scope.controlKey.toUpperCase()+a.$scope.bban.toUpperCase())},this.$scope.pasteIban=function(b){var c=b instanceof ClipboardEvent?b:b.originalEvent;a.setViewValue(c.clipboardData.getData("text/plain").replace(/ /g,"")),a.ngModelCtrl.$render(),c.target.blur()},this.$scope.selectInput=function(a){a.target.select()},this.$scope.setTouched=function(){a.setTouched()},this.$scope.controlKeyMappings={8:function(){a.$scope.controlKey||a.focusCountryInput()}},this.$scope.bbanMappings={8:function(){a.$scope.bban||a.focusControlInput()}}},a.prototype.getViewValue=function(){return this.ngModelCtrl.$viewValue},a.prototype.setViewValue=function(a){this.ngModelCtrl.$setViewValue(a),this.ngModelCtrl.$setTouched()},a.prototype.setTouched=function(){this.ngModelCtrl.$setTouched()},a.prototype.focusCountryInput=function(){this.countryInput[0].focus(),this.countryInput[0].selectionStart=this.countryInput[0].selectionEnd},a.prototype.focusControlInput=function(){this.controlInput[0].focus(),this.controlInput[0].selectionStart=this.controlInput[0].selectionEnd},a.IID="luidIbanController",a.$inject=["$scope","iban"],a}();a.LuidIbanController=b,angular.module("lui.iban").controller(b.IID,b)}(b=a.iban||(a.iban={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function b(){this.restrict="AE",this.templateUrl="lui/templates/iban/iban.view.html",this.require=[b.IID,"^ngModel"],this.controller=a.LuidIbanController.IID,this.scope={}}return b.factory=function(){var a=function(){return new b};return a},b.prototype.link=function(a,b,c,d){var e=d[0],f=d[1];e.setNgModelCtrl(f),e.setInputs(b)},b.IID="luidIban",b}();a.LuidIban=b,angular.module("lui.iban").directive(b.IID,b.factory())}(b=a.iban||(a.iban={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict"}(b=a.iban||(a.iban={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict"}(b=a.iban||(a.iban={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(){this.restrict="A"}return a.factory=function(){var b=function(){return new a};return b},a.prototype.link=function(a,b,c){b.on("input",function(a){if(b[0].maxLength&&b[0].value.length===b[0].maxLength){var c=b.next();c.length&&c[0].select()}})},a.IID="luidSelectNext",a}();a.LuidSelectNext=b,angular.module("lui.iban").directive(b.IID,b.factory())}(b=a.iban||(a.iban={}))}(lui||(lui={}));var lui;!function(a){"use strict"}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(){this.controller=c.IID,this.restrict="AE",this.scope={onCropped:"=",onCancelled:"=",croppingRatio:"=",croppingDisabled:"="},this.link=function(a,b,c){var d=function(c){var d=c.currentTarget.files[0],e=new FileReader;e.onload=function(c){a.$apply(function(e){a.image=c.target.result,a.fileName=d.name,a.croppingDisabled?a.onCropped(a.image,a.fileName):a.openCropper(),null!=b[0]&&(b[0].value="")})},e.readAsDataURL(d)};angular.element(b[0]).on("change",d)}}return a.Factory=function(){var b=function(){return new a};return b.$inject=[],b},a.IID="luidImageCropper",a}();a.LuidImageCropper=b;var c=function(){function a(a,b,c,e){a.image="",a.cropped="",a.openCropper=function(){var b={templateUrl:"lui/templates/image-picker/image-cropper.modal.html",controller:d.IID,size:"desktop",resolve:{image:function(){return a.image},fileName:function(){return a.fileName},croppingRatio:function(){return a.croppingRatio},cancelLabel:function(){return e.cancelLabel}}},f=c.open(b);f.result.then(function(b){var c=b.image,d=b.cropped;a.cropped=c;var e=d?a.fileName.substr(0,a.fileName.lastIndexOf("."))+".png":a.fileName;a.onCropped(c,e)},function(){a.onCancelled&&a.onCancelled()})}}return a.IID="luidImageCropperController",a.$inject=["$scope","moment","$uibModal","luisConfig"],a}(),d=function(){function a(a,b,c,d,e,f,g){var h=!1;a.image=d,a.fileName=e,a.cancelLabel=g,a.croppingRatio=f,a.crop=function(){h=!0,b.close({image:a.cropped,cropped:!0})},a.donotcrop=function(){h=!0,b.close({image:a.image,cropped:!1})},a.cancel=function(){h=!0,b.dismiss()},a.$on("modal.closing",function(a){h||a.preventDefault()})}return a.IID="luidImageCropperModalController",a.$inject=["$scope","$uibModalInstance","moment","image","croppingRatio","cancelLabel"],a}();angular.module("lui.crop").directive(b.IID,b.Factory()),angular.module("lui.crop").controller(c.IID,c),angular.module("lui.crop").controller(d.IID,d)}(b=a.imagepicker||(a.imagepicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(b){"use strict";var c=function(){function a(){this.restrict="E",this.templateUrl="lui/templates/image-picker/image-picker.html",this.require=["ngModel",a.IID],this.scope={placeholderUrl:"@",croppingRatio:"=",croppingDisabled:"=",deleteEnabled:"=?",hideEditHint:"=",isDisabled:"="},this.controller=d.IID}return a.factory=function(){var b=function(){return new a};return b},a.prototype.link=function(a,b,c,d){var e=d[0],f=d[1];f.setNgModelCtrl(e),f.setPlaceholder(a.placeholderUrl),f.setPopoverTrigger(b,a),f.setElements(b)},a.IID="luidImagePicker",a}(),d=function(){function b(a,b,c){var d=this;this.$scope=a,this.$scope.deleteEnabled=null==this.$scope.deleteEnabled||this.$scope.deleteEnabled,a.setTouched=function(){d.ngModelCtrl.$setTouched()},a.uploadNewImage=function(a){c(function(){d.inputElement.click(),d.closePopover()})},a.onCropped=function(c,e){a.uploading=!0,b.postDataURI(c,e).then(function(b){a.uploading=!1,d.setViewValue(b),d.$scope.pictureStyle={"background-image":"url('"+b.href+"')"}},function(b){d.ngModelCtrl.$setTouched(),a.uploading=!1})},a.onCancelled=function(){a.file=void 0,d.ngModelCtrl.$setTouched()},a.onDelete=function(){d.setViewValue(void 0),a.file=void 0,d.$scope.pictureStyle={"background-image":"url('"+d.placeholder+"')"},d.closePopover()}}return b.prototype.setNgModelCtrl=function(a){var b=this;this.ngModelCtrl=a,a.$render=function(){b.$scope.file=b.getViewValue(),b.$scope.file&&b.$scope.file.href?b.$scope.pictureStyle={"background-image":"url('"+b.$scope.file.href+"')"}:b.$scope.pictureStyle={"background-image":"url('"+b.placeholder+"')"}}},b.prototype.setPlaceholder=function(a){this.placeholder=a||"/static/common/images/placeholder-pp.png"},b.prototype.setPopoverTrigger=function(b,c){var d=this,e=function(){d.closePopover()};this.popoverController=new a.popover.ClickoutsideTrigger(b,c,e),c.popover={isOpen:!1},c.togglePopover=function(a){a.preventDefault(),c.file&&c.file.href&&c.deleteEnabled?d.togglePopover(a):d.$scope.uploadNewImage(a)}},b.prototype.setElements=function(a){this.inputElement=a.find("input")[0]},b.prototype.togglePopover=function(a){this.$scope.popover.isOpen?this.closePopover():this.openPopover(a)},b.prototype.closePopover=function(){this.popoverController&&this.popoverController.close()},b.prototype.openPopover=function(a){this.popoverController&&this.popoverController.open(a)},b.prototype.getViewValue=function(){return this.ngModelCtrl.$viewValue},b.prototype.setViewValue=function(a){this.ngModelCtrl.$setTouched(),this.ngModelCtrl.$setViewValue(a),this.$scope.file=a},b.IID="luidImagePickerController",b.$inject=["$scope","uploaderService","$timeout"],b}();angular.module("lui.crop").directive(c.IID,c.factory()),angular.module("lui.crop").controller(d.IID,d)}(b=a.imagepicker||(a.imagepicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";angular.module("lui.crop").config(["$translateProvider",function(a){a.translations("en",{LUIIMGPICKER_UPLOAD_IMAGE:"change picture",LUIIMGPICKER_MODIFY_IMAGE:"modify picture",LUIIMGPICKER_DELETE_IMAGE:"delete picture",LUIIMGCROPPER_CROP:"Crop",LUIIMGCROPPER_DO_NOT_CROP:"Do not crop"}),a.translations("de",{}),a.translations("es",{}),a.translations("fr",{LUIIMGPICKER_UPLOAD_IMAGE:"changer l'image",LUIIMGPICKER_MODIFY_IMAGE:"modifier l'image",LUIIMGPICKER_DELETE_IMAGE:"supprimer l'image",LUIIMGCROPPER_CROP:"Recadrer",LUIIMGCROPPER_DO_NOT_CROP:"Ne pas recadrer"}),a.translations("it",{}),a.translations("nl",{})}])}(b=a.imagepicker||(a.imagepicker={}))}(lui||(lui={}));var lui;!function(a){"use strict"}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a,b){this.message=a,this.details=b}return a}(),c="lui/templates/notify-service/error.html",d="lui/templates/notify-service/warning.html",e="lui/templates/notify-service/success.html",f="lui/templates/notify-service/loading.html",g="lui/templates/notify-service/alert.html",h="lui/templates/notify-service/confirm.html",i=function(){function a(a,b,c){this.duration=a,this.templateUrl=b,this.message=c}return a}(),j=function(a){function b(b){a.call(this,2e4,c,b)}return __extends(b,a),b}(i),k=function(a){function b(b){a.call(this,1e4,d,b)}return __extends(b,a),b}(i),l=function(a){function b(b){a.call(this,5e3,e,b)}return __extends(b,a),b}(i),m=function(a){function b(b,c){a.call(this,864e5,f,c),this.scope=b}return __extends(b,a),b}(i),n=function(){function a(a,b,c,d,e,f,g){this.cgNotify=a,this.$q=b,this.$log=c,this.$rootScope=d,this.$timeout=e,this.$uibModal=f,this.luisConfig=g,this.cgNotify.config({container:this.luisConfig.parentElt,startTop:this.luisConfig.startTop})}return a.prototype.error=function(a,c){this.$log.error(new b(a,c)),this.cgNotify(new j(a))},a.prototype.warning=function(a,c){this.$log.warn(new b(a,c)),this.cgNotify(new k(a))},a.prototype.success=function(a,c){this.$log.log(new b(a,c)),this.cgNotify(new l(a))},a.prototype.alert=function(a,b,c){return this.openModal(g,a,b||this.luisConfig.okLabel,c||this.luisConfig.cancelLabel,!1)},a.prototype.confirm=function(a,b,c){return this.openModal(h,a,b||this.luisConfig.okLabel,c||this.luisConfig.cancelLabel,!this.luisConfig.canDismissConfirm)},a.prototype.loading=function(a,c,d){var e=this,f=this.$rootScope.$new(!0);f.loading=!0,f.calloutClass="light",f.message=c;var g=this.cgNotify(new m(f,c)),h=function(a){e.$timeout(function(){g.close(),f.$destroy()},a)};d&&(f.canCancel=!0,f.cancel=function(){e.$log.warn(new b(c,"user cancelled")),d(),h(0)}),a.then(function(a){f.message=a,f.calloutClass="green",f.loading=!1,h(5e3)},function(a){f.message=a,f.calloutClass="red",f.loading=!1,e.$log.error(new b(c,"")),h(2e4)},function(a){f.message=a})},a.prototype.openModal=function(a,b,c,d,e){return this.$uibModal.open({templateUrl:a,controller:o.IID,size:"mobile",resolve:{message:function(){return b},okLabel:function(){return c},cancelLabel:function(){return d},preventDismiss:function(){return e}}}).result},a.IID="luisNotify",a.$inject=["notify","$q","$log","$rootScope","$timeout","$uibModal","luisConfig"],a}();a.NotifyService=n;var o=function(){function a(a,b,c,d,e,f){var g=this;a.message=c,a.okLabel=d,a.cancelLabel=e,a.ok=function(){g.doClose=!0,b.close(!0)},a.cancel=function(){g.doClose=!0,b.close(!1)},f&&a.$on("modal.closing",function(a){g.doClose||a.preventDefault()})}return a.IID="notifyModalController",a.$inject=["$scope","$uibModalInstance","message","okLabel","cancelLabel","preventDismiss"],a}();angular.module("lui.notify").service(n.IID,n),angular.module("lui.notify").controller(o.IID,o)}(b=a.notify||(a.notify={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a,b,c,d){var e=this;this.totalRequests=0,this.completedRequests=0,this.request=function(a){return e.isCached(a)||e.startRequest(a.method),a},this.requestError=function(a){return e.startRequest("GET"),e.$q.reject(a)},this.response=function(a){return a&&!e.isCached(a.config)&&e.endRequest(e.extractMethod(a)),a},this.responseError=function(a){return e.endRequest("GET"),e.$q.reject(a)},this.isCached=function(a){var b,c=e.$cacheFactory.get("$http");!a.cache||a.cache===!1||"GET"!==a.method&&"JSONP"!==a.method||(b=angular.isObject(a.cache)?a.cache:c);var d=void 0!==b&&void 0!==b.get(a.url);return void 0!==a.cached&&d!==a.cached?a.cached:(a.cached=d,d)},this.extractMethod=function(a){try{return a.config.method}catch(b){return"GET"}},this.startRequest=function(a){e.progressBarService.isListening()?e.progressBarService.getHttpRequestMethods().indexOf(a)>-1&&(0===e.totalRequests&&e.progressBarService.start(),e.totalRequests++):(e.totalRequests=0,e.completedRequests=0)},this.setComplete=function(){e.completeTimeout&&e.$timeout.cancel(e.completeTimeout),e.completeTimeout=e.$timeout(function(){e.progressBarService.complete(),e.totalRequests=0,e.completedRequests=0},200)},this.endRequest=function(a){e.progressBarService.isListening()&&e.progressBarService.getHttpRequestMethods().indexOf(a)>-1&&(e.completedRequests++,e.completedRequests>=e.totalRequests&&e.setComplete())},this.$q=a,this.$cacheFactory=b,this.$timeout=c,this.progressBarService=d}return a.IID="luiHttpInterceptor",a.$inject=["$q","$cacheFactory","$timeout","luisProgressBar"],a}();angular.module("lui").service(b.IID,b)}(b=a.progressbar||(a.progressbar={}))}(lui||(lui={}));var lui;!function(a){"use strict"}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a,b,c,d,e,f){this.latencyThreshold=200,this.httpResquestListening=!1,this.status=0,this.progressBarTemplate='
',this.$document=a,this.$window=b,this.$timeout=c,this.$interval=d,this.$log=e,this.luisConfig=f}return a.prototype.addProgressBar=function(a){void 0===a&&(a="primary"),this.progressbarEl&&this.progressbarEl.remove(),this.progressbarEl=angular.element(this.progressBarTemplate),this.progressbarEl.addClass(a),this.luisConfig.parentElt.append(this.progressbarEl)},a.prototype.startListening=function(a){this.httpResquestListening=!0,a?this.httpRequestMethods=a:this.httpRequestMethods=["GET"],this.setStatus(0)},a.prototype.stopListening=function(){this.httpResquestListening=!1,this.setStatus(0)},a.prototype.isListening=function(){return this.httpResquestListening},a.prototype.getHttpRequestMethods=function(){return this.httpRequestMethods},a.prototype.start=function(){var a=this;this.isStarted||(this.isStarted=!0,this.$timeout.cancel(this.completeTimeout),this.$interval.cancel(this.currentPromiseInterval),this.show(),this.currentPromiseInterval=this.$interval(function(){if(isNaN(a.status))a.$interval.cancel(a.currentPromiseInterval),a.setStatus(0),a.hide();else{var b=100-a.status;b>30?a.setStatus(a.status+.5*Math.sqrt(b)):a.setStatus(a.status+.15*Math.pow(1-Math.sqrt(b),2))}},this.latencyThreshold))},a.prototype.complete=function(){this.$interval.cancel(this.currentPromiseInterval),this.isStarted=!1,this.httpResquestListening=!1,this.setStatus(100),this.hide()},a.prototype.hide=function(){var a=this;this.$timeout(function(){a.progressbarEl&&(a.progressbarEl.removeClass("in"),a.progressbarEl.addClass("out"),a.setStatus(0))},300)},a.prototype.show=function(){this.progressbarEl&&(this.progressbarEl.removeClass("out"),this.progressbarEl.addClass("in"),this.setStatus(0))},a.prototype.setStatus=function(a){this.status=a,this.progressbarEl&&(this.progressbarEl.children().css("width",this.status+"%"),this.progressbarEl.children().attr("data-percentage",this.status))},a.IID="luisProgressBar",a.$inject=["$document","$window","$timeout","$interval","$log","luisConfig"],a}();angular.module("lui").service(b.IID,b)}(b=a.progressbar||(a.progressbar={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";!function(a){a[a.NONE=0]="NONE",a[a.TEXT=1]="TEXT",a[a.SELECT=2]="SELECT",a[a.MULTISELECT=3]="MULTISELECT"}(a.FilterType||(a.FilterType={}));a.FilterType}(b=a.tablegrid||(a.tablegrid={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function b(b,c,d,e){var f=0;c.isSelectable=angular.isDefined(c.selectable),c.internalRowClick=function(a,b){for(var d=a.target,e=!1;!e&&d.nodeName!==a.currentTarget.nodeName;)e=!!d.href||"checkbox"===d.type,d=d.parentElement;e||c.onRowClick({row:b})};var g=function(b){return b.tree.children.length||b.subChildren++,b.tree.children.forEach(function(a){var c=g({depth:b.depth+1,tree:a,subChildren:0,subDepth:0});b.subChildren+=c.subChildren,b.subDepth=Math.max(b.subDepth,c.subDepth)}),b.tree.children.length?b.subDepth++:c.colDefinitions.push(b.tree.node),b.tree.node&&(b.tree.node.rowspan=f-b.depth-b.subDepth,b.tree.node.colspan=b.subChildren,b.tree.children.length||b.tree.node.filterType!==a.FilterType.NONE||b.tree.node.rowspan++,c.headerRows[b.depth]?c.headerRows[b.depth].push(b.tree.node):c.headerRows[b.depth]=[b.tree.node]),b},h=function(a){var b=0;return a.children.forEach(function(a){b=Math.max(b,h(a))}),b+1};c.initFilter=function(){c.filters=[],_.each(c.colDefinitions,function(b,d){_.each(c.datas,function(e){if(c.filters[d]||(c.filters[d]={header:b,selectValues:[],currentValues:[]}),b.filterType===a.FilterType.SELECT||b.filterType===a.FilterType.MULTISELECT){var f=b.getValue(e)+"";b.getFilterValue&&(f=b.getFilterValue(e)+"");var g=f.split("|");_.each(g,function(a){_.contains(c.filters[d].selectValues,a)||c.filters[d].selectValues.push(a)})}}),c.filters[d].selectValues=_.sortBy(c.filters[d].selectValues,function(a){return a?a.toLowerCase():""})})};var i=function(){if(c.FilterTypeEnum={NONE:a.FilterType.NONE,TEXT:a.FilterType.TEXT,SELECT:a.FilterType.SELECT,MULTISELECT:a.FilterType.MULTISELECT},c.headerRows=[],c.bodyRows=[],c.colDefinitions=[],c.allChecked={value:!1},f=h(c.header),g({depth:0,subChildren:0,subDepth:0,tree:c.header}),c.existFixedRow=_.some(c.colDefinitions,function(a){return a.fixed}),c.selected={orderBy:null,reverse:!1},c.defaultOrder){var b=c.defaultOrder.substr(0,1);"-"!==b&&"+"!==b||(c.defaultOrder=c.defaultOrder.substr(1),c.selected.reverse="-"===b);var d=_.find(c.colDefinitions,function(a){return a.label===c.defaultOrder});c.selected.orderBy=d?d:null}_.each(c.datas,function(a){a._luiTableGridRow={isInFilteredDataset:!0},c.isSelectable&&(a._luiTableGridRow.isChecked=!1)})},j=function(){var a=_.filter(c.filteredAndOrderedRows,function(a){return a._luiTableGridRow.isChecked}).length;return 0===a?"":a===c.filteredAndOrderedRows.length?"checked":aa?+t+B-s+"px":+t+B+"px",k.style.width=p+"px",n.style.marginLeft=p+"px",o.style.marginLeft=-p+"px")},F=function(){D(),E()},G=function(a){z=(c.filteredAndOrderedRows.length-a)*v,z>t?(o.style.height=z+"px",l&&(l.style.height=z+"px")):(o.style.height=t+"px",l&&(l.style.height=t+"px"))},H=function(){if(c.filteredAndOrderedRows.length<=p)return c.visibleRows=c.filteredAndOrderedRows,void G(0);var a=yd&&(d=b[a].values.length),_.some(b[a].values,function(a){return""!==a.value})});if(0!==e.length){for(var f=0;f0){var c=d[a.CODES_TO_LANGUAGES[b.culturedLabels[0].cultureCode]].values.length;_.each(a.AVAILABLE_LANGUAGES,function(a){d[a].values.length!==c&&d[a].values.push({value:""})})}}),d):(_.each(a.AVAILABLE_LANGUAGES,function(a){d[a].values.push({value:""})}),d)},b.getEmptyCulturedLists=function(){var b={};return _.each(a.AVAILABLE_LANGUAGES,function(c){b[c]=new a.CulturedList(c)}),b},b.prototype.link=function(a,c,d,e){var f=e[0],g=d.mode;g||(g="lucca"),a.uniqueId=(Math.floor(9e3*Math.random())+1).toString(),a.onInputValueChanged=function(){f.$setViewValue(b.toModel(a.values,g)),f.$setTouched()},f.$render=function(){var c=b.parse(f.$viewValue,g);c&&(a.values=c)}},b.IID="luidTranslationsList",b}();angular.module("lui.translate").directive(b.IID,b.factory())}(b=a.translate||(a.translate={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict"}(b=a.translate||(a.translate={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a){this.restrict="A",this.require=["uiSelect"],this.$timeout=a}return a.factory=function(){var b=function(b){return new a(b)};return b.$inject=["$timeout"],b},a.prototype.link=function(a,b,c,d){var e=this,f=d[0];c.openOn&&a.$on(c.openOn,function(){e.$timeout(function(){f.activate()})})},a.IID="openOn",a}();angular.module("lui.translate").directive(b.IID,b.factory())}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict"}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=[{translationKey:"LUIDUSERPICKER_DEPARTMENT",name:"department.name",icon:"location"},{translationKey:"LUIDUSERPICKER_LEGALENTITY",name:"legalEntity.name",icon:"tree list"},{translationKey:"LUIDUSERPICKER_MAIL",name:"mail",icon:"email"}];a.MAGIC_PAGING=15,a.MAX_SEARCH_LIMIT=1e4;var c=function(){function c(a,b,c){var d=this;this.$scope=a,this.$q=b,this.userPickerService=c,this.userPickerService.setCustomHttpService(a.customHttpService),this.$scope.lastPagingOffset=0,this.$scope.users=new Array,this.userPickerService.getMyId().then(function(a){d.$scope.myId=a,d.refresh().then(function(a){d.initializeScope()})})}return c.prototype.initializeScope=function(){var b=this;this.$scope.$watch("displayMeFirst",function(a,c){if(b.$scope.displayMeFirst&&a){var d=_.findIndex(b.$scope.users,function(a){return a.id===b.$scope.myId});if(d!==-1){var e=b.$scope.users[d];b.$scope.users.splice(d,1),b.$scope.users.unshift(e)}else b.userPickerService.getMe().then(function(a){b.tidyUp([a]).then(function(a){b.$scope.users.unshift(a[0])})})}}),this.$scope.$watch("showFormerEmployees",function(a,c){void 0!==b.$scope.showFormerEmployees&&a!==c&&(b.$scope.$broadcast("toggleFormerEmployees"),b.resetUsers(),b.refresh(b.clue))}),this.$scope.$watchCollection("bypassOperationsFor",function(a,c){void 0!==a&&b.userPickerService.getUsersByIds(a).then(function(a){b.tidyUp(a).then(function(a){_.each(a,function(a){void 0===_.find(b.$scope.users,function(b){return b.id===a.id})&&b.$scope.users.push(a)})})})}),this.$scope.$watch("legalEntityIds",function(a,c){void 0!==b.$scope.legalEntityIds&&a!==c&&(b.resetUsers(),b.refresh(b.clue))}),this.$scope.$watchGroup(["appId","operations"],function(a,c){angular.isDefined(a)&&angular.isDefined(a[0])&&angular.isDefined(a[1])&&a[1].length>0&&a[0]!==c[0]&&!_.isEqual(a[1],c[1])&&(b.resetUsers(),b.refresh())}),this.$scope.find=function(a){b.clue=a,b.resetUsers(),b.refresh(a)},this.$scope.loadMore=function(){b.$scope.loadingMore||(b.$scope.lastPagingOffset+=a.MAGIC_PAGING,b.$scope.loadingMore=!0,b.refresh().then(function(){b.$scope.loadingMore=!1}))}},c.prototype.tidyUp=function(a,c){var d=this;void 0===c&&(c="");var e=new Array,f={},g={};_.each(a,function(a){a.hasLeft=!!a.dtContractEnd&&moment(a.dtContractEnd).isBefore(moment().startOf("day"))}),this.$scope.customInfo&&_.each(a,function(a){a.info=d.$scope.customInfo(a)}),this.$scope.customInfoAsync&&_.each(a,function(a){f[a.id.toString()]=e.push(d.$scope.customInfoAsync(a))-1});var h=this.userPickerService.getHomonyms(a);if(h&&h.length>0){var i=this.$scope.homonymsProperties&&this.$scope.homonymsProperties.length>0?this.$scope.homonymsProperties:b;_.each(h,function(a){g[a.id]=e.push(d.userPickerService.getAdditionalProperties(a,i))-1})}return this.$q.all(e).then(function(b){return h&&h.length>0&&(_.each(a,function(a){angular.isDefined(g[a.id])&&(a.additionalProperties=b[g[a.id.toString()]],a.hasHomonyms=!0)}),a=d.userPickerService.reduceAdditionalProperties(a)),d.$scope.customInfoAsync&&_.each(a,function(a){var c=f[a.id.toString()];angular.isDefined(a.info)&&""!==a.info?a.info=a.info+" "+b[c]:a.info=b[c]}),a})},c.prototype.refresh=function(a){var b=this;return void 0===a&&(a=""),this.getUsers(a).then(function(c){b.tidyUpAndAssign(c,a)})},c.prototype.getUsers=function(b){var c=this;void 0===b&&(b="");var d=a.MAGIC_PAGING,e=this.$scope.lastPagingOffset,f=d,g=e;this.$scope.customFilter&&(f=a.MAX_SEARCH_LIMIT,g=0);var h=function(){return c.userPickerService.getUsers(c.getFilter(b),f,g).then(function(a){return c.$scope.customFilter?_.chain(a).filter(function(a){return c.$scope.customFilter(a)}).rest(e).first(d).value():a})};return this.$q.all([h(),this.userPickerService.getMe()]).then(function(a){var d=a[0],f=a[1];if(!e){if(!b&&c.$scope.displayAllUsers){var g={id:-1,firstName:"",lastName:"",dtContractStart:"",employeeNumber:""};d.unshift(g)}if(!b&&c.$scope.displayMeFirst){var h=_.findIndex(d,function(a){return a.id===c.$scope.myId});h!==-1&&d.splice(h,1),d.unshift(f)}}return d})},c.prototype.tidyUpAndAssign=function(a,b){var c=this;return this.tidyUp(a,b).then(function(a){return c.$scope.users=c.$scope.users||[],(b=c.$scope.users).push.apply(b,_.filter(a,function(a){return!_.any(c.$scope.users,function(b){return b.id===a.id})})),c.$scope.users;var b})},c.prototype.resetUsers=function(){this.$scope.users=[],this.$scope.lastPagingOffset=0},c.prototype.getFilter=function(a){var b=this.$scope,c="formerEmployees="+(b.showFormerEmployees?b.showFormerEmployees.toString():"false")+(b.appId&&b.operations&&b.operations.length>0?"&appinstanceid="+b.appId+"&operations="+b.operations.join(","):"")+(a?"&clue="+a:"")+"&searchByEmployeeNumber="+(b.searchByEmployeeNumber?"true":"false")+(b.legalEntityIds&&b.legalEntityIds.length>0?"&legalEntityIds="+b.legalEntityIds.join(","):"");return c},c.IID="luidUserPickerController",c.$inject=["$scope","$q","userPickerService"],c}();a.LuidUserPickerController=c,angular.module("lui").controller(c.IID,c),angular.module("lui").filter("luifHighlight",["$filter","$translate",function(a,b){return function(c,d,e,f){var g=a("highlight");return(e?''+e+"":"")+(f?""+b.instant(f)+" ":"")+""+g(c,d)+""}}]),angular.module("lui.translate").config(["$translateProvider",function(a){a.translations("en",{LUIDUSERPICKER_FORMEREMPLOYEE:"Left on {{dtContractEnd | luifMoment : 'LL'}}",LUIDUSERPICKER_NORESULTS:"No results",LUIDUSERPICKER_ERR_GET_USERS:"Error while loading users",LUIDUSERPICKER_OVERFLOW:"{{cnt}} displayed results of {{all}}",LUIDUSERPICKER_DEPARTMENT:"Department",LUIDUSERPICKER_LEGALENTITY:"Legal entity",LUIDUSERPICKER_EMPLOYEENUMBER:"Employee number",LUIDUSERPICKER_MAIL:"Email",LUIDUSERPICKER_ME:"Me:",LUIDUSERPICKER_ALL:"All users"}),a.translations("de",{LUIDUSERPICKER_FORMEREMPLOYEE:"Verließ die {{dtContractEnd | luifMoment : 'LL'}}",LUIDUSERPICKER_NORESULTS:"Keine Ergebnisse",LUIDUSERPICKER_ERR_GET_USERS:"Fehler",LUIDUSERPICKER_OVERFLOW:"Es werden {{cnt}} auf {{all}} Benutzernamen",LUIDUSERPICKER_DEPARTMENT:"Abteilung",LUIDUSERPICKER_LEGALENTITY:"Rechtsträger",LUIDUSERPICKER_EMPLOYEENUMBER:"Betriebsnummer",LUIDUSERPICKER_MAIL:"E-mail",LUIDUSERPICKER_ME:"Mir:",LUIDUSERPICKER_ALL:"Alle Benutzer"}),a.translations("fr",{LUIDUSERPICKER_FORMEREMPLOYEE:"Parti(e) le {{dtContractEnd | luifMoment : 'LL'}}",LUIDUSERPICKER_NORESULTS:"Aucun résultat",LUIDUSERPICKER_ERR_GET_USERS:"Erreur lors de la récupération des utilisateurs",LUIDUSERPICKER_OVERFLOW:"{{cnt}} résultats affichés sur {{all}}",LUIDUSERPICKER_DEPARTMENT:"Service",LUIDUSERPICKER_LEGALENTITY:"Entité légale",LUIDUSERPICKER_EMPLOYEENUMBER:"Matricule",LUIDUSERPICKER_MAIL:"Email",LUIDUSERPICKER_ME:"Moi :",LUIDUSERPICKER_ALL:"Tous les utilisateurs"})}])}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function b(){this.restrict="E",this.templateUrl="lui/templates/user-picker/user-picker.html",this.require=["ngModel",b.IID],this.scope={placeholder:"@",onSelect:"&",onRemove:"&",allowClear:"=?",controlDisabled:"=",showFormerEmployees:"=",homonymsProperties:"=",customFilter:"=",appId:"=",operations:"=",customInfo:"=",customInfoAsync:"=",displayMeFirst:"=",displayAllUsers:"=",customHttpService:"=",bypassOperationsFor:"=",searchByEmployeeNumber:"=",legalEntityIds:"="},this.controller=a.LuidUserPickerController.IID}return b.factory=function(){return function(){return new b}},b.prototype.link=function(a,b,c,d){a.onOpen=function(a){a?b.addClass("ng-open"):b.removeClass("ng-open")}},b.IID="luidUserPicker",b}();angular.module("lui.translate").directive(b.IID,b.factory())}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function b(){this.restrict="E",this.templateUrl="lui/templates/user-picker/user-picker.multiple.html",this.require=["ngModel",b.IID],this.scope={placeholder:"@",onSelect:"&",onRemove:"&",allowClear:"=?",controlDisabled:"=",showFormerEmployees:"=",homonymsProperties:"=",customFilter:"=",appId:"=",operations:"=",customInfo:"=",customInfoAsync:"=",displayMeFirst:"=",customHttpService:"=",bypassOperationsFor:"=",legalEntityIds:"="},this.controller=a.LuidUserPickerController.IID}return b.factory=function(){return function(){return new b}},b.prototype.link=function(a,b,c,d){a.onOpen=function(a){a?b.addClass("ng-open"):b.removeClass("ng-open")}},b.IID="luidUserPickerMultiple",b}();angular.module("lui.translate").directive(b.IID,b.factory())}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict"}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function b(a,b,c){this.meApiUrl="/api/v3/users/me",this.userLookUpApiUrl="/api/v3/users/find",this.userApiUrl="/api/v3/users",this.userLookupFields="fields=id,firstName,lastName,dtContractStart,dtContractEnd,employeeNumber",this.$http=a,this.defaultHttpService=a,this.$q=b,this.stripAccents=c("luifStripAccents")}return b.prototype.getMyId=function(){return this.getMe().then(function(a){return a.id})},b.prototype.getMe=function(){var a=this;return void 0!==this.meCache?this.$q.resolve(this.meCache):this.$http.get(this.meApiUrl+"?"+this.userLookupFields).then(function(b){return a.meCache=b.data.data,a.meCache})["catch"](function(a){})},b.prototype.getHomonyms=function(a){var b=this;return _.chain(a).groupBy(function(a){return b.concatName(a)}).filter(function(a){return a.length>1}).flatten().value()},b.prototype.getUsers=function(b,c,d){void 0===c&&(c=a.MAGIC_PAGING),void 0===d&&(d=0);var e="paging="+[d,c].join(",");return this.$http.get(this.userLookUpApiUrl+"?"+b+"&"+e+"&"+this.userLookupFields).then(function(a){return a.data.data.items})},b.prototype.getUserById=function(a){return this.$http.get(this.userApiUrl+"?id="+a.toString()+"&"+this.userLookupFields).then(function(a){var b=a.data.data.items;if(b&&0!==b.length)return b[0]})},b.prototype.getUsersByIds=function(a){var b=this,c=new Array;return _.each(a,function(a){c.push(b.getUserById(a))}),this.$q.all(c)},b.prototype.getAdditionalProperties=function(a,b){var c=this,d=_.map(b,function(a){return a.name}).join(",");return this.$http.get(this.userApiUrl+"?id="+a.id.toString()+"&fields="+d).then(function(a){var d=a.data.data.items,e=new Array;if(d&&d.length){var f=d[0];_.each(b,function(a){var b=c.getProperty(f,a.name);b&&e.push({translationKey:a.translationKey,name:a.name,icon:a.icon,value:b})})}return e})},b.prototype.reduceAdditionalProperties=function(a){var b=this,c=_.chain(a).groupBy(function(a){return b.concatName(a)}).filter(function(a){return a.length>1}).value();return 0===c.length?a:(_.each(c,function(a){var b=new Array,c=_.chain(a).map(function(a){return a.additionalProperties}).flatten().groupBy(function(a){return a.name}).value();_.each(c,function(a){var c=_.uniq(a,function(a){return a.value});1===c.length&&b.push(a[0].name)}),_.each(b,function(b){_.each(a,function(a){var c=_.findIndex(a.additionalProperties,function(a){return a.name===b});a.additionalProperties.splice(c,1)})})}),a)},b.prototype.setCustomHttpService=function(a){this.$http=a?a:this.defaultHttpService},b.prototype.getProperty=function(a,b){var c=b.split("."),d=a;return _.each(c,function(a){d=d&&d[a]?d[a]:void 0}),d},b.prototype.concatName=function(a){return this.stripAccents(a.firstName.toLowerCase())+this.stripAccents(a.lastName.toLowerCase())},b.IID="userPickerService",b.$inject=["$http","$q","$filter"],b}();angular.module("lui").service(b.IID,b)}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){"use strict"}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a){this.format=a||"moment"}return a.prototype.parseValue=function(a){switch(this.format){case"moment":return this.parseMoment(a);case"date":return this.parseDate(a);default:return this.parseString(a)}},a.prototype.formatValue=function(a){if(!a)return a;switch(this.format){case"moment":return this.formatMoment(a);case"date":return this.formatDate(a);default:return this.formatString(a)}},a.prototype.parseMoment=function(a){return a?moment(a):void 0},a.prototype.parseDate=function(a){return a?moment(a):void 0},a.prototype.parseString=function(a){return a&&moment(a,this.format).isValid()?moment(a,this.format):void 0},a.prototype.formatMoment=function(a){return moment(a)},a.prototype.formatDate=function(a){return a.toDate()},a.prototype.formatString=function(a){return a.format(this.format)},a}();a.MomentFormatter=b}(b=a.formatter||(a.formatter={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=100,c=function(){function a(a,c,d){function e(a){i.clickedOutside?i.clickedOutside():i.close()}function f(){e(),i.$scope.$digest()}function g(a){a.stopPropagation()}var h=this;this.elt=a,this.body=angular.element(document.getElementsByTagName("body")[0]),this.$scope=c,this.clickedOutside=d;var i=this;this.open=function(a){h.$scope.popover.isOpen=!0,setTimeout(function(){h.body.on("click",f),h.elt.on("click",g)},b)},this.close=function(a){h.$scope.popover.isOpen=!1,h.body&&(h.body.off("click",f),h.elt.off("click",g))}}return a.prototype.toggle=function(a){this.$scope.popover.isOpen?this.close(a):this.open(a)},a}();a.ClickoutsideTrigger=c}(b=a.popover||(a.popover={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";angular.module("lui").directive("luidOnScrollBottom",function(){return{restrict:"A",scope:{luidOnScrollBottom:"&"},link:function(a,b){b.bind("scroll",function(b){var c=b.target||event.srcElement,d=c.scrollHeight-c.clientHeight;Math.abs(d-c.scrollTop)<2&&a.luidOnScrollBottom&&a.luidOnScrollBottom()})}}})}(b=a.scroll||(a.scroll={}))}(lui||(lui={}));var lui;!function(a){"use strict"}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a,b,c,d){this.mainApiUrl="/api/files",this.$http=a,this.$q=b,this._=c,this.moment=d}return a.prototype.postFromUrl=function(a,b){var c=this,d=this.$q.defer(),e=new XMLHttpRequest;return e.open("GET",a,!0),e.responseType="arraybuffer",e.onload=function(a){var f=new Blob([e.response],{type:"image/jpeg"});c.postBlob(f,b).then(function(a){d.resolve(a)},function(a){d.reject(a.data.Message)})},e.send(),d.promise},a.prototype.postDataURI=function(a,b){var c=this.dataURItoBlob(a);return this.postBlob(c,b)},a.prototype.postBlob=function(a,b){var c=this.$q.defer(),d=this.mainApiUrl,e=new FormData;return e.append(b.substring(0,b.lastIndexOf(".")),a,b),this.$http({method:"POST",url:d,data:e,headers:{"Content-Type":void 0,Accept:void 0},transformRequest:angular.identity}).then(function(a){c.resolve(a.data.data)},function(a){c.reject(a.data.Message)}),c.promise},a.prototype.dataURItoBlob=function(a){for(var b=atob(a.split(",")[1]),c=a.split(",")[0].split(":")[1].split(";")[0],d=new ArrayBuffer(b.length),e=new Uint8Array(d),f=0;f
{{ calendar.date | luifMoment : calendar.currentYear ? "MMMM" : "MMMM - YYYY" }} {{ calendar.date | luifMoment : "YYYY" }} {{ calendar.date.year() }} - {{ calendar.date.year() + 11 }}
{{ ::dayLabel }}
{{ ::day.dayNum }}
  • {{ m.date | luifMoment : "MMM" }}
  • {{ y.date | luifMoment : "YYYY" }}
'),a.put("lui/templates/date-picker/datepicker-popup.html",'
'),a.put("lui/templates/date-picker/daterangepicker-popover.html",'
{{ calendar.date | luifMoment : calendar.currentYear ? "MMMM" : "MMMM - YYYY" }} {{ calendar.date | luifMoment : "YYYY" }} {{ calendar.date.year() }} - {{ calendar.date.year() + 11 }}
{{ ::dayLabel }}
{{ ::day.dayNum }}
  • {{ m.date | luifMoment : "MMM" }}
  • {{ y.date | luifMoment : "YYYY" }}
'),a.put("lui/templates/date-picker/daterangepicker.html",'
'),a.put("lui/templates/department-picker/department-picker.html",'{{ $select.selected.name }}
'),a.put("lui/templates/formly/fields/api-select-multiple.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/api-select.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'), +c.initFilter(),null!==c.selected.orderBy&&c.orderBySelectedHeader(),_.each(c.datas,function(a){a._luiTableGridRow={isInFilteredDataset:!0}}),c.updateViewAfterFiltering())}),window.addEventListener("resize",function(){d.$timeout.cancel(q),q=d.$timeout(function(){F()},100)}),n.addEventListener("scroll",function(a){(c.existFixedRow||f.selectable)&&(m.scrollTop=n.scrollTop),i[0].style.left=-n.scrollLeft+"px",c.visibleRows.length!==c.filteredAndOrderedRows.length&&(H(),c.$digest()),y=n.scrollTop})},0)},this.$timeout=c}return a.Factory=function(){var b=function(b){return new a(b)};return b.$inject=["$timeout"],b},a.defaultHeight=20,a.IID="luidTableGrid",a}();a.LuidTableGrid=c,angular.module("lui.tablegrid").directive(c.IID,c.Factory())}(b=a.tablegrid||(a.tablegrid={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";angular.module("lui.tablegrid").config(["$translateProvider",function(a){a.translations("en",{SELECT_ITEM:"Select an item",SELECT_ITEMS:"Select items"}),a.translations("de",{}),a.translations("es",{}),a.translations("fr",{SELECT_ITEM:"Sélectionnez un élément",SELECT_ITEMS:"Sélectionnez des éléments"}),a.translations("it",{}),a.translations("nl",{})}])}(b=a.tablegrid||(a.tablegrid={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict"}(b=a.tablegrid||(a.tablegrid={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";a.AVAILABLE_LANGUAGES=["en","fr","de","es","it","nl","pt"],a.LANGUAGES_TO_CODE={en:1033,de:1031,es:1034,fr:1036,it:1040,nl:2067,pt:2070},a.CODES_TO_LANGUAGES={1033:"en",1031:"de",1034:"es",1036:"fr",1040:"it",2067:"nl",2070:"pt"};var b=function(){function a(a){this.culture=a,this.originalId=void 0,this.values=new Array}return a}();a.CulturedList=b}(b=a.translate||(a.translate={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function b(b,c,d){var e=this;this.$scope=b,b.currentCulture=c.preferredLanguage(),b.currentCulture||(b.currentCulture="en"),b.cultures=a.AVAILABLE_LANGUAGES;var f=_.indexOf(b.cultures,b.currentCulture);f!==-1&&(b.cultures.splice(f,1),b.cultures.unshift(b.currentCulture)),b.selectedCulture=b.currentCulture,b.values={},b.selectCulture=function(a){b.selectedCulture=a},b.addValue=function(){_.each(a.AVAILABLE_LANGUAGES,function(a){b.values[a].values.push({value:""})})};var g=function(c){_.each(a.AVAILABLE_LANGUAGES,function(a){b.values[a].values.splice(c,1)}),0===b.values[a.AVAILABLE_LANGUAGES[0]].values.length&&_.each(a.AVAILABLE_LANGUAGES,function(a){b.values[a].values.push({value:""})}),b.onInputValueChanged()};b.deleteValue=function(a){return void 0===b.deletionCallback?void g(a):void b.deletionCallback().then(function(b){b&&g(a)})},b.isAddValueDisabled=function(){return!_.some(a.AVAILABLE_LANGUAGES,function(a){var b=e.$scope.values[a].values;return""!==b[b.length-1].value})},b.onPaste=function(c,d){if(!b.isDisabled){var e=c instanceof ClipboardEvent?c:c.originalEvent,f=_.reject(e.clipboardData.getData("text/plain").split(/\r\n|\r|\n/g),function(a){return""===a});if(1!==f.length){for(var g=0;gd&&(d=b[a].values.length),_.some(b[a].values,function(a){return""!==a.value})});if(0!==e.length){for(var f=0;f0){var c=d[a.CODES_TO_LANGUAGES[b.culturedLabels[0].cultureCode]].values.length;_.each(a.AVAILABLE_LANGUAGES,function(a){d[a].values.length!==c&&d[a].values.push({value:""})})}}),d):(_.each(a.AVAILABLE_LANGUAGES,function(a){d[a].values.push({value:""})}),d)},b.getEmptyCulturedLists=function(){var b={};return _.each(a.AVAILABLE_LANGUAGES,function(c){b[c]=new a.CulturedList(c)}),b},b.prototype.link=function(a,c,d,e){var f=e[0],g=d.mode;g||(g="lucca"),a.uniqueId=(Math.floor(9e3*Math.random())+1).toString(),a.onInputValueChanged=function(){f.$setViewValue(b.toModel(a.values,g)),f.$setTouched()},f.$render=function(){var c=b.parse(f.$viewValue,g);c&&(a.values=c)}},b.IID="luidTranslationsList",b}();angular.module("lui.translate").directive(b.IID,b.factory())}(b=a.translate||(a.translate={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict"}(b=a.translate||(a.translate={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a){this.restrict="A",this.require=["uiSelect"],this.$timeout=a}return a.factory=function(){var b=function(b){return new a(b)};return b.$inject=["$timeout"],b},a.prototype.link=function(a,b,c,d){var e=this,f=d[0];c.openOn&&a.$on(c.openOn,function(){e.$timeout(function(){f.activate()})})},a.IID="openOn",a}();angular.module("lui.translate").directive(b.IID,b.factory())}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict"}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=[{translationKey:"LUIDUSERPICKER_DEPARTMENT",name:"department.name",icon:"location"},{translationKey:"LUIDUSERPICKER_LEGALENTITY",name:"legalEntity.name",icon:"tree list"},{translationKey:"LUIDUSERPICKER_MAIL",name:"mail",icon:"email"}];a.MAGIC_PAGING=15,a.MAX_SEARCH_LIMIT=1e4;var c=function(){function c(a,b,c){var d=this;this.$scope=a,this.$q=b,this.userPickerService=c,this.userPickerService.setCustomHttpService(a.customHttpService),this.$scope.lastPagingOffset=0,this.$scope.users=new Array,this.userPickerService.getMyId().then(function(a){d.$scope.myId=a,d.refresh().then(function(a){d.initializeScope()})})}return c.prototype.initializeScope=function(){var b=this;this.$scope.$watch("displayMeFirst",function(a,c){if(b.$scope.displayMeFirst&&a){var d=_.findIndex(b.$scope.users,function(a){return a.id===b.$scope.myId});if(d!==-1){var e=b.$scope.users[d];b.$scope.users.splice(d,1),b.$scope.users.unshift(e)}else b.userPickerService.getMe().then(function(a){b.tidyUp([a]).then(function(a){b.$scope.users.unshift(a[0])})})}}),this.$scope.$watch("showFormerEmployees",function(a,c){void 0!==b.$scope.showFormerEmployees&&a!==c&&(b.$scope.$broadcast("toggleFormerEmployees"),b.resetUsers(),b.refresh(b.clue))}),this.$scope.$watchCollection("bypassOperationsFor",function(a,c){void 0!==a&&b.userPickerService.getUsersByIds(a).then(function(a){b.tidyUp(a).then(function(a){_.each(a,function(a){void 0===_.find(b.$scope.users,function(b){return b.id===a.id})&&b.$scope.users.push(a)})})})}),this.$scope.$watch("legalEntityIds",function(a,c){void 0!==b.$scope.legalEntityIds&&a!==c&&(b.resetUsers(),b.refresh(b.clue))}),this.$scope.$watchGroup(["appId","operations"],function(a,c){angular.isDefined(a)&&angular.isDefined(a[0])&&angular.isDefined(a[1])&&a[1].length>0&&a[0]!==c[0]&&!_.isEqual(a[1],c[1])&&(b.resetUsers(),b.refresh())}),this.$scope.find=function(a){b.clue=a,b.resetUsers(),b.refresh(a)},this.$scope.loadMore=function(){b.$scope.loadingMore||(b.$scope.lastPagingOffset+=a.MAGIC_PAGING,b.$scope.loadingMore=!0,b.refresh().then(function(){b.$scope.loadingMore=!1}))}},c.prototype.tidyUp=function(a,c){var d=this;void 0===c&&(c="");var e=new Array,f={},g={};_.each(a,function(a){a.hasLeft=!!a.dtContractEnd&&moment(a.dtContractEnd).isBefore(moment().startOf("day"))}),this.$scope.customInfo&&_.each(a,function(a){a.info=d.$scope.customInfo(a)}),this.$scope.customInfoAsync&&_.each(a,function(a){f[a.id.toString()]=e.push(d.$scope.customInfoAsync(a))-1});var h=this.userPickerService.getHomonyms(a);if(h&&h.length>0){var i=this.$scope.homonymsProperties&&this.$scope.homonymsProperties.length>0?this.$scope.homonymsProperties:b;_.each(h,function(a){g[a.id]=e.push(d.userPickerService.getAdditionalProperties(a,i))-1})}return this.$q.all(e).then(function(b){return h&&h.length>0&&(_.each(a,function(a){angular.isDefined(g[a.id])&&(a.additionalProperties=b[g[a.id.toString()]],a.hasHomonyms=!0)}),a=d.userPickerService.reduceAdditionalProperties(a)),d.$scope.customInfoAsync&&_.each(a,function(a){var c=f[a.id.toString()];angular.isDefined(a.info)&&""!==a.info?a.info=a.info+" "+b[c]:a.info=b[c]}),a})},c.prototype.refresh=function(a){var b=this;return void 0===a&&(a=""),this.getUsers(a).then(function(c){b.tidyUpAndAssign(c,a)})},c.prototype.getUsers=function(b){var c=this;void 0===b&&(b="");var d=a.MAGIC_PAGING,e=this.$scope.lastPagingOffset,f=d,g=e;this.$scope.customFilter&&(f=a.MAX_SEARCH_LIMIT,g=0);var h=function(){return c.userPickerService.getUsers(c.getFilter(b),f,g).then(function(a){return c.$scope.customFilter?_.chain(a).filter(function(a){return c.$scope.customFilter(a)}).rest(e).first(d).value():a})};return this.$q.all([h(),this.userPickerService.getMe()]).then(function(a){var d=a[0],f=a[1];if(!e){if(!b&&c.$scope.displayAllUsers){var g={id:-1,firstName:"",lastName:"",dtContractStart:"",employeeNumber:""};d.unshift(g)}if(!b&&c.$scope.displayMeFirst){var h=_.findIndex(d,function(a){return a.id===c.$scope.myId});h!==-1&&d.splice(h,1),d.unshift(f)}}return d})},c.prototype.tidyUpAndAssign=function(a,b){var c=this;return this.tidyUp(a,b).then(function(a){return c.$scope.users=c.$scope.users||[],(b=c.$scope.users).push.apply(b,_.filter(a,function(a){return!_.any(c.$scope.users,function(b){return b.id===a.id})})),c.$scope.users;var b})},c.prototype.resetUsers=function(){this.$scope.users=[],this.$scope.lastPagingOffset=0},c.prototype.getFilter=function(a){var b=this.$scope,c="formerEmployees="+(b.showFormerEmployees?b.showFormerEmployees.toString():"false")+(b.appId&&b.operations&&b.operations.length>0?"&appinstanceid="+b.appId+"&operations="+b.operations.join(","):"")+(a?"&clue="+a:"")+"&searchByEmployeeNumber="+(b.searchByEmployeeNumber?"true":"false")+(b.legalEntityIds&&b.legalEntityIds.length>0?"&legalEntityIds="+b.legalEntityIds.join(","):"");return c},c.IID="luidUserPickerController",c.$inject=["$scope","$q","userPickerService"],c}();a.LuidUserPickerController=c,angular.module("lui").controller(c.IID,c),angular.module("lui").filter("luifHighlight",["$filter","$translate",function(a,b){return function(c,d,e,f){var g=a("highlight");return(e?''+e+"":"")+(f?""+b.instant(f)+" ":"")+""+g(c,d)+""}}]),angular.module("lui.translate").config(["$translateProvider",function(a){a.translations("en",{LUIDUSERPICKER_FORMEREMPLOYEE:"Left on {{dtContractEnd | luifMoment : 'LL'}}",LUIDUSERPICKER_NORESULTS:"No results",LUIDUSERPICKER_ERR_GET_USERS:"Error while loading users",LUIDUSERPICKER_OVERFLOW:"{{cnt}} displayed results of {{all}}",LUIDUSERPICKER_DEPARTMENT:"Department",LUIDUSERPICKER_LEGALENTITY:"Legal entity",LUIDUSERPICKER_EMPLOYEENUMBER:"Employee number",LUIDUSERPICKER_MAIL:"Email",LUIDUSERPICKER_ME:"Me:",LUIDUSERPICKER_ALL:"All users"}),a.translations("de",{LUIDUSERPICKER_FORMEREMPLOYEE:"Verließ die {{dtContractEnd | luifMoment : 'LL'}}",LUIDUSERPICKER_NORESULTS:"Keine Ergebnisse",LUIDUSERPICKER_ERR_GET_USERS:"Fehler",LUIDUSERPICKER_OVERFLOW:"Es werden {{cnt}} auf {{all}} Benutzernamen",LUIDUSERPICKER_DEPARTMENT:"Abteilung",LUIDUSERPICKER_LEGALENTITY:"Rechtsträger",LUIDUSERPICKER_EMPLOYEENUMBER:"Betriebsnummer",LUIDUSERPICKER_MAIL:"E-mail",LUIDUSERPICKER_ME:"Mir:",LUIDUSERPICKER_ALL:"Alle Benutzer"}),a.translations("fr",{LUIDUSERPICKER_FORMEREMPLOYEE:"Parti(e) le {{dtContractEnd | luifMoment : 'LL'}}",LUIDUSERPICKER_NORESULTS:"Aucun résultat",LUIDUSERPICKER_ERR_GET_USERS:"Erreur lors de la récupération des utilisateurs",LUIDUSERPICKER_OVERFLOW:"{{cnt}} résultats affichés sur {{all}}",LUIDUSERPICKER_DEPARTMENT:"Service",LUIDUSERPICKER_LEGALENTITY:"Entité légale",LUIDUSERPICKER_EMPLOYEENUMBER:"Matricule",LUIDUSERPICKER_MAIL:"Email",LUIDUSERPICKER_ME:"Moi :",LUIDUSERPICKER_ALL:"Tous les utilisateurs"})}])}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function b(){this.restrict="E",this.templateUrl="lui/templates/user-picker/user-picker.html",this.require=["ngModel",b.IID],this.scope={placeholder:"@",onSelect:"&",onRemove:"&",allowClear:"=?",controlDisabled:"=",showFormerEmployees:"=",homonymsProperties:"=",customFilter:"=",appId:"=",operations:"=",customInfo:"=",customInfoAsync:"=",displayMeFirst:"=",displayAllUsers:"=",customHttpService:"=",bypassOperationsFor:"=",searchByEmployeeNumber:"=",legalEntityIds:"="},this.controller=a.LuidUserPickerController.IID}return b.factory=function(){return function(){return new b}},b.prototype.link=function(a,b,c,d){a.onOpen=function(a){a?b.addClass("ng-open"):b.removeClass("ng-open")}},b.IID="luidUserPicker",b}();angular.module("lui.translate").directive(b.IID,b.factory())}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function b(){this.restrict="E",this.templateUrl="lui/templates/user-picker/user-picker.multiple.html",this.require=["ngModel",b.IID],this.scope={placeholder:"@",onSelect:"&",onRemove:"&",allowClear:"=?",controlDisabled:"=",showFormerEmployees:"=",homonymsProperties:"=",customFilter:"=",appId:"=",operations:"=",customInfo:"=",customInfoAsync:"=",displayMeFirst:"=",customHttpService:"=",bypassOperationsFor:"=",legalEntityIds:"="},this.controller=a.LuidUserPickerController.IID}return b.factory=function(){return function(){return new b}},b.prototype.link=function(a,b,c,d){a.onOpen=function(a){a?b.addClass("ng-open"):b.removeClass("ng-open")}},b.IID="luidUserPickerMultiple",b}();angular.module("lui.translate").directive(b.IID,b.factory())}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict"}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function b(a,b,c){this.meApiUrl="/api/v3/users/me",this.userLookUpApiUrl="/api/v3/users/find",this.userApiUrl="/api/v3/users",this.userLookupFields="fields=id,firstName,lastName,dtContractStart,dtContractEnd,employeeNumber",this.$http=a,this.defaultHttpService=a,this.$q=b,this.stripAccents=c("luifStripAccents")}return b.prototype.getMyId=function(){return this.getMe().then(function(a){return a.id})},b.prototype.getMe=function(){var a=this;return void 0!==this.meCache?this.$q.resolve(this.meCache):this.$http.get(this.meApiUrl+"?"+this.userLookupFields).then(function(b){return a.meCache=b.data.data,a.meCache})["catch"](function(a){})},b.prototype.getHomonyms=function(a){var b=this;return _.chain(a).groupBy(function(a){return b.concatName(a)}).filter(function(a){return a.length>1}).flatten().value()},b.prototype.getUsers=function(b,c,d){void 0===c&&(c=a.MAGIC_PAGING),void 0===d&&(d=0);var e="paging="+[d,c].join(",");return this.$http.get(this.userLookUpApiUrl+"?"+b+"&"+e+"&"+this.userLookupFields).then(function(a){return a.data.data.items})},b.prototype.getUserById=function(a){return this.$http.get(this.userApiUrl+"?id="+a.toString()+"&"+this.userLookupFields).then(function(a){var b=a.data.data.items;if(b&&0!==b.length)return b[0]})},b.prototype.getUsersByIds=function(a){var b=this,c=new Array;return _.each(a,function(a){c.push(b.getUserById(a))}),this.$q.all(c)},b.prototype.getAdditionalProperties=function(a,b){var c=this,d=_.map(b,function(a){return a.name}).join(",");return this.$http.get(this.userApiUrl+"?id="+a.id.toString()+"&fields="+d).then(function(a){var d=a.data.data.items,e=new Array;if(d&&d.length){var f=d[0];_.each(b,function(a){var b=c.getProperty(f,a.name);b&&e.push({translationKey:a.translationKey,name:a.name,icon:a.icon,value:b})})}return e})},b.prototype.reduceAdditionalProperties=function(a){var b=this,c=_.chain(a).groupBy(function(a){return b.concatName(a)}).filter(function(a){return a.length>1}).value();return 0===c.length?a:(_.each(c,function(a){var b=new Array,c=_.chain(a).map(function(a){return a.additionalProperties}).flatten().groupBy(function(a){return a.name}).value();_.each(c,function(a){var c=_.uniq(a,function(a){return a.value});1===c.length&&b.push(a[0].name)}),_.each(b,function(b){_.each(a,function(a){var c=_.findIndex(a.additionalProperties,function(a){return a.name===b});a.additionalProperties.splice(c,1)})})}),a)},b.prototype.setCustomHttpService=function(a){this.$http=a?a:this.defaultHttpService},b.prototype.getProperty=function(a,b){var c=b.split("."),d=a;return _.each(c,function(a){d=d&&d[a]?d[a]:void 0}),d},b.prototype.concatName=function(a){return this.stripAccents(a.firstName.toLowerCase())+this.stripAccents(a.lastName.toLowerCase())},b.IID="userPickerService",b.$inject=["$http","$q","$filter"],b}();angular.module("lui").service(b.IID,b)}(b=a.userpicker||(a.userpicker={}))}(lui||(lui={}));var lui;!function(a){"use strict"}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a){this.format=a||"moment"}return a.prototype.parseValue=function(a){switch(this.format){case"moment":return this.parseMoment(a);case"date":return this.parseDate(a);default:return this.parseString(a)}},a.prototype.formatValue=function(a){if(!a)return a;switch(this.format){case"moment":return this.formatMoment(a);case"date":return this.formatDate(a);default:return this.formatString(a)}},a.prototype.parseMoment=function(a){return a?moment(a):void 0},a.prototype.parseDate=function(a){return a?moment(a):void 0},a.prototype.parseString=function(a){return a&&moment(a,this.format).isValid()?moment(a,this.format):void 0},a.prototype.formatMoment=function(a){return moment(a)},a.prototype.formatDate=function(a){return a.toDate()},a.prototype.formatString=function(a){return a.format(this.format)},a}();a.MomentFormatter=b}(b=a.formatter||(a.formatter={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=100,c=function(){function a(a,c,d){function e(a){i.clickedOutside?i.clickedOutside():i.close()}function f(){e(),i.$scope.$digest()}function g(a){a.stopPropagation()}var h=this;this.elt=a,this.body=angular.element(document.getElementsByTagName("body")[0]),this.$scope=c,this.clickedOutside=d;var i=this;this.open=function(a){h.$scope.popover.isOpen=!0,setTimeout(function(){h.body.on("click",f),h.elt.on("click",g)},b)},this.close=function(a){h.$scope.popover.isOpen=!1,h.body&&(h.body.off("click",f),h.elt.off("click",g))}}return a.prototype.toggle=function(a){this.$scope.popover.isOpen?this.close(a):this.open(a)},a}();a.ClickoutsideTrigger=c}(b=a.popover||(a.popover={}))}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";angular.module("lui").directive("luidOnScrollBottom",function(){return{restrict:"A",scope:{luidOnScrollBottom:"&"},link:function(a,b){b.bind("scroll",function(b){var c=b.target||event.srcElement,d=c.scrollHeight-c.clientHeight;Math.abs(d-c.scrollTop)<2&&a.luidOnScrollBottom&&a.luidOnScrollBottom()})}}})}(b=a.scroll||(a.scroll={}))}(lui||(lui={}));var lui;!function(a){"use strict"}(lui||(lui={}));var lui;!function(a){var b;!function(a){"use strict";var b=function(){function a(a,b,c,d){this.mainApiUrl="/api/files",this.$http=a,this.$q=b,this._=c,this.moment=d}return a.prototype.postFromUrl=function(a,b){var c=this,d=this.$q.defer(),e=new XMLHttpRequest;return e.open("GET",a,!0),e.responseType="arraybuffer",e.onload=function(a){var f=new Blob([e.response],{type:"image/jpeg"});c.postBlob(f,b).then(function(a){d.resolve(a)},function(a){d.reject(a.data.Message)})},e.send(),d.promise},a.prototype.postDataURI=function(a,b){var c=this.dataURItoBlob(a);return this.postBlob(c,b)},a.prototype.postBlob=function(a,b){var c=this.$q.defer(),d=this.mainApiUrl,e=new FormData;return e.append(b.substring(0,b.lastIndexOf(".")),a,b),this.$http({method:"POST",url:d,data:e,headers:{"Content-Type":void 0,Accept:void 0},transformRequest:angular.identity}).then(function(a){c.resolve(a.data.data)},function(a){c.reject(a.data.Message)}),c.promise},a.prototype.dataURItoBlob=function(a){for(var b=atob(a.split(",")[1]),c=a.split(",")[0].split(":")[1].split(";")[0],d=new ArrayBuffer(b.length),e=new Uint8Array(d),f=0;f
{{ calendar.date | luifMoment : calendar.currentYear ? "MMMM" : "MMMM - YYYY" }} {{ calendar.date | luifMoment : "YYYY" }} {{ calendar.date.year() }} - {{ calendar.date.year() + 11 }}
{{ ::dayLabel }}
{{ ::day.dayNum }}
  • {{ m.date | luifMoment : "MMM" }}
  • {{ y.date | luifMoment : "YYYY" }}
'),a.put("lui/templates/date-picker/datepicker-popup.html",'
'),a.put("lui/templates/date-picker/daterangepicker-popover.html",'
{{ calendar.date | luifMoment : calendar.currentYear ? "MMMM" : "MMMM - YYYY" }} {{ calendar.date | luifMoment : "YYYY" }} {{ calendar.date.year() }} - {{ calendar.date.year() + 11 }}
{{ ::dayLabel }}
{{ ::day.dayNum }}
  • {{ m.date | luifMoment : "MMM" }}
  • {{ y.date | luifMoment : "YYYY" }}
'),a.put("lui/templates/date-picker/daterangepicker.html",'
'),a.put("lui/templates/department-picker/department-picker.html",'{{ $select.selected.name }}
'),a.put("lui/templates/formly/fields/api-select-multiple.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/api-select.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'), a.put("lui/templates/formly/fields/checkbox.html",'
{{ options.templateOptions.helper }}
'),a.put("lui/templates/formly/fields/date.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/daterange.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/department.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/email.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}} {{::options.templateOptions.emailError}}
'),a.put("lui/templates/formly/fields/iban.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}} {{::options.templateOptions.ibanError}}
'),a.put("lui/templates/formly/fields/number.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/picture.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/portrait.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/radio.html",'
{{ options.templateOptions.helper}} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/select.html",'
{{$select.selected.label}}
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/text.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/textarea.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/user-multiple.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/fields/user.html",'
{{ options.templateOptions.helper }} {{::options.templateOptions.requiredError}}
'),a.put("lui/templates/formly/inputs/api-select-multiple.html",'{{$item.name}}
'),a.put("lui/templates/formly/inputs/api-select.html",'{{$select.selected.name}}
'),a.put("lui/templates/iban/iban.view.html",' '),a.put("lui/templates/image-picker/image-cropper.modal.html",'
{{ \'LUIIMGCROPPER_CROP\' | translate }}
{{ \'LUIIMGCROPPER_DO_NOT_CROP\' | translate }}
{{ cancelLabel }}
'),a.put("lui/templates/image-picker/image-picker-popovermenu.html",'
'),a.put("lui/templates/image-picker/image-picker.html",'
'),a.put("lui/templates/notify-service/alert.html",'
{{message}}
'),a.put("lui/templates/notify-service/confirm.html",'
{{message}}
'),a.put("lui/templates/notify-service/error.html",'
Error
{{ $message }}
'),a.put("lui/templates/notify-service/loading.html",'
  Loading
  {{ message }}
'),a.put("lui/templates/notify-service/success.html",'
Success
{{ $message }}
'),a.put("lui/templates/notify-service/warning.html",'
Warning
{{ $message }}
'),a.put("lui/templates/table-grid/table-grid.html",'
'),a.put("lui/templates/table-grid/table-grid.table.html",'
{{ header.label }}
{{ $item }}
{{ $select.selected }}
'),a.put("lui/templates/translations-list/translations-list.html",'
'),a.put("lui/templates/user-picker/user-picker.html",'LUIDUSERPICKER_ALL
LUIDUSERPICKER_ALL
LUIDUSERPICKER_FORMEREMPLOYEE
'),a.put("lui/templates/user-picker/user-picker.multiple.html",'{{$item.lastName}} {{$item.firstName}}
LUIDUSERPICKER_ALL
LUIDUSERPICKER_FORMEREMPLOYEE
')}]),function(){"use strict";var a=function(){return{template:'
{{controller.date | luifMoment: \'dddd\'}}
{{controller.date | luifMoment:\'DD\'}}
{{controller.date | luifMoment: \'MMM\'}}
{{controller.date | luifMoment: \'YYYY\'}}
',scope:{date:"=",showDay:"=",primaryColor:"=",secondaryColor:"="},restrict:"E",bindToController:!0,controllerAs:"controller",controller:"luidDayBlockController"}};angular.module("lui").directive("luidDayBlock",a).controller("luidDayBlockController",function(){var a=this;a.weekdayStyleOverride=function(){return{color:a.primaryColor}},a.dayStyleOverride=function(){return{"background-color":a.primaryColor,"border-color":a.primaryColor,color:a.secondaryColor}},a.monthStyleOverride=function(){return{"background-color":a.secondaryColor,"border-color":a.primaryColor,color:a.primaryColor}},a.yearStyleOverride=function(){return{"background-color":a.secondaryColor,"border-color":a.primaryColor,color:a.primaryColor}}})}(),function(){"use strict";angular.module("lui").directive("luidKeydown",function(){return{restrict:"A",scope:{mappings:"="},link:function(a,b,c){b.on("keydown",function(b){a.mappings&&a.mappings[b.which]&&a.mappings[b.which](b)})}}}),angular.module("lui").directive("luidSelectOnClick",function(){return{restrict:"A",link:function(a,b,c){b.on("click",function(){this.select()}),b.on("focus",function(){this.select()})}}}),angular.module("lui").directive("luidFocusOn",function(){return function(a,b,c){a.$on(c.luidFocusOn,function(c){setTimeout(function(){b[0].focus(),a.$apply()},1)})}})}(),function(){"use strict";angular.module("lui.translate").directive("luidTranslations",["$translate","_","$filter","$timeout",function(a,b,c,d){function e(c,d,e,f){var g=f[1],h=f[0],i={en:1033,de:1031,es:1034,fr:1036,it:1040,nl:2067},j=b.keys(i);c.cultures=j,c.currentCulture=a.preferredLanguage()||"en";var k=e.mode?e.mode:"dictionary";"dictionary"===k&&void 0!==g.$viewValue&&b.each(j,function(a){c.$watch(function(){return g.$viewValue?g.$viewValue[a]:g.$viewValue},function(){g.$render()})}),g.$render=function(){c.internal=l(g.$viewValue),h.updateTooltip()},h.updateViewValue=function(){switch(k){case"dictionary":return p(c.internal);case"|":case"pipe":return r(c.internal);case"lucca":return n(c.internal)}},h.updateTooltip=function(){var a="";if(!c.internal)return void(c.tooltipText=void 0);for(var b=0;b\t
\t\t\t\t{{currentCulture}}\t
\t
')}])}(),function(){"use strict";var a=200;angular.module("lui").directive("luidMoment",["moment",function(a){function b(b,c,d,e){var f=e[1],g=e[0];if(d.format){var h=b.$eval(d.format);f.getValue=function(){var b=f.$viewValue;if(b){var c=a(b,h);if(c.isValid())return c}},f.$render=function(){var a=f.getValue();b.hours=a?a.format("HH"):void 0,b.mins=a?a.format("mm"):void 0,f.$validate()},f.setValue=function(a){f.$setViewValue(a?a.format(h):void 0)},f.$validators.min=function(b,c){return!c||g.checkMin(a(b,h))},f.$validators.max=function(b,c){return!c||g.checkMax(a(b,h))}}else f.getValue=function(){var b=f.$viewValue;if(b){var c=a(b);if(b.isValid())return c}},f.$render=function(){var a=f.getValue(),c=!!a&&a.isValid();b.hours=c?a.format("HH"):void 0,b.mins=c?a.format("mm"):void 0,f.$validate()},f.setValue=function(a){f.$setViewValue(a)},f.$validators.min=function(a,b){return!b||g.checkMin(a)},f.$validators.max=function(a,b){return!b||g.checkMax(a)};b.ngModelCtrl=f,f.$validators.hours=function(a,c){return void 0!==b.hours&&""!==b.hours&&!isNaN(parseInt(b.hours))},f.$validators.minutes=function(a,c){return void 0!==b.mins&&""!==b.mins&&parseInt(b.mins)<60};var i=c.querySelectorAll(".input");g.setupEvents(c,angular.element(i[0]),angular.element(i[1])),b.$watch("min",function(){f.$validate()}),b.$watch("max",function(){f.$validate()})}return{require:["luidMoment","^ngModel"],controller:"luidMomentController",scope:{ min:"=",max:"=",step:"=",referenceDate:"=",isDisabled:"=",showButtons:"=",enforceValid:"=",format:"=",minOffset:"=",maxOffset:"="},templateUrl:"lui/directives/luidMoment.html",restrict:"EA",link:b}}]).controller("luidMomentController",["$scope","$timeout","moment","$element",function(b,c,d,e){function f(a){function c(){function b(a,b){return a.indexOf(b)!==-1}var c=d(s());c&&c.isValid()||(c=o().startOf("day")),b(z,Math.abs(a))&&c.minutes()%a!==0&&(a=a<0?-(c.minutes()%a):-c.minutes()%a+a);var e=c.add(a,"m");return e.seconds(0),e}b.isDisabled||g(c(),!0)}function g(a,c){h(a,c),b.ngModelCtrl.$render()}function h(a,c){function d(a,b,c){switch(!0){case!a:return a;case b&&b.diff(a)>0:return b;case c&&c.diff(a)<0:return c;default:return a}}var f=q(),g=r();if(c){var h=d(a,f,g);h.format("HH:mm")!==a.format("HH:mm")&&(a=h,e.addClass("autocorrect"),setTimeout(function(){e.removeClass("autocorrect")},200))}b.maxed=a&&g&&g.diff(a)<=0,b.mined=a&&f&&f.diff(a)>=0,b.ngModelCtrl.setValue(a)}function i(){return void 0===b.hours||""===b.hours||void 0===b.mins||""===b.mins}function j(){if(!i()){var a=parseInt(b.hours),c=parseInt(b.mins);c>60&&(c=59,b.mins="59");var d=o().hours(a).minutes(c).seconds(0),e=k(d);return e}}function k(a){var b,c=d(a),e=d(c),f=d(c),g=q(),h=r();return g&&c.isBefore(g)&&(b=Math.ceil(g.diff(c,"day",!0)),e.add(b,"day")),h&&c.isAfter(h)&&(b=Math.floor(h.diff(c,"day",!0)),f.add(b,"days")),h&&(e.isBefore(h)||e.isSame(h))?e:g&&(f.isAfter(g)||f.isSame(g))?f:c}function l(){function a(a){a&&(c.cancel(a),a=void 0)}a(x),a(y)}function m(){g(s(),b.enforceValid)}function n(){return isNaN(parseInt(b.step))?5:parseInt(b.step)}function o(){function a(a){return a&&d(a).isValid()?d(a):void 0}return a(b.referenceDate)||a(b.min)||a(b.max)||d()}function p(a,b,c){function e(){switch(!0){case!!a.isValid&&!!a.isValid():return d(a);case d(a,"YYYY-MM-DD HH:mm").isValid():return d(a,"YYYY-MM-DD HH:mm");case d(a,"HH:mm").isValid():var b=o(),e=d(a,"HH:mm").year(b.year()).month(b.month()).date(b.date());return c&&e.hours()+e.minutes()===0&&e.add(1,"d"),e}}if(a){var f=e();return f.add(d.duration(b)),f}}function q(){return p(b.min,b.minOffset,!1)}function r(){return p(b.max,b.maxOffset,!0)}function s(){return b.format?d(b.ngModelCtrl.$viewValue,b.format):b.ngModelCtrl.$viewValue}function t(a,c){l(),f(c),b.$broadcast(a)}function u(a){l(),b.minsFocused=!!a,b.hoursFocused=!a}function v(a,d){var e=b.ngModelCtrl.$modelValue;h(e),a=c(function(){a=!1,m()},200)}function w(a){return void 0===a||""===a}var x,y,z=[5,10,15,20,30];b.pattern=/^([0-9]{0,2})?$/,b.incrHours=function(){t("focusHours",60)},b.decrHours=function(){t("focusHours",-60)},b.incrMins=function(){t("focusMinutes",n())},b.decrMins=function(){t("focusMinutes",-n())},b.changeHours=function(){return w(b.hours)?h(void 0):(w(b.mins)&&(b.mins="00"),2==b.hours.length?(parseInt(b.hours)>23&&(b.hours="23"),b.$broadcast("focusMinutes")):1==b.hours.length&&parseInt(b.hours)>2&&(b.hours=0+b.hours,b.$broadcast("focusMinutes")),void h(j()))},b.changeMins=function(){!b.mins||b.mins.length<2?b.ngModelCtrl.$setValidity("minutes",!1):h(j())},b.formatInputValue=function(){b.ngModelCtrl.$render()},b.getDayGap=function(){var a=o().startOf("day");return d.duration(d(s()).startOf("d").diff(a)).asDays()},b.blurHours=function(){v(x,b.hoursFocused)},b.blurMins=function(){b.mins?b.mins.length<2&&(b.mins="0"+b.mins):""===b.hours||void 0===b.hours?b.mins=void 0:b.mins="00",v(y,b.minsFocused)},b.focusHours=function(){u(!1)},b.focusMins=function(){u(!0)},this.checkMin=function(a){var b=q();return!b||b.diff(a)<=0},this.checkMax=function(a){var b=r();return!b||b.diff(a)>=0},this.setupEvents=function(c,d,e){function g(a,c){function d(a,c){switch(a.which){case 38:a.preventDefault(),f(c),b.$apply();break;case 40:a.preventDefault(),f(-c),b.$apply();break;case 13:a.preventDefault(),b.formatInputValue(),b.$apply()}}var e=n();a.bind("keydown",function(a){d(a,60)}),c.bind("keydown",function(a){d(a,e)})}function h(c,d,e){function g(a){a=a.originalEvent?a.originalEvent:a;var b=a.wheelDelta?a.wheelDelta:-a.deltaY;return a.detail||b>0}function h(a,c){!b.isDisabled&&j&&(b.$apply(f(g(a)?c:-c)),a.preventDefault())}var i,j=!1;c.bind("mouseenter",function(b){i=setTimeout(function(){j=!0},a)}),c.bind("mouseleave",function(a){i&&clearTimeout(i),j=!1});var k=n();d.bind("mousewheel wheel",function(a){h(a,60)}),e.bind("mousewheel wheel",function(a){h(a,k)})}var i=angular.element(d.find("input")[0]),j=angular.element(e.find("input")[0]);g(i,j),h(c,d,e)}}]),angular.module("lui").run(["$templateCache",function(a){a.put("lui/directives/luidMoment.html","
\t\t\t
:
\t\t\t
")}])}(),function(){"use strict";angular.module("lui").directive("luidPercentage",function(){function a(a,b,c,d){var e=d[1],f=d[0];if(a.pattern=/^([0-9]+)(\.([0-9]*)?)?$/i,c.format){if("0.XX"!==c.format&&"1.XX"!==c.format&&"XX"!==c.format)return void(e.$render=function(){a.intPct="unsupported format"})}else a.format="0.XX";a.ngModelCtrl=e,e.$render=function(){return void 0===this.$viewValue?void(a.intPct=void 0):void(a.intPct=a.parse(parseFloat(this.$viewValue)))},e.$viewChangeListeners.push(function(){a.$eval(c.ngChange)}),f.setupEvents(b.find("input"))}return{require:["luidPercentage","^ngModel"],controller:"luidPercentageController",scope:{step:"=",format:"@",ngDisabled:"=",placeholder:"@"},restrict:"EA",link:a,template:"
%
"}}).controller("luidPercentageController",["$scope",function(a){function b(b){c(parseFloat(a.intPct)+b)}function c(b){d(b),a.ngModelCtrl.$render()}function d(b){function c(b){switch(a.format||"0.XX"){case"XX":return b;case"0.XX":return b/100;case"1.XX":return b/100+1;default:return 0}}var d=void 0===b?void 0:c(b);a.ngModelCtrl.$setViewValue(d)}this.setupEvents=function(c){function d(){return isNaN(parseInt(a.step))?5:parseInt(a.step)}function e(c){var e=d();c.bind("keydown",function(c){switch(c.which){case 38:c.preventDefault(),b(e),a.$apply();break;case 40:c.preventDefault(),b(-e),a.$apply();break;case 13:c.preventDefault(),a.formatInputValue(),a.$apply()}})}function f(c){function e(a){a=a.originalEvent?a.originalEvent:a;var b=a.wheelDelta?a.wheelDelta:-a.deltaY;return a.detail||b>0}var f=d();c.bind("mousewheel wheel",function(c){this===document.activeElement&&(a.$apply(b(e(c)?f:-f)),c.preventDefault())})}e(c),f(c)},a.updateValue=function(){d(a.intPct)},a.parse=function(b){switch(a.format||"0.XX"){case"XX":return b;case"0.XX":return Math.round(1e4*b)/100;case"1.XX":return Math.round(1e4*(b-1))/100;default:return 0}},a.formatInputValue=function(){a.ngModelCtrl.$render()}}])}(),function(){"use strict";angular.module("lui").directive("luidTimespan",["moment",function(a){function b(b,c,d,e){var f=e[1],g=e[0];if(b.pattern=/^\-?([0-9]+)((h([0-9]{2})?)?(m(in)?)?)?$/i,d.unit){var h=b.$eval(d.unit);"h"!=h&&"hour"!=h&&"hours"!=h||(b.useHours=!0)}b.ngModelCtrl=f,f.$render=function(){if(b.strDuration="",this.$viewValue){var c=a.duration(this.$viewValue);c<0&&(b.strDuration+="-",c=a.duration(-c));var d=Math.floor(c.asHours()),e=c.minutes();0===d?b.strDuration+=e+"m":b.strDuration+=(d<10?"0":"")+d+"h"+(e<10?"0":"")+e}},g.setupEvents(c.find("input")),g.mode=d.mode?d.mode:"timespan"}return{require:["luidTimespan","^ngModel"],controller:"luidTimespanController",scope:{step:"=",unit:"=",ngDisabled:"=",placeholder:"@",mode:"=",min:"=",max:"="},restrict:"EA",link:b,template:"
"}}]).controller("luidTimespanController",["$scope","moment",function(a,b){function c(c){function d(a){var c=b.duration(),d=a.split(/h/i),e=parseInt(d[0])>=0;c.add(parseInt(d[0]),"hours");var f=d[1];return f&&f.length>=2&&(e?c.add(parseInt(f.substring(0,2)),"minutes"):c.subtract(parseInt(f.substring(0,2)),"minutes")),c}function e(a){var c=b.duration(),d=a.split(/m/i);return c.add(parseInt(d[0]),"minutes"),c}function f(a){var c=b.duration(),d=a.split(/h/i);return c.add(parseInt(d[0]),"hours"),c}switch(!0){case/h/i.test(c):return d(c);case/m/i.test(c):return e(c);case a.useHours:return f(c);default:return e(c)}}function d(a){var c=b.duration(g()).add(a,"minutes");c.asMilliseconds()<0&&(c=b.duration()),e(c)}function e(b){f(b),a.ngModelCtrl.$render()}function f(c){function d(c){function d(c){var d=a.min?b.duration(a.min):void 0;return!d||d<=c?c:d}function e(c){var d=a.max?b.duration(a.max):void 0;return!d||d>=c?c:d}return e(d(c))}function e(a){if("timespan"===h.mode){var c="";return a.asMilliseconds()<0&&(c+="-",a=b.duration(-a)),c+=(a.days()>0?Math.floor(a.asDays())+".":"")+(a.hours()<10?"0":"")+a.hours()+":"+(a.minutes()<10?"0":"")+a.minutes()+":00"}return a}if(void 0===c)return a.ngModelCtrl.$setViewValue(void 0);c=d(c);var f=e(c);a.ngModelCtrl.$setViewValue(f)}function g(){return a.ngModelCtrl.$viewValue}var h=this;this.setupEvents=function(b){function c(){return isNaN(parseInt(a.step))?5:parseInt(a.step)}function e(b){var e=c();b.bind("keydown",function(b){switch(b.which){case 38:b.preventDefault(),d(e),a.$apply();break;case 40:b.preventDefault(),d(-e),a.$apply();break;case 13:b.preventDefault(),a.formatInputValue(),a.$apply()}})}function f(b){function e(a){a=a.originalEvent?a.originalEvent:a;var b=a.wheelDelta?a.wheelDelta:-a.deltaY;return a.detail||b>0}var f=c();b.bind("mousewheel wheel",function(b){this===document.activeElement&&(a.$apply(d(e(b)?f:-f)),b.preventDefault())})}e(b),f(b)},a.updateValue=function(){if(!a.strDuration)return f(void 0);var b=c(a.strDuration);f(b)},a.formatInputValue=function(){a.ngModelCtrl.$render()}}])}(),function(){"use strict";function a(a,b,c){function d(a){return a.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")}return a?a.replace(new RegExp(d(b),"g"),c):""}angular.module("lui").filter("luifPlaceholder",function(){return function(a,b){return a?a:b}}).filter("luifDefaultCode",function(){return function(b){return a(b," ","_").toUpperCase()}}).filter("luifStartFrom",function(){return function(a,b){return b=+b,a.slice(b)}}).filter("luifNumber",["$sce","$filter",function(a,b){return function(c,d,e){function f(a,b){return void 0===a?'':0===parseInt(a)?''+b+a+"":""+b+a+""}var g=void 0===e?"":e,h=void 0===c||null===c||""===c||c!=c?g:c,i=b("number")(1.1,1)[1],j=void 0===d||null===d||d!=d?2:d,k=b("number")(h,j),l=(k||b("number")(0,j)).split(i)[1],m=f(l,i);if(""===h||!k)return a.trustAsHtml(h+m);var n=k.split(i)[0];return a.trustAsHtml(n+m)}}])}(),function(){"use strict";var a=function(a,b){if(!a)return"";var c=moment(a);return c.isValid()?c.format(b):a};angular.module("lui").filter("luifFriendlyRange",function(){function a(a,c,d,e){if(a&&a[c]&&a[c][d])return a[c][d];if(a&&a[c]&&a[c][e])return a[c][e];var f="en";if(a&&a[f]&&a[f][d])return a[f][d];if(a&&a[f]&&a[f][e])return a[f][e];var g=b;return g&&g[c]&&g[c][d]?g[c][d]:g&&g[c]&&g[c][e]?g[c][e]:g&&g[f]&&g[f][d]?g[f][d]:g&&g[f]&&g[f][e]?g[f][e]:void 0}var b={en:{startOnly:"date(dddd, LL) onwards",startOnlyThisYear:"date(dddd, MMMM Do) onwards",endOnly:"until date(dddd, LL)",endOnlyThisYear:"until date(dddd, MMMM Do)",date:"date(LL)",sameDay:"start(dddd, LL)",sameDayThisYear:"start(dddd, MMMM Do)",sameMonth:"start(MMMM Do) - end(Do, YYYY)",sameMonthThisYear:"start(MMMM Do) - end(Do)",sameYear:"start(MMMM Do) - end(LL)",sameYearThisYear:"start(MMMM Do) - end(MMMM Do)",other:"start(LL) - end(LL)"},fr:{startOnly:"à partir du date(dddd LL)",startOnlyThisYear:"à partir du date(dddd Do MMMM)",endOnly:"jusqu'au date(dddd LL)",endOnlyThisYear:"jusqu'au date(dddd Do MMMM)",date:"date(LL)",sameDay:"le start(dddd LL)",sameDayThisYear:"le start(dddd Do MMMM)",sameMonth:"du start(Do) au end(LL)",sameMonthThisYear:"du start(Do) au end(Do MMMM)",sameYear:"du start(Do MMMM) au end(LL)",sameYearThisYear:"du start(Do MMMM) au end(Do MMMM)",other:"du start(LL) au end(LL)"},de:{startOnly:"von date(Do MMMM)",startOnlyThisYear:"von date(LL)",endOnly:"bis date(Do MMMM)",endOnlyThisYear:"bis date(LL)",date:"date(LL)",sameDay:"der start(dddd LL)",sameDayThisYear:"der start(dddd Do MMMM)",sameMonth:"von start(Do) bis end(LL)",sameMonthThisYear:"von start(Do) bis end(Do MMMM)",sameYear:"von start(Do MMMM) bis end(LL)",sameYearThisYear:"von start(Do MMMM) bis end(Do MMMM)",other:"von start(LL) bis end(LL)"}};return function(b,c,d){if(b){var e=b.start||b.startsAt||b.startsOn||b.startDate,f=b.end||b.endsAt||b.endsOn||b.endDate;if(!e&&!f)return"";e=e?moment(e):void 0,f=f?moment(f):void 0,c&&f.add(-1,"minutes");var g,h,i;if(e&&f)return h=e.year()===f.year()?e.month()===f.month()?e.date()===f.date()?"sameDay":"sameMonth":"sameYear":"other",moment().year()===e.year()&&moment().year()===f.year()&&(h+="ThisYear"),g=a(d,moment.locale(),h,"other"),i=/(start\((.*?)\))(.*(end\((.*?)\))){0,1}/gi.exec(g),g.replace(i[1],e.format(i[2])).replace(i[4],f.format(i[5]));h=e?"startOnly":"endOnly";var j=e||f;return moment().year()===j.year()&&(h+="ThisYear"),g=a(d,moment.locale(),h,"date"),i=/(date\((.*?)\))/gi.exec(g),g.replace(i[1],j.format(i[2]))}}}).filter("luifMoment",function(){return function(b,c){return c||(c="LLL"),a(b,c)}}).filter("luifCalendar",function(){return function(a,b){var c=moment(a);b&&moment(b).isValid()?moment(b):moment();return c.isValid()?c.calendar(b):a}}).filter("luifDuration",["$filter",function(a){return function(b,c,d,e){function f(a){switch(a){case"d":case"day":case"days":return 0;case void 0:case"":case"h":case"hour":case"hours":return 1;case"m":case"min":case"mins":case"minute":case"minutes":return 2;case"s":case"sec":case"second":case"seconds":return 3;case"ms":case"millisec":case"millisecond":case"milliseconds":return 4}}function g(a,b){return 4===b?4:0!==a[b]?b:g(a,b+1)}function h(a,b){return 0===b?0:0!==a[b]?b:h(a,b-1)}function i(a){switch(!0){case 0===Math.floor(10*a%10)&&0===Math.floor(100*a%10):return 0;case 0===Math.floor(100*a%10):return 1;default:return 2}}function j(a,b,c){switch(b){case c:return a;case 2:case 3:return a<10?"0"+a:a;case 4:return a<10?"00"+a:a<100?"0"+a:a;default:return a}}function k(a,b){if(a){if(b.asMilliseconds()>0)return"+";if(b.asMilliseconds()<0)return"-"}return""}function l(a,b){var c=["d ","h","m","s","ms"];switch(moment.locale()){case"fr":c[0]="j "}return a<=3&&4===b&&(c[3]=".",c[4]="s"),a<=1&&2===b&&(c[2]=""),2===a&&3===b&&(c[3]=""),c}var m=[{index:0,unit:"d",dateConversion:"asDays",expectedPrecision:"h"},{index:1,unit:"h",dateConversion:"asHours",expectedPrecision:"m"},{index:2,unit:"m",dateConversion:"asMinutes",expectedPrecision:"s"},{index:3,unit:"s",dateConversion:"asSeconds",expectedPrecision:"s"},{index:4,unit:"ms",dateConversion:"asMilliseconds",expectedPrecision:"ms"}],n=moment.duration(b);if(0===n.asMilliseconds())return"";var o=[Math.abs(n.days()),Math.abs(n.hours()),Math.abs(n.minutes()),Math.abs(n.seconds()),Math.abs(n.milliseconds())],p=m[f(d)],q=Math.max(p.index,g(o,0));if(o[p.index]=Math.abs(n[p.dateConversion]()>=0?Math.floor(n[p.dateConversion]()):Math.ceil(n[p.dateConversion]())),0===p.index&&0===f(e)&&0!==n.asDays()){var r=Math.abs(n.asDays()),s=i(r);q=0,o[0]=a("number")(r,s)}for(var t=h(o,f(e||p.expectedPrecision)),u=l(q,t),v="",w=q;w<=t;w++)v+=j(o[w],w,q)+u[w];var x=v?k(c,n):"";return x+v}}]).filter("luifHumanize",function(){return function(a,b){b=!!b;var c=moment.duration(a);return c.humanize(b)}})}(); \ No newline at end of file diff --git a/package.json b/package.json index 0e83a12e..86848882 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lucca-ui", - "version": "4.1.1", + "version": "4.1.2", "description": "less and js framework by lucca", "main": "dist/lucca-ui.js", "dependencies": {