{"version":3,"sources":["angular-strap.js","tooltip/tooltip.js","helpers/compiler.js","datepicker/datepicker.js","typeahead/typeahead.js","timepicker/timepicker.js","tab/tab.js","select/select.js","scrollspy/scrollspy.js","popover/popover.js","navbar/navbar.js","dropdown/dropdown.js","modal/modal.js","helpers/raf.js","helpers/parse-options.js","helpers/dimensions.js","helpers/debounce.js","helpers/date-parser.js","helpers/date-formatter.js","collapse/collapse.js","button/button.js","alert/alert.js","aside/aside.js","affix/affix.js","module.js"],"names":["prefixClass","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","module","$http","get","defaults","animation","data","this","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","angular","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","all","templateEl","Error","findElement","contentTemplate","templates","contentEl","removeAttr","html","replace","next","remove","outerHTML","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","bsCompilerService","$inject","target","provider","placement","titleTemplate","trigger","keyboard","show","title","type","delay","autoClose","bsEnabled","viewport","selector","padding","$get","isTouch","TooltipFactory","$tooltip","$scope","$rootScope","$new","split","enterAnimateCallback","$emit","prefixEvent","leaveAnimateCallback","_tipToHide","evt","preventDefault","destroyTipElement","triggers","nodeName","on","toggle","enter","unbindTriggerEvents","length","$onFocusElementMouseDown","off","i","bindKeyboardEvents","tipElement","$onKeyUp","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","$timeout","$body","hide","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","$element","elRect","getBoundingClientRect","rect","p","width","height","top","left","dimensions","offset","el","scroll","outerDims","isBody","document","documentElement","scrollTop","body","prop","clientWidth","innerHeight","position","actualWidth","actualHeight","marginLeft","isNaN","setOffset","using","parseInt","props","css","right","marginTop","tip","offsetHeight","getViewportAdjustedDelta","delta","offsetWidth","isVertical","arrowDelta","replaceArrow","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","test","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","clearTimeout","timeout","$isShown","tipScope","$destroy","$$phase","$options","config","$promise","$bsCompiler","toLowerCase","$id","attr","map","parseFloat","$sce","trustAsHtml","$setEnabled","$$postDigest","id","$hide","setEnabled","isEnabled","hoverState","compileData","promise","tipContainer","init","container","bindTriggerEvents","isElement","destroy","focus","parent","after","lastChild","display","visibility","clonedElement","addClass","safeDigest","version","prepend","$$rAF","$applyPlacement","$animate","leave","_blur","blur","autoPlace","autoToken","elementPosition","tipWidth","tipHeight","viewportPosition","originalPlacement","removeClass","tipPosition","getCalculatedOffset","applyPlacement","stopPropagation","directive","$root","$digest","restrict","query","querySelectorAll","tooltip","transclusion","falseValueRegExp","isDefined","dataTarget","hasOwnProperty","oldValue","$observe","newValue","bsTooltip","bsShow","$watch","match","setViewport","$on","minLength","filter","limit","autoSelect","comparator","trimValue","$typeahead","parentScope","$resetMatches","$window","$matches","activate","$activeIndex","select","index","$select","matches","$isVisible","update","$render","equals","$onMouseDown","keyCode","$onKeyDown","TypeaheadFactory","array","isFunction","$filter","expression","results","postLink","require","bsOptions","parsedOptions","$parseOptions","typeahead","watchedOptions","$watchCollection","values","watchOptions","$match","ngModel","$modelValue","valuesFn","selectMode","$setViewValue","$viewValue","substring","displayValue","slice","$formatters","push","modelValue","selected","val","label","toString","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","isNative","$timepicker","timepickerFactory","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","end","start","setSelectionRange","isUndefined","collapse","selectionStart","moveStart","selectionEnd","moveEnd","focusElement","_init","floorMinutes","time","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","$dateValue","hoursFormat","$dateFormatter","timeSeparator","minute","minutesFormat","secondsFormat","showSeconds","$iconUp","$moveIndex","$switchMeridian","switchMeridian","isDate","getMinutes","getTime","$build","keep","Date","setHours","setMinutes","setSeconds","midIndex","hours","disabled","minutes","$date","seconds","rows","$isDisabled","showAM","$isSelected","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","targetDate","targetEl","triggerHandler","hoursLength","minutesLength","sepLength","lateralMove","count","selectRange","incr","isSeconds","isMeridian","secondsLength","createSelection","createTextRange","_destroy","_show","_hide","navigator","userAgent","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","timepicker","dateParser","$dateParser","validateAgainstMinMaxTime","timezoneOffsetAdjust","NaN","parse","self","navClass","activeClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$active","$attrs","$navClass","$remove","active","activeIndex","indexOf","splice","$setActive","name","fn","$pane","$tab","transclude","ngModelCtrl","bsTabsCtrl","attrs","bsActivePane","parsedBsActivePane","assign","$parse","controllers","render","$isActive","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$isMultiple","$showAllNoneButtons","$iconCheckmark","$allText","$activate","$selectNone","$updateActiveIndex","a","b","$apply","isArray","$selectScrollFix","$isIE","stopImmediatePropagation","ua","activeElement","tagName","e","dataMultiple","inputEl","addEventListener","join","$getIndex","$isEmpty","spies","$document","windowEl","debounce","bodyEl","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","sortedElements","activeTarget","debouncedCheckOffsets","viewportHeight","debouncedCheckPosition","throttledCheckPosition","checkPositionWithEventLoop","checkOffsets","checkPosition","docEl","$activateElement","offsetTop","setTimeout","source","$getTrackedElement","targetElement","querySelector","trackedElement","trackElement","toDelete","untrackElement","scrollspy","childEl","child","content","$popover","PopoverFactory","requestAnimationFrame","bsPopover","popover","routeAttr","$navbar","liElements","li","liElement","pattern","path","RegExp","regexp","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","parentEl","hasClass","prototype","tAttrs","nextSibling","nodeType","parentNode","removeChild","bsDropdown","dropdown","backdrop","size","bodyElement","backdropCount","dialogBaseZindex","validSizes","ModalFactory","$modal","unbindBackdropEvents","modalElement","hideOnBackdropClick","backdropElement","preventEventDefault","modalScope","$show","bottom","destroyModalElement","z-index","backdropBaseZindex","customClass","minor","backdropAnimation","bindBackdropEvents","defaultPrevented","which","lg","sm","modalClass","bsModal","modal","dot","cancelAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","raf","timer","cancel","supported","$values","valueName","keyName","displayFn","valueFn","ParseOptionsFactory","groupByFn","factory","offsetParent","docElement","ownerDocument","outer","window","getComputedStyle","extra","currentStyle","boxRect","style","curPosition","curLeft","curCSSTop","curTop","calculatePosition","curElem","curCSSLeft","curOffset","call","offsetParentRect","offsetParentEl","offsetParentElement","func","immediate","args","context","callNow","leading","wait","trailing","year","$localeProvider","milliseconds","ParseDate","noop","indexOfCaseInsensitive","len","str","strict","DateParserFactory","day","month","getFullYear","getMonth","proto","isNumeric","toDate","regExpMap","sss","$locale","dateFilter","mm","literalRegex","formatParts","escapedLiteralFormat","dateElements","keys","escapedFormat","isFormatStringLiteral","part","trimLiteralEscapeChars","dateRegexParts","escapeReservedSymbols","text","re","abstractRegex","buildDateParseRegex","setMapForFormat","buildDateAbstractRegex","buildDateParseValuesMap","Object","valuesMatch","keyIndex","valueKey","valuesFunctionMap","valueFunction","valuesRegex","exec","setFnMap","setMap","m","HH","H","hh","h","EEEE","EEE","DATETIME_FORMATS","SHORTDAY","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","s","setDate","setMonth","regex","$format","regExpForFormat","baseDate","formatRegex","formatSetMap","fromDate","getDate","today","getDateForAttribute","substr","getTimeForAttribute","daylightSavingAdjust","undo","getTimezoneOffset","getDefaultLocale","getDatetimeFormat","weekdaysShort","splitTimeFormat","service","dateType","dateFormat","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","minDate","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","DatepickerFactory","$datepicker","pickerViews","views","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","$toggleMode","setMode","updateDisabledDates","disabledDateRanges","dateRanges","mode","pristine","$updateSelected","built","$setDisabledEl","isDisabled","steps","getUTCFullYear","getUTCMonth","UTC","getUTCDate","shiftKey","altKey","onKeyDown","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","parsedDate","getDateFormattedString","validateAgainstMinMaxDate","disabledDates","arrays","mod","n","arr","weekDaysMin","weekDaysLabelsHtml","picker","weekDaysLabels","concat","firstDayOfMonth","firstDayOfMonthOffset","firstDate","firstDateOffset","build","days","isToday","toDateString","muted","showLabels","labels","isSelected","getDay","months","lastDate","actualMonth","firstYear","years","actualYear","Array","setYear","startCollapsed","allowMultiple","activeIndexes","$targets","activeItems","activateItem","$collapse","$viewChangeListeners","$registerToggle","$toggles","$unregisterToggle","$unregisterTarget","deactivateItem","fixActiveItemIndexes","disallowToggle","isActive","$activeIndexes","bsCollapseCtrl","bsCollapseToggle","$registerTarget","action","toggleEvent","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","checked","bind","toggleClass","$eval","v","duration","dismissable","AlertFactory","$alert","bsAlert","alert","AsideFactory","$aside","bsAside","aside","AffixFactory","$affix","inlineStyles","reset","initialOffsetTop","getRequiredAffixClass","_unpin","getScrollTop","scrollHeight","getScrollHeight","offsetBottom","elementHeight","initialAffixTop","pageYOffset","affixed","unpin","$parseOffsets","affix","setWidth","offsetUnpin","$onResize","$debouncedOnResize","initialPosition","affixTarget","option"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\n\n// Source: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n titleTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var isTouch = 'createTouch' in $window.document;\n var $body = angular.element($window.document);\n\n function TooltipFactory (element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if (options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if (options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function (isEnabled) {\n scope.$$postDigest(function () {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $tooltip.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $tooltip.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout;\n var hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData;\n var tipElement;\n var tipContainer;\n var tipScope;\n promise.then(function (data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function () {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if (options.container === 'self') {\n tipContainer = element;\n } else if (angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if (options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if (options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n if (options.trigger === 'focus') {\n element[0].focus();\n } else {\n $tooltip.show();\n }\n });\n }\n\n };\n\n $tooltip.destroy = function () {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function () {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function () {\n if (hoverState === 'in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function () {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent;\n var after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if (tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function (clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if (options.animation) tipElement.addClass(options.animation);\n // Options: type\n if (options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if (options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n if (after) {\n after.after(tipElement);\n } else {\n parent.prepend(tipElement);\n }\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if (tipElement) tipElement.css({visibility: 'visible'});\n\n // Bind events\n if (options.keyboard) {\n if (options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n });\n\n if (options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function () {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function (blur) {\n\n if (!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if (options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if (options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if (_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function (evt) {\n if (evt) { evt.preventDefault(); }\n if ($tooltip.$isShown) {\n $tooltip.leave();\n } else {\n $tooltip.enter();\n }\n };\n\n $tooltip.focus = function () {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function (isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function (viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function () {\n if (!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement;\n var autoToken = /\\s?auto?\\s?/i;\n var autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition();\n var tipWidth = tipElement.prop('offsetWidth');\n var tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n if (/bottom/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (/top/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n if (/left/.test(originalPlacement) && elementPosition.left - tipWidth < viewportPosition.left) {\n placement = placement.replace('left', 'right');\n } else if (/right/.test(originalPlacement) && elementPosition.right + tipWidth > viewportPosition.width) {\n placement = placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function (evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function (evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function (evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n if ($tooltip.$isShown) {\n element[0].blur();\n } else {\n element[0].focus();\n }\n };\n\n // bind/unbind events\n function bindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function (trigger) {\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.on(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n });\n }\n\n function unbindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.off(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n }\n\n function bindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents () {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents () {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation (event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition ($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0];\n var isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n /* eslint-disable guard-for-in */\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n /* eslint-enable guard-for-in */\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, {width: elRect.right - elRect.left, height: elRect.bottom - elRect.top});\n }\n var elOffset = isBody ? {top: 0, left: 0} : dimensions.offset(el);\n var scroll = {scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0};\n var outerDims = isBody ? {width: document.documentElement.clientWidth, height: $window.innerHeight} : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset (placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if (!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if (split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n break;\n default:\n break;\n }\n } else if (split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight + position.height;\n break;\n case 'bottom':\n offset.top = position.top;\n break;\n default:\n break;\n }\n }\n\n return offset;\n }\n\n function applyPlacement (offset, placement) {\n var tip = tipElement[0];\n var width = tip.offsetWidth;\n var height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10);\n var marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth;\n var actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement);\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight;\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta (placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow (delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement () {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if ($tooltip.$isShown && tipElement !== null) {\n if (options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if (options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if (tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if (tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function ($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n var tooltip;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'titleTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function (newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }\n });\n\n attr.$observe('disabled', function (newValue) {\n if (newValue && tooltip.$isShown) {\n tooltip.hide();\n }\n });\n\n // Support scope as an object\n if (attr.bsTooltip) {\n scope.$watch(attr.bsTooltip, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n if (newValue === true) {\n tooltip.show();\n } else {\n tooltip.hide();\n }\n });\n }\n\n // Enabled binding support\n if (attr.bsEnabled) {\n scope.$watch(attr.bsEnabled, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n if (newValue === false) {\n tooltip.setEnabled(false);\n } else {\n tooltip.setEnabled(true);\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n }\n\n // Initialize popover\n tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n\n// Source: typeahead/typeahead.js\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n function TypeaheadFactory (element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function () {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function (matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function (index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function (index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function () {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $typeahead.$onMouseDown = function (evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function (evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n // Navigate with keyboard\n } else if (evt.keyCode === 38 && scope.$activeIndex > 0) {\n scope.$activeIndex--;\n } else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) {\n scope.$activeIndex++;\n } else if (angular.isUndefined(scope.$activeIndex)) {\n scope.$activeIndex = 0;\n }\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function () {\n if ($typeahead.$element) {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $typeahead.$onKeyDown);\n }\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function () {\n if ($typeahead.$element) $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect) {\n $typeahead.activate(-1);\n }\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function ($filter) {\n return function (array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function (results) {\n return $filter('filter')(results, expression, comparator);\n });\n }\n return $filter('filter')(array, expression, comparator);\n };\n })\n\n .directive('bsTypeahead', function ($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Fixes firefox bug when using objects in model with typeahead\n // Yes this breaks any other directive using a 'change' event on this input,\n // but if it is using the 'change' event why is it used with typeahead?\n element.off('change');\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue', 'filter'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = angular.isDefined(options.filter) ? options.filter : defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) {\n bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n }\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function (values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (angular.isDefined(modelValue) && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = index !== -1 ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n\n// Source: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory (element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes (time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format);\n var timeSeparator = $dateFormatter.timeSeparator(format);\n var minutesFormat = $dateFormatter.minutesFormat(format);\n var secondsFormat = $dateFormatter.secondsFormat(format);\n var showSeconds = $dateFormatter.showSeconds(format);\n var showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function (date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function (value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function (date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function (date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function (date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function (date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function () {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i;\n var midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [];\n var hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [];\n var minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [];\n var second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function (date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function (date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function (value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function (value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function (value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours();\n var hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes();\n var minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds();\n var secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection (start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if ($timepicker.$element) $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function (blur) {\n if (!$timepicker.$isShown) return;\n if ($timepicker.$element) $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n if (newValue === true) {\n timepicker.show();\n } else {\n timepicker.hide();\n }\n });\n }\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n if (!isNaN(timepicker.$options[key])) timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n }\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime (parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n }\n validateAgainstMinMaxTime(parsedTime);\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n\n// Source: tab/tab.js\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function (pane) {\n if (angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function (pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if (angular.isString(active)) {\n activeIndex = self.$panes.map(function (pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n } else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if (activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function (value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function ($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function () {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function ($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function (element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function (newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function ($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function (newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if (bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function (newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function () {\n bsTabsCtrl.$remove(scope);\n });\n\n function render () {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: select/select.js\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function ($window, $document, $rootScope, $tooltip, $timeout) {\n\n // var bodyEl = angular.element($window.document.body);\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory (element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n } else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $select.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $select.$isVisible();\n };\n\n scope.$isActive = function (index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function (matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function (index) {\n if (options.multiple) {\n if ($select.$isActive(index)) {\n scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1);\n } else {\n scope.$activeIndex.push(index);\n }\n if (options.sort) scope.$activeIndex.sort(function (a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function (index) {\n var value = scope.$matches[index].value;\n scope.$apply(function () {\n $select.activate(index);\n if (options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function (index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function () {\n if (options.multiple) {\n if (angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function (value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if (angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\n }\n };\n\n $select.$isVisible = function () {\n if (!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function (index) {\n if (options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n }\n return scope.$activeIndex === index;\n };\n\n $select.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $select.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function (evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if (!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function () {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function (e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function () {\n _show();\n if (options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function () {\n if (!options.multiple && angular.isUndefined(controller.$modelValue)) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function ($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if (angular.isDefined(dataMultiple)) {\n if (falseValueRegExp.test(dataMultiple)) {\n options.multiple = false;\n } else {\n options.multiple = dataMultiple;\n }\n }\n\n // Add support for select markup\n if (element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watch(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n select.update(values);\n controller.$render();\n });\n }, true);\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected;\n var index;\n if (options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function (value) {\n index = select.$getIndex(value);\n return index !== -1 ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if (selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = index !== -1 ? select.$scope.$matches[index].label : false;\n }\n element.html((selected || options.placeholder) + (options.caretHtml || defaults.caretHtml));\n };\n\n if (options.multiple) {\n controller.$isEmpty = function (value) {\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n\n// Source: scrollspy/scrollspy.js\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function () {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function ($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName (element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory (config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if (!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if (spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded;\n var unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n /* eslint-disable no-unused-vars */\n var viewportHeight;\n /* eslint-enable no-unused-vars */\n var scrollTop;\n\n $scrollspy.init = function () {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if (scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function () {\n\n // Check internal ref counter\n this.$$count--;\n if (this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function () {\n\n // Not ready yet\n if (!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if (activeTarget === sortedElements[i].target) continue;\n if (scrollTop < sortedElements[i].offsetTop) continue;\n if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function () {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function (element) {\n if (activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if (activeElement) {\n activeElement.source.removeClass('active');\n if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function (target) {\n return trackedElements.filter(function (obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function () {\n\n angular.forEach(trackedElements, function (trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function (el) {\n return el.offsetTop !== null;\n })\n .sort(function (a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function (target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function (target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if (trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function (i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink (scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function () {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink (element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n\n// Source: popover/popover.js\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function ($tooltip) {\n\n function PopoverFactory (element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if (options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function ($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr) {\n\n var popover;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsPopover) {\n scope.$watch(attr.bsPopover, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n if (newValue === true) {\n popover.show();\n } else {\n popover.hide();\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n }\n\n // Initialize popover\n popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n\n// Source: navbar/navbar.js\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function ($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function () {\n\n return $location.path();\n\n }, function (newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function (li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if (options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if (regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n\n// Source: dropdown/dropdown.js\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory (element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n /* var scope = */$dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function (evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function (el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if (options.keyboard && $dropdown.$element) $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n if (parentEl.hasClass('dropdown')) parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function () {\n if (!$dropdown.$isShown) return;\n if (options.keyboard && $dropdown.$element) $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n if (parentEl.hasClass('dropdown')) parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function () {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick (evt) {\n if (evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function ($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n compile: function (tElement, tAttrs) {\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling && nextSibling.className.split(' ').indexOf('dropdown-menu') >= 0) {\n tAttrs.template = nextSibling.outerHTML;\n tAttrs.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink (scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id', 'autoClose'], function (key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Support scope as an object\n if (attr.bsDropdown) {\n scope.$watch(attr.bsDropdown, function (newValue, oldValue) {\n scope.content = newValue;\n }, true);\n }\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!dropdown || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n if (newValue === true) {\n dropdown.show();\n } else {\n dropdown.hide();\n }\n });\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n };\n }\n };\n\n });\n\n// Source: modal/modal.js\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n customClass: '',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true,\n size: null\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n var backdropCount = 0;\n var dialogBaseZindex = 1050;\n var backdropBaseZindex = 1040;\n\n var validSizes = {\n lg: 'modal-lg',\n sm: 'modal-sm'\n };\n\n function ModalFactory (config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if (!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function (key) {\n if (options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $modal.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $modal.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData;\n var modalElement;\n var modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position: 'fixed', top: '0px', left: '0px', bottom: '0px', right: '0px'});\n promise.then(function (data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function () {\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function () {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if (backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function () {\n if ($modal.$isShown) return;\n\n var parent;\n var after;\n if (angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if (modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function (clonedElement, scope) {});\n\n if (options.backdrop) {\n // set z-index\n modalElement.css({'z-index': dialogBaseZindex + (backdropCount * 20)});\n backdropElement.css({'z-index': backdropBaseZindex + (backdropCount * 20)});\n\n // increment number of backdrops\n backdropCount++;\n }\n\n if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: customClass\n if (options.customClass) {\n modalElement.addClass(options.customClass);\n }\n\n // Options: size\n if (options.size && validSizes[options.size]) {\n angular.element(findElement('.modal-dialog', modalElement[0])).addClass(validSizes[options.size]);\n }\n\n // Options: animation\n if (options.animation) {\n if (options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if (options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function () {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function () {\n if (!$modal.$isShown) return;\n\n if (options.backdrop) {\n // decrement number of modals\n backdropCount--;\n }\n\n if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if (options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function () {\n if ($modal.$isShown) {\n $modal.hide();\n } else {\n $modal.show();\n }\n };\n\n $modal.focus = function () {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function (evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents () {\n if (options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents () {\n if (options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick (evt) {\n if (evt.target !== evt.currentTarget) return;\n if (options.backdrop === 'static') {\n $modal.focus();\n } else {\n $modal.hide();\n }\n }\n\n function preventEventDefault (evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement () {\n if ($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if (modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if (modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function ($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass', 'customClass', 'modalClass', 'size'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Options: alias modalClass to customClass\n if (options.modalClass) {\n options.customClass = options.modalClass;\n }\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsModal) {\n scope.$watch(attr.bsModal, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n\n// Source: helpers/raf.js\nif (angular.version.minor < 3 && angular.version.dot < 14) {\n angular.module('ng')\n\n .factory('$$rAF', function ($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function (fn) {\n var id = requestAnimationFrame(fn);\n return function () {\n cancelAnimationFrame(id);\n };\n } :\n function (fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function () {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n });\n}\n\n// Source: helpers/parse-options.js\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function () {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function ($parse, $q) {\n\n function ParseOptionsFactory (attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match;\n var displayFn;\n var valueName;\n /* eslint-disable no-unused-vars */\n var keyName;\n var groupByFn;\n /* eslint-enable no-unused-vars */\n var valueFn;\n var valuesFn;\n\n $parseOptions.init = function () {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]);\n valueName = match[4] || match[6];\n keyName = match[5];\n groupByFn = $parse(match[3] || '');\n valueFn = $parse(match[2] ? match[1] : valueName);\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function (scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function (values) {\n if (!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function (modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues (values, scope) {\n return values.map(function (match, index) {\n var locals = {};\n var label;\n var value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n\n// Source: helpers/dimensions.js\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function () {\n\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function (element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function (element, prop, extra) {\n var value;\n if (element.currentStyle) { // IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function (element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n\n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition;\n var curLeft;\n var curCSSTop;\n var curTop;\n var curOffset;\n var curCSSLeft;\n var calculatePosition;\n var position = fn.css(element, 'position');\n var curElem = angular.element(element);\n var props = {};\n\n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n\n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') &&\n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n\n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n\n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n\n if (options.top !== null) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if (options.left !== null) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function (element) {\n\n var offsetParentRect = {top: 0, left: 0};\n var offsetParentEl;\n var offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentEl\n offsetParentEl = offsetParentElement(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentEl, 'html')) {\n offsetParentRect = fn.offset(offsetParentEl);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentEl, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n function offsetParentElement (element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if (nodeName(offsetParent, '#document')) return docElement.documentElement;\n while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n }\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function (element, outer) {\n var value = element.offsetHeight;\n if (outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function (element, outer) {\n var value = element.offsetWidth;\n if (outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n\n// Source: helpers/debounce.js\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function ($timeout) {\n return function (func, wait, immediate) {\n var timeout = null;\n return function () {\n var context = this;\n var args = arguments;\n var callNow = immediate && !timeout;\n if (timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if (callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function ($timeout) {\n return function (func, wait, options) {\n var timeout = null;\n if (!options) options = {};\n return function () {\n var context = this;\n var args = arguments;\n if (!timeout) {\n if (options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n\n// Source: helpers/date-parser.js\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function ($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate () {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function (value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function (value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function (value) { this.minutes = value; };\n ParseDate.prototype.setHours = function (value) { this.hours = value; };\n ParseDate.prototype.getHours = function () { return this.hours; };\n ParseDate.prototype.setDate = function (value) { this.day = value; };\n ParseDate.prototype.setMonth = function (value) { this.month = value; };\n ParseDate.prototype.setFullYear = function (value) { this.year = value; };\n ParseDate.prototype.fromDate = function (value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function () {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop () {\n }\n\n function isNumeric (n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive (array, value) {\n var len = array.length;\n var str = value.toString().toLowerCase();\n for (var i = 0; i < len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function ($locale, dateFilter) {\n\n var DateParserFactory = function (config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n /* eslint-disable key-spacing, quote-props */\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}'\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function (value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function (value) { return this.setMonth(1 * value - 1); },\n 'M' : function (value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function (value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : function (value) { return (1 * value <= 50 && value.length === 2) ? this.setFullYear(2000 + 1 * value) : this.setFullYear(1 * value); }\n };\n /* eslint-enable key-spacing, quote-props */\n\n var regex;\n var setMap;\n\n $dateParser.init = function () {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function (date) {\n if (angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function (value, baseDate, format, timezone) {\n // check for date format special names\n if (format) format = $locale.DATETIME_FORMATS[format] || format;\n if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if (!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for (var i = 0; i < matches.length - 1; i++) {\n if (formatSetMap[i]) formatSetMap[i].call(date, matches[i + 1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function (key, value) {\n var date;\n\n if (value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if (isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && value.length === 0) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function (key, value) {\n var time;\n\n if (value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if (isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.length === 0) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function (date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function (date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function regExpForFormat (format) {\n // `format` string can contain literal values.\n // These need to be escaped by surrounding with\n // single quotes (e.g. `\"h 'in the morning'\"`).\n // In order to output a single quote, escape it - i.e.,\n // two single quotes in a sequence (e.g. `\"h 'o''clock'\"`).\n\n var re = buildDateAbstractRegex(format);\n return buildDateParseRegex(re);\n }\n\n function buildDateAbstractRegex (format) {\n var escapedFormat = escapeReservedSymbols(format);\n var escapedLiteralFormat = escapedFormat.replace(/''/g, '\\\\\\'');\n var literalRegex = /('(?:\\\\'|.)*?')/;\n var formatParts = escapedLiteralFormat.split(literalRegex);\n var dateElements = Object.keys(regExpMap);\n var dateRegexParts = [];\n\n angular.forEach(formatParts, function (part) {\n if (isFormatStringLiteral(part)) {\n part = trimLiteralEscapeChars(part);\n } else {\n // Abstract replaces to avoid collisions\n for (var i = 0; i < dateElements.length; i++) {\n part = part.split(dateElements[i]).join('${' + i + '}');\n }\n }\n dateRegexParts.push(part);\n });\n\n return dateRegexParts.join('');\n }\n\n function escapeReservedSymbols (text) {\n return text.replace(/\\\\/g, '[\\\\\\\\]')\n .replace(/-/g, '[-]')\n .replace(/\\./g, '[.]')\n .replace(/\\*/g, '[*]')\n .replace(/\\+/g, '[+]')\n .replace(/\\?/g, '[?]')\n .replace(/\\$/g, '[$]')\n .replace(/\\^/g, '[^]')\n .replace(/\\//g, '[/]')\n .replace(/\\\\s/g, '[\\\\s]');\n }\n\n function isFormatStringLiteral (text) {\n return /^'.*'$/.test(text);\n }\n\n function trimLiteralEscapeChars (text) {\n return text.replace(/^'(.*)'$/, '$1');\n }\n\n function buildDateParseRegex (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var re = abstractRegex;\n\n // Replace abstracted values\n for (var i = 0; i < dateElements.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')');\n }\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n function setMapForFormat (format) {\n var re = buildDateAbstractRegex(format);\n return buildDateParseValuesMap(re);\n }\n\n function buildDateParseValuesMap (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var valuesRegex = new RegExp('\\\\${(\\\\d+)}', 'g');\n var valuesMatch;\n var keyIndex;\n var valueKey;\n var valueFunction;\n var valuesFunctionMap = [];\n\n /* eslint-disable no-cond-assign */\n while ((valuesMatch = valuesRegex.exec(abstractRegex)) !== null) {\n keyIndex = valuesMatch[1];\n valueKey = dateElements[keyIndex];\n valueFunction = setFnMap[valueKey];\n\n valuesFunctionMap.push(valueFunction);\n }\n\n return valuesFunctionMap;\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n\n// Source: helpers/date-formatter.js\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function ($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function () {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function (format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function (lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat (format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function (timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function (date, format, lang, timezone) {\n return dateFilter(date, format, timezone);\n };\n\n });\n\n// Source: helpers/compiler.js\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService ($q, $http, $injector, $compile, $controller, $templateCache) {\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function (options) {\n\n if (options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function (value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\n }\n\n if (options.titleTemplate) {\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.titleTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n findElement('[ng-bind=\"title\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n return templateEl[0].outerHTML;\n });\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if (!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function (locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link (scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate (template) {\n if (fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function (res) {\n return res.data;\n }));\n }\n\n}\n\n// Source: datepicker/datepicker.js\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // Uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory (element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if (options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function (date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function (value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function () {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function (date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function (dateRanges) {\n options.disabledDateRanges = dateRanges;\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function (date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if (!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if (!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function (mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function (pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if (pristine === true && $picker.built) return;\n if (pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function () {\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function (date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function (el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function (value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if (evt.keyCode === 13) {\n if (!scope.$mode) {\n $datepicker.hide(true);\n } else {\n scope.$apply(function () { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected (el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // if $datepicker is no longer showing, don't setup events\n if (!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function (blur) {\n if (!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n // var defaults = $datepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!datepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n if (newValue === true) {\n datepicker.show();\n } else {\n datepicker.hide();\n }\n });\n }\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n if (!isNaN(datepicker.$options[key])) datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n }\n });\n\n // Observe date format\n if (angular.isDefined(attr.dateFormat)) {\n attr.$observe('dateFormat', function (newValue) {\n datepicker.$options.dateFormat = newValue;\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges (ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function (disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate (parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n }\n validateAgainstMinMaxDate(parsedDate);\n\n if (options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.dateType === 'number') {\n return date.getTime();\n } else if (options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.dateType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if (options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if (isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function () {\n\n // var defaults = this.defaults = {\n // dayFormat: 'dd',\n // daySplit: 7\n // };\n\n // Split array into smaller arrays\n function split (arr, size) {\n var arrays = [];\n while (arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod (n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function ($dateFormatter, $dateParser, $sce) {\n\n return function (picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: {month: 1},\n update: function (date, force) {\n if (!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1);\n var firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5);\n var firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if (firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [];\n var day;\n for (var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function (date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if (evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if (evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if (evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if (evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: {year: 1},\n update: function (date, force) {\n if (!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n // var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [];\n var month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if (evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if (evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if (evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: {year: 12},\n update: function (date, force) {\n if (!this.built || force || parseInt(date.getFullYear() / 20, 10) !== parseInt(viewDate.year / 20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [];\n var year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if (evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if (evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if (evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n\n// Source: collapse/collapse.js\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function () {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function (element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function (element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function (element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function (element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function (value) {\n if (angular.isArray(value)) {\n self.$targets.$active = value;\n } else if (!self.$options.disallowToggle && isActive(value)) {\n deactivateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function () {\n if (self.$options.allowMultiple) {\n return self.$targets.$active;\n }\n return self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes (index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for (var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive (value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) !== -1;\n }\n\n function deactivateItem (value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem (value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function () {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function ($window, $animate, $collapse) {\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n } else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n } else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function () {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function () {\n if (!attrs.disabled) {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n }\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function ($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if (bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render () {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n } else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: button/button.js\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n toggleEvent: 'click'\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if (constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if (constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if (hasExoticValues) {\n controller.$parsers.push(function (viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if (!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if (!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function (child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function (v) {\n if (typeof v !== 'boolean' && constantValueRegExp.test(v)) {\n value = scope.$eval(v);\n } else {\n value = v;\n }\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n\n// Source: alert/alert.js\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function ($modal, $timeout) {\n\n function AlertFactory (config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if (options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if (options.duration) {\n $alert.show = function () {\n show();\n $timeout(function () {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function ($window, $sce, $alert) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAlert) {\n scope.$watch(attr.bsAlert, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n\n// Source: aside/aside.js\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function ($modal) {\n\n function AsideFactory (config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function ($window, $sce, $aside) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAside) {\n scope.$watch(attr.bsAside, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n\n// Source: affix/affix.js\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function () {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function ($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory (element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom';\n var setWidth = false;\n var initialAffixTop = 0;\n var initialOffsetTop = 0;\n var offsetTop = 0;\n var offsetBottom = 0;\n var affixed = null;\n var unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n } else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function () {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function () {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function () {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function () {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if (affixed === affix) return;\n affixed = affix;\n\n if (affix === 'top') {\n unpin = null;\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if (affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n } else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if (setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function () {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function () {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if (options.offsetTop) {\n if (options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if (options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if (options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n } else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n } else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if (options.offsetBottom) {\n if (options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n } else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles) {\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass (_unpin, position, elementHeight) {\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if (scrollTop <= offsetTop) {\n return 'top';\n } else if (_unpin !== null && (scrollTop + _unpin <= position.top)) {\n return 'middle';\n } else if (offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n }\n return 'middle';\n }\n\n function getScrollTop () {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight () {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function ($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink (scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function (key) {\n if (angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function () {\n if (affix) affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function () {\n return {\n controller: function ($element) {\n this.$element = $element;\n }\n };\n });\n\n// Source: module.js\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n\n})(window, document);\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n titleTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var isTouch = 'createTouch' in $window.document;\n var $body = angular.element($window.document);\n\n function TooltipFactory (element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if (options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if (options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function (isEnabled) {\n scope.$$postDigest(function () {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $tooltip.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $tooltip.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout;\n var hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData;\n var tipElement;\n var tipContainer;\n var tipScope;\n promise.then(function (data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function () {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if (options.container === 'self') {\n tipContainer = element;\n } else if (angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if (options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if (options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n if (options.trigger === 'focus') {\n element[0].focus();\n } else {\n $tooltip.show();\n }\n });\n }\n\n };\n\n $tooltip.destroy = function () {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function () {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function () {\n if (hoverState === 'in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function () {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent;\n var after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if (tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function (clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if (options.animation) tipElement.addClass(options.animation);\n // Options: type\n if (options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if (options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n if (after) {\n after.after(tipElement);\n } else {\n parent.prepend(tipElement);\n }\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if (tipElement) tipElement.css({visibility: 'visible'});\n\n // Bind events\n if (options.keyboard) {\n if (options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n });\n\n if (options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function () {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function (blur) {\n\n if (!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if (options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if (options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if (_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function (evt) {\n if (evt) { evt.preventDefault(); }\n if ($tooltip.$isShown) {\n $tooltip.leave();\n } else {\n $tooltip.enter();\n }\n };\n\n $tooltip.focus = function () {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function (isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function (viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function () {\n if (!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement;\n var autoToken = /\\s?auto?\\s?/i;\n var autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition();\n var tipWidth = tipElement.prop('offsetWidth');\n var tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n if (/bottom/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (/top/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n if (/left/.test(originalPlacement) && elementPosition.left - tipWidth < viewportPosition.left) {\n placement = placement.replace('left', 'right');\n } else if (/right/.test(originalPlacement) && elementPosition.right + tipWidth > viewportPosition.width) {\n placement = placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function (evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function (evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function (evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n if ($tooltip.$isShown) {\n element[0].blur();\n } else {\n element[0].focus();\n }\n };\n\n // bind/unbind events\n function bindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function (trigger) {\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.on(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n });\n }\n\n function unbindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.off(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n }\n\n function bindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents () {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents () {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation (event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition ($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0];\n var isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n /* eslint-disable guard-for-in */\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n /* eslint-enable guard-for-in */\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, {width: elRect.right - elRect.left, height: elRect.bottom - elRect.top});\n }\n var elOffset = isBody ? {top: 0, left: 0} : dimensions.offset(el);\n var scroll = {scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0};\n var outerDims = isBody ? {width: document.documentElement.clientWidth, height: $window.innerHeight} : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset (placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if (!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if (split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n break;\n default:\n break;\n }\n } else if (split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight + position.height;\n break;\n case 'bottom':\n offset.top = position.top;\n break;\n default:\n break;\n }\n }\n\n return offset;\n }\n\n function applyPlacement (offset, placement) {\n var tip = tipElement[0];\n var width = tip.offsetWidth;\n var height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10);\n var marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth;\n var actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement);\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight;\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta (placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow (delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement () {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if ($tooltip.$isShown && tipElement !== null) {\n if (options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if (options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if (tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if (tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function ($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n var tooltip;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'titleTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function (newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }\n });\n\n attr.$observe('disabled', function (newValue) {\n if (newValue && tooltip.$isShown) {\n tooltip.hide();\n }\n });\n\n // Support scope as an object\n if (attr.bsTooltip) {\n scope.$watch(attr.bsTooltip, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n if (newValue === true) {\n tooltip.show();\n } else {\n tooltip.hide();\n }\n });\n }\n\n // Enabled binding support\n if (attr.bsEnabled) {\n scope.$watch(attr.bsEnabled, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n if (newValue === false) {\n tooltip.setEnabled(false);\n } else {\n tooltip.setEnabled(true);\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n }\n\n // Initialize popover\n tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService ($q, $http, $injector, $compile, $controller, $templateCache) {\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function (options) {\n\n if (options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function (value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\n }\n\n if (options.titleTemplate) {\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.titleTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n findElement('[ng-bind=\"title\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n return templateEl[0].outerHTML;\n });\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if (!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function (locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link (scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate (template) {\n if (fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function (res) {\n return res.data;\n }));\n }\n\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // Uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory (element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if (options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function (date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function (value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function () {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function (date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function (dateRanges) {\n options.disabledDateRanges = dateRanges;\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function (date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if (!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if (!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function (mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function (pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if (pristine === true && $picker.built) return;\n if (pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function () {\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function (date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function (el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function (value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if (evt.keyCode === 13) {\n if (!scope.$mode) {\n $datepicker.hide(true);\n } else {\n scope.$apply(function () { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected (el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // if $datepicker is no longer showing, don't setup events\n if (!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function (blur) {\n if (!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n // var defaults = $datepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!datepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n if (newValue === true) {\n datepicker.show();\n } else {\n datepicker.hide();\n }\n });\n }\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n if (!isNaN(datepicker.$options[key])) datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n }\n });\n\n // Observe date format\n if (angular.isDefined(attr.dateFormat)) {\n attr.$observe('dateFormat', function (newValue) {\n datepicker.$options.dateFormat = newValue;\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges (ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function (disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate (parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n }\n validateAgainstMinMaxDate(parsedDate);\n\n if (options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.dateType === 'number') {\n return date.getTime();\n } else if (options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.dateType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if (options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if (isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function () {\n\n // var defaults = this.defaults = {\n // dayFormat: 'dd',\n // daySplit: 7\n // };\n\n // Split array into smaller arrays\n function split (arr, size) {\n var arrays = [];\n while (arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod (n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function ($dateFormatter, $dateParser, $sce) {\n\n return function (picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: {month: 1},\n update: function (date, force) {\n if (!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1);\n var firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5);\n var firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if (firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [];\n var day;\n for (var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function (date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if (evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if (evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if (evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if (evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: {year: 1},\n update: function (date, force) {\n if (!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n // var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [];\n var month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if (evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if (evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if (evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: {year: 12},\n update: function (date, force) {\n if (!this.built || force || parseInt(date.getFullYear() / 20, 10) !== parseInt(viewDate.year / 20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [];\n var year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if (evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if (evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if (evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n function TypeaheadFactory (element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function () {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function (matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function (index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function (index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function () {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $typeahead.$onMouseDown = function (evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function (evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n // Navigate with keyboard\n } else if (evt.keyCode === 38 && scope.$activeIndex > 0) {\n scope.$activeIndex--;\n } else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) {\n scope.$activeIndex++;\n } else if (angular.isUndefined(scope.$activeIndex)) {\n scope.$activeIndex = 0;\n }\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function () {\n if ($typeahead.$element) {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $typeahead.$onKeyDown);\n }\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function () {\n if ($typeahead.$element) $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect) {\n $typeahead.activate(-1);\n }\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function ($filter) {\n return function (array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function (results) {\n return $filter('filter')(results, expression, comparator);\n });\n }\n return $filter('filter')(array, expression, comparator);\n };\n })\n\n .directive('bsTypeahead', function ($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Fixes firefox bug when using objects in model with typeahead\n // Yes this breaks any other directive using a 'change' event on this input,\n // but if it is using the 'change' event why is it used with typeahead?\n element.off('change');\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue', 'filter'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = angular.isDefined(options.filter) ? options.filter : defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) {\n bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n }\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function (values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (angular.isDefined(modelValue) && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = index !== -1 ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory (element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes (time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format);\n var timeSeparator = $dateFormatter.timeSeparator(format);\n var minutesFormat = $dateFormatter.minutesFormat(format);\n var secondsFormat = $dateFormatter.secondsFormat(format);\n var showSeconds = $dateFormatter.showSeconds(format);\n var showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function (date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function (value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function (date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function (date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function (date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function (date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function () {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i;\n var midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [];\n var hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [];\n var minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [];\n var second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function (date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function (date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function (value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function (value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function (value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours();\n var hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes();\n var minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds();\n var secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection (start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if ($timepicker.$element) $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function (blur) {\n if (!$timepicker.$isShown) return;\n if ($timepicker.$element) $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n if (newValue === true) {\n timepicker.show();\n } else {\n timepicker.hide();\n }\n });\n }\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n if (!isNaN(timepicker.$options[key])) timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n }\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime (parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n }\n validateAgainstMinMaxTime(parsedTime);\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function (pane) {\n if (angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function (pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if (angular.isString(active)) {\n activeIndex = self.$panes.map(function (pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n } else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if (activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function (value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function ($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function () {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function ($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function (element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function (newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function ($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function (newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if (bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function (newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function () {\n bsTabsCtrl.$remove(scope);\n });\n\n function render () {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function ($window, $document, $rootScope, $tooltip, $timeout) {\n\n // var bodyEl = angular.element($window.document.body);\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory (element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n } else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $select.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $select.$isVisible();\n };\n\n scope.$isActive = function (index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function (matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function (index) {\n if (options.multiple) {\n if ($select.$isActive(index)) {\n scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1);\n } else {\n scope.$activeIndex.push(index);\n }\n if (options.sort) scope.$activeIndex.sort(function (a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function (index) {\n var value = scope.$matches[index].value;\n scope.$apply(function () {\n $select.activate(index);\n if (options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function (index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function () {\n if (options.multiple) {\n if (angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function (value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if (angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\n }\n };\n\n $select.$isVisible = function () {\n if (!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function (index) {\n if (options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n }\n return scope.$activeIndex === index;\n };\n\n $select.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $select.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function (evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if (!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function () {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function (e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function () {\n _show();\n if (options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function () {\n if (!options.multiple && angular.isUndefined(controller.$modelValue)) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function ($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if (angular.isDefined(dataMultiple)) {\n if (falseValueRegExp.test(dataMultiple)) {\n options.multiple = false;\n } else {\n options.multiple = dataMultiple;\n }\n }\n\n // Add support for select markup\n if (element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watch(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n select.update(values);\n controller.$render();\n });\n }, true);\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected;\n var index;\n if (options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function (value) {\n index = select.$getIndex(value);\n return index !== -1 ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if (selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = index !== -1 ? select.$scope.$matches[index].label : false;\n }\n element.html((selected || options.placeholder) + (options.caretHtml || defaults.caretHtml));\n };\n\n if (options.multiple) {\n controller.$isEmpty = function (value) {\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function () {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function ($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName (element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory (config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if (!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if (spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded;\n var unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n /* eslint-disable no-unused-vars */\n var viewportHeight;\n /* eslint-enable no-unused-vars */\n var scrollTop;\n\n $scrollspy.init = function () {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if (scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function () {\n\n // Check internal ref counter\n this.$$count--;\n if (this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function () {\n\n // Not ready yet\n if (!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if (activeTarget === sortedElements[i].target) continue;\n if (scrollTop < sortedElements[i].offsetTop) continue;\n if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function () {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function (element) {\n if (activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if (activeElement) {\n activeElement.source.removeClass('active');\n if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function (target) {\n return trackedElements.filter(function (obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function () {\n\n angular.forEach(trackedElements, function (trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function (el) {\n return el.offsetTop !== null;\n })\n .sort(function (a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function (target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function (target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if (trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function (i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink (scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function () {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink (element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function ($tooltip) {\n\n function PopoverFactory (element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if (options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function ($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr) {\n\n var popover;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsPopover) {\n scope.$watch(attr.bsPopover, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n if (newValue === true) {\n popover.show();\n } else {\n popover.hide();\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n }\n\n // Initialize popover\n popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function ($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function () {\n\n return $location.path();\n\n }, function (newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function (li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if (options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if (regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory (element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n /* var scope = */$dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function (evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function (el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if (options.keyboard && $dropdown.$element) $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n if (parentEl.hasClass('dropdown')) parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function () {\n if (!$dropdown.$isShown) return;\n if (options.keyboard && $dropdown.$element) $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n if (parentEl.hasClass('dropdown')) parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function () {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick (evt) {\n if (evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function ($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n compile: function (tElement, tAttrs) {\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling && nextSibling.className.split(' ').indexOf('dropdown-menu') >= 0) {\n tAttrs.template = nextSibling.outerHTML;\n tAttrs.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink (scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id', 'autoClose'], function (key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Support scope as an object\n if (attr.bsDropdown) {\n scope.$watch(attr.bsDropdown, function (newValue, oldValue) {\n scope.content = newValue;\n }, true);\n }\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!dropdown || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n if (newValue === true) {\n dropdown.show();\n } else {\n dropdown.hide();\n }\n });\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n };\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n customClass: '',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true,\n size: null\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n var backdropCount = 0;\n var dialogBaseZindex = 1050;\n var backdropBaseZindex = 1040;\n\n var validSizes = {\n lg: 'modal-lg',\n sm: 'modal-sm'\n };\n\n function ModalFactory (config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if (!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function (key) {\n if (options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $modal.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $modal.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData;\n var modalElement;\n var modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position: 'fixed', top: '0px', left: '0px', bottom: '0px', right: '0px'});\n promise.then(function (data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function () {\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function () {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if (backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function () {\n if ($modal.$isShown) return;\n\n var parent;\n var after;\n if (angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if (modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function (clonedElement, scope) {});\n\n if (options.backdrop) {\n // set z-index\n modalElement.css({'z-index': dialogBaseZindex + (backdropCount * 20)});\n backdropElement.css({'z-index': backdropBaseZindex + (backdropCount * 20)});\n\n // increment number of backdrops\n backdropCount++;\n }\n\n if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: customClass\n if (options.customClass) {\n modalElement.addClass(options.customClass);\n }\n\n // Options: size\n if (options.size && validSizes[options.size]) {\n angular.element(findElement('.modal-dialog', modalElement[0])).addClass(validSizes[options.size]);\n }\n\n // Options: animation\n if (options.animation) {\n if (options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if (options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function () {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function () {\n if (!$modal.$isShown) return;\n\n if (options.backdrop) {\n // decrement number of modals\n backdropCount--;\n }\n\n if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if (options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function () {\n if ($modal.$isShown) {\n $modal.hide();\n } else {\n $modal.show();\n }\n };\n\n $modal.focus = function () {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function (evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents () {\n if (options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents () {\n if (options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick (evt) {\n if (evt.target !== evt.currentTarget) return;\n if (options.backdrop === 'static') {\n $modal.focus();\n } else {\n $modal.hide();\n }\n }\n\n function preventEventDefault (evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement () {\n if ($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if (modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if (modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function ($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass', 'customClass', 'modalClass', 'size'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Options: alias modalClass to customClass\n if (options.modalClass) {\n options.customClass = options.modalClass;\n }\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsModal) {\n scope.$watch(attr.bsModal, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nif (angular.version.minor < 3 && angular.version.dot < 14) {\n angular.module('ng')\n\n .factory('$$rAF', function ($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function (fn) {\n var id = requestAnimationFrame(fn);\n return function () {\n cancelAnimationFrame(id);\n };\n } :\n function (fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function () {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n });\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function () {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function ($parse, $q) {\n\n function ParseOptionsFactory (attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match;\n var displayFn;\n var valueName;\n /* eslint-disable no-unused-vars */\n var keyName;\n var groupByFn;\n /* eslint-enable no-unused-vars */\n var valueFn;\n var valuesFn;\n\n $parseOptions.init = function () {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]);\n valueName = match[4] || match[6];\n keyName = match[5];\n groupByFn = $parse(match[3] || '');\n valueFn = $parse(match[2] ? match[1] : valueName);\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function (scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function (values) {\n if (!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function (modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues (values, scope) {\n return values.map(function (match, index) {\n var locals = {};\n var label;\n var value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function () {\n\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function (element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function (element, prop, extra) {\n var value;\n if (element.currentStyle) { // IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function (element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n\n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition;\n var curLeft;\n var curCSSTop;\n var curTop;\n var curOffset;\n var curCSSLeft;\n var calculatePosition;\n var position = fn.css(element, 'position');\n var curElem = angular.element(element);\n var props = {};\n\n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n\n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') &&\n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n\n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n\n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n\n if (options.top !== null) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if (options.left !== null) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function (element) {\n\n var offsetParentRect = {top: 0, left: 0};\n var offsetParentEl;\n var offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentEl\n offsetParentEl = offsetParentElement(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentEl, 'html')) {\n offsetParentRect = fn.offset(offsetParentEl);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentEl, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n function offsetParentElement (element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if (nodeName(offsetParent, '#document')) return docElement.documentElement;\n while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n }\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function (element, outer) {\n var value = element.offsetHeight;\n if (outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function (element, outer) {\n var value = element.offsetWidth;\n if (outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function ($timeout) {\n return function (func, wait, immediate) {\n var timeout = null;\n return function () {\n var context = this;\n var args = arguments;\n var callNow = immediate && !timeout;\n if (timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if (callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function ($timeout) {\n return function (func, wait, options) {\n var timeout = null;\n if (!options) options = {};\n return function () {\n var context = this;\n var args = arguments;\n if (!timeout) {\n if (options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function ($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate () {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function (value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function (value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function (value) { this.minutes = value; };\n ParseDate.prototype.setHours = function (value) { this.hours = value; };\n ParseDate.prototype.getHours = function () { return this.hours; };\n ParseDate.prototype.setDate = function (value) { this.day = value; };\n ParseDate.prototype.setMonth = function (value) { this.month = value; };\n ParseDate.prototype.setFullYear = function (value) { this.year = value; };\n ParseDate.prototype.fromDate = function (value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function () {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop () {\n }\n\n function isNumeric (n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive (array, value) {\n var len = array.length;\n var str = value.toString().toLowerCase();\n for (var i = 0; i < len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function ($locale, dateFilter) {\n\n var DateParserFactory = function (config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n /* eslint-disable key-spacing, quote-props */\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}'\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function (value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function (value) { return this.setMonth(1 * value - 1); },\n 'M' : function (value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function (value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : function (value) { return (1 * value <= 50 && value.length === 2) ? this.setFullYear(2000 + 1 * value) : this.setFullYear(1 * value); }\n };\n /* eslint-enable key-spacing, quote-props */\n\n var regex;\n var setMap;\n\n $dateParser.init = function () {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function (date) {\n if (angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function (value, baseDate, format, timezone) {\n // check for date format special names\n if (format) format = $locale.DATETIME_FORMATS[format] || format;\n if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if (!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for (var i = 0; i < matches.length - 1; i++) {\n if (formatSetMap[i]) formatSetMap[i].call(date, matches[i + 1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function (key, value) {\n var date;\n\n if (value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if (isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && value.length === 0) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function (key, value) {\n var time;\n\n if (value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if (isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.length === 0) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function (date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function (date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function regExpForFormat (format) {\n // `format` string can contain literal values.\n // These need to be escaped by surrounding with\n // single quotes (e.g. `\"h 'in the morning'\"`).\n // In order to output a single quote, escape it - i.e.,\n // two single quotes in a sequence (e.g. `\"h 'o''clock'\"`).\n\n var re = buildDateAbstractRegex(format);\n return buildDateParseRegex(re);\n }\n\n function buildDateAbstractRegex (format) {\n var escapedFormat = escapeReservedSymbols(format);\n var escapedLiteralFormat = escapedFormat.replace(/''/g, '\\\\\\'');\n var literalRegex = /('(?:\\\\'|.)*?')/;\n var formatParts = escapedLiteralFormat.split(literalRegex);\n var dateElements = Object.keys(regExpMap);\n var dateRegexParts = [];\n\n angular.forEach(formatParts, function (part) {\n if (isFormatStringLiteral(part)) {\n part = trimLiteralEscapeChars(part);\n } else {\n // Abstract replaces to avoid collisions\n for (var i = 0; i < dateElements.length; i++) {\n part = part.split(dateElements[i]).join('${' + i + '}');\n }\n }\n dateRegexParts.push(part);\n });\n\n return dateRegexParts.join('');\n }\n\n function escapeReservedSymbols (text) {\n return text.replace(/\\\\/g, '[\\\\\\\\]')\n .replace(/-/g, '[-]')\n .replace(/\\./g, '[.]')\n .replace(/\\*/g, '[*]')\n .replace(/\\+/g, '[+]')\n .replace(/\\?/g, '[?]')\n .replace(/\\$/g, '[$]')\n .replace(/\\^/g, '[^]')\n .replace(/\\//g, '[/]')\n .replace(/\\\\s/g, '[\\\\s]');\n }\n\n function isFormatStringLiteral (text) {\n return /^'.*'$/.test(text);\n }\n\n function trimLiteralEscapeChars (text) {\n return text.replace(/^'(.*)'$/, '$1');\n }\n\n function buildDateParseRegex (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var re = abstractRegex;\n\n // Replace abstracted values\n for (var i = 0; i < dateElements.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')');\n }\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n function setMapForFormat (format) {\n var re = buildDateAbstractRegex(format);\n return buildDateParseValuesMap(re);\n }\n\n function buildDateParseValuesMap (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var valuesRegex = new RegExp('\\\\${(\\\\d+)}', 'g');\n var valuesMatch;\n var keyIndex;\n var valueKey;\n var valueFunction;\n var valuesFunctionMap = [];\n\n /* eslint-disable no-cond-assign */\n while ((valuesMatch = valuesRegex.exec(abstractRegex)) !== null) {\n keyIndex = valuesMatch[1];\n valueKey = dateElements[keyIndex];\n valueFunction = setFnMap[valueKey];\n\n valuesFunctionMap.push(valueFunction);\n }\n\n return valuesFunctionMap;\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function ($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function () {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function (format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function (lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat (format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function (timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function (date, format, lang, timezone) {\n return dateFilter(date, format, timezone);\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function () {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function (element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function (element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function (element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function (element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function (value) {\n if (angular.isArray(value)) {\n self.$targets.$active = value;\n } else if (!self.$options.disallowToggle && isActive(value)) {\n deactivateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function () {\n if (self.$options.allowMultiple) {\n return self.$targets.$active;\n }\n return self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes (index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for (var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive (value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) !== -1;\n }\n\n function deactivateItem (value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem (value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function () {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function ($window, $animate, $collapse) {\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n } else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n } else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function () {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function () {\n if (!attrs.disabled) {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n }\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function ($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if (bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render () {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n } else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n toggleEvent: 'click'\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if (constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if (constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if (hasExoticValues) {\n controller.$parsers.push(function (viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if (!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if (!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function (child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function (v) {\n if (typeof v !== 'boolean' && constantValueRegExp.test(v)) {\n value = scope.$eval(v);\n } else {\n value = v;\n }\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n","'use strict';\n\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function ($modal, $timeout) {\n\n function AlertFactory (config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if (options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if (options.duration) {\n $alert.show = function () {\n show();\n $timeout(function () {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function ($window, $sce, $alert) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAlert) {\n scope.$watch(attr.bsAlert, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function ($modal) {\n\n function AsideFactory (config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function ($window, $sce, $aside) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAside) {\n scope.$watch(attr.bsAside, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function () {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function ($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory (element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom';\n var setWidth = false;\n var initialAffixTop = 0;\n var initialOffsetTop = 0;\n var offsetTop = 0;\n var offsetBottom = 0;\n var affixed = null;\n var unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n } else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function () {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function () {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function () {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function () {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if (affixed === affix) return;\n affixed = affix;\n\n if (affix === 'top') {\n unpin = null;\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if (affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n } else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if (setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function () {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function () {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if (options.offsetTop) {\n if (options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if (options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if (options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n } else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n } else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if (options.offsetBottom) {\n if (options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n } else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles) {\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass (_unpin, position, elementHeight) {\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if (scrollTop <= offsetTop) {\n return 'top';\n } else if (_unpin !== null && (scrollTop + _unpin <= position.top)) {\n return 'middle';\n } else if (offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n }\n return 'middle';\n }\n\n function getScrollTop () {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight () {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function ($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink (scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function (key) {\n if (angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function () {\n if (affix) affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function () {\n return {\n controller: function ($element) {\n this.$element = $element;\n }\n };\n });\n","\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n"],"sourceRoot":"/source/"}