From be231838d94eda2e9ebcec03877fdfb2de8d196f Mon Sep 17 00:00:00 2001 From: Olivier Louvignes Date: Thu, 28 May 2015 22:42:36 +0200 Subject: [PATCH] chore(release): cut the v2.2.4 release --- bower.json | 2 +- dist/angular-strap.js | 298 +++++++++++++++-------------- dist/angular-strap.min.js | 8 +- dist/angular-strap.min.js.map | 2 +- dist/angular-strap.tpl.js | 2 +- dist/angular-strap.tpl.min.js | 2 +- dist/modules/affix.js | 2 +- dist/modules/affix.min.js | 2 +- dist/modules/alert.js | 2 +- dist/modules/alert.min.js | 2 +- dist/modules/alert.tpl.js | 2 +- dist/modules/alert.tpl.min.js | 2 +- dist/modules/aside.js | 2 +- dist/modules/aside.min.js | 2 +- dist/modules/aside.tpl.js | 2 +- dist/modules/aside.tpl.min.js | 2 +- dist/modules/button.js | 2 +- dist/modules/button.min.js | 2 +- dist/modules/collapse.js | 2 +- dist/modules/collapse.min.js | 2 +- dist/modules/date-formatter.js | 2 +- dist/modules/date-formatter.min.js | 2 +- dist/modules/date-parser.js | 2 +- dist/modules/date-parser.min.js | 2 +- dist/modules/datepicker.js | 2 +- dist/modules/datepicker.min.js | 2 +- dist/modules/datepicker.tpl.js | 2 +- dist/modules/datepicker.tpl.min.js | 2 +- dist/modules/debounce.js | 2 +- dist/modules/debounce.min.js | 2 +- dist/modules/dimensions.js | 2 +- dist/modules/dimensions.min.js | 2 +- dist/modules/dropdown.js | 6 +- dist/modules/dropdown.min.js | 4 +- dist/modules/dropdown.min.js.map | 2 +- dist/modules/dropdown.tpl.js | 2 +- dist/modules/dropdown.tpl.min.js | 2 +- dist/modules/modal.js | 16 +- dist/modules/modal.min.js | 4 +- dist/modules/modal.min.js.map | 2 +- dist/modules/modal.tpl.js | 2 +- dist/modules/modal.tpl.min.js | 2 +- dist/modules/navbar.js | 2 +- dist/modules/navbar.min.js | 2 +- dist/modules/parse-options.js | 2 +- dist/modules/parse-options.min.js | 2 +- dist/modules/popover.js | 2 +- dist/modules/popover.min.js | 2 +- dist/modules/popover.tpl.js | 2 +- dist/modules/popover.tpl.min.js | 2 +- dist/modules/raf.js | 2 +- dist/modules/raf.min.js | 2 +- dist/modules/scrollspy.js | 2 +- dist/modules/scrollspy.min.js | 2 +- dist/modules/select.js | 6 +- dist/modules/select.min.js | 4 +- dist/modules/select.min.js.map | 2 +- dist/modules/select.tpl.js | 2 +- dist/modules/select.tpl.min.js | 2 +- dist/modules/tab.js | 2 +- dist/modules/tab.min.js | 2 +- dist/modules/tab.tpl.js | 2 +- dist/modules/tab.tpl.min.js | 2 +- dist/modules/timepicker.js | 10 +- dist/modules/timepicker.min.js | 4 +- dist/modules/timepicker.min.js.map | 2 +- dist/modules/timepicker.tpl.js | 2 +- dist/modules/timepicker.tpl.min.js | 2 +- dist/modules/tooltip.js | 16 +- dist/modules/tooltip.min.js | 4 +- dist/modules/tooltip.min.js.map | 2 +- dist/modules/tooltip.tpl.js | 2 +- dist/modules/tooltip.tpl.min.js | 2 +- dist/modules/typeahead.js | 16 +- dist/modules/typeahead.min.js | 4 +- dist/modules/typeahead.min.js.map | 2 +- dist/modules/typeahead.tpl.js | 2 +- dist/modules/typeahead.tpl.min.js | 2 +- docs/scripts/app.js | 2 +- package.json | 12 +- 80 files changed, 289 insertions(+), 253 deletions(-) diff --git a/bower.json b/bower.json index 6654e9bea..a7a9390ea 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "angular-strap", "description": "AngularStrap - AngularJS directives for Bootstrap", - "version": "2.2.3", + "version": "2.2.4", "keywords": [ "angular", "bootstrap" diff --git a/dist/angular-strap.js b/dist/angular-strap.js index 9f0e3641e..2081691cc 100644 --- a/dist/angular-strap.js +++ b/dist/angular-strap.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -182,125 +182,6 @@ } ] }; }); - angular.module('mgcrea.ngStrap.button', []).provider('$button', function() { - var defaults = this.defaults = { - activeClass: 'active', - toggleEvent: 'click' - }; - this.$get = function() { - return { - defaults: defaults - }; - }; - }).directive('bsCheckboxGroup', function() { - return { - restrict: 'A', - require: 'ngModel', - compile: function postLink(element, attr) { - element.attr('data-toggle', 'buttons'); - element.removeAttr('ng-model'); - var children = element[0].querySelectorAll('input[type="checkbox"]'); - angular.forEach(children, function(child) { - var childEl = angular.element(child); - childEl.attr('bs-checkbox', ''); - childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value')); - }); - } - }; - }).directive('bsCheckbox', [ '$button', '$$rAF', function($button, $$rAF) { - var defaults = $button.defaults; - var constantValueRegExp = /^(true|false|\d+)$/; - return { - restrict: 'A', - require: 'ngModel', - link: function postLink(scope, element, attr, controller) { - var options = defaults; - var isInput = element[0].nodeName === 'INPUT'; - var activeElement = isInput ? element.parent() : element; - var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true; - if (constantValueRegExp.test(attr.trueValue)) { - trueValue = scope.$eval(attr.trueValue); - } - var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false; - if (constantValueRegExp.test(attr.falseValue)) { - falseValue = scope.$eval(attr.falseValue); - } - var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean'; - if (hasExoticValues) { - controller.$parsers.push(function(viewValue) { - return viewValue ? trueValue : falseValue; - }); - controller.$formatters.push(function(modelValue) { - return angular.equals(modelValue, trueValue); - }); - scope.$watch(attr.ngModel, function(newValue, oldValue) { - controller.$render(); - }); - } - controller.$render = function() { - var isActive = angular.equals(controller.$modelValue, trueValue); - $$rAF(function() { - if (isInput) element[0].checked = isActive; - activeElement.toggleClass(options.activeClass, isActive); - }); - }; - element.bind(options.toggleEvent, function() { - scope.$apply(function() { - if (!isInput) { - controller.$setViewValue(!activeElement.hasClass('active')); - } - if (!hasExoticValues) { - controller.$render(); - } - }); - }); - } - }; - } ]).directive('bsRadioGroup', function() { - return { - restrict: 'A', - require: 'ngModel', - compile: function postLink(element, attr) { - element.attr('data-toggle', 'buttons'); - element.removeAttr('ng-model'); - var children = element[0].querySelectorAll('input[type="radio"]'); - angular.forEach(children, function(child) { - angular.element(child).attr('bs-radio', ''); - angular.element(child).attr('ng-model', attr.ngModel); - }); - } - }; - }).directive('bsRadio', [ '$button', '$$rAF', function($button, $$rAF) { - var defaults = $button.defaults; - var constantValueRegExp = /^(true|false|\d+)$/; - return { - restrict: 'A', - require: 'ngModel', - link: function postLink(scope, element, attr, controller) { - var options = defaults; - var isInput = element[0].nodeName === 'INPUT'; - var activeElement = isInput ? element.parent() : element; - var value; - attr.$observe('value', function(v) { - value = constantValueRegExp.test(v) ? scope.$eval(v) : v; - controller.$render(); - }); - controller.$render = function() { - var isActive = angular.equals(controller.$modelValue, value); - $$rAF(function() { - if (isInput) element[0].checked = isActive; - activeElement.toggleClass(options.activeClass, isActive); - }); - }; - element.bind(options.toggleEvent, function() { - scope.$apply(function() { - controller.$setViewValue(value); - controller.$render(); - }); - }); - } - }; - } ]); angular.module('mgcrea.ngStrap.alert', [ 'mgcrea.ngStrap.modal' ]).provider('$alert', function() { var defaults = this.defaults = { animation: 'am-fade', @@ -1211,7 +1092,7 @@ $dropdown.show = function() { show(); $timeout(function() { - options.keyboard && $dropdown.$element.on('keydown', $dropdown.$onKeyDown); + options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown); bodyEl.on('click', onBodyClick); }, 0, false); parentEl.hasClass('dropdown') && parentEl.addClass('open'); @@ -1219,7 +1100,7 @@ var hide = $dropdown.hide; $dropdown.hide = function() { if (!$dropdown.$isShown) return; - options.keyboard && $dropdown.$element.off('keydown', $dropdown.$onKeyDown); + options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown); bodyEl.off('click', onBodyClick); parentEl.hasClass('dropdown') && parentEl.removeClass('open'); hide(); @@ -1269,6 +1150,125 @@ } }; } ]); + angular.module('mgcrea.ngStrap.button', []).provider('$button', function() { + var defaults = this.defaults = { + activeClass: 'active', + toggleEvent: 'click' + }; + this.$get = function() { + return { + defaults: defaults + }; + }; + }).directive('bsCheckboxGroup', function() { + return { + restrict: 'A', + require: 'ngModel', + compile: function postLink(element, attr) { + element.attr('data-toggle', 'buttons'); + element.removeAttr('ng-model'); + var children = element[0].querySelectorAll('input[type="checkbox"]'); + angular.forEach(children, function(child) { + var childEl = angular.element(child); + childEl.attr('bs-checkbox', ''); + childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value')); + }); + } + }; + }).directive('bsCheckbox', [ '$button', '$$rAF', function($button, $$rAF) { + var defaults = $button.defaults; + var constantValueRegExp = /^(true|false|\d+)$/; + return { + restrict: 'A', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = defaults; + var isInput = element[0].nodeName === 'INPUT'; + var activeElement = isInput ? element.parent() : element; + var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true; + if (constantValueRegExp.test(attr.trueValue)) { + trueValue = scope.$eval(attr.trueValue); + } + var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false; + if (constantValueRegExp.test(attr.falseValue)) { + falseValue = scope.$eval(attr.falseValue); + } + var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean'; + if (hasExoticValues) { + controller.$parsers.push(function(viewValue) { + return viewValue ? trueValue : falseValue; + }); + controller.$formatters.push(function(modelValue) { + return angular.equals(modelValue, trueValue); + }); + scope.$watch(attr.ngModel, function(newValue, oldValue) { + controller.$render(); + }); + } + controller.$render = function() { + var isActive = angular.equals(controller.$modelValue, trueValue); + $$rAF(function() { + if (isInput) element[0].checked = isActive; + activeElement.toggleClass(options.activeClass, isActive); + }); + }; + element.bind(options.toggleEvent, function() { + scope.$apply(function() { + if (!isInput) { + controller.$setViewValue(!activeElement.hasClass('active')); + } + if (!hasExoticValues) { + controller.$render(); + } + }); + }); + } + }; + } ]).directive('bsRadioGroup', function() { + return { + restrict: 'A', + require: 'ngModel', + compile: function postLink(element, attr) { + element.attr('data-toggle', 'buttons'); + element.removeAttr('ng-model'); + var children = element[0].querySelectorAll('input[type="radio"]'); + angular.forEach(children, function(child) { + angular.element(child).attr('bs-radio', ''); + angular.element(child).attr('ng-model', attr.ngModel); + }); + } + }; + }).directive('bsRadio', [ '$button', '$$rAF', function($button, $$rAF) { + var defaults = $button.defaults; + var constantValueRegExp = /^(true|false|\d+)$/; + return { + restrict: 'A', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = defaults; + var isInput = element[0].nodeName === 'INPUT'; + var activeElement = isInput ? element.parent() : element; + var value; + attr.$observe('value', function(v) { + value = constantValueRegExp.test(v) ? scope.$eval(v) : v; + controller.$render(); + }); + controller.$render = function() { + var isActive = angular.equals(controller.$modelValue, value); + $$rAF(function() { + if (isInput) element[0].checked = isActive; + activeElement.toggleClass(options.activeClass, isActive); + }); + }; + element.bind(options.toggleEvent, function() { + scope.$apply(function() { + controller.$setViewValue(value); + controller.$render(); + }); + }); + } + }; + } ]); angular.module('mgcrea.ngStrap.helpers.dateFormatter', []).service('$dateFormatter', [ '$locale', 'dateFilter', function($locale, dateFilter) { this.getDefaultLocale = function() { return $locale.id; @@ -1890,8 +1890,11 @@ if (options.backdrop) { $animate.enter(backdropElement, bodyElement, null); } - var promise = $animate.enter(modalElement, parent, after, enterAnimateCallback); - if (promise && promise.then) promise.then(enterAnimateCallback); + if (angular.version.minor <= 2) { + $animate.enter(modalElement, parent, after, enterAnimateCallback); + } else { + $animate.enter(modalElement, parent, after).then(enterAnimateCallback); + } $modal.$isShown = scope.$isShown = true; safeDigest(scope); var el = modalElement[0]; @@ -1919,8 +1922,11 @@ if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) { return; } - var promise = $animate.leave(modalElement, leaveAnimateCallback); - if (promise && promise.then) promise.then(leaveAnimateCallback); + if (angular.version.minor <= 2) { + $animate.leave(modalElement, leaveAnimateCallback); + } else { + $animate.leave(modalElement).then(leaveAnimateCallback); + } if (options.backdrop) { $animate.leave(backdropElement); } @@ -2397,7 +2403,9 @@ $select.activate = function(index) { if (options.multiple) { $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index); - if (options.sort) scope.$activeIndex.sort(); + if (options.sort) scope.$activeIndex.sort(function(a, b) { + return a - b; + }); } else { scope.$activeIndex = index; } @@ -3010,18 +3018,18 @@ $timepicker.show = function() { _show(); $timeout(function() { - $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); + $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); if (options.keyboard) { - element.on('keydown', $timepicker.$onKeyDown); + element && element.on('keydown', $timepicker.$onKeyDown); } }, 0, false); }; var _hide = $timepicker.hide; $timepicker.hide = function(blur) { if (!$timepicker.$isShown) return; - $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); + $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); if (options.keyboard) { - element.off('keydown', $timepicker.$onKeyDown); + element && element.off('keydown', $timepicker.$onKeyDown); } _hide(blur); }; @@ -3306,8 +3314,11 @@ $tooltip.$isShown = scope.$isShown = true; safeDigest(scope); $tooltip.$applyPlacement(); - var promise = $animate.enter(tipElement, parent, after, enterAnimateCallback); - if (promise && promise.then) promise.then(enterAnimateCallback); + if (angular.version.minor <= 2) { + $animate.enter(tipElement, parent, after, enterAnimateCallback); + } else { + $animate.enter(tipElement, parent, after).then(enterAnimateCallback); + } safeDigest(scope); $$rAF(function() { if (tipElement) tipElement.css({ @@ -3346,8 +3357,11 @@ scope.$emit(options.prefixEvent + '.hide.before', $tooltip); _blur = blur; _tipToHide = tipElement; - var promise = $animate.leave(tipElement, leaveAnimateCallback); - if (promise && promise.then) promise.then(leaveAnimateCallback); + if (angular.version.minor <= 2) { + $animate.leave(tipElement, leaveAnimateCallback); + } else { + $animate.leave(tipElement).then(leaveAnimateCallback); + } $tooltip.$isShown = scope.$isShown = false; safeDigest(scope); if (options.keyboard && tipElement !== null) { @@ -3824,17 +3838,17 @@ $typeahead.show = function() { show(); $timeout(function() { - $typeahead.$element.on('mousedown', $typeahead.$onMouseDown); + $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown); if (options.keyboard) { - element.on('keydown', $typeahead.$onKeyDown); + element && element.on('keydown', $typeahead.$onKeyDown); } }, 0, false); }; var hide = $typeahead.hide; $typeahead.hide = function() { - $typeahead.$element.off('mousedown', $typeahead.$onMouseDown); + $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown); if (options.keyboard) { - element.off('keydown', $typeahead.$onKeyDown); + element && element.off('keydown', $typeahead.$onKeyDown); } if (!options.autoSelect) $typeahead.activate(-1); hide(); @@ -3896,7 +3910,11 @@ }); controller.$formatters.push(function(modelValue) { var displayValue = parsedOptions.displayValue(modelValue); - return displayValue === undefined ? '' : displayValue; + if (displayValue) return displayValue; + if (modelValue && typeof modelValue !== 'object') { + return modelValue; + } + return ''; }); controller.$render = function() { if (controller.$isEmpty(controller.$viewValue)) return element.val(''); diff --git a/dist/angular-strap.min.js b/dist/angular-strap.min.js index df63500bf..7ebb4d3a1 100644 --- a/dist/angular-strap.min.js +++ b/dist/angular-strap.min.js @@ -1,11 +1,11 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -!function(e,t,n){'use strict';angular.module('mgcrea.ngStrap',['mgcrea.ngStrap.modal','mgcrea.ngStrap.aside','mgcrea.ngStrap.alert','mgcrea.ngStrap.button','mgcrea.ngStrap.select','mgcrea.ngStrap.datepicker','mgcrea.ngStrap.timepicker','mgcrea.ngStrap.navbar','mgcrea.ngStrap.tooltip','mgcrea.ngStrap.popover','mgcrea.ngStrap.dropdown','mgcrea.ngStrap.typeahead','mgcrea.ngStrap.scrollspy','mgcrea.ngStrap.affix','mgcrea.ngStrap.tab','mgcrea.ngStrap.collapse']),angular.module('mgcrea.ngStrap.affix',['mgcrea.ngStrap.helpers.dimensions','mgcrea.ngStrap.helpers.debounce']).provider('$affix',function(){var e=this.defaults={offsetTop:'auto',inlineStyles:!0};this.$get=['$window','debounce','dimensions',function(t,n,a){function o(o,s){function l(e,t,n){var a=u(),o=c();return v>=a?'top':null!==e&&a+e<=t.top?'middle':null!==w&&t.top+n+$>=o-w?'bottom':'middle'}function u(){return p[0]===t?t.pageYOffset:p[0].scrollTop}function c(){return p[0]===t?t.document.body.scrollHeight:p[0].scrollHeight}var d={},f=angular.extend({},e,s),p=f.target,g='affix affix-top affix-bottom',m=!1,$=0,h=0,v=0,w=0,y=null,b=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var k=0;k<1*f.offsetParent-1;k++)D=D.parent();else D=angular.element(f.offsetParent);return d.init=function(){this.$parseOffsets(),h=a.offset(o[0]).top+$,m=!o[0].style.width,p.on('scroll',this.checkPosition),p.on('click',this.checkPositionWithEventLoop),r.on('resize',this.$debouncedOnResize),this.checkPosition(),this.checkPositionWithEventLoop()},d.destroy=function(){p.off('scroll',this.checkPosition),p.off('click',this.checkPositionWithEventLoop),r.off('resize',this.$debouncedOnResize)},d.checkPositionWithEventLoop=function(){setTimeout(d.checkPosition,1)},d.checkPosition=function(){var e=u(),t=a.offset(o[0]),n=a.height(o[0]),r=l(b,t,n);y!==r&&(y=r,o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')),'top'===r?(b=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(b=f.offsetUnpin?-(1*f.offsetUnpin):t.top-e,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',f.offsetParent?'':i[0].offsetHeight-w-n-h+'px'))):(b=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))))},d.$onResize=function(){d.$parseOffsets(),d.checkPosition()},d.$debouncedOnResize=n(d.$onResize,50),d.$parseOffsets=function(){var e=o.css('position');f.inlineStyles&&o.css('position',f.offsetParent?'':'relative'),f.offsetTop&&('auto'===f.offsetTop&&(f.offsetTop='+0'),f.offsetTop.match(/^[-+]\d+$/)?($=1*-f.offsetTop,v=f.offsetParent?a.offset(D[0]).top+1*f.offsetTop:a.offset(o[0]).top-a.css(o[0],'marginTop',!0)+1*f.offsetTop):v=1*f.offsetTop),f.offsetBottom&&(w=f.offsetParent&&f.offsetBottom.match(/^[-+]\d+$/)?c()-(a.offset(D[0]).top+a.height(D[0]))+1*f.offsetBottom+1:1*f.offsetBottom),f.inlineStyles&&o.css('position',e)},d.init(),d}var i=angular.element(t.document.body),r=angular.element(t);return o}]}).directive('bsAffix',['$affix','$window',function(e,t){return{restrict:'EAC',require:'^?bsAffixTarget',link:function(n,a,o,i){var r={scope:n,target:i?i.$element:angular.element(t)};angular.forEach(['offsetTop','offsetBottom','offsetParent','offsetUnpin','inlineStyles'],function(e){if(angular.isDefined(o[e])){var t=o[e];/true/i.test(t)&&(t=!0),/false/i.test(t)&&(t=!1),r[e]=t}});var s=e(a,r);n.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]).directive('bsAffixTarget',function(){return{controller:['$element',function(e){this.$element=e}]}}),angular.module('mgcrea.ngStrap.button',[]).provider('$button',function(){var e=this.defaults={activeClass:'active',toggleEvent:'click'};this.$get=function(){return{defaults:e}}}).directive('bsCheckboxGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="checkbox"]');angular.forEach(n,function(e){var n=angular.element(e);n.attr('bs-checkbox',''),n.attr('ng-model',t.ngModel+'.'+n.attr('value'))})}}}).directive('bsCheckbox',['$button','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s=n,l='INPUT'===o[0].nodeName,u=l?o.parent():o,c=angular.isDefined(i.trueValue)?i.trueValue:!0;a.test(i.trueValue)&&(c=e.$eval(i.trueValue));var d=angular.isDefined(i.falseValue)?i.falseValue:!1;a.test(i.falseValue)&&(d=e.$eval(i.falseValue));var f='boolean'!=typeof c||'boolean'!=typeof d;f&&(r.$parsers.push(function(e){return e?c:d}),r.$formatters.push(function(e){return angular.equals(e,c)}),e.$watch(i.ngModel,function(e,t){r.$render()})),r.$render=function(){var e=angular.equals(r.$modelValue,c);t(function(){l&&(o[0].checked=e),u.toggleClass(s.activeClass,e)})},o.bind(s.toggleEvent,function(){e.$apply(function(){l||r.$setViewValue(!u.hasClass('active')),f||r.$render()})})}}}]).directive('bsRadioGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="radio"]');angular.forEach(n,function(e){angular.element(e).attr('bs-radio',''),angular.element(e).attr('ng-model',t.ngModel)})}}}).directive('bsRadio',['$button','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s,l=n,u='INPUT'===o[0].nodeName,c=u?o.parent():o;i.$observe('value',function(t){s=a.test(t)?e.$eval(t):t,r.$render()}),r.$render=function(){var e=angular.equals(r.$modelValue,s);t(function(){u&&(o[0].checked=e),c.toggleClass(l.activeClass,e)})},o.bind(l.toggleEvent,function(){e.$apply(function(){r.$setViewValue(s),r.$render()})})}}}]),angular.module('mgcrea.ngStrap.alert',['mgcrea.ngStrap.modal']).provider('$alert',function(){var e=this.defaults={animation:'am-fade',prefixClass:'alert',prefixEvent:'alert',placement:null,template:'alert/alert.tpl.html',container:!1,element:null,backdrop:!1,keyboard:!0,show:!0,duration:!1,type:!1,dismissable:!0};this.$get=['$modal','$timeout',function(t,n){function a(a){var o={},i=angular.extend({},e,a);o=t(i),o.$scope.dismissable=!!i.dismissable,i.type&&(o.$scope.type=i.type);var r=o.show;return i.duration&&(o.show=function(){r(),n(function(){o.hide()},1e3*i.duration)}),o}return a}]}).directive('bsAlert',['$window','$sce','$alert',function(e,t,n){e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','placement','keyboard','html','container','animation','duration','dismissable'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['keyboard','html','container','dismissable'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),e.hasOwnProperty('title')||(e.title=''),angular.forEach(['title','content','type'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsAlert&&e.$watch(o.bsAlert,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.aside',['mgcrea.ngStrap.modal']).provider('$aside',function(){var e=this.defaults={animation:'am-fade-and-slide-right',prefixClass:'aside',prefixEvent:'aside',placement:'right',template:'aside/aside.tpl.html',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$modal',function(t){function n(n){var a={},o=angular.extend({},e,n);return a=t(o)}return n}]}).directive('bsAside',['$window','$sce','$aside',function(e,t,n){e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','contentTemplate','placement','backdrop','keyboard','html','container','animation'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsAside&&e.$watch(o.bsAside,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.collapse',[]).provider('$collapse',function(){var e=this.defaults={animation:'am-collapse',disallowToggle:!1,activeClass:'in',startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,n,a){function o(e){for(var t=l.$targets.$active,n=0;nt;t++)angular.forEach(g.rows[t],u.$setDisabledEl)},u.select=function(e,t){angular.isDate(n.$dateValue)||(n.$dateValue=new Date(e)),!g.$mode||t?(n.$setViewValue(angular.copy(e)),n.$render(),p.autoclose&&!t&&l(function(){u.hide(!0)})):(angular.extend($,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),u.setMode(g.$mode-1),u.$build())},u.setMode=function(e){g.$mode=e,h=u.$views[g.$mode],u.$build()},u.$build=function(e){e===!0&&h.built||(e!==!1||h.built)&&h.build.call(h)},u.$updateSelected=function(){for(var e=0,t=g.rows.length;t>e;e++)angular.forEach(g.rows[e],o)},u.$isSelected=function(e){return h.isSelected(e)},u.$setDisabledEl=function(e){e.disabled=h.isDisabled(e.date)},u.$selectPane=function(e){var t=h.steps,n=new Date(Date.UTC($.year+(t.year||0)*e,$.month+(t.month||0)*e,1));angular.extend($,{year:n.getUTCFullYear(),month:n.getUTCMonth(),date:n.getUTCDate()}),u.$build()},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},u.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return g.$mode?g.$apply(function(){u.setMode(g.$mode-1)}):u.hide(!0);h.onKeyDown(e),f.$digest()}};var v=u.init;u.init=function(){return c&&p.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',i)),void v())};var w=u.destroy;u.destroy=function(){c&&p.useNative&&t.off('click',i),w()};var y=u.show;u.show=function(){y(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1)};var b=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),b(e))},u}var c=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),d='createTouch'in t.document&&c;return e.lang||(e.lang=i.getDefaultLocale()),u.defaults=e,u}]}).directive('bsDatepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$datepicker',function(e,t,n,a,o,i){var r=(i.defaults,/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent));return{restrict:'EAC',require:'ngModel',link:function(e,t,n,s){function l(e){return e&&e.length?e:null}function u(e){if(angular.isDate(e)){var t=isNaN(p.$options.minDate)||e.getTime()>=p.$options.minDate,n=isNaN(p.$options.maxDate)||e.getTime()<=p.$options.maxDate,a=t&&n;s.$setValidity('date',a),s.$setValidity('min',t),s.$setValidity('max',n),a&&(s.$dateValue=e)}}function c(){return!s.$dateValue||isNaN(s.$dateValue.getTime())?'':m(s.$dateValue,d.dateFormat)}var d={scope:e,controller:s};angular.forEach(['placement','container','delay','trigger','html','animation','template','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?p.show():p.hide())});var p=i(t,s,d);d=p.$options,r&&d.useNative&&(d.dateFormat='yyyy-MM-dd');var g=d.lang,m=function(e,t){return a.formatDate(e,t,g)},$=o({format:d.dateFormat,lang:g,strict:d.strictFormat});angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getDateForAttribute(e,t),!isNaN(p.$options[e])&&p.$build(!1),u(s.$dateValue)})}),e.$watch(n.ngModel,function(e,t){p.update(s.$dateValue)},!0),angular.isDefined(n.disabledDates)&&e.$watch(n.disabledDates,function(e,t){e=l(e),t=l(t),e&&p.updateDisabledDates(e)}),s.$parsers.unshift(function(e){var t;if(!e)return s.$setValidity('date',!0),null;var n=$.parse(e,s.$dateValue);return!n||isNaN(n.getTime())?void s.$setValidity('date',!1):(u(n),'string'===d.dateType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelDateFormat||d.dateFormat)):(t=$.timezoneOffsetAdjust(s.$dateValue,d.timezone,!0),'number'===d.dateType?t.getTime():'unix'===d.dateType?t.getTime()/1e3:'iso'===d.dateType?t.toISOString():new Date(t)))}),s.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):new Date('unix'===d.dateType?1e3*e:e),s.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),s.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]).provider('datepickerViews',function(){function e(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n}function t(e,t){return(e%t+t)%t}this.defaults={dayFormat:'dd',daySplit:7};this.$get=['$dateFormatter','$dateParser','$sce',function(n,a,o){return function(i){var r=i.$scope,s=i.$options,l=s.lang,u=function(e,t){return n.formatDate(e,t,l)},c=a({format:s.dateFormat,lang:l,strict:s.strictFormat}),d=n.weekdaysShort(l),f=d.slice(s.startWeek).concat(d.slice(0,s.startWeek)),p=o.trustAsHtml(''+f.join('')+''),g=i.$date||(s.startDate?c.getDateForAttribute('startDate',s.startDate):new Date),m={year:g.getFullYear(),month:g.getMonth(),date:g.getDate()},$=[{format:s.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==m.year||e.getMonth()!==m.month?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):(e.getDate()!==m.date||1===e.getDate())&&(m.date=i.$date.getDate(),i.$updateSelected())},build:function(){var n=new Date(m.year,m.month,1),a=n.getTimezoneOffset(),o=new Date(+n-864e5*t(n.getDay()-s.startWeek,7)),l=o.getTimezoneOffset(),d=c.timezoneOffsetAdjust(new Date,s.timezone).toDateString();l!==a&&(o=new Date(+o+6e4*(l-a)));for(var f,g=[],$=0;42>$;$++)f=c.daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth(),o.getDate()+$)),g.push({date:f,isToday:f.toDateString()===d,label:u(f,this.format),selected:i.$date&&this.isSelected(f),muted:f.getMonth()!==m.month,disabled:this.isDisabled(f)});r.title=u(n,s.monthTitleFormat),r.showLabels=!0,r.labels=p,r.rows=e(g,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()&&e.getDate()===i.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(ts.maxDate)return!0;if(-1!==s.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(s.disabledDateRanges)for(var n=0;n=s.disabledDateRanges[n].start&&t<=s.disabledDateRanges[n].end)return!0;return!1},onKeyDown:function(e){if(i.$date){var t,n=i.$date.getTime();37===e.keyCode?t=new Date(n-864e5):38===e.keyCode?t=new Date(n-6048e5):39===e.keyCode?t=new Date(n+864e5):40===e.keyCode&&(t=new Date(n+6048e5)),this.isDisabled(t)||i.select(t,!0)}}},{name:'month',format:s.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===m.year?e.getMonth()!==m.month&&(angular.extend(m,{month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected()):(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build())},build:function(){for(var t,n=(new Date(m.year,0,1),[]),a=0;12>a;a++)t=new Date(m.year,a,1),n.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=u(t,s.yearTitleFormat),r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getMonth(),n=new Date(i.$date);37===e.keyCode?n.setMonth(t-1):38===e.keyCode?n.setMonth(t-4):39===e.keyCode?n.setMonth(t+1):40===e.keyCode&&n.setMonth(t+4),this.isDisabled(n)||i.select(n,!0)}}},{name:'year',format:s.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt(m.year/20,10)?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getFullYear()!==m.year&&(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected())},build:function(){for(var t,n=m.year-m.year%(3*this.split),a=[],o=0;12>o;o++)t=new Date(n+o,0,1),a.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=a[0].label+'-'+a[a.length-1].label,r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getFullYear(),n=new Date(i.$date);37===e.keyCode?n.setYear(t-1):38===e.keyCode?n.setYear(t-4):39===e.keyCode?n.setYear(t+1):40===e.keyCode&&n.setYear(t+4),this.isDisabled(n)||i.select(n,!0)}}}];return{views:s.minView?Array.prototype.slice.call($,s.minView):$,viewDate:m}}}]}),angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$dropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',template:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(t,n,a,o){function i(t,i){function l(e){return e.target!==t[0]?e.target!==t[0]&&u.hide():void 0}{var u={},c=angular.extend({},e,i);u.$scope=c.scope&&c.scope.$new()||n.$new()}u=a(t,c);var d=t.parent();u.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var t=angular.element(u.$element[0].querySelectorAll('li:not(.divider) a'));if(t.length){var n;angular.forEach(t,function(e,t){s&&s.call(e,':focus')&&(n=t)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&no;o++)if(e[o].toLowerCase()===a)return o;return-1}t.prototype.setMilliseconds=function(e){this.milliseconds=e},t.prototype.setSeconds=function(e){this.seconds=e},t.prototype.setMinutes=function(e){this.minutes=e},t.prototype.setHours=function(e){this.hours=e},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(e){this.day=e},t.prototype.setMonth=function(e){this.month=e},t.prototype.setFullYear=function(e){this.year=e},t.prototype.fromDate=function(e){return this.year=e.getFullYear(),this.month=e.getMonth(),this.day=e.getDate(),this.hours=e.getHours(),this.minutes=e.getMinutes(),this.seconds=e.getSeconds(),this.milliseconds=e.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=t.prototype,r=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(e,s){var l=function(l){function u(e){var t,n=Object.keys(h),a=[],o=[],i=e;for(t=0;t1){var r=i.search(n[t]);e=e.split(n[t]).join(''),h[n[t]]&&(a[r]=h[n[t]])}return angular.forEach(a,function(e){e&&o.push(e)}),o}function c(e){return e.replace(/\//g,'[\\/]').replace('/-/g','[-]').replace(/\./g,'[.]').replace(/\\s/g,'[\\s]')}function d(e){var t,n=Object.keys($),a=e;for(t=0;t12?e.getHours()+2:0),e):null},m.timezoneOffsetAdjust=function(e,t,n){return e?(t&&'UTC'===t&&(e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+(n?-1:1)*e.getTimezoneOffset())),e):null},m.init(),m};return l}]}]),angular.module('mgcrea.ngStrap.helpers.debounce',[]).factory('debounce',['$timeout',function(e){return function(t,n,a){var o=null;return function(){var i=this,r=arguments,s=a&&!o;return o&&e.cancel(o),o=e(function(){o=null,a||t.apply(i,r)},n,!1),s&&t.apply(i,r),o}}}]).factory('throttle',['$timeout',function(e){return function(t,n,a){var o=null;return a||(a={}),function(){var i=this,r=arguments;o||(a.leading!==!1&&t.apply(i,r),o=e(function(){o=null,a.trailing!==!1&&t.apply(i,r)},n,!1))}}}]),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('dimensions',['$document','$window',function(t,n){var a=(angular.element,{}),o=a.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()};a.css=function(t,n,a){var o;return o=t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n],a===!0?parseFloat(o)||0:o},a.offset=function(t){var n=t.getBoundingClientRect(),a=t.ownerDocument;return{width:n.width||t.offsetWidth,height:n.height||t.offsetHeight,top:n.top+(e.pageYOffset||a.documentElement.scrollTop)-(a.documentElement.clientTop||0),left:n.left+(e.pageXOffset||a.documentElement.scrollLeft)-(a.documentElement.clientLeft||0)}},a.setOffset=function(e,t,n){var o,i,r,s,l,u,c,d=a.css(e,'position'),f=angular.element(e),p={};'static'===d&&(e.style.position='relative'),l=a.offset(e),r=a.css(e,'top'),u=a.css(e,'left'),c=('absolute'===d||'fixed'===d)&&(r+u).indexOf('auto')>-1,c?(o=a.position(e),s=o.top,i=o.left):(s=parseFloat(r)||0,i=parseFloat(u)||0),angular.isFunction(t)&&(t=t.call(e,n,l)), -null!==t.top&&(p.top=t.top-l.top+s),null!==t.left&&(p.left=t.left-l.left+i),'using'in t?t.using.call(f,p):f.css({top:p.top+'px',left:p.left+'px'})},a.position=function(e){var t,n,r={top:0,left:0};return'fixed'===a.css(e,'position')?n=e.getBoundingClientRect():(t=i(e),n=a.offset(e),o(t,'html')||(r=a.offset(t)),r.top+=a.css(t,'borderTopWidth',!0),r.left+=a.css(t,'borderLeftWidth',!0)),{width:e.offsetWidth,height:e.offsetHeight,top:n.top-r.top-a.css(e,'marginTop',!0),left:n.left-r.left-a.css(e,'marginLeft',!0)}};var i=function(e){var t=e.ownerDocument,n=e.offsetParent||t;if(o(n,'#document'))return t.documentElement;for(;n&&!o(n,'html')&&'static'===a.css(n,'position');)n=n.offsetParent;return n||t.documentElement};return a.height=function(e,t){var n=e.offsetHeight;return t?n+=a.css(e,'marginTop',!0)+a.css(e,'marginBottom',!0):n-=a.css(e,'paddingTop',!0)+a.css(e,'paddingBottom',!0)+a.css(e,'borderTopWidth',!0)+a.css(e,'borderBottomWidth',!0),n},a.width=function(e,t){var n=e.offsetWidth;return t?n+=a.css(e,'marginLeft',!0)+a.css(e,'marginRight',!0):n-=a.css(e,'paddingLeft',!0)+a.css(e,'paddingRight',!0)+a.css(e,'borderLeftWidth',!0)+a.css(e,'borderRightWidth',!0),n},a}]),angular.module('mgcrea.ngStrap.helpers.parseOptions',[]).provider('$parseOptions',function(){var e=this.defaults={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+(.*?))?$/};this.$get=['$parse','$q',function(t,n){function a(a,o){function i(e,t){return e.map(function(e,n){var a,o,i={};return i[c]=e,a=u(t,i),o=p(t,i),{label:a,value:o,index:n}})}var r={},s=angular.extend({},e,o);r.$values=[];var l,u,c,d,f,p,g;return r.init=function(){r.$match=l=a.match(s.regexp),u=t(l[2]||l[1]),c=l[4]||l[6],d=l[5],f=t(l[3]||''),p=t(l[2]?l[1]:c),g=t(l[7])},r.valuesFn=function(e,t){return n.when(g(e,t)).then(function(t){return r.$values=t?i(t,e):{},r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.version.minor<3&&angular.version.dot<14&&angular.module('ng').factory('$$rAF',['$window','$timeout',function(e,t){var n=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame,a=e.cancelAnimationFrame||e.webkitCancelAnimationFrame||e.mozCancelAnimationFrame||e.webkitCancelRequestAnimationFrame,o=!!n,i=o?function(e){var t=n(e);return function(){a(t)}}:function(e){var n=t(e,16.66,!1);return function(){t.cancel(n)}};return i.supported=o,i}]),angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',template:'modal/modal.tpl.html',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$compile','$q','$templateCache','$http','$animate','$timeout','$sce','dimensions',function(n,a,o,i,r,s,l,u,c,d){function f(t){function n(){f.$emit(d.prefixEvent+'.show',u)}function i(){f.$emit(d.prefixEvent+'.hide',u),w.removeClass(d.prefixClass+'-open'),d.animation&&w.removeClass(d.prefixClass+'-with-'+d.animation)}function r(e){e.target===e.currentTarget&&('static'===d.backdrop?u.focus():u.hide())}function s(e){e.preventDefault()}var u={},d=u.$options=angular.extend({},e,t);u.$promise=m(d.template);var f=u.$scope=d.scope&&d.scope.$new()||a.$new();d.element||d.container||(d.container='body'),u.$id=d.id||d.element&&d.element.attr('id')||'',$(['title','content'],function(e){d[e]&&(f[e]=c.trustAsHtml(d[e]))}),f.$hide=function(){f.$$postDigest(function(){u.hide()})},f.$show=function(){f.$$postDigest(function(){u.show()})},f.$toggle=function(){f.$$postDigest(function(){u.toggle()})},u.$isShown=f.$isShown=!1,d.contentTemplate&&(u.$promise=u.$promise.then(function(e){var n=angular.element(e);return m(d.contentTemplate).then(function(e){var a=g('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e);return t.template||a.next().remove(),n[0].outerHTML})}));var b,D,k=angular.element('
');return k.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),u.$promise.then(function(e){angular.isObject(e)&&(e=e.data),d.html&&(e=e.replace(y,'ng-bind-html="')),e=h.apply(e),b=o(e),u.init()}),u.init=function(){d.show&&f.$$postDigest(function(){u.show()})},u.destroy=function(){D&&(D.remove(),D=null),k&&(k.remove(),k=null),f.$destroy()},u.show=function(){if(!u.$isShown){var e,t;if(angular.isElement(d.container)?(e=d.container,t=d.container[0].lastChild?angular.element(d.container[0].lastChild):null):d.container?(e=g(d.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=d.element),D=u.$element=b(f,function(e,t){}),!f.$emit(d.prefixEvent+'.show.before',u).defaultPrevented){D.css({display:'block'}).addClass(d.placement),d.animation&&(d.backdrop&&k.addClass(d.backdropAnimation),D.addClass(d.animation)),d.backdrop&&l.enter(k,w,null);var a=l.enter(D,e,t,n);a&&a.then&&a.then(n),u.$isShown=f.$isShown=!0,p(f);var o=D[0];v(function(){o.focus()}),w.addClass(d.prefixClass+'-open'),d.animation&&w.addClass(d.prefixClass+'-with-'+d.animation),d.backdrop&&(D.on('click',r),k.on('click',r),k.on('wheel',s)),d.keyboard&&D.on('keyup',u.$onKeyUp)}}},u.hide=function(){if(u.$isShown&&!f.$emit(d.prefixEvent+'.hide.before',u).defaultPrevented){var e=l.leave(D,i);e&&e.then&&e.then(i),d.backdrop&&l.leave(k),u.$isShown=f.$isShown=!1,p(f),d.backdrop&&(D.off('click',r),k.off('click',r),k.off('wheel',s)),d.keyboard&&D.off('keyup',u.$onKeyUp)}},u.toggle=function(){u.$isShown?u.hide():u.show()},u.focus=function(){D[0].focus()},u.$onKeyUp=function(e){27===e.which&&u.$isShown&&(u.hide(),e.stopPropagation())},u}function p(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function g(e,n){return angular.element((n||t).querySelectorAll(e))}function m(e){return b[e]?b[e]:b[e]=s.get(e,{cache:r}).then(function(e){return e.data})}var $=angular.forEach,h=String.prototype.trim,v=n.requestAnimationFrame||n.setTimeout,w=angular.element(n.document.body),y=/ng-bind="/gi,b={};return f}]}).directive('bsModal',['$window','$sce','$modal',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','contentTemplate','placement','backdrop','keyboard','html','container','animation','id','prefixEvent','prefixClass'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsModal&&e.$watch(o.bsModal,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.navbar',[]).provider('$navbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$navbar',function(e,t,n){var a=n.defaults;return{restrict:'A',link:function(e,n,o,i){var r=angular.copy(a);angular.forEach(Object.keys(a),function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),e.$watch(function(){return t.path()},function(e,t){var a=n[0].querySelectorAll('li['+r.routeAttr+']');angular.forEach(a,function(t){var n=angular.element(t),a=n.attr(r.routeAttr).replace('/','\\/');r.strict&&(a='^'+a+'$');var o=new RegExp(a,'i');o.test(e)?n.addClass(r.activeClass):n.removeClass(r.activeClass)})})}}}]),angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',template:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$tooltip',function(t){function n(n,a){var o=angular.extend({},e,a),i=t(n,o);return o.content&&(i.$scope.content=o.content),i}return n}]}).directive('bsPopover',['$window','$sce','$popover',function(e,t,n){var a=e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,o,i){var r={scope:e};angular.forEach(['template','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(e){angular.isDefined(i[e])&&(r[e]=i[e])});var s=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(e){angular.isDefined(i[e])&&s.test(i[e])&&(r[e]=!1)});var l=o.attr('data-target');angular.isDefined(l)&&(r.target=s.test(l)?!1:l),angular.forEach(['title','content'],function(n){i[n]&&i.$observe(n,function(o,i){e[n]=t.trustAsHtml(o),angular.isDefined(i)&&a(function(){u&&u.$applyPlacement()})})}),i.bsPopover&&e.$watch(i.bsPopover,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t,angular.isDefined(n)&&a(function(){u&&u.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){u&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(popover),?/i)),e===!0?u.show():u.hide())}),i.viewport&&e.$watch(i.viewport,function(e){u&&angular.isDefined(e)&&u.setViewport(e)});var u=n(o,r);e.$on('$destroy',function(){u&&u.destroy(),r=null,u=null})}}}]),angular.module('mgcrea.ngStrap.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$scrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','dimensions','debounce','throttle',function(a,o,i,r,s,l){function u(e,t){return e[0].nodeName&&e[0].nodeName.toLowerCase()===t.toLowerCase()}function c(o){var c=angular.extend({},n,o);c.element||(c.element=p);var g=u(c.element,'body'),m=g?d:c.element,$=g?'window':c.id;if(e[$])return e[$].$$count++,e[$];var h,v,w,y,b,D,k,S,x={},T=x.$trackedElements=[],C=[];return x.init=function(){this.$$count=1,y=s(this.checkPosition,c.debounce),b=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',y),m.on('scroll',b),D=s(this.checkOffsets,c.debounce),h=i.$on('$viewContentLoaded',D),v=i.$on('$includeContentLoaded',D),D(),$&&(e[$]=x)},x.destroy=function(){this.$$count--,this.$$count>0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',y),m.off('scroll',b),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(C.length){if(S=(g?a.pageYOffset:m.prop('scrollTop'))||0,k=Math.max(a.innerHeight,f.prop('clientHeight')),SC[e+1].offsetTop))return x.$activateElement(C[e])}},x.checkPositionWithEventLoop=function(){setTimeout(x.checkPosition,1)},x.$activateElement=function(e){if(w){var t=x.$getTrackedElement(w);t&&(t.source.removeClass('active'),u(t.source,'li')&&u(t.source.parent().parent(),'li')&&t.source.parent().parent().removeClass('active'))}w=e.target,e.source.addClass('active'),u(e.source,'li')&&u(e.source.parent().parent(),'li')&&e.source.parent().parent().addClass('active')},x.$getTrackedElement=function(e){return T.filter(function(t){return t.target===e})[0]},x.checkOffsets=function(){angular.forEach(T,function(e){var n=t.querySelector(e.target);e.offsetTop=n?r.offset(n).top:null,c.offset&&null!==e.offsetTop&&(e.offsetTop-=1*c.offset)}),C=T.filter(function(e){return null!==e.offsetTop}).sort(function(e,t){return e.offsetTop-t.offsetTop}),y()},x.trackElement=function(e,t){T.push({target:e,source:t})},x.untrackElement=function(e,t){for(var n,a=T.length;a--;)if(T[a].target===e&&T[a].source===t){n=a;break}T=T.splice(n,1)},x.activate=function(e){T[e].addClass('active')},x.init(),x}var d=angular.element(a),f=angular.element(o.prop('documentElement')),p=angular.element(a.document.body);return c}]}).directive('bsScrollspy',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'EAC',link:function(e,t,n){var o={scope:e};angular.forEach(['offset','target'],function(e){angular.isDefined(n[e])&&(o[e]=n[e])});var i=a(o);i.trackElement(o.target,t),e.$on('$destroy',function(){i&&(i.untrackElement(o.target,t),i.destroy()),o=null,i=null})}}}]).directive('bsScrollspyList',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'A',compile:function(e,t){var n=e[0].querySelectorAll('li > a[href]');angular.forEach(n,function(e){var t=angular.element(e);t.parent().attr('bs-scrollspy','').attr('data-target',t.attr('href'))})}}}]),angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$select',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',template:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:' ',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,o,i){function r(t,n,a){var r={},s=angular.extend({},e,a);r=o(t,s);var u=r.$scope;u.$matches=[],u.$activeIndex=s.multiple?[]:-1,u.$isMultiple=s.multiple,u.$showAllNoneButtons=s.allNoneButtons&&s.multiple,u.$iconCheckmark=s.iconCheckmark,u.$allText=s.allText,u.$noneText=s.noneText,u.$activate=function(e){u.$$postDigest(function(){r.activate(e)})},u.$select=function(e,t){u.$$postDigest(function(){r.select(e)})},u.$isVisible=function(){return r.$isVisible()},u.$isActive=function(e){return r.$isActive(e)},u.$selectAll=function(){for(var e=0;e=u.$matches.length&&(u.$activeIndex=s.multiple?[]:0)},r.$isVisible=function(){return s.minLength&&n?u.$matches.length&&n.$viewValue.length>=s.minLength:u.$matches.length},r.$isActive=function(e){return s.multiple?-1!==u.$activeIndex.indexOf(e):u.$activeIndex===e},r.$getIndex=function(e){var t=u.$matches.length,n=t;if(t){for(n=t;n--&&u.$matches[n].value!==e;);if(!(0>n))return n}},r.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},r.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(e.preventDefault(),e.stopPropagation(),s.multiple&&9===e.keyCode?r.hide():s.multiple||13!==e.keyCode&&9!==e.keyCode?void(s.multiple||(38===e.keyCode&&u.$activeIndex>0?u.$activeIndex--:38===e.keyCode&&u.$activeIndex<0?u.$activeIndex=u.$matches.length-1:40===e.keyCode&&u.$activeIndex'),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s),p=d.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(p,function(t,n){d.valuesFn(e,r).then(function(e){f.update(e),r.$render()})}),e.$watch(n.ngModel,function(e,t){f.$updateActiveIndex(),r.$render()},!0),r.$render=function(){var e,n;s.multiple&&angular.isArray(r.$modelValue)?(e=r.$modelValue.map(function(e){return n=f.$getIndex(e),angular.isDefined(n)?f.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(s.maxLength||i.maxLength)?e.length+' '+(s.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=f.$getIndex(r.$modelValue),e=angular.isDefined(n)?f.$scope.$matches[n].label:!1),t.html((e?e:s.placeholder)+(s.caretHtml?s.caretHtml:i.caretHtml))},s.multiple&&(r.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){f&&f.destroy(),s=null,f=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$tab',function(){var e=this.defaults={animation:'am-fade',template:'tab/tab.tpl.html',navClass:'nav-tabs',activeClass:'active'},t=this.controller=function(t,n,a){var o=this;o.$options=angular.copy(e),angular.forEach(['animation','navClass','activeClass'],function(e){angular.isDefined(a[e])&&(o.$options[e]=a[e])}),t.$navClass=o.$options.navClass,t.$activeClass=o.$options.activeClass,o.$panes=t.$panes=[],o.$activePaneChangeListeners=o.$viewChangeListeners=[],o.$push=function(e){angular.isUndefined(o.$panes.$active)&&t.$setActive(e.name||0),o.$panes.push(e)},o.$remove=function(e){var t,n=o.$panes.indexOf(e),a=o.$panes.$active;t=angular.isString(a)?o.$panes.map(function(e){return e.name}).indexOf(a):o.$panes.$active,o.$panes.splice(n,1),t>n?t--:n===t&&t===o.$panes.length&&t--,t>=0&&tt?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},f.$build=function(){var e,t,n=m.midIndex=parseInt(g.length/2,10),a=[];for(e=0;e1*g.maxTime},m.$arrowAction=function(e,t){'picker'===g.arrowBehavior?f.$setTimeByStep(e,t):f.$moveIndex(e,t)},f.$setTimeByStep=function(e,t){{var n=new Date(f.$date),a=n.getHours(),o=(h(n,k).length,n.getMinutes()),i=(h(n,x).length,n.getSeconds());h(n,T).length}0===t?n.setHours(a-parseInt(g.hourStep,10)*e):1===t?n.setMinutes(o-parseInt(g.minuteStep,10)*e):2===t&&n.setSeconds(i-parseInt(g.secondStep,10)*e),f.select(n,t,!0)},f.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,b.hour+e*g.length,b.minute,b.second),angular.extend(b,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,b.hour,b.minute+e*g.length*g.minuteStep,b.second),angular.extend(b,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,b.hour,b.minute,b.second+e*g.length*g.secondStep),angular.extend(b,{second:n.getSeconds()})),f.$build()},f.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},f.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,k).length,o=t.getMinutes(),i=h(t,x).length,r=t.getSeconds(),s=h(t,T).length,u=1,c=/(37|39)/.test(e.keyCode),d=2+1*C+1*M;c&&(37===e.keyCode?v=1>v?d-1:v-1:39===e.keyCode&&(v=d-1>v?v+1:0));var m=[0,a],$=0;38===e.keyCode&&($=-1),40===e.keyCode&&($=1);var w=2===v&&C,y=2===v&&!C||3===v&&C;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,k).length,m=[0,a]):1===v?(t.setMinutes(o+$*parseInt(g.minuteStep,10)),i=h(t,x).length,m=[a+u,i]):w?(t.setSeconds(r+$*parseInt(g.secondStep,10)),s=h(t,T).length,m=[a+u+i+u,s]):y&&(c||f.switchMeridian(),m=[a+u+i+u+(s+u)*C,2]),f.select(t,v,!0),l(m[0],m[1]),p.$digest()}};var E=f.init;f.init=function(){return u&&g.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',d)),void E())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){F(),s(function(){f.$element.on(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t.on('keydown',f.$onKeyDown)},0,!1)};var V=f.hide;return f.hide=function(e){f.$isShown&&(f.$element.off(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t.off('keydown',f.$onKeyDown),V(e))},f}var u=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,n,a,o,i){{var r=i.defaults,s=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);e.requestAnimationFrame||e.setTimeout}return{restrict:'EAC',require:'ngModel',link:function(e,t,n,l){function u(e){if(angular.isDate(e)){var t=isNaN(d.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=d.minTime,n=isNaN(d.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=d.maxTime,a=t&&n;l.$setValidity('date',a),l.$setValidity('min',t),l.$setValidity('max',n),a&&(l.$dateValue=e)}}function c(){return!l.$dateValue||isNaN(l.$dateValue.getTime())?'':m(l.$dateValue,d.timeFormat)}var d={scope:e,controller:l};angular.forEach(['placement','container','delay','trigger','keyboard','html','animation','template','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?p.show():p.hide())}),s&&(d.useNative||r.useNative)&&(d.timeFormat='HH:mm');var p=i(t,l,d);d=p.$options;var g=d.lang,m=function(e,t,n){return a.formatDate(e,t,g,n)},$=o({format:d.timeFormat,lang:g});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getTimeForAttribute(e,t),!isNaN(p.$options[e])&&p.$build(),u(l.$dateValue)})}),e.$watch(n.ngModel,function(e,t){p.update(l.$dateValue)},!0),l.$parsers.unshift(function(e){var t;if(!e)return l.$setValidity('date',!0),null;var n=angular.isDate(e)?e:$.parse(e,l.$dateValue);return!n||isNaN(n.getTime())?void l.$setValidity('date',!1):(u(n),'string'===d.timeType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelTimeFormat||d.timeFormat)):(t=$.timezoneOffsetAdjust(l.$dateValue,d.timezone,!0),'number'===d.timeType?t.getTime():'unix'===d.timeType?t.getTime()/1e3:'iso'===d.timeType?t.toISOString():new Date(t)))}),l.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===d.timeType?$.parse(e,null,d.modelTimeFormat):new Date('unix'===d.timeType?1e3*e:e),l.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),l.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.helpers.dimensions']).provider('$tooltip',function(){var e=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',template:'tooltip/tooltip.tpl.html',contentTemplate:!1,trigger:'hover focus',keyboard:!1,html:!1,show:!1,title:'',type:'',delay:0,autoClose:!1,bsEnabled:!0,viewport:{selector:'body',padding:0}};this.$get=['$window','$rootScope','$compile','$q','$templateCache','$http','$animate','$sce','dimensions','$$rAF','$timeout',function(n,a,o,i,r,s,l,u,c,d,f){function p(i,r){function s(){N.$emit(H.prefixEvent+'.show',I)}function p(){if(N.$emit(H.prefixEvent+'.hide',I),z===B){if(W&&'focus'===H.trigger)return i[0].blur();O()}}function b(){var e=H.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',I.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',I.enter),i.on('hover'===e?'mouseleave':'blur',I.leave),'button'===P&&'hover'!==e&&i.on(v?'touchstart':'mousedown',I.$onFocusElementMouseDown))})}function D(){for(var e=H.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',I.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',I.enter),i.off('hover'===n?'mouseleave':'blur',I.leave),'button'===P&&'hover'!==n&&i.off(v?'touchstart':'mousedown',I.$onFocusElementMouseDown))}}function k(){'focus'!==H.trigger?z.on('keyup',I.$onKeyUp):i.on('keyup',I.$onFocusKeyUp)}function S(){'focus'!==H.trigger?z.off('keyup',I.$onKeyUp):i.off('keyup',I.$onFocusKeyUp)}function x(){f(function(){z.on('click',C),y.on('click',I.hide),_=!0},0,!1)}function T(){_&&(z.off('click',C),y.off('click',I.hide),_=!1)}function C(e){e.stopPropagation()}function M(e){e=e||H.target||i;var a=e[0],o='BODY'===a.tagName,r=a.getBoundingClientRect(),s={};for(var l in r)s[l]=r[l];null===s.width&&(s=angular.extend({},s,{width:r.right-r.left,height:r.bottom-r.top}));var u=o?{top:0,left:0}:c.offset(a),d={scroll:o?t.documentElement.scrollTop||t.body.scrollTop:e.prop('scrollTop')||0},f=o?{width:t.documentElement.clientWidth,height:n.innerHeight}:null;return angular.extend({},s,d,f,u)}function E(e,t,n,a){var o,i=e.split('-');switch(i[0]){case'right':o={top:t.top+t.height/2-a/2,left:t.left+t.width};break;case'bottom':o={top:t.top+t.height,left:t.left+t.width/2-n/2};break;case'left': -o={top:t.top+t.height/2-a/2,left:t.left-n};break;default:o={top:t.top-a,left:t.left+t.width/2-n/2}}if(!i[1])return o;if('top'===i[0]||'bottom'===i[0])switch(i[1]){case'left':o.left=t.left;break;case'right':o.left=t.left+t.width-n}else if('left'===i[0]||'right'===i[0])switch(i[1]){case'top':o.top=t.top-a;break;case'bottom':o.top=t.top+t.height}return o}function A(e,t){var n=z[0],a=n.offsetWidth,o=n.offsetHeight,i=parseInt(c.css(n,'margin-top'),10),r=parseInt(c.css(n,'margin-left'),10);isNaN(i)&&(i=0),isNaN(r)&&(r=0),e.top=e.top+i,e.left=e.left+r,c.setOffset(n,angular.extend({using:function(e){z.css({top:Math.round(e.top)+'px',left:Math.round(e.left)+'px',right:''})}},e),0);var s=n.offsetWidth,l=n.offsetHeight;if('top'===t&&l!==o&&(e.top=e.top+o-l),!/top-left|top-right|bottom-left|bottom-right/.test(t)){var u=F(t,e,s,l);if(u.left?e.left+=u.left:e.top+=u.top,c.setOffset(n,e),/top|right|bottom|left/.test(t)){var d=/top|bottom/.test(t),f=d?2*u.left-a+s:2*u.top-o+l,p=d?'offsetWidth':'offsetHeight';V(f,n[p],d)}}}function F(e,t,n,a){var o={top:0,left:0},i=H.viewport&&m(H.viewport.selector||H.viewport);if(!i)return o;var r=H.viewport&&H.viewport.padding||0,s=M(i);if(/right|left/.test(e)){var l=t.top-r-s.scroll,u=t.top+r-s.scroll+a;ls.top+s.height&&(o.top=s.top+s.height-u)}else{var c=t.left-r,d=t.left+r+n;cs.width&&(o.left=s.left+s.width-d)}return o}function V(e,t,n){var a=m('.tooltip-arrow, .arrow',z[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function O(){clearTimeout(R),I.$isShown&&null!==z&&(H.autoClose&&T(),H.keyboard&&S()),j&&(j.$destroy(),j=null),z&&(z.remove(),z=I.$element=null)}var I={},P=i[0].nodeName.toLowerCase(),H=I.$options=angular.extend({},e,r);I.$promise=$(H.template);var N=I.$scope=H.scope&&H.scope.$new()||a.$new();if(H.delay&&angular.isString(H.delay)){var L=H.delay.split(',').map(parseFloat);H.delay=L.length>1?{show:L[0],hide:L[1]}:L[0]}I.$id=H.id||i.attr('id')||'',H.title&&(N.title=u.trustAsHtml(H.title)),N.$setEnabled=function(e){N.$$postDigest(function(){I.setEnabled(e)})},N.$hide=function(){N.$$postDigest(function(){I.hide()})},N.$show=function(){N.$$postDigest(function(){I.show()})},N.$toggle=function(){N.$$postDigest(function(){I.toggle()})},I.$isShown=N.$isShown=!1;var R,Y;H.contentTemplate&&(I.$promise=I.$promise.then(function(e){var t=angular.element(e);return $(H.contentTemplate).then(function(e){var n=m('[ng-bind="content"]',t[0]);return n.length||(n=m('[ng-bind="title"]',t[0])),n.removeAttr('ng-bind').html(e),t[0].outerHTML})}));var q,z,K,U,j;I.$promise.then(function(e){angular.isObject(e)&&(e=e.data),H.html&&(e=e.replace(w,'ng-bind-html="')),e=h.apply(e),K=e,q=o(e),I.init()}),I.init=function(){H.delay&&angular.isNumber(H.delay)&&(H.delay={show:H.delay,hide:H.delay}),'self'===H.container?U=i:angular.isElement(H.container)?U=H.container:H.container&&(U=m(H.container)),b(),H.target&&(H.target=angular.isElement(H.target)?H.target:m(H.target)),H.show&&N.$$postDigest(function(){'focus'===H.trigger?i[0].focus():I.show()})},I.destroy=function(){D(),O(),N.$destroy()},I.enter=function(){return clearTimeout(R),Y='in',H.delay&&H.delay.show?void(R=setTimeout(function(){'in'===Y&&I.show()},H.delay.show)):I.show()},I.show=function(){if(H.bsEnabled&&!I.$isShown){N.$emit(H.prefixEvent+'.show.before',I);var e,t;H.container?(e=U,t=U[0].lastChild?angular.element(U[0].lastChild):null):(e=null,t=i),z&&O(),j=I.$scope.$new(),z=I.$element=q(j,function(e,t){}),z.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),H.animation&&z.addClass(H.animation),H.type&&z.addClass(H.prefixClass+'-'+H.type),H.customClass&&z.addClass(H.customClass),t?t.after(z):e.prepend(z),I.$isShown=N.$isShown=!0,g(N),I.$applyPlacement();var n=l.enter(z,e,t,s);n&&n.then&&n.then(s),g(N),d(function(){z&&z.css({visibility:'visible'})}),H.keyboard&&('focus'!==H.trigger&&I.focus(),k()),H.autoClose&&x()}},I.leave=function(){return clearTimeout(R),Y='out',H.delay&&H.delay.hide?void(R=setTimeout(function(){'out'===Y&&I.hide()},H.delay.hide)):I.hide()};var W,B;I.hide=function(e){if(I.$isShown){N.$emit(H.prefixEvent+'.hide.before',I),W=e,B=z;var t=l.leave(z,p);t&&t.then&&t.then(p),I.$isShown=N.$isShown=!1,g(N),H.keyboard&&null!==z&&S(),H.autoClose&&null!==z&&T()}},I.toggle=function(){I.$isShown?I.leave():I.enter()},I.focus=function(){z[0].focus()},I.setEnabled=function(e){H.bsEnabled=e},I.setViewport=function(e){H.viewport=e},I.$applyPlacement=function(){if(z){var t=H.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),z.addClass(H.placement);var o=M(),r=z.prop('offsetWidth'),s=z.prop('offsetHeight');if(a){var l=t,u=H.container?m(H.container):i.parent(),c=M(u);l.indexOf('bottom')>=0&&o.bottom+s>c.bottom?t=l.replace('bottom','top'):l.indexOf('top')>=0&&o.top-sc.width?t='right'===l?'left':t.replace('left','right'):('left'===l||'bottom-right'===l||'top-right'===l)&&o.left-r=e.length&&(u.$activeIndex=s.autoSelect?0:-1),/^(bottom|bottom-left|bottom-right)$/.test(s.placement)||o(r.$applyPlacement)},r.activate=function(e){u.$activeIndex=e},r.select=function(e){if(-1!==e){var t=u.$matches[e].value;n.$setViewValue(t),n.$render(),u.$resetMatches(),l&&l.$digest(),u.$emit(s.prefixEvent+'.select',t,e,r)}},r.$isVisible=function(){return s.minLength&&n?u.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=s.minLength:!!u.$matches.length},r.$getIndex=function(e){var t=u.$matches.length,n=t;if(t){for(n=t;n--&&u.$matches[n].value!==e;);if(!(0>n))return n}},r.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},r.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!r.$isVisible()||13===e.keyCode&&-1===u.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&u.$matches.length?r.select(u.$activeIndex):38===e.keyCode&&u.$activeIndex>0?u.$activeIndex--:40===e.keyCode&&u.$activeIndex0)return void s.$setViewValue(s.$viewValue.substring(0,s.$viewValue.length-1));e.length>d&&(e=e.slice(0,d));var n=m.$isVisible();n&&m.update(e),(1!==e.length||e[0].value!==t)&&(!n&&m.update(e),s.$render())})}),s.$formatters.push(function(e){var t=g.displayValue(e);return t===n?'':t}),s.$render=function(){if(s.$isEmpty(s.$viewValue))return t.val('');var e=m.$getIndex(s.$modelValue),n=angular.isDefined(e)?m.$scope.$matches[e].label:s.$viewValue;n=angular.isObject(n)?g.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'';t.val(l.trimValue===!1?a:a.trim())},e.$on('$destroy',function(){m&&m.destroy(),l=null,m=null})}}}])}(window,document); +!function(e,t,n){'use strict';angular.module('mgcrea.ngStrap',['mgcrea.ngStrap.modal','mgcrea.ngStrap.aside','mgcrea.ngStrap.alert','mgcrea.ngStrap.button','mgcrea.ngStrap.select','mgcrea.ngStrap.datepicker','mgcrea.ngStrap.timepicker','mgcrea.ngStrap.navbar','mgcrea.ngStrap.tooltip','mgcrea.ngStrap.popover','mgcrea.ngStrap.dropdown','mgcrea.ngStrap.typeahead','mgcrea.ngStrap.scrollspy','mgcrea.ngStrap.affix','mgcrea.ngStrap.tab','mgcrea.ngStrap.collapse']),angular.module('mgcrea.ngStrap.affix',['mgcrea.ngStrap.helpers.dimensions','mgcrea.ngStrap.helpers.debounce']).provider('$affix',function(){var e=this.defaults={offsetTop:'auto',inlineStyles:!0};this.$get=['$window','debounce','dimensions',function(t,n,a){function o(o,s){function l(e,t,n){var a=u(),o=c();return v>=a?'top':null!==e&&a+e<=t.top?'middle':null!==w&&t.top+n+$>=o-w?'bottom':'middle'}function u(){return p[0]===t?t.pageYOffset:p[0].scrollTop}function c(){return p[0]===t?t.document.body.scrollHeight:p[0].scrollHeight}var d={},f=angular.extend({},e,s),p=f.target,g='affix affix-top affix-bottom',m=!1,$=0,h=0,v=0,w=0,y=null,b=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var k=0;k<1*f.offsetParent-1;k++)D=D.parent();else D=angular.element(f.offsetParent);return d.init=function(){this.$parseOffsets(),h=a.offset(o[0]).top+$,m=!o[0].style.width,p.on('scroll',this.checkPosition),p.on('click',this.checkPositionWithEventLoop),r.on('resize',this.$debouncedOnResize),this.checkPosition(),this.checkPositionWithEventLoop()},d.destroy=function(){p.off('scroll',this.checkPosition),p.off('click',this.checkPositionWithEventLoop),r.off('resize',this.$debouncedOnResize)},d.checkPositionWithEventLoop=function(){setTimeout(d.checkPosition,1)},d.checkPosition=function(){var e=u(),t=a.offset(o[0]),n=a.height(o[0]),r=l(b,t,n);y!==r&&(y=r,o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')),'top'===r?(b=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(b=f.offsetUnpin?-(1*f.offsetUnpin):t.top-e,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',f.offsetParent?'':i[0].offsetHeight-w-n-h+'px'))):(b=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))))},d.$onResize=function(){d.$parseOffsets(),d.checkPosition()},d.$debouncedOnResize=n(d.$onResize,50),d.$parseOffsets=function(){var e=o.css('position');f.inlineStyles&&o.css('position',f.offsetParent?'':'relative'),f.offsetTop&&('auto'===f.offsetTop&&(f.offsetTop='+0'),f.offsetTop.match(/^[-+]\d+$/)?($=1*-f.offsetTop,v=f.offsetParent?a.offset(D[0]).top+1*f.offsetTop:a.offset(o[0]).top-a.css(o[0],'marginTop',!0)+1*f.offsetTop):v=1*f.offsetTop),f.offsetBottom&&(w=f.offsetParent&&f.offsetBottom.match(/^[-+]\d+$/)?c()-(a.offset(D[0]).top+a.height(D[0]))+1*f.offsetBottom+1:1*f.offsetBottom),f.inlineStyles&&o.css('position',e)},d.init(),d}var i=angular.element(t.document.body),r=angular.element(t);return o}]}).directive('bsAffix',['$affix','$window',function(e,t){return{restrict:'EAC',require:'^?bsAffixTarget',link:function(n,a,o,i){var r={scope:n,target:i?i.$element:angular.element(t)};angular.forEach(['offsetTop','offsetBottom','offsetParent','offsetUnpin','inlineStyles'],function(e){if(angular.isDefined(o[e])){var t=o[e];/true/i.test(t)&&(t=!0),/false/i.test(t)&&(t=!1),r[e]=t}});var s=e(a,r);n.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]).directive('bsAffixTarget',function(){return{controller:['$element',function(e){this.$element=e}]}}),angular.module('mgcrea.ngStrap.alert',['mgcrea.ngStrap.modal']).provider('$alert',function(){var e=this.defaults={animation:'am-fade',prefixClass:'alert',prefixEvent:'alert',placement:null,template:'alert/alert.tpl.html',container:!1,element:null,backdrop:!1,keyboard:!0,show:!0,duration:!1,type:!1,dismissable:!0};this.$get=['$modal','$timeout',function(t,n){function a(a){var o={},i=angular.extend({},e,a);o=t(i),o.$scope.dismissable=!!i.dismissable,i.type&&(o.$scope.type=i.type);var r=o.show;return i.duration&&(o.show=function(){r(),n(function(){o.hide()},1e3*i.duration)}),o}return a}]}).directive('bsAlert',['$window','$sce','$alert',function(e,t,n){e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','placement','keyboard','html','container','animation','duration','dismissable'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['keyboard','html','container','dismissable'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),e.hasOwnProperty('title')||(e.title=''),angular.forEach(['title','content','type'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsAlert&&e.$watch(o.bsAlert,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.aside',['mgcrea.ngStrap.modal']).provider('$aside',function(){var e=this.defaults={animation:'am-fade-and-slide-right',prefixClass:'aside',prefixEvent:'aside',placement:'right',template:'aside/aside.tpl.html',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$modal',function(t){function n(n){var a={},o=angular.extend({},e,n);return a=t(o)}return n}]}).directive('bsAside',['$window','$sce','$aside',function(e,t,n){e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','contentTemplate','placement','backdrop','keyboard','html','container','animation'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsAside&&e.$watch(o.bsAside,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.collapse',[]).provider('$collapse',function(){var e=this.defaults={animation:'am-collapse',disallowToggle:!1,activeClass:'in',startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,n,a){function o(e){for(var t=l.$targets.$active,n=0;nt;t++)angular.forEach(g.rows[t],u.$setDisabledEl)},u.select=function(e,t){angular.isDate(n.$dateValue)||(n.$dateValue=new Date(e)),!g.$mode||t?(n.$setViewValue(angular.copy(e)),n.$render(),p.autoclose&&!t&&l(function(){u.hide(!0)})):(angular.extend($,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),u.setMode(g.$mode-1),u.$build())},u.setMode=function(e){g.$mode=e,h=u.$views[g.$mode],u.$build()},u.$build=function(e){e===!0&&h.built||(e!==!1||h.built)&&h.build.call(h)},u.$updateSelected=function(){for(var e=0,t=g.rows.length;t>e;e++)angular.forEach(g.rows[e],o)},u.$isSelected=function(e){return h.isSelected(e)},u.$setDisabledEl=function(e){e.disabled=h.isDisabled(e.date)},u.$selectPane=function(e){var t=h.steps,n=new Date(Date.UTC($.year+(t.year||0)*e,$.month+(t.month||0)*e,1));angular.extend($,{year:n.getUTCFullYear(),month:n.getUTCMonth(),date:n.getUTCDate()}),u.$build()},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},u.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return g.$mode?g.$apply(function(){u.setMode(g.$mode-1)}):u.hide(!0);h.onKeyDown(e),f.$digest()}};var v=u.init;u.init=function(){return c&&p.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',i)),void v())};var w=u.destroy;u.destroy=function(){c&&p.useNative&&t.off('click',i),w()};var y=u.show;u.show=function(){y(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1)};var b=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),b(e))},u}var c=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),d='createTouch'in t.document&&c;return e.lang||(e.lang=i.getDefaultLocale()),u.defaults=e,u}]}).directive('bsDatepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$datepicker',function(e,t,n,a,o,i){var r=(i.defaults,/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent));return{restrict:'EAC',require:'ngModel',link:function(e,t,n,s){function l(e){return e&&e.length?e:null}function u(e){if(angular.isDate(e)){var t=isNaN(p.$options.minDate)||e.getTime()>=p.$options.minDate,n=isNaN(p.$options.maxDate)||e.getTime()<=p.$options.maxDate,a=t&&n;s.$setValidity('date',a),s.$setValidity('min',t),s.$setValidity('max',n),a&&(s.$dateValue=e)}}function c(){return!s.$dateValue||isNaN(s.$dateValue.getTime())?'':m(s.$dateValue,d.dateFormat)}var d={scope:e,controller:s};angular.forEach(['placement','container','delay','trigger','html','animation','template','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?p.show():p.hide())});var p=i(t,s,d);d=p.$options,r&&d.useNative&&(d.dateFormat='yyyy-MM-dd');var g=d.lang,m=function(e,t){return a.formatDate(e,t,g)},$=o({format:d.dateFormat,lang:g,strict:d.strictFormat});angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getDateForAttribute(e,t),!isNaN(p.$options[e])&&p.$build(!1),u(s.$dateValue)})}),e.$watch(n.ngModel,function(e,t){p.update(s.$dateValue)},!0),angular.isDefined(n.disabledDates)&&e.$watch(n.disabledDates,function(e,t){e=l(e),t=l(t),e&&p.updateDisabledDates(e)}),s.$parsers.unshift(function(e){var t;if(!e)return s.$setValidity('date',!0),null;var n=$.parse(e,s.$dateValue);return!n||isNaN(n.getTime())?void s.$setValidity('date',!1):(u(n),'string'===d.dateType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelDateFormat||d.dateFormat)):(t=$.timezoneOffsetAdjust(s.$dateValue,d.timezone,!0),'number'===d.dateType?t.getTime():'unix'===d.dateType?t.getTime()/1e3:'iso'===d.dateType?t.toISOString():new Date(t)))}),s.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):new Date('unix'===d.dateType?1e3*e:e),s.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),s.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]).provider('datepickerViews',function(){function e(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n}function t(e,t){return(e%t+t)%t}this.defaults={dayFormat:'dd',daySplit:7};this.$get=['$dateFormatter','$dateParser','$sce',function(n,a,o){return function(i){var r=i.$scope,s=i.$options,l=s.lang,u=function(e,t){return n.formatDate(e,t,l)},c=a({format:s.dateFormat,lang:l,strict:s.strictFormat}),d=n.weekdaysShort(l),f=d.slice(s.startWeek).concat(d.slice(0,s.startWeek)),p=o.trustAsHtml(''+f.join('')+''),g=i.$date||(s.startDate?c.getDateForAttribute('startDate',s.startDate):new Date),m={year:g.getFullYear(),month:g.getMonth(),date:g.getDate()},$=[{format:s.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==m.year||e.getMonth()!==m.month?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):(e.getDate()!==m.date||1===e.getDate())&&(m.date=i.$date.getDate(),i.$updateSelected())},build:function(){var n=new Date(m.year,m.month,1),a=n.getTimezoneOffset(),o=new Date(+n-864e5*t(n.getDay()-s.startWeek,7)),l=o.getTimezoneOffset(),d=c.timezoneOffsetAdjust(new Date,s.timezone).toDateString();l!==a&&(o=new Date(+o+6e4*(l-a)));for(var f,g=[],$=0;42>$;$++)f=c.daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth(),o.getDate()+$)),g.push({date:f,isToday:f.toDateString()===d,label:u(f,this.format),selected:i.$date&&this.isSelected(f),muted:f.getMonth()!==m.month,disabled:this.isDisabled(f)});r.title=u(n,s.monthTitleFormat),r.showLabels=!0,r.labels=p,r.rows=e(g,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()&&e.getDate()===i.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(ts.maxDate)return!0;if(-1!==s.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(s.disabledDateRanges)for(var n=0;n=s.disabledDateRanges[n].start&&t<=s.disabledDateRanges[n].end)return!0;return!1},onKeyDown:function(e){if(i.$date){var t,n=i.$date.getTime();37===e.keyCode?t=new Date(n-864e5):38===e.keyCode?t=new Date(n-6048e5):39===e.keyCode?t=new Date(n+864e5):40===e.keyCode&&(t=new Date(n+6048e5)),this.isDisabled(t)||i.select(t,!0)}}},{name:'month',format:s.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===m.year?e.getMonth()!==m.month&&(angular.extend(m,{month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected()):(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build())},build:function(){for(var t,n=(new Date(m.year,0,1),[]),a=0;12>a;a++)t=new Date(m.year,a,1),n.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=u(t,s.yearTitleFormat),r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getMonth(),n=new Date(i.$date);37===e.keyCode?n.setMonth(t-1):38===e.keyCode?n.setMonth(t-4):39===e.keyCode?n.setMonth(t+1):40===e.keyCode&&n.setMonth(t+4),this.isDisabled(n)||i.select(n,!0)}}},{name:'year',format:s.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt(m.year/20,10)?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getFullYear()!==m.year&&(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected())},build:function(){for(var t,n=m.year-m.year%(3*this.split),a=[],o=0;12>o;o++)t=new Date(n+o,0,1),a.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=a[0].label+'-'+a[a.length-1].label,r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getFullYear(),n=new Date(i.$date);37===e.keyCode?n.setYear(t-1):38===e.keyCode?n.setYear(t-4):39===e.keyCode?n.setYear(t+1):40===e.keyCode&&n.setYear(t+4),this.isDisabled(n)||i.select(n,!0)}}}];return{views:s.minView?Array.prototype.slice.call($,s.minView):$,viewDate:m}}}]}),angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$dropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',template:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(t,n,a,o){function i(t,i){function l(e){return e.target!==t[0]?e.target!==t[0]&&u.hide():void 0}{var u={},c=angular.extend({},e,i);u.$scope=c.scope&&c.scope.$new()||n.$new()}u=a(t,c);var d=t.parent();u.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var t=angular.element(u.$element[0].querySelectorAll('li:not(.divider) a'));if(t.length){var n;angular.forEach(t,function(e,t){s&&s.call(e,':focus')&&(n=t)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&no;o++)if(e[o].toLowerCase()===a)return o;return-1}t.prototype.setMilliseconds=function(e){this.milliseconds=e},t.prototype.setSeconds=function(e){this.seconds=e},t.prototype.setMinutes=function(e){this.minutes=e},t.prototype.setHours=function(e){this.hours=e},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(e){this.day=e},t.prototype.setMonth=function(e){this.month=e},t.prototype.setFullYear=function(e){this.year=e},t.prototype.fromDate=function(e){return this.year=e.getFullYear(),this.month=e.getMonth(),this.day=e.getDate(),this.hours=e.getHours(),this.minutes=e.getMinutes(),this.seconds=e.getSeconds(),this.milliseconds=e.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=t.prototype,r=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(e,s){var l=function(l){function u(e){var t,n=Object.keys(h),a=[],o=[],i=e;for(t=0;t1){var r=i.search(n[t]);e=e.split(n[t]).join(''),h[n[t]]&&(a[r]=h[n[t]])}return angular.forEach(a,function(e){e&&o.push(e)}),o}function c(e){return e.replace(/\//g,'[\\/]').replace('/-/g','[-]').replace(/\./g,'[.]').replace(/\\s/g,'[\\s]')}function d(e){var t,n=Object.keys($),a=e;for(t=0;t12?e.getHours()+2:0),e):null},m.timezoneOffsetAdjust=function(e,t,n){return e?(t&&'UTC'===t&&(e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+(n?-1:1)*e.getTimezoneOffset())),e):null},m.init(),m};return l}]}]),angular.module('mgcrea.ngStrap.helpers.debounce',[]).factory('debounce',['$timeout',function(e){return function(t,n,a){var o=null;return function(){var i=this,r=arguments,s=a&&!o;return o&&e.cancel(o),o=e(function(){o=null,a||t.apply(i,r)},n,!1),s&&t.apply(i,r),o}}}]).factory('throttle',['$timeout',function(e){return function(t,n,a){var o=null;return a||(a={}),function(){var i=this,r=arguments;o||(a.leading!==!1&&t.apply(i,r),o=e(function(){o=null,a.trailing!==!1&&t.apply(i,r)},n,!1))}}}]),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('dimensions',['$document','$window',function(t,n){var a=(angular.element,{}),o=a.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()};a.css=function(t,n,a){var o;return o=t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n],a===!0?parseFloat(o)||0:o},a.offset=function(t){var n=t.getBoundingClientRect(),a=t.ownerDocument;return{width:n.width||t.offsetWidth,height:n.height||t.offsetHeight,top:n.top+(e.pageYOffset||a.documentElement.scrollTop)-(a.documentElement.clientTop||0),left:n.left+(e.pageXOffset||a.documentElement.scrollLeft)-(a.documentElement.clientLeft||0)}},a.setOffset=function(e,t,n){var o,i,r,s,l,u,c,d=a.css(e,'position'),f=angular.element(e),p={};'static'===d&&(e.style.position='relative'),l=a.offset(e),r=a.css(e,'top'),u=a.css(e,'left'),c=('absolute'===d||'fixed'===d)&&(r+u).indexOf('auto')>-1,c?(o=a.position(e),s=o.top,i=o.left):(s=parseFloat(r)||0,i=parseFloat(u)||0),angular.isFunction(t)&&(t=t.call(e,n,l)), +null!==t.top&&(p.top=t.top-l.top+s),null!==t.left&&(p.left=t.left-l.left+i),'using'in t?t.using.call(f,p):f.css({top:p.top+'px',left:p.left+'px'})},a.position=function(e){var t,n,r={top:0,left:0};return'fixed'===a.css(e,'position')?n=e.getBoundingClientRect():(t=i(e),n=a.offset(e),o(t,'html')||(r=a.offset(t)),r.top+=a.css(t,'borderTopWidth',!0),r.left+=a.css(t,'borderLeftWidth',!0)),{width:e.offsetWidth,height:e.offsetHeight,top:n.top-r.top-a.css(e,'marginTop',!0),left:n.left-r.left-a.css(e,'marginLeft',!0)}};var i=function(e){var t=e.ownerDocument,n=e.offsetParent||t;if(o(n,'#document'))return t.documentElement;for(;n&&!o(n,'html')&&'static'===a.css(n,'position');)n=n.offsetParent;return n||t.documentElement};return a.height=function(e,t){var n=e.offsetHeight;return t?n+=a.css(e,'marginTop',!0)+a.css(e,'marginBottom',!0):n-=a.css(e,'paddingTop',!0)+a.css(e,'paddingBottom',!0)+a.css(e,'borderTopWidth',!0)+a.css(e,'borderBottomWidth',!0),n},a.width=function(e,t){var n=e.offsetWidth;return t?n+=a.css(e,'marginLeft',!0)+a.css(e,'marginRight',!0):n-=a.css(e,'paddingLeft',!0)+a.css(e,'paddingRight',!0)+a.css(e,'borderLeftWidth',!0)+a.css(e,'borderRightWidth',!0),n},a}]),angular.module('mgcrea.ngStrap.helpers.parseOptions',[]).provider('$parseOptions',function(){var e=this.defaults={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+(.*?))?$/};this.$get=['$parse','$q',function(t,n){function a(a,o){function i(e,t){return e.map(function(e,n){var a,o,i={};return i[c]=e,a=u(t,i),o=p(t,i),{label:a,value:o,index:n}})}var r={},s=angular.extend({},e,o);r.$values=[];var l,u,c,d,f,p,g;return r.init=function(){r.$match=l=a.match(s.regexp),u=t(l[2]||l[1]),c=l[4]||l[6],d=l[5],f=t(l[3]||''),p=t(l[2]?l[1]:c),g=t(l[7])},r.valuesFn=function(e,t){return n.when(g(e,t)).then(function(t){return r.$values=t?i(t,e):{},r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.version.minor<3&&angular.version.dot<14&&angular.module('ng').factory('$$rAF',['$window','$timeout',function(e,t){var n=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame,a=e.cancelAnimationFrame||e.webkitCancelAnimationFrame||e.mozCancelAnimationFrame||e.webkitCancelRequestAnimationFrame,o=!!n,i=o?function(e){var t=n(e);return function(){a(t)}}:function(e){var n=t(e,16.66,!1);return function(){t.cancel(n)}};return i.supported=o,i}]),angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',template:'modal/modal.tpl.html',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$compile','$q','$templateCache','$http','$animate','$timeout','$sce','dimensions',function(n,a,o,i,r,s,l,u,c,d){function f(t){function n(){f.$emit(d.prefixEvent+'.show',u)}function i(){f.$emit(d.prefixEvent+'.hide',u),w.removeClass(d.prefixClass+'-open'),d.animation&&w.removeClass(d.prefixClass+'-with-'+d.animation)}function r(e){e.target===e.currentTarget&&('static'===d.backdrop?u.focus():u.hide())}function s(e){e.preventDefault()}var u={},d=u.$options=angular.extend({},e,t);u.$promise=m(d.template);var f=u.$scope=d.scope&&d.scope.$new()||a.$new();d.element||d.container||(d.container='body'),u.$id=d.id||d.element&&d.element.attr('id')||'',$(['title','content'],function(e){d[e]&&(f[e]=c.trustAsHtml(d[e]))}),f.$hide=function(){f.$$postDigest(function(){u.hide()})},f.$show=function(){f.$$postDigest(function(){u.show()})},f.$toggle=function(){f.$$postDigest(function(){u.toggle()})},u.$isShown=f.$isShown=!1,d.contentTemplate&&(u.$promise=u.$promise.then(function(e){var n=angular.element(e);return m(d.contentTemplate).then(function(e){var a=g('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e);return t.template||a.next().remove(),n[0].outerHTML})}));var b,D,k=angular.element('
');return k.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),u.$promise.then(function(e){angular.isObject(e)&&(e=e.data),d.html&&(e=e.replace(y,'ng-bind-html="')),e=h.apply(e),b=o(e),u.init()}),u.init=function(){d.show&&f.$$postDigest(function(){u.show()})},u.destroy=function(){D&&(D.remove(),D=null),k&&(k.remove(),k=null),f.$destroy()},u.show=function(){if(!u.$isShown){var e,t;if(angular.isElement(d.container)?(e=d.container,t=d.container[0].lastChild?angular.element(d.container[0].lastChild):null):d.container?(e=g(d.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=d.element),D=u.$element=b(f,function(e,t){}),!f.$emit(d.prefixEvent+'.show.before',u).defaultPrevented){D.css({display:'block'}).addClass(d.placement),d.animation&&(d.backdrop&&k.addClass(d.backdropAnimation),D.addClass(d.animation)),d.backdrop&&l.enter(k,w,null),angular.version.minor<=2?l.enter(D,e,t,n):l.enter(D,e,t).then(n),u.$isShown=f.$isShown=!0,p(f);var a=D[0];v(function(){a.focus()}),w.addClass(d.prefixClass+'-open'),d.animation&&w.addClass(d.prefixClass+'-with-'+d.animation),d.backdrop&&(D.on('click',r),k.on('click',r),k.on('wheel',s)),d.keyboard&&D.on('keyup',u.$onKeyUp)}}},u.hide=function(){u.$isShown&&(f.$emit(d.prefixEvent+'.hide.before',u).defaultPrevented||(angular.version.minor<=2?l.leave(D,i):l.leave(D).then(i),d.backdrop&&l.leave(k),u.$isShown=f.$isShown=!1,p(f),d.backdrop&&(D.off('click',r),k.off('click',r),k.off('wheel',s)),d.keyboard&&D.off('keyup',u.$onKeyUp)))},u.toggle=function(){u.$isShown?u.hide():u.show()},u.focus=function(){D[0].focus()},u.$onKeyUp=function(e){27===e.which&&u.$isShown&&(u.hide(),e.stopPropagation())},u}function p(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function g(e,n){return angular.element((n||t).querySelectorAll(e))}function m(e){return b[e]?b[e]:b[e]=s.get(e,{cache:r}).then(function(e){return e.data})}var $=angular.forEach,h=String.prototype.trim,v=n.requestAnimationFrame||n.setTimeout,w=angular.element(n.document.body),y=/ng-bind="/gi,b={};return f}]}).directive('bsModal',['$window','$sce','$modal',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','contentTemplate','placement','backdrop','keyboard','html','container','animation','id','prefixEvent','prefixClass'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsModal&&e.$watch(o.bsModal,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.navbar',[]).provider('$navbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$navbar',function(e,t,n){var a=n.defaults;return{restrict:'A',link:function(e,n,o,i){var r=angular.copy(a);angular.forEach(Object.keys(a),function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),e.$watch(function(){return t.path()},function(e,t){var a=n[0].querySelectorAll('li['+r.routeAttr+']');angular.forEach(a,function(t){var n=angular.element(t),a=n.attr(r.routeAttr).replace('/','\\/');r.strict&&(a='^'+a+'$');var o=new RegExp(a,'i');o.test(e)?n.addClass(r.activeClass):n.removeClass(r.activeClass)})})}}}]),angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',template:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$tooltip',function(t){function n(n,a){var o=angular.extend({},e,a),i=t(n,o);return o.content&&(i.$scope.content=o.content),i}return n}]}).directive('bsPopover',['$window','$sce','$popover',function(e,t,n){var a=e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,o,i){var r={scope:e};angular.forEach(['template','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(e){angular.isDefined(i[e])&&(r[e]=i[e])});var s=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(e){angular.isDefined(i[e])&&s.test(i[e])&&(r[e]=!1)});var l=o.attr('data-target');angular.isDefined(l)&&(r.target=s.test(l)?!1:l),angular.forEach(['title','content'],function(n){i[n]&&i.$observe(n,function(o,i){e[n]=t.trustAsHtml(o),angular.isDefined(i)&&a(function(){u&&u.$applyPlacement()})})}),i.bsPopover&&e.$watch(i.bsPopover,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t,angular.isDefined(n)&&a(function(){u&&u.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){u&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(popover),?/i)),e===!0?u.show():u.hide())}),i.viewport&&e.$watch(i.viewport,function(e){u&&angular.isDefined(e)&&u.setViewport(e)});var u=n(o,r);e.$on('$destroy',function(){u&&u.destroy(),r=null,u=null})}}}]),angular.module('mgcrea.ngStrap.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$scrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','dimensions','debounce','throttle',function(a,o,i,r,s,l){function u(e,t){return e[0].nodeName&&e[0].nodeName.toLowerCase()===t.toLowerCase()}function c(o){var c=angular.extend({},n,o);c.element||(c.element=p);var g=u(c.element,'body'),m=g?d:c.element,$=g?'window':c.id;if(e[$])return e[$].$$count++,e[$];var h,v,w,y,b,D,k,S,x={},T=x.$trackedElements=[],C=[];return x.init=function(){this.$$count=1,y=s(this.checkPosition,c.debounce),b=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',y),m.on('scroll',b),D=s(this.checkOffsets,c.debounce),h=i.$on('$viewContentLoaded',D),v=i.$on('$includeContentLoaded',D),D(),$&&(e[$]=x)},x.destroy=function(){this.$$count--,this.$$count>0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',y),m.off('scroll',b),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(C.length){if(S=(g?a.pageYOffset:m.prop('scrollTop'))||0,k=Math.max(a.innerHeight,f.prop('clientHeight')),SC[e+1].offsetTop))return x.$activateElement(C[e])}},x.checkPositionWithEventLoop=function(){setTimeout(x.checkPosition,1)},x.$activateElement=function(e){if(w){var t=x.$getTrackedElement(w);t&&(t.source.removeClass('active'),u(t.source,'li')&&u(t.source.parent().parent(),'li')&&t.source.parent().parent().removeClass('active'))}w=e.target,e.source.addClass('active'),u(e.source,'li')&&u(e.source.parent().parent(),'li')&&e.source.parent().parent().addClass('active')},x.$getTrackedElement=function(e){return T.filter(function(t){return t.target===e})[0]},x.checkOffsets=function(){angular.forEach(T,function(e){var n=t.querySelector(e.target);e.offsetTop=n?r.offset(n).top:null,c.offset&&null!==e.offsetTop&&(e.offsetTop-=1*c.offset)}),C=T.filter(function(e){return null!==e.offsetTop}).sort(function(e,t){return e.offsetTop-t.offsetTop}),y()},x.trackElement=function(e,t){T.push({target:e,source:t})},x.untrackElement=function(e,t){for(var n,a=T.length;a--;)if(T[a].target===e&&T[a].source===t){n=a;break}T=T.splice(n,1)},x.activate=function(e){T[e].addClass('active')},x.init(),x}var d=angular.element(a),f=angular.element(o.prop('documentElement')),p=angular.element(a.document.body);return c}]}).directive('bsScrollspy',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'EAC',link:function(e,t,n){var o={scope:e};angular.forEach(['offset','target'],function(e){angular.isDefined(n[e])&&(o[e]=n[e])});var i=a(o);i.trackElement(o.target,t),e.$on('$destroy',function(){i&&(i.untrackElement(o.target,t),i.destroy()),o=null,i=null})}}}]).directive('bsScrollspyList',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'A',compile:function(e,t){var n=e[0].querySelectorAll('li > a[href]');angular.forEach(n,function(e){var t=angular.element(e);t.parent().attr('bs-scrollspy','').attr('data-target',t.attr('href'))})}}}]),angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$select',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',template:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:' ',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,o,i){function r(t,n,a){var r={},s=angular.extend({},e,a);r=o(t,s);var u=r.$scope;u.$matches=[],u.$activeIndex=s.multiple?[]:-1,u.$isMultiple=s.multiple,u.$showAllNoneButtons=s.allNoneButtons&&s.multiple,u.$iconCheckmark=s.iconCheckmark,u.$allText=s.allText,u.$noneText=s.noneText,u.$activate=function(e){u.$$postDigest(function(){r.activate(e)})},u.$select=function(e,t){u.$$postDigest(function(){r.select(e)})},u.$isVisible=function(){return r.$isVisible()},u.$isActive=function(e){return r.$isActive(e)},u.$selectAll=function(){for(var e=0;e=u.$matches.length&&(u.$activeIndex=s.multiple?[]:0)},r.$isVisible=function(){return s.minLength&&n?u.$matches.length&&n.$viewValue.length>=s.minLength:u.$matches.length},r.$isActive=function(e){return s.multiple?-1!==u.$activeIndex.indexOf(e):u.$activeIndex===e},r.$getIndex=function(e){var t=u.$matches.length,n=t;if(t){for(n=t;n--&&u.$matches[n].value!==e;);if(!(0>n))return n}},r.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},r.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(e.preventDefault(),e.stopPropagation(),s.multiple&&9===e.keyCode?r.hide():s.multiple||13!==e.keyCode&&9!==e.keyCode?void(s.multiple||(38===e.keyCode&&u.$activeIndex>0?u.$activeIndex--:38===e.keyCode&&u.$activeIndex<0?u.$activeIndex=u.$matches.length-1:40===e.keyCode&&u.$activeIndex'),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s),p=d.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(p,function(t,n){d.valuesFn(e,r).then(function(e){f.update(e),r.$render()})}),e.$watch(n.ngModel,function(e,t){f.$updateActiveIndex(),r.$render()},!0),r.$render=function(){var e,n;s.multiple&&angular.isArray(r.$modelValue)?(e=r.$modelValue.map(function(e){return n=f.$getIndex(e),angular.isDefined(n)?f.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(s.maxLength||i.maxLength)?e.length+' '+(s.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=f.$getIndex(r.$modelValue),e=angular.isDefined(n)?f.$scope.$matches[n].label:!1),t.html((e?e:s.placeholder)+(s.caretHtml?s.caretHtml:i.caretHtml))},s.multiple&&(r.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){f&&f.destroy(),s=null,f=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$tab',function(){var e=this.defaults={animation:'am-fade',template:'tab/tab.tpl.html',navClass:'nav-tabs',activeClass:'active'},t=this.controller=function(t,n,a){var o=this;o.$options=angular.copy(e),angular.forEach(['animation','navClass','activeClass'],function(e){angular.isDefined(a[e])&&(o.$options[e]=a[e])}),t.$navClass=o.$options.navClass,t.$activeClass=o.$options.activeClass,o.$panes=t.$panes=[],o.$activePaneChangeListeners=o.$viewChangeListeners=[],o.$push=function(e){angular.isUndefined(o.$panes.$active)&&t.$setActive(e.name||0),o.$panes.push(e)},o.$remove=function(e){var t,n=o.$panes.indexOf(e),a=o.$panes.$active;t=angular.isString(a)?o.$panes.map(function(e){return e.name}).indexOf(a):o.$panes.$active,o.$panes.splice(n,1),t>n?t--:n===t&&t===o.$panes.length&&t--,t>=0&&tt?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},f.$build=function(){var e,t,n=m.midIndex=parseInt(g.length/2,10),a=[];for(e=0;e1*g.maxTime},m.$arrowAction=function(e,t){'picker'===g.arrowBehavior?f.$setTimeByStep(e,t):f.$moveIndex(e,t)},f.$setTimeByStep=function(e,t){{var n=new Date(f.$date),a=n.getHours(),o=(h(n,k).length,n.getMinutes()),i=(h(n,x).length,n.getSeconds());h(n,T).length}0===t?n.setHours(a-parseInt(g.hourStep,10)*e):1===t?n.setMinutes(o-parseInt(g.minuteStep,10)*e):2===t&&n.setSeconds(i-parseInt(g.secondStep,10)*e),f.select(n,t,!0)},f.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,b.hour+e*g.length,b.minute,b.second),angular.extend(b,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,b.hour,b.minute+e*g.length*g.minuteStep,b.second),angular.extend(b,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,b.hour,b.minute,b.second+e*g.length*g.secondStep),angular.extend(b,{second:n.getSeconds()})),f.$build()},f.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},f.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,k).length,o=t.getMinutes(),i=h(t,x).length,r=t.getSeconds(),s=h(t,T).length,u=1,c=/(37|39)/.test(e.keyCode),d=2+1*C+1*M;c&&(37===e.keyCode?v=1>v?d-1:v-1:39===e.keyCode&&(v=d-1>v?v+1:0));var m=[0,a],$=0;38===e.keyCode&&($=-1),40===e.keyCode&&($=1);var w=2===v&&C,y=2===v&&!C||3===v&&C;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,k).length,m=[0,a]):1===v?(t.setMinutes(o+$*parseInt(g.minuteStep,10)),i=h(t,x).length,m=[a+u,i]):w?(t.setSeconds(r+$*parseInt(g.secondStep,10)),s=h(t,T).length,m=[a+u+i+u,s]):y&&(c||f.switchMeridian(),m=[a+u+i+u+(s+u)*C,2]),f.select(t,v,!0),l(m[0],m[1]),p.$digest()}};var E=f.init;f.init=function(){return u&&g.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',d)),void E())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){F(),s(function(){f.$element&&f.$element.on(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.on('keydown',f.$onKeyDown)},0,!1)};var V=f.hide;return f.hide=function(e){f.$isShown&&(f.$element&&f.$element.off(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.off('keydown',f.$onKeyDown),V(e))},f}var u=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,n,a,o,i){{var r=i.defaults,s=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);e.requestAnimationFrame||e.setTimeout}return{restrict:'EAC',require:'ngModel',link:function(e,t,n,l){function u(e){if(angular.isDate(e)){var t=isNaN(d.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=d.minTime,n=isNaN(d.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=d.maxTime,a=t&&n;l.$setValidity('date',a),l.$setValidity('min',t),l.$setValidity('max',n),a&&(l.$dateValue=e)}}function c(){return!l.$dateValue||isNaN(l.$dateValue.getTime())?'':m(l.$dateValue,d.timeFormat)}var d={scope:e,controller:l};angular.forEach(['placement','container','delay','trigger','keyboard','html','animation','template','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?p.show():p.hide())}),s&&(d.useNative||r.useNative)&&(d.timeFormat='HH:mm');var p=i(t,l,d);d=p.$options;var g=d.lang,m=function(e,t,n){return a.formatDate(e,t,g,n)},$=o({format:d.timeFormat,lang:g});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getTimeForAttribute(e,t),!isNaN(p.$options[e])&&p.$build(),u(l.$dateValue)})}),e.$watch(n.ngModel,function(e,t){p.update(l.$dateValue)},!0),l.$parsers.unshift(function(e){var t;if(!e)return l.$setValidity('date',!0),null;var n=angular.isDate(e)?e:$.parse(e,l.$dateValue);return!n||isNaN(n.getTime())?void l.$setValidity('date',!1):(u(n),'string'===d.timeType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelTimeFormat||d.timeFormat)):(t=$.timezoneOffsetAdjust(l.$dateValue,d.timezone,!0),'number'===d.timeType?t.getTime():'unix'===d.timeType?t.getTime()/1e3:'iso'===d.timeType?t.toISOString():new Date(t)))}),l.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===d.timeType?$.parse(e,null,d.modelTimeFormat):new Date('unix'===d.timeType?1e3*e:e),l.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),l.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.helpers.dimensions']).provider('$tooltip',function(){var e=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',template:'tooltip/tooltip.tpl.html',contentTemplate:!1,trigger:'hover focus',keyboard:!1,html:!1,show:!1,title:'',type:'',delay:0,autoClose:!1,bsEnabled:!0,viewport:{selector:'body',padding:0}};this.$get=['$window','$rootScope','$compile','$q','$templateCache','$http','$animate','$sce','dimensions','$$rAF','$timeout',function(n,a,o,i,r,s,l,u,c,d,f){function p(i,r){function s(){N.$emit(H.prefixEvent+'.show',I)}function p(){if(N.$emit(H.prefixEvent+'.hide',I),z===B){if(W&&'focus'===H.trigger)return i[0].blur();O()}}function b(){var e=H.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',I.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',I.enter),i.on('hover'===e?'mouseleave':'blur',I.leave),'button'===P&&'hover'!==e&&i.on(v?'touchstart':'mousedown',I.$onFocusElementMouseDown))})}function D(){for(var e=H.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',I.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',I.enter),i.off('hover'===n?'mouseleave':'blur',I.leave),'button'===P&&'hover'!==n&&i.off(v?'touchstart':'mousedown',I.$onFocusElementMouseDown))}}function k(){'focus'!==H.trigger?z.on('keyup',I.$onKeyUp):i.on('keyup',I.$onFocusKeyUp)}function S(){'focus'!==H.trigger?z.off('keyup',I.$onKeyUp):i.off('keyup',I.$onFocusKeyUp)}function x(){f(function(){z.on('click',C),y.on('click',I.hide),_=!0},0,!1)}function T(){_&&(z.off('click',C),y.off('click',I.hide),_=!1)}function C(e){e.stopPropagation()}function M(e){e=e||H.target||i;var a=e[0],o='BODY'===a.tagName,r=a.getBoundingClientRect(),s={};for(var l in r)s[l]=r[l];null===s.width&&(s=angular.extend({},s,{width:r.right-r.left,height:r.bottom-r.top}));var u=o?{top:0,left:0}:c.offset(a),d={scroll:o?t.documentElement.scrollTop||t.body.scrollTop:e.prop('scrollTop')||0},f=o?{width:t.documentElement.clientWidth,height:n.innerHeight}:null;return angular.extend({},s,d,f,u)}function E(e,t,n,a){var o,i=e.split('-');switch(i[0]){case'right':o={top:t.top+t.height/2-a/2,left:t.left+t.width +};break;case'bottom':o={top:t.top+t.height,left:t.left+t.width/2-n/2};break;case'left':o={top:t.top+t.height/2-a/2,left:t.left-n};break;default:o={top:t.top-a,left:t.left+t.width/2-n/2}}if(!i[1])return o;if('top'===i[0]||'bottom'===i[0])switch(i[1]){case'left':o.left=t.left;break;case'right':o.left=t.left+t.width-n}else if('left'===i[0]||'right'===i[0])switch(i[1]){case'top':o.top=t.top-a;break;case'bottom':o.top=t.top+t.height}return o}function A(e,t){var n=z[0],a=n.offsetWidth,o=n.offsetHeight,i=parseInt(c.css(n,'margin-top'),10),r=parseInt(c.css(n,'margin-left'),10);isNaN(i)&&(i=0),isNaN(r)&&(r=0),e.top=e.top+i,e.left=e.left+r,c.setOffset(n,angular.extend({using:function(e){z.css({top:Math.round(e.top)+'px',left:Math.round(e.left)+'px',right:''})}},e),0);var s=n.offsetWidth,l=n.offsetHeight;if('top'===t&&l!==o&&(e.top=e.top+o-l),!/top-left|top-right|bottom-left|bottom-right/.test(t)){var u=F(t,e,s,l);if(u.left?e.left+=u.left:e.top+=u.top,c.setOffset(n,e),/top|right|bottom|left/.test(t)){var d=/top|bottom/.test(t),f=d?2*u.left-a+s:2*u.top-o+l,p=d?'offsetWidth':'offsetHeight';V(f,n[p],d)}}}function F(e,t,n,a){var o={top:0,left:0},i=H.viewport&&m(H.viewport.selector||H.viewport);if(!i)return o;var r=H.viewport&&H.viewport.padding||0,s=M(i);if(/right|left/.test(e)){var l=t.top-r-s.scroll,u=t.top+r-s.scroll+a;ls.top+s.height&&(o.top=s.top+s.height-u)}else{var c=t.left-r,d=t.left+r+n;cs.width&&(o.left=s.left+s.width-d)}return o}function V(e,t,n){var a=m('.tooltip-arrow, .arrow',z[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function O(){clearTimeout(R),I.$isShown&&null!==z&&(H.autoClose&&T(),H.keyboard&&S()),j&&(j.$destroy(),j=null),z&&(z.remove(),z=I.$element=null)}var I={},P=i[0].nodeName.toLowerCase(),H=I.$options=angular.extend({},e,r);I.$promise=$(H.template);var N=I.$scope=H.scope&&H.scope.$new()||a.$new();if(H.delay&&angular.isString(H.delay)){var L=H.delay.split(',').map(parseFloat);H.delay=L.length>1?{show:L[0],hide:L[1]}:L[0]}I.$id=H.id||i.attr('id')||'',H.title&&(N.title=u.trustAsHtml(H.title)),N.$setEnabled=function(e){N.$$postDigest(function(){I.setEnabled(e)})},N.$hide=function(){N.$$postDigest(function(){I.hide()})},N.$show=function(){N.$$postDigest(function(){I.show()})},N.$toggle=function(){N.$$postDigest(function(){I.toggle()})},I.$isShown=N.$isShown=!1;var R,Y;H.contentTemplate&&(I.$promise=I.$promise.then(function(e){var t=angular.element(e);return $(H.contentTemplate).then(function(e){var n=m('[ng-bind="content"]',t[0]);return n.length||(n=m('[ng-bind="title"]',t[0])),n.removeAttr('ng-bind').html(e),t[0].outerHTML})}));var q,z,K,U,j;I.$promise.then(function(e){angular.isObject(e)&&(e=e.data),H.html&&(e=e.replace(w,'ng-bind-html="')),e=h.apply(e),K=e,q=o(e),I.init()}),I.init=function(){H.delay&&angular.isNumber(H.delay)&&(H.delay={show:H.delay,hide:H.delay}),'self'===H.container?U=i:angular.isElement(H.container)?U=H.container:H.container&&(U=m(H.container)),b(),H.target&&(H.target=angular.isElement(H.target)?H.target:m(H.target)),H.show&&N.$$postDigest(function(){'focus'===H.trigger?i[0].focus():I.show()})},I.destroy=function(){D(),O(),N.$destroy()},I.enter=function(){return clearTimeout(R),Y='in',H.delay&&H.delay.show?void(R=setTimeout(function(){'in'===Y&&I.show()},H.delay.show)):I.show()},I.show=function(){if(H.bsEnabled&&!I.$isShown){N.$emit(H.prefixEvent+'.show.before',I);var e,t;H.container?(e=U,t=U[0].lastChild?angular.element(U[0].lastChild):null):(e=null,t=i),z&&O(),j=I.$scope.$new(),z=I.$element=q(j,function(e,t){}),z.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),H.animation&&z.addClass(H.animation),H.type&&z.addClass(H.prefixClass+'-'+H.type),H.customClass&&z.addClass(H.customClass),t?t.after(z):e.prepend(z),I.$isShown=N.$isShown=!0,g(N),I.$applyPlacement(),angular.version.minor<=2?l.enter(z,e,t,s):l.enter(z,e,t).then(s),g(N),d(function(){z&&z.css({visibility:'visible'})}),H.keyboard&&('focus'!==H.trigger&&I.focus(),k()),H.autoClose&&x()}},I.leave=function(){return clearTimeout(R),Y='out',H.delay&&H.delay.hide?void(R=setTimeout(function(){'out'===Y&&I.hide()},H.delay.hide)):I.hide()};var W,B;I.hide=function(e){I.$isShown&&(N.$emit(H.prefixEvent+'.hide.before',I),W=e,B=z,angular.version.minor<=2?l.leave(z,p):l.leave(z).then(p),I.$isShown=N.$isShown=!1,g(N),H.keyboard&&null!==z&&S(),H.autoClose&&null!==z&&T())},I.toggle=function(){I.$isShown?I.leave():I.enter()},I.focus=function(){z[0].focus()},I.setEnabled=function(e){H.bsEnabled=e},I.setViewport=function(e){H.viewport=e},I.$applyPlacement=function(){if(z){var t=H.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),z.addClass(H.placement);var o=M(),r=z.prop('offsetWidth'),s=z.prop('offsetHeight');if(a){var l=t,u=H.container?m(H.container):i.parent(),c=M(u);l.indexOf('bottom')>=0&&o.bottom+s>c.bottom?t=l.replace('bottom','top'):l.indexOf('top')>=0&&o.top-sc.width?t='right'===l?'left':t.replace('left','right'):('left'===l||'bottom-right'===l||'top-right'===l)&&o.left-r=e.length&&(u.$activeIndex=s.autoSelect?0:-1),/^(bottom|bottom-left|bottom-right)$/.test(s.placement)||o(r.$applyPlacement)},r.activate=function(e){u.$activeIndex=e},r.select=function(e){if(-1!==e){var t=u.$matches[e].value;n.$setViewValue(t),n.$render(),u.$resetMatches(),l&&l.$digest(),u.$emit(s.prefixEvent+'.select',t,e,r)}},r.$isVisible=function(){return s.minLength&&n?u.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=s.minLength:!!u.$matches.length},r.$getIndex=function(e){var t=u.$matches.length,n=t;if(t){for(n=t;n--&&u.$matches[n].value!==e;);if(!(0>n))return n}},r.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},r.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!r.$isVisible()||13===e.keyCode&&-1===u.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&u.$matches.length?r.select(u.$activeIndex):38===e.keyCode&&u.$activeIndex>0?u.$activeIndex--:40===e.keyCode&&u.$activeIndex0)return void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1));e.length>c&&(e=e.slice(0,c));var n=g.$isVisible();n&&g.update(e),(1!==e.length||e[0].value!==t)&&(!n&&g.update(e),r.$render())})}),r.$formatters.push(function(e){var t=p.displayValue(e);return t?t:e&&'object'!=typeof e?e:''}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=g.$getIndex(r.$modelValue),n=angular.isDefined(e)?g.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?p.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'';t.val(s.trimValue===!1?a:a.trim())},e.$on('$destroy',function(){g&&g.destroy(),s=null,g=null})}}}])}(window,document); //# sourceMappingURL=angular-strap.min.js.map \ No newline at end of file diff --git a/dist/angular-strap.min.js.map b/dist/angular-strap.min.js.map index 275447aa7..2e07a6a99 100644 --- a/dist/angular-strap.min.js.map +++ b/dist/angular-strap.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["angular-strap.js","affix/affix.js","button/button.js","alert/alert.js","aside/aside.js","collapse/collapse.js","datepicker/datepicker.js","dropdown/dropdown.js","helpers/date-formatter.js","helpers/date-parser.js","helpers/debounce.js","helpers/dimensions.js","helpers/parse-options.js","helpers/raf.js","modal/modal.js","navbar/navbar.js","popover/popover.js","scrollspy/scrollspy.js","select/select.js","tab/tab.js","timepicker/timepicker.js","tooltip/tooltip.js","typeahead/typeahead.js"],"names":["window","document","undefined","angular","bodyEl","$window","body","windowEl","defaults","AffixFactory","offsetTop","$affix","inlineStyles","options","this","$get","reset","setWidth","initialAffixTop","offsetParent","match","getRequiredAffixClass","unpin","position","top","scrollTop","getScrollTop","scrollHeight","getScrollHeight","targetEl","pageYOffset","directive","parent","target","initialOffsetTop","offsetBottom","affixed","element","init","i","$parseOffsets","on","checkPosition","require","checkPositionWithEventLoop","dimensions","offset","destroy","style","width","off","affix","setTimeout","elementHeight","height","css","addClass","offsetUnpin","offsetHeight","offsetWidth","$debouncedOnResize","$onResize","initialPosition","restrict","affixTarget","$element","forEach","link","key","scope","option","$on","attr","test","controller","activeClass","toggleEvent","compile","children","querySelectorAll","childEl","ngModel","removeAttr","child","$button","constantValueRegExp","isInput","trueValue","falseValue","isDefined","hasExoticValues","viewValue","$formatters","push","$render","modelValue","isActive","equals","checked","activeElement","bind","$modelValue","$$rAF","$setViewValue","toggleClass","$apply","hasClass","$observe","value","nodeName","module","container","provider","backdrop","keyboard","show","duration","type","dismissable","AlertFactory","$alert","$scope","config","extend","$timeout","hide","falseValueRegExp","hasOwnProperty","title","newValue","oldValue","trustAsHtml","bsAlert","content","alert","trigger","toggle","animation","contentTemplate","html","AsideFactory","$aside","requestAnimationFrame","$modal","bsAside","$watch","aside","self","startCollapsed","allowMultiple","$attrs","activeIndexes","$targets","$active","length","index","indexOf","activeItems","splice","activateItem","$options","$collapse","copy","$toggles","$unregisterToggle","$registerToggle","$unregisterTarget","deactivateItem","$viewChangeListeners","fn","fixActiveItemIndexes","$setActive","disallowToggle","$activeIndexes","bsCollapseCtrl","controllers","$animate","ngModelCtrl","attrs","isArray","bsCollapseToggle","$registerTarget","render","active","action","prefixClass","delay","useNative","dateType","dateFormat","timezone","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","autoclose","minDate","Infinity","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","isNative","DatepickerFactory","parentScope","$datepicker","pickerViews","views","el","selected","date","focus","viewDate","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","$toggleMode","setMode","select","isDate","$build","updateDisabledDates","disabledDateRanges","dateRanges","$date","$dateValue","keep","Date","year","getFullYear","month","getDate","mode","pristine","call","$updateSelected","rows","built","$isSelected","$setDisabledEl","disabled","isDisabled","steps","targetDate","getUTCFullYear","getUTCMonth","UTC","$onMouseDown","evt","preventDefault","stopPropagation","isTouch","getUTCDate","$onKeyDown","keyCode","shiftKey","altKey","updateSelected","onKeyDown","$digest","prop","focusElement","_init","_destroy","_show","_hide","blur","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","isMaxValid","isValid","isMinValid","isNaN","parsedDate","getTime","$parsers","unshift","$setValidity","getDateFormattedString","formatDate","bsShow","lang","format","$dateFormatter","dateParser","$dateParser","strict","validateAgainstMinMaxDate","getDateForAttribute","disabledDates","parse","timezoneOffsetAdjust","isUndefined","NaN","daySplit","arr","mod","n","m","arrays","size","$sce","weekDaysMin","weekdaysShort","weekDaysLabelsHtml","startDate","picker","weekDaysLabels","slice","concat","split","getMonth","update","firstDayOfMonth","firstDate","getDay","today","firstDateOffset","build","day","days","isToday","toDateString","label","muted","showLabels","labels","time","isSelected","newDate","name","firstMonth","months","lastDate","actualMonth","parseInt","firstYear","years","actualYear","setYear","placement","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","$rootScope","$new","parentEl","$isShown","removeClass","prototype","transclusion","bsDropdown","dropdown","isString","getDefaultLocale","id","splitTimeFormat","timeFormat","exec","DATETIME_FORMATS","$locale","getDatetimeFormat","SHORTDAY","hoursFormat","minutesFormat","secondsFormat","timeSeparator","showSeconds","dateFilter","ParseDate","seconds","$localeProvider","milliseconds","hours","array","isNumeric","parseFloat","isFinite","indexOfCaseInsensitive","len","str","toString","toLowerCase","DateParserFactory","minutes","getHours","getMilliseconds","getMinutes","proto","noop","toDate","regExpMap","sss","mm","keys","setFnMap","map","clonedFormat","search","v","sortedMap","regExpForFormat","re","join","text","replace","Object","escapeReservedSymbols","RegExp","regex","HH","H","hh","h","a","EEEE","EEE","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","setSeconds","s","setMinutes","setHours","setDate","setMonth","setFullYear","$format","baseDate","setMap","formatRegex","formatSetMap","setMapForFormat","matches","fromDate","substr","getTimeForAttribute","daylightSavingAdjust","undo","func","timeout","context","factory","immediate","apply","args","cancel","callNow","leading","trailing","wait","currentStyle","getComputedStyle","extra","boxRect","getBoundingClientRect","left","docElement","ownerDocument","curPosition","curLeft","curCSSTop","documentElement","clientTop","pageXOffset","scrollLeft","clientLeft","curCSSLeft","calculatePosition","curTop","curOffset","curElem","props","isFunction","using","offsetParentRect","offsetParentElement","outer","$parseOptions","$values","regexp","$match","displayFn","locals","valueName","valueFn","ParseOptionsFactory","groupByFn","valuesFn","$parse","keyName","cancelAnimationFrame","when","values","parseValues","raf","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","timer","prefixEvent","template","trim","bodyElement","htmlReplaceRegExp","ModalFactory","enterAnimateCallback","promise","modalElement","leaveAnimateCallback","currentTarget","safeDigest","preventEventDefault","$hide","$$postDigest","$id","$show","$promise","templateEl","fetchTemplate","outerHTML","then","modalLinker","backdropElement","right","z-index","data","$compile","remove","$destroy","after","isElement","$emit","defaultPrevented","clonedElement","display","enter","hideOnBackdropClick","$onKeyUp","leave","which","fetchPromises","cache","$templateCache","res","$http","get","bsModal","modal","routeAttr","$navbar","liElements","li","liElement","pattern","path","autoClose","$popover","PopoverFactory","$tooltip","dataTarget","popover","bsPopover","isObject","$applyPlacement","setViewport","viewport","spies","$document","debounce","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","$trackedElements","sortedElements","activeTarget","debouncedCheckPosition","viewportHeight","throttledCheckPosition","debouncedCheckOffsets","checkOffsets","docEl","$activateElement","source","$getTrackedElement","filter","targetElement","querySelector","trackedElement","b","trackElement","toDelete","untrackElement","activate","scrollspy","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$select","$activeIndex","$isMultiple","$showAllNoneButtons","$allText","$iconCheckmark","$isActive","$isVisible","$selectNone","$matches","$updateActiveIndex","$getIndex","minLength","$viewValue","l","dataMultiple","inputEl","watchedOptions","$watchCollection","parsedOptions","bsOptions","$isEmpty","navClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$navClass","$remove","activeIndex","$pane","$tab","transclude","templateUrl","postLink","bsTabsCtrl","bsActivePane","parsedBsActivePane","assign","timeType","modelTimeFormat","minTime","maxTime","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","timepickerFactory","hour","meridian","coeff","selRange","end","start","setSelectionRange","collapse","selectionStart","moveStart","selectionEnd","moveEnd","$timepicker","floorMinutes","floor","selectedIndex","defaultDate","second","getSeconds","millisecond","$iconUp","$iconDown","$moveIndex","$switchMeridian","switchMeridian","minute","midIndex","$isDisabled","showAM","isAM","selectedTime","$arrowAction","$setTimeByStep","hoursLength","triggerHandler","secondsLength","sepLength","lateralMove","count","minutesLength","selectRange","incr","isSeconds","isMeridian","createSelection","createTextRange","parsedTime","getTimeFormattedString","timepicker","validateAgainstMinMaxTime","bsEnabled","selector","padding","String","$body","_tipToHide","tipElement","triggers","unbindTriggerEvents","bindKeyboardEvents","$onFocusElementMouseDown","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","rect","elRect","p","scroll","isBody","getCalculatedOffset","actualWidth","actualHeight","outerDims","clientWidth","innerHeight","tip","marginTop","marginLeft","setOffset","delta","getViewportAdjustedDelta","isVertical","replaceArrow","arrowDelta","arrowOffsetPosition","viewportPadding","topEdgeOffset","$viewport","viewportDimensions","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","findElement","$arrow","clearTimeout","tipScope","$$phase","$setEnabled","setEnabled","isEnabled","contentEl","tipLinker","tipTemplate","isNumber","tipContainer","bindTriggerEvents","destroyTipElement","hoverState","lastChild","visibility","prepend","_blur","elementPosition","autoPlace","originalPlacement","containerPosition","tipHeight","tipPosition","applyPlacement","tipWidth","TooltipFactory","$location","tooltip","bsTooltip","limit","autoSelect","comparator","trimValue","$typeahead","$resetMatches","TypeaheadFactory","typeahead","watchOptions","selectMode","isVisible","displayValue","val"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\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// 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 setWidth = false,\n initialAffixTop = 0,\n initialOffsetTop = 0,\n offsetTop = 0,\n offsetBottom = 0,\n affixed = null,\n 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 }\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 // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + 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 }\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 };\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 }\n else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\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 }\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\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 } else {\n return 'middle';\n }\n\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 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: 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 value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\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 template: '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 var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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', '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]))\n 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 attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAlert && 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 // 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 template: '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 var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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', '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]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && 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 // 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: 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 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 }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n 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 ? false : true;\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 var defaults = $collapse.defaults;\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 }\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 }\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 var index = attrs.bsCollapseToggle || bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\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 }\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: 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 template: '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 bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)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 return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\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 _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(a|o)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, controller: controller};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'html', 'animation', 'template', '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 // Visibility binding support\n attr.bsShow && 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 newValue === true ? datepicker.show() : datepicker.hide();\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 // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && 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 !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\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 } else {\n validateAgainstMinMaxDate(parsedDate);\n }\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 } else {\n return new Date(date);\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 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), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), 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 = [], 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 = [], 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 = [], 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 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: 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 template: '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 options.keyboard && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n 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 link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\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// 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/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, str=value.toString().toLowerCase();\n for (var i=0; i 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 setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\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 args = arguments,\n 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 options || (options = {});\n return function() {\n var context = this,\n 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/dimensions.js\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function($document, $window) {\n\n var jqLite = angular.element;\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 curLeft,\n curCSSTop,\n curTop,\n curOffset,\n curCSSLeft,\n calculatePosition,\n position = fn.css(element, 'position'),\n curElem = angular.element(element),\n 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 offsetParentElement,\n 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* offsetParentElement\n offsetParentElement = offsetParent(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentElement, 'html')) {\n offsetParentRect = fn.offset(offsetParentElement);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentElement, '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 var offsetParent = 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/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, displayFn, valueName, keyName, groupByFn, valueFn, 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 $parseOptions.$values = values ? 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 = {}, label, 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/raf.js\n(angular.version.minor < 3 && angular.version.dot < 14) && 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// .factory('$$animateReflow', function($$rAF, $document) {\n\n// var bodyEl = $document[0].body;\n\n// return function(fn) {\n// //the returned function acts as the cancellation function\n// return $$rAF(function() {\n// //the line below will force the browser to perform a repaint\n// //so that all the animated elements within the animation frame\n// //will be properly updated and drawn on screen. This is\n// //required to perform multi-class CSS based animations with\n// //Firefox. DO NOT REMOVE THIS LINE.\n// var a = bodyEl.offsetWidth + 1;\n// fn();\n// });\n// };\n\n// });\n\n// Source: modal/modal.js\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n template: 'modal/modal.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($window, $rootScope, $compile, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n $modal.$promise = fetchTemplate(options.template);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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 // Support contentTemplate option\n if(options.contentTemplate) {\n $modal.$promise = $modal.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(contentTemplate);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!config.template) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize modal\n var modalLinker, modalElement;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n $modal.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n modalLinker = $compile(template);\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 if(modalElement) {\n modalElement.remove();\n modalElement = null;\n }\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, 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 // Fetch a cloned element linked from template\n modalElement = $modal.$element = modalLinker(scope, function(clonedElement, scope) {});\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: 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 // Support v1.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n var promise = $animate.enter(modalElement, parent, after, enterAnimateCallback);\n if(promise && promise.then) promise.then(enterAnimateCallback);\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 if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\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(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n var promise = $animate.leave(modalElement, leaveAnimateCallback);\n // Support v1.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n if(promise && promise.then) promise.then(leaveAnimateCallback);\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\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\n $modal.$isShown ? $modal.hide() : $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 // Private methods\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', '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(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && 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 // 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: 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: 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 template: '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 // Directive options\n var options = {scope: scope};\n angular.forEach(['template', '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]))\n 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 // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && 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 angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var 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: 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, unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n var viewportHeight;\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 = 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: 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 template: '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(a|o)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 }\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 $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.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 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(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\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 } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 evt.preventDefault();\n evt.stopPropagation();\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 // 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 && !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(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // 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 // 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 // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(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 });\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, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? 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 = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? 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: 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 }\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: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n '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 template: '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 bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)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 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 {\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 = {hour: startDate.getHours(), meridian: startDate.getHours() < 12, minute: startDate.getMinutes(), second: startDate.getSeconds(), millisecond: startDate.getMilliseconds()};\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n 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, {hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(), millisecond: date.getMilliseconds()});\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() { $timepicker.hide(true); });\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, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [], 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({date: hour, label: formatDate(hour, hoursFormat), selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), disabled: $timepicker.$isDisabled(hour, 0)});\n }\n var minutes = [], 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({date: minute, label: formatDate(minute, minutesFormat), selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), disabled: $timepicker.$isDisabled(minute, 1)});\n }\n var seconds = [], 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({date: second, label: formatDate(second, secondsFormat), selected: $timepicker.$date && $timepicker.$isSelected(second, 2), disabled: $timepicker.$isDisabled(second, 2)});\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);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), secondsLength = formatDate(newDate, secondsFormat).length;\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n }\n else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n }\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, {hour: targetDate.getHours()});\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, {minute: targetDate.getMinutes()});\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, {second: targetDate.getSeconds()});\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) return $timepicker.hide(true);\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), 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 _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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 $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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, controller: controller};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Visibility binding support\n attr.bsShow && 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 newValue === true ? timepicker.show() : timepicker.hide();\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 // Initialize parser\n var dateParser = $dateParser({format: options.timeFormat, lang: lang});\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\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;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\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 } else {\n return new Date(date);\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 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: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['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 template: 'tooltip/tooltip.tpl.html',\n contentTemplate: 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, $compile, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var nodeName = element[0].nodeName.toLowerCase();\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n $tooltip.$promise = fetchTemplate(options.template);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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, hoverState;\n\n // Support contentTemplate option\n if(options.contentTemplate) {\n $tooltip.$promise = $tooltip.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]);\n if(!contentEl.length) contentEl = findElement('[ng-bind=\"title\"]', templateEl[0]);\n contentEl.removeAttr('ng-bind').html(contentTemplate);\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize tooltip\n var tipLinker, tipElement, tipTemplate, tipContainer, tipScope;\n $tooltip.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n tipTemplate = template;\n tipLinker = $compile(template);\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 options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\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, 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 = tipLinker(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 after ? after.after(tipElement) : parent.prepend(tipElement);\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.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n var promise = $animate.enter(tipElement, parent, after, enterAnimateCallback);\n if(promise && promise.then) promise.then(enterAnimateCallback);\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\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\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.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n var promise = $animate.leave(tipElement, leaveAnimateCallback);\n if(promise && promise.then) promise.then(leaveAnimateCallback);\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() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\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 autoToken = /\\s?auto?\\s?/i,\n 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 tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var container = options.container ? findElement(options.container) : element.parent();\n var containerPosition = getPosition(container);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > containerPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < containerPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > containerPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < containerPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : 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 $tooltip.$isShown ? element[0].blur() : element[0].focus();\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') {\n element.on('click', $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 nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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') {\n element.off('click', $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 nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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 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 for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\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 scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n 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 }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n 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 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 arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 },\n $viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n if (!$viewport) {\n return delta;\n }\n\n var viewportPadding = options.viewport && options.viewport.padding || 0,\n viewportDimensions = getPosition($viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll,\n 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 rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.width) { // 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 scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'contentTemplate', '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 // 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 // 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && 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 newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var 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 template: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'filter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\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 // When the placement is not one of the bottom placements, re-calc the positioning\n // so the results render correctly.\n if (/^(bottom|bottom-left|bottom-right)$/.test(options.placement)) return;\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n $timeout($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 l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 }\n\n // Navigate with keyboard\n else if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\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 // 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 imediately.\n $timeout(function() {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $typeahead.$onKeyDown);\n }\n if(!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n element.attr('autocomplete' ,'off');\n\n // Build proper bsOptions\n var 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) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\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 var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if(values.length === 1 && values[0].value === newValue) return;\n !isVisible && 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 return displayValue === undefined ? '' : displayValue;\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)) return element.val('');\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? 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})(window, document);\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 setWidth = false,\n initialAffixTop = 0,\n initialOffsetTop = 0,\n offsetTop = 0,\n offsetBottom = 0,\n affixed = null,\n 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 }\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 // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + 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 }\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 };\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 }\n else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\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 }\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\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 } else {\n return 'middle';\n }\n\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 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","'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 value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\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 template: '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 var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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', '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]))\n 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 attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAlert && 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 // 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 template: '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 var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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', '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]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && 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 // 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.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 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 }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n 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 ? false : true;\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 var defaults = $collapse.defaults;\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 }\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 }\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 var index = attrs.bsCollapseToggle || bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\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 }\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.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 template: '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 bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)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 return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\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 _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(a|o)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, controller: controller};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'html', 'animation', 'template', '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 // Visibility binding support\n attr.bsShow && 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 newValue === true ? datepicker.show() : datepicker.hide();\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 // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && 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 !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\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 } else {\n validateAgainstMinMaxDate(parsedDate);\n }\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 } else {\n return new Date(date);\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 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), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), 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 = [], 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 = [], 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 = [], 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 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.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 template: '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 options.keyboard && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n 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 link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\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","'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.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, str=value.toString().toLowerCase();\n for (var i=0; i 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 setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\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.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 args = arguments,\n 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 options || (options = {});\n return function() {\n var context = this,\n 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","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function($document, $window) {\n\n var jqLite = angular.element;\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 curLeft,\n curCSSTop,\n curTop,\n curOffset,\n curCSSLeft,\n calculatePosition,\n position = fn.css(element, 'position'),\n curElem = angular.element(element),\n 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 offsetParentElement,\n 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* offsetParentElement\n offsetParentElement = offsetParent(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentElement, 'html')) {\n offsetParentRect = fn.offset(offsetParentElement);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentElement, '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 var offsetParent = 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.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, displayFn, valueName, keyName, groupByFn, valueFn, 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 $parseOptions.$values = values ? 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 = {}, label, 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\n(angular.version.minor < 3 && angular.version.dot < 14) && 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// .factory('$$animateReflow', function($$rAF, $document) {\n\n// var bodyEl = $document[0].body;\n\n// return function(fn) {\n// //the returned function acts as the cancellation function\n// return $$rAF(function() {\n// //the line below will force the browser to perform a repaint\n// //so that all the animated elements within the animation frame\n// //will be properly updated and drawn on screen. This is\n// //required to perform multi-class CSS based animations with\n// //Firefox. DO NOT REMOVE THIS LINE.\n// var a = bodyEl.offsetWidth + 1;\n// fn();\n// });\n// };\n\n// });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n template: 'modal/modal.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($window, $rootScope, $compile, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n $modal.$promise = fetchTemplate(options.template);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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 // Support contentTemplate option\n if(options.contentTemplate) {\n $modal.$promise = $modal.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(contentTemplate);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!config.template) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize modal\n var modalLinker, modalElement;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n $modal.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n modalLinker = $compile(template);\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 if(modalElement) {\n modalElement.remove();\n modalElement = null;\n }\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, 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 // Fetch a cloned element linked from template\n modalElement = $modal.$element = modalLinker(scope, function(clonedElement, scope) {});\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: 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 // Support v1.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n var promise = $animate.enter(modalElement, parent, after, enterAnimateCallback);\n if(promise && promise.then) promise.then(enterAnimateCallback);\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 if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\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(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n var promise = $animate.leave(modalElement, leaveAnimateCallback);\n // Support v1.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n if(promise && promise.then) promise.then(leaveAnimateCallback);\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\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\n $modal.$isShown ? $modal.hide() : $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 // Private methods\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', '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(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && 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 // 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\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.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 template: '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 // Directive options\n var options = {scope: scope};\n angular.forEach(['template', '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]))\n 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 // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && 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 angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var 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.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, unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n var viewportHeight;\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 = 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.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 template: '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(a|o)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 }\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 $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.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 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(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\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 } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 evt.preventDefault();\n evt.stopPropagation();\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 // 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 && !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(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // 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 // 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 // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(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 });\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, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? 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 = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? 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.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 }\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.timepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n '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 template: '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 bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)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 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 {\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 = {hour: startDate.getHours(), meridian: startDate.getHours() < 12, minute: startDate.getMinutes(), second: startDate.getSeconds(), millisecond: startDate.getMilliseconds()};\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n 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, {hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(), millisecond: date.getMilliseconds()});\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() { $timepicker.hide(true); });\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, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [], 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({date: hour, label: formatDate(hour, hoursFormat), selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), disabled: $timepicker.$isDisabled(hour, 0)});\n }\n var minutes = [], 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({date: minute, label: formatDate(minute, minutesFormat), selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), disabled: $timepicker.$isDisabled(minute, 1)});\n }\n var seconds = [], 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({date: second, label: formatDate(second, secondsFormat), selected: $timepicker.$date && $timepicker.$isSelected(second, 2), disabled: $timepicker.$isDisabled(second, 2)});\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);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), secondsLength = formatDate(newDate, secondsFormat).length;\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n }\n else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n }\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, {hour: targetDate.getHours()});\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, {minute: targetDate.getMinutes()});\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, {second: targetDate.getSeconds()});\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) return $timepicker.hide(true);\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), 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 _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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 $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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, controller: controller};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Visibility binding support\n attr.bsShow && 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 newValue === true ? timepicker.show() : timepicker.hide();\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 // Initialize parser\n var dateParser = $dateParser({format: options.timeFormat, lang: lang});\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\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;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\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 } else {\n return new Date(date);\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 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.tooltip', ['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 template: 'tooltip/tooltip.tpl.html',\n contentTemplate: 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, $compile, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var nodeName = element[0].nodeName.toLowerCase();\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n $tooltip.$promise = fetchTemplate(options.template);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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, hoverState;\n\n // Support contentTemplate option\n if(options.contentTemplate) {\n $tooltip.$promise = $tooltip.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]);\n if(!contentEl.length) contentEl = findElement('[ng-bind=\"title\"]', templateEl[0]);\n contentEl.removeAttr('ng-bind').html(contentTemplate);\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize tooltip\n var tipLinker, tipElement, tipTemplate, tipContainer, tipScope;\n $tooltip.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n tipTemplate = template;\n tipLinker = $compile(template);\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 options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\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, 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 = tipLinker(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 after ? after.after(tipElement) : parent.prepend(tipElement);\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.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n var promise = $animate.enter(tipElement, parent, after, enterAnimateCallback);\n if(promise && promise.then) promise.then(enterAnimateCallback);\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\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\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.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n var promise = $animate.leave(tipElement, leaveAnimateCallback);\n if(promise && promise.then) promise.then(leaveAnimateCallback);\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() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\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 autoToken = /\\s?auto?\\s?/i,\n 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 tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var container = options.container ? findElement(options.container) : element.parent();\n var containerPosition = getPosition(container);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > containerPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < containerPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > containerPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < containerPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : 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 $tooltip.$isShown ? element[0].blur() : element[0].focus();\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') {\n element.on('click', $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 nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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') {\n element.off('click', $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 nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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 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 for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\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 scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n 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 }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n 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 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 arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 },\n $viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n if (!$viewport) {\n return delta;\n }\n\n var viewportPadding = options.viewport && options.viewport.padding || 0,\n viewportDimensions = getPosition($viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll,\n 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 rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.width) { // 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 scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'contentTemplate', '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 // 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 // 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && 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 newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var 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\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 template: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'filter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\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 // When the placement is not one of the bottom placements, re-calc the positioning\n // so the results render correctly.\n if (/^(bottom|bottom-left|bottom-right)$/.test(options.placement)) return;\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n $timeout($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 l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 }\n\n // Navigate with keyboard\n else if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\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 // 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 imediately.\n $timeout(function() {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $typeahead.$onKeyDown);\n }\n if(!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n element.attr('autocomplete' ,'off');\n\n // Build proper bsOptions\n var 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) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\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 var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if(values.length === 1 && values[0].value === newValue) return;\n !isVisible && 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 return displayValue === undefined ? '' : displayValue;\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)) return element.val('');\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? 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"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["angular-strap.js","affix/affix.js","alert/alert.js","aside/aside.js","collapse/collapse.js","datepicker/datepicker.js","dropdown/dropdown.js","button/button.js","helpers/date-formatter.js","helpers/date-parser.js","helpers/debounce.js","helpers/dimensions.js","helpers/parse-options.js","helpers/raf.js","modal/modal.js","navbar/navbar.js","popover/popover.js","scrollspy/scrollspy.js","select/select.js","tab/tab.js","timepicker/timepicker.js","tooltip/tooltip.js","typeahead/typeahead.js"],"names":["window","document","undefined","angular","bodyEl","$window","body","windowEl","defaults","AffixFactory","offsetTop","$affix","inlineStyles","options","this","$get","reset","setWidth","initialAffixTop","offsetParent","match","getRequiredAffixClass","unpin","position","top","scrollTop","getScrollTop","scrollHeight","getScrollHeight","targetEl","pageYOffset","directive","parent","target","initialOffsetTop","offsetBottom","affixed","element","init","i","$parseOffsets","on","checkPosition","require","checkPositionWithEventLoop","dimensions","offset","destroy","style","width","off","affix","setTimeout","elementHeight","height","css","addClass","offsetUnpin","offsetHeight","offsetWidth","$debouncedOnResize","$onResize","initialPosition","restrict","affixTarget","$element","forEach","link","key","scope","option","$on","attr","test","controller","animation","prefixClass","container","provider","backdrop","keyboard","show","duration","type","dismissable","AlertFactory","$alert","$scope","config","extend","$timeout","hide","isDefined","falseValueRegExp","hasOwnProperty","title","newValue","oldValue","trustAsHtml","bsAlert","$observe","content","alert","trigger","toggle","module","contentTemplate","html","AsideFactory","$aside","requestAnimationFrame","$modal","bsAside","$watch","aside","self","startCollapsed","allowMultiple","$attrs","activeIndexes","$targets","$active","length","index","value","indexOf","activeItems","splice","activateItem","$options","$collapse","copy","$toggles","push","$unregisterToggle","$registerToggle","$unregisterTarget","deactivateItem","$viewChangeListeners","fn","fixActiveItemIndexes","$setActive","disallowToggle","isActive","$activeIndexes","bsCollapseCtrl","controllers","$animate","ngModelCtrl","$setViewValue","$formatters","attrs","modelValue","isArray","bsCollapseToggle","$apply","$registerTarget","render","active","action","activeClass","delay","useNative","dateType","dateFormat","timezone","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","autoclose","minDate","Infinity","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","isNative","DatepickerFactory","parentScope","$datepicker","pickerViews","views","el","selected","date","focus","viewDate","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","$toggleMode","setMode","select","isDate","$build","updateDisabledDates","disabledDateRanges","dateRanges","$date","$dateValue","$render","keep","Date","year","getFullYear","month","getDate","mode","pristine","call","$updateSelected","rows","built","$isSelected","$setDisabledEl","disabled","isDisabled","steps","targetDate","getUTCFullYear","getUTCMonth","UTC","$onMouseDown","evt","preventDefault","stopPropagation","isTouch","getUTCDate","$onKeyDown","nodeName","keyCode","shiftKey","altKey","updateSelected","onKeyDown","$digest","prop","focusElement","_init","_destroy","_show","_hide","blur","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","isMaxValid","isValid","isMinValid","isNaN","parsedDate","getTime","$parsers","unshift","viewValue","$setValidity","getDateFormattedString","formatDate","bsShow","lang","format","$dateFormatter","dateParser","$dateParser","strict","validateAgainstMinMaxDate","ngModel","getDateForAttribute","disabledDates","parse","timezoneOffsetAdjust","isUndefined","NaN","daySplit","arr","mod","n","m","arrays","size","$sce","weekDaysMin","weekdaysShort","weekDaysLabelsHtml","startDate","picker","weekDaysLabels","slice","concat","split","getMonth","update","firstDayOfMonth","firstDate","getDay","today","firstDateOffset","build","day","days","isToday","toDateString","label","muted","showLabels","labels","time","isSelected","newDate","name","firstMonth","months","lastDate","actualMonth","parseInt","firstYear","years","actualYear","setYear","placement","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","querySelectorAll","$rootScope","$new","parentEl","hasClass","$isShown","removeClass","prototype","transclusion","bsDropdown","dropdown","isString","compile","children","childEl","removeAttr","child","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","equals","checked","activeElement","bind","toggleEvent","$modelValue","$$rAF","toggleClass","getDefaultLocale","splitTimeFormat","timeFormat","exec","DATETIME_FORMATS","$locale","id","getDatetimeFormat","SHORTDAY","hoursFormat","minutesFormat","secondsFormat","timeSeparator","showSeconds","dateFilter","ParseDate","seconds","$localeProvider","milliseconds","hours","array","isNumeric","parseFloat","isFinite","indexOfCaseInsensitive","len","str","toString","toLowerCase","DateParserFactory","minutes","getHours","getMilliseconds","getMinutes","proto","noop","toDate","regExpMap","sss","mm","keys","setFnMap","map","clonedFormat","search","v","sortedMap","regExpForFormat","re","join","text","replace","Object","escapeReservedSymbols","RegExp","regex","HH","H","hh","h","a","EEEE","EEE","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","setSeconds","s","setMinutes","setHours","setDate","setMonth","setFullYear","$format","baseDate","setMap","formatRegex","formatSetMap","setMapForFormat","matches","fromDate","substr","getTimeForAttribute","daylightSavingAdjust","undo","func","timeout","context","factory","immediate","apply","args","cancel","callNow","leading","trailing","wait","currentStyle","getComputedStyle","extra","boxRect","getBoundingClientRect","left","docElement","ownerDocument","curPosition","curLeft","curCSSTop","documentElement","clientTop","pageXOffset","scrollLeft","clientLeft","curCSSLeft","calculatePosition","curTop","curOffset","curElem","props","isFunction","using","offsetParentRect","offsetParentElement","outer","$parseOptions","$values","regexp","$match","displayFn","locals","valueName","valueFn","ParseOptionsFactory","groupByFn","valuesFn","$parse","keyName","cancelAnimationFrame","when","values","parseValues","raf","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","timer","prefixEvent","template","trim","bodyElement","htmlReplaceRegExp","ModalFactory","enterAnimateCallback","version","minor","modalElement","currentTarget","safeDigest","preventEventDefault","$hide","$$postDigest","$id","$show","$promise","templateEl","fetchTemplate","outerHTML","then","modalLinker","backdropElement","right","z-index","data","$compile","remove","$destroy","after","isElement","$emit","defaultPrevented","clonedElement","display","enter","backdropAnimation","hideOnBackdropClick","$onKeyUp","leave","leaveAnimateCallback","which","fetchPromises","cache","$templateCache","res","$http","get","bsModal","modal","routeAttr","$navbar","liElements","li","liElement","pattern","path","autoClose","$popover","PopoverFactory","$tooltip","dataTarget","popover","bsPopover","isObject","$applyPlacement","setViewport","viewport","spies","$document","debounce","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","$trackedElements","sortedElements","activeTarget","debouncedCheckPosition","viewportHeight","throttledCheckPosition","debouncedCheckOffsets","checkOffsets","docEl","$activateElement","source","$getTrackedElement","filter","targetElement","querySelector","trackedElement","b","trackElement","toDelete","untrackElement","activate","scrollspy","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$select","$activeIndex","$isMultiple","$showAllNoneButtons","$allText","$iconCheckmark","$isActive","$isVisible","$selectNone","$matches","$updateActiveIndex","$getIndex","minLength","$viewValue","l","dataMultiple","inputEl","watchedOptions","$watchCollection","parsedOptions","bsOptions","$isEmpty","navClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$navClass","$remove","activeIndex","$pane","$tab","transclude","templateUrl","postLink","bsTabsCtrl","bsActivePane","parsedBsActivePane","assign","timeType","modelTimeFormat","minTime","maxTime","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","timepickerFactory","hour","meridian","coeff","selRange","end","start","setSelectionRange","collapse","selectionStart","moveStart","selectionEnd","moveEnd","$timepicker","floorMinutes","floor","selectedIndex","defaultDate","second","getSeconds","millisecond","$iconUp","$iconDown","$moveIndex","$switchMeridian","switchMeridian","minute","midIndex","$isDisabled","showAM","isAM","selectedTime","$arrowAction","$setTimeByStep","hoursLength","triggerHandler","secondsLength","sepLength","lateralMove","count","minutesLength","selectRange","incr","isSeconds","isMeridian","createSelection","createTextRange","parsedTime","getTimeFormattedString","timepicker","validateAgainstMinMaxTime","bsEnabled","selector","padding","String","$body","_tipToHide","tipElement","triggers","unbindTriggerEvents","bindKeyboardEvents","$onFocusElementMouseDown","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","rect","elRect","p","scroll","isBody","getCalculatedOffset","actualWidth","actualHeight","outerDims","clientWidth","innerHeight","tip","marginTop","marginLeft","setOffset","delta","getViewportAdjustedDelta","isVertical","replaceArrow","arrowDelta","arrowOffsetPosition","viewportPadding","topEdgeOffset","$viewport","viewportDimensions","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","findElement","$arrow","clearTimeout","tipScope","$$phase","$setEnabled","setEnabled","isEnabled","contentEl","tipLinker","tipTemplate","isNumber","tipContainer","bindTriggerEvents","destroyTipElement","hoverState","lastChild","visibility","customClass","_blur","elementPosition","autoPlace","originalPlacement","containerPosition","tipHeight","tipPosition","applyPlacement","tipWidth","TooltipFactory","$location","tooltip","bsTooltip","limit","autoSelect","comparator","trimValue","$typeahead","$resetMatches","TypeaheadFactory","typeahead","watchOptions","selectMode","isVisible","displayValue","val"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\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// 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 setWidth = false,\n initialAffixTop = 0,\n initialOffsetTop = 0,\n offsetTop = 0,\n offsetBottom = 0,\n affixed = null,\n 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 }\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 // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + 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 }\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 };\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 }\n else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\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 }\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\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 } else {\n return 'middle';\n }\n\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 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: 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 template: '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 var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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', '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]))\n 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 attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAlert && 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 // 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 template: '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 var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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', '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]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && 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 // 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: 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 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 }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n 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 ? false : true;\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 var defaults = $collapse.defaults;\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 }\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 }\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 var index = attrs.bsCollapseToggle || bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\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 }\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: 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 template: '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 bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)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 return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\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 _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(a|o)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, controller: controller};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'html', 'animation', 'template', '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 // Visibility binding support\n attr.bsShow && 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 newValue === true ? datepicker.show() : datepicker.hide();\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 // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && 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 !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\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 } else {\n validateAgainstMinMaxDate(parsedDate);\n }\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 } else {\n return new Date(date);\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 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), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), 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 = [], 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 = [], 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 = [], 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 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: 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 template: '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 options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n 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 link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\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// 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 value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\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: 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/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, str=value.toString().toLowerCase();\n for (var i=0; i 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 setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\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 args = arguments,\n 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 options || (options = {});\n return function() {\n var context = this,\n 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/dimensions.js\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function($document, $window) {\n\n var jqLite = angular.element;\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 curLeft,\n curCSSTop,\n curTop,\n curOffset,\n curCSSLeft,\n calculatePosition,\n position = fn.css(element, 'position'),\n curElem = angular.element(element),\n 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 offsetParentElement,\n 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* offsetParentElement\n offsetParentElement = offsetParent(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentElement, 'html')) {\n offsetParentRect = fn.offset(offsetParentElement);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentElement, '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 var offsetParent = 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/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, displayFn, valueName, keyName, groupByFn, valueFn, 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 $parseOptions.$values = values ? 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 = {}, label, 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/raf.js\n(angular.version.minor < 3 && angular.version.dot < 14) && 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// .factory('$$animateReflow', function($$rAF, $document) {\n\n// var bodyEl = $document[0].body;\n\n// return function(fn) {\n// //the returned function acts as the cancellation function\n// return $$rAF(function() {\n// //the line below will force the browser to perform a repaint\n// //so that all the animated elements within the animation frame\n// //will be properly updated and drawn on screen. This is\n// //required to perform multi-class CSS based animations with\n// //Firefox. DO NOT REMOVE THIS LINE.\n// var a = bodyEl.offsetWidth + 1;\n// fn();\n// });\n// };\n\n// });\n\n// Source: modal/modal.js\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n template: 'modal/modal.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($window, $rootScope, $compile, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n $modal.$promise = fetchTemplate(options.template);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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 // Support contentTemplate option\n if(options.contentTemplate) {\n $modal.$promise = $modal.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(contentTemplate);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!config.template) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize modal\n var modalLinker, modalElement;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n $modal.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n modalLinker = $compile(template);\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 if(modalElement) {\n modalElement.remove();\n modalElement = null;\n }\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, 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 // Fetch a cloned element linked from template\n modalElement = $modal.$element = modalLinker(scope, function(clonedElement, scope) {});\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: 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 if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\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(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 if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\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\n $modal.$isShown ? $modal.hide() : $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 // Private methods\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', '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(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && 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 // 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: 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: 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 template: '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 // Directive options\n var options = {scope: scope};\n angular.forEach(['template', '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]))\n 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 // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && 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 angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var 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: 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, unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n var viewportHeight;\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 = 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: 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 template: '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(a|o)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 }\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 $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\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 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(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\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 } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 evt.preventDefault();\n evt.stopPropagation();\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 // 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 && !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(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // 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 // 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 // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(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 });\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, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? 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 = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? 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: 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 }\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: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n '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 template: '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 bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)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 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 {\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 = {hour: startDate.getHours(), meridian: startDate.getHours() < 12, minute: startDate.getMinutes(), second: startDate.getSeconds(), millisecond: startDate.getMilliseconds()};\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n 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, {hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(), millisecond: date.getMilliseconds()});\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() { $timepicker.hide(true); });\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, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [], 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({date: hour, label: formatDate(hour, hoursFormat), selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), disabled: $timepicker.$isDisabled(hour, 0)});\n }\n var minutes = [], 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({date: minute, label: formatDate(minute, minutesFormat), selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), disabled: $timepicker.$isDisabled(minute, 1)});\n }\n var seconds = [], 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({date: second, label: formatDate(second, secondsFormat), selected: $timepicker.$date && $timepicker.$isSelected(second, 2), disabled: $timepicker.$isDisabled(second, 2)});\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);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), secondsLength = formatDate(newDate, secondsFormat).length;\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n }\n else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n }\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, {hour: targetDate.getHours()});\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, {minute: targetDate.getMinutes()});\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, {second: targetDate.getSeconds()});\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) return $timepicker.hide(true);\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), 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 _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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 $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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, controller: controller};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Visibility binding support\n attr.bsShow && 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 newValue === true ? timepicker.show() : timepicker.hide();\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 // Initialize parser\n var dateParser = $dateParser({format: options.timeFormat, lang: lang});\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\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;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\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 } else {\n return new Date(date);\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 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: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['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 template: 'tooltip/tooltip.tpl.html',\n contentTemplate: 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, $compile, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var nodeName = element[0].nodeName.toLowerCase();\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n $tooltip.$promise = fetchTemplate(options.template);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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, hoverState;\n\n // Support contentTemplate option\n if(options.contentTemplate) {\n $tooltip.$promise = $tooltip.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]);\n if(!contentEl.length) contentEl = findElement('[ng-bind=\"title\"]', templateEl[0]);\n contentEl.removeAttr('ng-bind').html(contentTemplate);\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize tooltip\n var tipLinker, tipElement, tipTemplate, tipContainer, tipScope;\n $tooltip.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n tipTemplate = template;\n tipLinker = $compile(template);\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 options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\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, 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 = tipLinker(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 after ? after.after(tipElement) : parent.prepend(tipElement);\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\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\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() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\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 autoToken = /\\s?auto?\\s?/i,\n 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 tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var container = options.container ? findElement(options.container) : element.parent();\n var containerPosition = getPosition(container);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > containerPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < containerPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > containerPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < containerPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : 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 $tooltip.$isShown ? element[0].blur() : element[0].focus();\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') {\n element.on('click', $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 nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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') {\n element.off('click', $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 nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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 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 for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\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 scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n 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 }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n 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 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 arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 },\n $viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n if (!$viewport) {\n return delta;\n }\n\n var viewportPadding = options.viewport && options.viewport.padding || 0,\n viewportDimensions = getPosition($viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll,\n 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 rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.width) { // 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 scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'contentTemplate', '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 // 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 // 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && 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 newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var 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 template: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'filter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\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 // When the placement is not one of the bottom placements, re-calc the positioning\n // so the results render correctly.\n if (/^(bottom|bottom-left|bottom-right)$/.test(options.placement)) return;\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n $timeout($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 l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 }\n\n // Navigate with keyboard\n else if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\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 // 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 $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element && element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element && element.off('keydown', $typeahead.$onKeyDown);\n }\n if(!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n element.attr('autocomplete' ,'off');\n\n // Build proper bsOptions\n var 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) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\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 var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if(values.length === 1 && values[0].value === newValue) return;\n !isVisible && 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) return displayValue;\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 (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)) return element.val('');\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? 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})(window, document);\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 setWidth = false,\n initialAffixTop = 0,\n initialOffsetTop = 0,\n offsetTop = 0,\n offsetBottom = 0,\n affixed = null,\n 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 }\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 // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + 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 }\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 };\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 }\n else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\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 }\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\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 } else {\n return 'middle';\n }\n\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 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","'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 template: '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 var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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', '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]))\n 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 attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAlert && 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 // 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 template: '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 var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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', '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]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && 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 // 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.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 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 }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n 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 ? false : true;\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 var defaults = $collapse.defaults;\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 }\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 }\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 var index = attrs.bsCollapseToggle || bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\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 }\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.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 template: '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 bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)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 return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\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 _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(a|o)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, controller: controller};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'html', 'animation', 'template', '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 // Visibility binding support\n attr.bsShow && 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 newValue === true ? datepicker.show() : datepicker.hide();\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 // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && 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 !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\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 } else {\n validateAgainstMinMaxDate(parsedDate);\n }\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 } else {\n return new Date(date);\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 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), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), 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 = [], 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 = [], 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 = [], 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 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.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 template: '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 options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n 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 link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\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","'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 value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\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\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.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, str=value.toString().toLowerCase();\n for (var i=0; i 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 setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\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.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 args = arguments,\n 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 options || (options = {});\n return function() {\n var context = this,\n 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","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function($document, $window) {\n\n var jqLite = angular.element;\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 curLeft,\n curCSSTop,\n curTop,\n curOffset,\n curCSSLeft,\n calculatePosition,\n position = fn.css(element, 'position'),\n curElem = angular.element(element),\n 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 offsetParentElement,\n 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* offsetParentElement\n offsetParentElement = offsetParent(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentElement, 'html')) {\n offsetParentRect = fn.offset(offsetParentElement);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentElement, '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 var offsetParent = 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.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, displayFn, valueName, keyName, groupByFn, valueFn, 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 $parseOptions.$values = values ? 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 = {}, label, 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\n(angular.version.minor < 3 && angular.version.dot < 14) && 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// .factory('$$animateReflow', function($$rAF, $document) {\n\n// var bodyEl = $document[0].body;\n\n// return function(fn) {\n// //the returned function acts as the cancellation function\n// return $$rAF(function() {\n// //the line below will force the browser to perform a repaint\n// //so that all the animated elements within the animation frame\n// //will be properly updated and drawn on screen. This is\n// //required to perform multi-class CSS based animations with\n// //Firefox. DO NOT REMOVE THIS LINE.\n// var a = bodyEl.offsetWidth + 1;\n// fn();\n// });\n// };\n\n// });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n template: 'modal/modal.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($window, $rootScope, $compile, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n $modal.$promise = fetchTemplate(options.template);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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 // Support contentTemplate option\n if(options.contentTemplate) {\n $modal.$promise = $modal.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(contentTemplate);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!config.template) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize modal\n var modalLinker, modalElement;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n $modal.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n modalLinker = $compile(template);\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 if(modalElement) {\n modalElement.remove();\n modalElement = null;\n }\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, 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 // Fetch a cloned element linked from template\n modalElement = $modal.$element = modalLinker(scope, function(clonedElement, scope) {});\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: 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 if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\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(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 if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\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\n $modal.$isShown ? $modal.hide() : $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 // Private methods\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', '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(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && 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 // 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\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.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 template: '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 // Directive options\n var options = {scope: scope};\n angular.forEach(['template', '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]))\n 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 // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && 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 angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var 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.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, unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n var viewportHeight;\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 = 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.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 template: '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(a|o)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 }\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 $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\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 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(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\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 } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 evt.preventDefault();\n evt.stopPropagation();\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 // 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 && !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(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // 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 // 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 // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(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 });\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, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? 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 = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? 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.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 }\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.timepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n '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 template: '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 bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)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 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 {\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 = {hour: startDate.getHours(), meridian: startDate.getHours() < 12, minute: startDate.getMinutes(), second: startDate.getSeconds(), millisecond: startDate.getMilliseconds()};\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n 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, {hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(), millisecond: date.getMilliseconds()});\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() { $timepicker.hide(true); });\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, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [], 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({date: hour, label: formatDate(hour, hoursFormat), selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), disabled: $timepicker.$isDisabled(hour, 0)});\n }\n var minutes = [], 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({date: minute, label: formatDate(minute, minutesFormat), selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), disabled: $timepicker.$isDisabled(minute, 1)});\n }\n var seconds = [], 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({date: second, label: formatDate(second, secondsFormat), selected: $timepicker.$date && $timepicker.$isSelected(second, 2), disabled: $timepicker.$isDisabled(second, 2)});\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);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), secondsLength = formatDate(newDate, secondsFormat).length;\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n }\n else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n }\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, {hour: targetDate.getHours()});\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, {minute: targetDate.getMinutes()});\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, {second: targetDate.getSeconds()});\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) return $timepicker.hide(true);\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), 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 _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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 $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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, controller: controller};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Visibility binding support\n attr.bsShow && 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 newValue === true ? timepicker.show() : timepicker.hide();\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 // Initialize parser\n var dateParser = $dateParser({format: options.timeFormat, lang: lang});\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\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;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\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 } else {\n return new Date(date);\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 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.tooltip', ['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 template: 'tooltip/tooltip.tpl.html',\n contentTemplate: 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, $compile, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var nodeName = element[0].nodeName.toLowerCase();\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n $tooltip.$promise = fetchTemplate(options.template);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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, hoverState;\n\n // Support contentTemplate option\n if(options.contentTemplate) {\n $tooltip.$promise = $tooltip.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]);\n if(!contentEl.length) contentEl = findElement('[ng-bind=\"title\"]', templateEl[0]);\n contentEl.removeAttr('ng-bind').html(contentTemplate);\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize tooltip\n var tipLinker, tipElement, tipTemplate, tipContainer, tipScope;\n $tooltip.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n tipTemplate = template;\n tipLinker = $compile(template);\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 options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\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, 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 = tipLinker(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 after ? after.after(tipElement) : parent.prepend(tipElement);\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\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\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() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\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 autoToken = /\\s?auto?\\s?/i,\n 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 tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var container = options.container ? findElement(options.container) : element.parent();\n var containerPosition = getPosition(container);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > containerPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < containerPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > containerPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < containerPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : 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 $tooltip.$isShown ? element[0].blur() : element[0].focus();\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') {\n element.on('click', $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 nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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') {\n element.off('click', $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 nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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 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 for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\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 scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n 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 }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n 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 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 arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 },\n $viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n if (!$viewport) {\n return delta;\n }\n\n var viewportPadding = options.viewport && options.viewport.padding || 0,\n viewportDimensions = getPosition($viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll,\n 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 rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.width) { // 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 scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'contentTemplate', '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 // 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 // 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && 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 newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var 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\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 template: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'filter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\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 // When the placement is not one of the bottom placements, re-calc the positioning\n // so the results render correctly.\n if (/^(bottom|bottom-left|bottom-right)$/.test(options.placement)) return;\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n $timeout($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 l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 }\n\n // Navigate with keyboard\n else if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\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 // 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 $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element && element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element && element.off('keydown', $typeahead.$onKeyDown);\n }\n if(!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n element.attr('autocomplete' ,'off');\n\n // Build proper bsOptions\n var 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) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\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 var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if(values.length === 1 && values[0].value === newValue) return;\n !isVisible && 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) return displayValue;\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 (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)) return element.val('');\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? 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"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/angular-strap.tpl.js b/dist/angular-strap.tpl.js index 9322ff30e..9d3c26117 100644 --- a/dist/angular-strap.tpl.js +++ b/dist/angular-strap.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/angular-strap.tpl.min.js b/dist/angular-strap.tpl.min.js index 24d6894f6..af8b2681f 100644 --- a/dist/angular-strap.tpl.min.js +++ b/dist/angular-strap.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/affix.js b/dist/modules/affix.js index a50c99abb..d656d74bd 100644 --- a/dist/modules/affix.js +++ b/dist/modules/affix.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/affix.min.js b/dist/modules/affix.min.js index bcfc9f9eb..99be337cd 100644 --- a/dist/modules/affix.min.js +++ b/dist/modules/affix.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/alert.js b/dist/modules/alert.js index 6d17cc44a..e99c158e5 100644 --- a/dist/modules/alert.js +++ b/dist/modules/alert.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/alert.min.js b/dist/modules/alert.min.js index d22c7b4e5..6f3874de1 100644 --- a/dist/modules/alert.min.js +++ b/dist/modules/alert.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/alert.tpl.js b/dist/modules/alert.tpl.js index f66e6ae8b..69300440a 100644 --- a/dist/modules/alert.tpl.js +++ b/dist/modules/alert.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/alert.tpl.min.js b/dist/modules/alert.tpl.min.js index 55d890bc6..786214857 100644 --- a/dist/modules/alert.tpl.min.js +++ b/dist/modules/alert.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/aside.js b/dist/modules/aside.js index f8de665b6..6d2b47cbd 100644 --- a/dist/modules/aside.js +++ b/dist/modules/aside.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/aside.min.js b/dist/modules/aside.min.js index dd9df3d48..86fdf693c 100644 --- a/dist/modules/aside.min.js +++ b/dist/modules/aside.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/aside.tpl.js b/dist/modules/aside.tpl.js index 3e12abc70..ced0112b7 100644 --- a/dist/modules/aside.tpl.js +++ b/dist/modules/aside.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/aside.tpl.min.js b/dist/modules/aside.tpl.min.js index ab8010aa4..6f2fd9508 100644 --- a/dist/modules/aside.tpl.min.js +++ b/dist/modules/aside.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/button.js b/dist/modules/button.js index 8bb01f626..12eb4f9e1 100644 --- a/dist/modules/button.js +++ b/dist/modules/button.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/button.min.js b/dist/modules/button.min.js index 1a9674941..ba1707006 100644 --- a/dist/modules/button.min.js +++ b/dist/modules/button.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/collapse.js b/dist/modules/collapse.js index 516e41432..16f72cfd3 100644 --- a/dist/modules/collapse.js +++ b/dist/modules/collapse.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/collapse.min.js b/dist/modules/collapse.min.js index 5538e9697..f6dba3111 100644 --- a/dist/modules/collapse.min.js +++ b/dist/modules/collapse.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/date-formatter.js b/dist/modules/date-formatter.js index 1a34cba54..8e93ac6b9 100644 --- a/dist/modules/date-formatter.js +++ b/dist/modules/date-formatter.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/date-formatter.min.js b/dist/modules/date-formatter.min.js index fb6851a66..6e11481c3 100644 --- a/dist/modules/date-formatter.min.js +++ b/dist/modules/date-formatter.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/date-parser.js b/dist/modules/date-parser.js index 7bdaa8412..75775c749 100644 --- a/dist/modules/date-parser.js +++ b/dist/modules/date-parser.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/date-parser.min.js b/dist/modules/date-parser.min.js index dc72f00a1..3eb7ac8ba 100644 --- a/dist/modules/date-parser.min.js +++ b/dist/modules/date-parser.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/datepicker.js b/dist/modules/datepicker.js index 9ba9b4d59..b74e43198 100644 --- a/dist/modules/datepicker.js +++ b/dist/modules/datepicker.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/datepicker.min.js b/dist/modules/datepicker.min.js index c902f6148..137f21fa5 100644 --- a/dist/modules/datepicker.min.js +++ b/dist/modules/datepicker.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/datepicker.tpl.js b/dist/modules/datepicker.tpl.js index 53093e85a..ffd0d04b6 100644 --- a/dist/modules/datepicker.tpl.js +++ b/dist/modules/datepicker.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/datepicker.tpl.min.js b/dist/modules/datepicker.tpl.min.js index 3dec18465..8028a719d 100644 --- a/dist/modules/datepicker.tpl.min.js +++ b/dist/modules/datepicker.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/debounce.js b/dist/modules/debounce.js index 067bf7b18..9c8a68ed1 100644 --- a/dist/modules/debounce.js +++ b/dist/modules/debounce.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/debounce.min.js b/dist/modules/debounce.min.js index 7a78b6451..a5dca06cd 100644 --- a/dist/modules/debounce.min.js +++ b/dist/modules/debounce.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/dimensions.js b/dist/modules/dimensions.js index 365aeee3d..fbf661e0d 100644 --- a/dist/modules/dimensions.js +++ b/dist/modules/dimensions.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/dimensions.min.js b/dist/modules/dimensions.min.js index edf58299e..4e59d1932 100644 --- a/dist/modules/dimensions.min.js +++ b/dist/modules/dimensions.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/dropdown.js b/dist/modules/dropdown.js index 779cc8a80..b9f202531 100644 --- a/dist/modules/dropdown.js +++ b/dist/modules/dropdown.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -46,7 +46,7 @@ angular.module('mgcrea.ngStrap.dropdown', [ 'mgcrea.ngStrap.tooltip' ]).provider $dropdown.show = function() { show(); $timeout(function() { - options.keyboard && $dropdown.$element.on('keydown', $dropdown.$onKeyDown); + options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown); bodyEl.on('click', onBodyClick); }, 0, false); parentEl.hasClass('dropdown') && parentEl.addClass('open'); @@ -54,7 +54,7 @@ angular.module('mgcrea.ngStrap.dropdown', [ 'mgcrea.ngStrap.tooltip' ]).provider var hide = $dropdown.hide; $dropdown.hide = function() { if (!$dropdown.$isShown) return; - options.keyboard && $dropdown.$element.off('keydown', $dropdown.$onKeyDown); + options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown); bodyEl.off('click', onBodyClick); parentEl.hasClass('dropdown') && parentEl.removeClass('open'); hide(); diff --git a/dist/modules/dropdown.min.js b/dist/modules/dropdown.min.js index b62ee995f..141961641 100644 --- a/dist/modules/dropdown.min.js +++ b/dist/modules/dropdown.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$dropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',template:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(o,n,t,r){function a(o,a){function c(e){return e.target!==o[0]?e.target!==o[0]&&d.hide():void 0}{var d={},s=angular.extend({},e,a);d.$scope=s.scope&&s.scope.$new()||n.$new()}d=t(o,s);var p=o.parent();d.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var o=angular.element(d.$element[0].querySelectorAll('li:not(.divider) a'));if(o.length){var n;angular.forEach(o,function(e,o){l&&l.call(e,':focus')&&(n=o)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&n0?n--:40===e.keyCode&&n 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 options.keyboard && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n 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 link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\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"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/dropdown.js"],"names":["angular","trigger","provider","container","this","defaults","keyboard","html","delay","placement","$get","bodyEl","matchesSelector","DropdownFactory","$dropdown","options","element","evt","keyCode","onBodyClick","directive","target","hide","stopPropagation","items","$element","querySelectorAll","$rootScope","$new","parentEl","index","forEach","preventDefault","focus","length","show","el","i","$onKeyDown","on","hasClass","$isShown","removeClass","destroy","off","scope","parent","prototype","$window","$sce","restrict","link","falseValueRegExp","attr","transclusion","bsDropdown","$watch","newValue","oldValue","content","dropdown","key","isString","match","bsShow","isDefined","$on"],"mappings":"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","file":"modules/dropdown.min.js","sourcesContent":["'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 template: '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 options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n 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 link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\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"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/dropdown.tpl.js b/dist/modules/dropdown.tpl.js index d3e09d535..bc08d0d51 100644 --- a/dist/modules/dropdown.tpl.js +++ b/dist/modules/dropdown.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/dropdown.tpl.min.js b/dist/modules/dropdown.tpl.min.js index 7e0fc87ff..bdf54b526 100644 --- a/dist/modules/dropdown.tpl.min.js +++ b/dist/modules/dropdown.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/modal.js b/dist/modules/modal.js index f9522d24e..b05c9b2f0 100644 --- a/dist/modules/modal.js +++ b/dist/modules/modal.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -133,8 +133,11 @@ angular.module('mgcrea.ngStrap.modal', [ 'mgcrea.ngStrap.helpers.dimensions' ]). if (options.backdrop) { $animate.enter(backdropElement, bodyElement, null); } - var promise = $animate.enter(modalElement, parent, after, enterAnimateCallback); - if (promise && promise.then) promise.then(enterAnimateCallback); + if (angular.version.minor <= 2) { + $animate.enter(modalElement, parent, after, enterAnimateCallback); + } else { + $animate.enter(modalElement, parent, after).then(enterAnimateCallback); + } $modal.$isShown = scope.$isShown = true; safeDigest(scope); var el = modalElement[0]; @@ -162,8 +165,11 @@ angular.module('mgcrea.ngStrap.modal', [ 'mgcrea.ngStrap.helpers.dimensions' ]). if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) { return; } - var promise = $animate.leave(modalElement, leaveAnimateCallback); - if (promise && promise.then) promise.then(leaveAnimateCallback); + if (angular.version.minor <= 2) { + $animate.leave(modalElement, leaveAnimateCallback); + } else { + $animate.leave(modalElement).then(leaveAnimateCallback); + } if (options.backdrop) { $animate.leave(backdropElement); } diff --git a/dist/modules/modal.min.js b/dist/modules/modal.min.js index 612df2296..4cd4862a7 100644 --- a/dist/modules/modal.min.js +++ b/dist/modules/modal.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',template:'modal/modal.tpl.html',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$compile','$q','$templateCache','$http','$animate','$timeout','$sce','dimensions',function(n,t,o,i,a,r,l,c,s,u){function d(n){function i(){w.$emit(d.prefixEvent+'.show',u)}function a(){w.$emit(d.prefixEvent+'.hide',u),v.removeClass(d.prefixClass+'-open'),d.animation&&v.removeClass(d.prefixClass+'-with-'+d.animation)}function r(e){e.target===e.currentTarget&&('static'===d.backdrop?u.focus():u.hide())}function c(e){e.preventDefault()}var u={},d=u.$options=angular.extend({},e,n);u.$promise=m(d.template);var w=u.$scope=d.scope&&d.scope.$new()||t.$new();d.element||d.container||(d.container='body'),u.$id=d.id||d.element&&d.element.attr('id')||'',h(['title','content'],function(e){d[e]&&(w[e]=s.trustAsHtml(d[e]))}),w.$hide=function(){w.$$postDigest(function(){u.hide()})},w.$show=function(){w.$$postDigest(function(){u.show()})},w.$toggle=function(){w.$$postDigest(function(){u.toggle()})},u.$isShown=w.$isShown=!1,d.contentTemplate&&(u.$promise=u.$promise.then(function(e){var t=angular.element(e);return m(d.contentTemplate).then(function(e){var o=p('[ng-bind="content"]',t[0]).removeAttr('ng-bind').html(e);return n.template||o.next().remove(),t[0].outerHTML})}));var k,x,y=angular.element('
');return y.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),u.$promise.then(function(e){angular.isObject(e)&&(e=e.data),d.html&&(e=e.replace(b,'ng-bind-html="')),e=$.apply(e),k=o(e),u.init()}),u.init=function(){d.show&&w.$$postDigest(function(){u.show()})},u.destroy=function(){x&&(x.remove(),x=null),y&&(y.remove(),y=null),w.$destroy()},u.show=function(){if(!u.$isShown){var e,n;if(angular.isElement(d.container)?(e=d.container,n=d.container[0].lastChild?angular.element(d.container[0].lastChild):null):d.container?(e=p(d.container),n=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,n=d.element),x=u.$element=k(w,function(e,n){}),!w.$emit(d.prefixEvent+'.show.before',u).defaultPrevented){x.css({display:'block'}).addClass(d.placement),d.animation&&(d.backdrop&&y.addClass(d.backdropAnimation),x.addClass(d.animation)),d.backdrop&&l.enter(y,v,null);var t=l.enter(x,e,n,i);t&&t.then&&t.then(i),u.$isShown=w.$isShown=!0,f(w);var o=x[0];g(function(){o.focus()}),v.addClass(d.prefixClass+'-open'),d.animation&&v.addClass(d.prefixClass+'-with-'+d.animation),d.backdrop&&(x.on('click',r),y.on('click',r),y.on('wheel',c)),d.keyboard&&x.on('keyup',u.$onKeyUp)}}},u.hide=function(){if(u.$isShown&&!w.$emit(d.prefixEvent+'.hide.before',u).defaultPrevented){var e=l.leave(x,a);e&&e.then&&e.then(a),d.backdrop&&l.leave(y),u.$isShown=w.$isShown=!1,f(w),d.backdrop&&(x.off('click',r),y.off('click',r),y.off('wheel',c)),d.keyboard&&x.off('keyup',u.$onKeyUp)}},u.toggle=function(){u.$isShown?u.hide():u.show()},u.focus=function(){x[0].focus()},u.$onKeyUp=function(e){27===e.which&&u.$isShown&&(u.hide(),e.stopPropagation())},u}function f(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function p(e,n){return angular.element((n||document).querySelectorAll(e))}function m(e){return w[e]?w[e]:w[e]=r.get(e,{cache:a}).then(function(e){return e.data})}var h=angular.forEach,$=String.prototype.trim,g=n.requestAnimationFrame||n.setTimeout,v=angular.element(n.document.body),b=/ng-bind="/gi,w={};return d}]}).directive('bsModal',['$window','$sce','$modal',function(e,n,t){return{restrict:'EAC',scope:!0,link:function(e,o,i,a){var r={scope:e,element:o,show:!1};angular.forEach(['template','contentTemplate','placement','backdrop','keyboard','html','container','animation','id','prefixEvent','prefixClass'],function(e){angular.isDefined(i[e])&&(r[e]=i[e])});var l=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(i[e])&&l.test(i[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(t){i[t]&&i.$observe(t,function(o,i){e[t]=n.trustAsHtml(o)})}),i.bsModal&&e.$watch(i.bsModal,function(n,t){angular.isObject(n)?angular.extend(e,n):e.content=n},!0);var c=t(r);o.on(i.trigger||'click',c.toggle),e.$on('$destroy',function(){c&&c.destroy(),r=null,c=null})}}}]); +'use strict';angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',template:'modal/modal.tpl.html',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$compile','$q','$templateCache','$http','$animate','$timeout','$sce','dimensions',function(n,t,o,i,a,r,l,s,c,u){function d(n){function i(){w.$emit(d.prefixEvent+'.show',u)}function a(){w.$emit(d.prefixEvent+'.hide',u),v.removeClass(d.prefixClass+'-open'),d.animation&&v.removeClass(d.prefixClass+'-with-'+d.animation)}function r(e){e.target===e.currentTarget&&('static'===d.backdrop?u.focus():u.hide())}function s(e){e.preventDefault()}var u={},d=u.$options=angular.extend({},e,n);u.$promise=f(d.template);var w=u.$scope=d.scope&&d.scope.$new()||t.$new();d.element||d.container||(d.container='body'),u.$id=d.id||d.element&&d.element.attr('id')||'',h(['title','content'],function(e){d[e]&&(w[e]=c.trustAsHtml(d[e]))}),w.$hide=function(){w.$$postDigest(function(){u.hide()})},w.$show=function(){w.$$postDigest(function(){u.show()})},w.$toggle=function(){w.$$postDigest(function(){u.toggle()})},u.$isShown=w.$isShown=!1,d.contentTemplate&&(u.$promise=u.$promise.then(function(e){var t=angular.element(e);return f(d.contentTemplate).then(function(e){var o=p('[ng-bind="content"]',t[0]).removeAttr('ng-bind').html(e);return n.template||o.next().remove(),t[0].outerHTML})}));var k,x,y=angular.element('
');return y.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),u.$promise.then(function(e){angular.isObject(e)&&(e=e.data),d.html&&(e=e.replace(b,'ng-bind-html="')),e=$.apply(e),k=o(e),u.init()}),u.init=function(){d.show&&w.$$postDigest(function(){u.show()})},u.destroy=function(){x&&(x.remove(),x=null),y&&(y.remove(),y=null),w.$destroy()},u.show=function(){if(!u.$isShown){var e,n;if(angular.isElement(d.container)?(e=d.container,n=d.container[0].lastChild?angular.element(d.container[0].lastChild):null):d.container?(e=p(d.container),n=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,n=d.element),x=u.$element=k(w,function(e,n){}),!w.$emit(d.prefixEvent+'.show.before',u).defaultPrevented){x.css({display:'block'}).addClass(d.placement),d.animation&&(d.backdrop&&y.addClass(d.backdropAnimation),x.addClass(d.animation)),d.backdrop&&l.enter(y,v,null),angular.version.minor<=2?l.enter(x,e,n,i):l.enter(x,e,n).then(i),u.$isShown=w.$isShown=!0,m(w);var t=x[0];g(function(){t.focus()}),v.addClass(d.prefixClass+'-open'),d.animation&&v.addClass(d.prefixClass+'-with-'+d.animation),d.backdrop&&(x.on('click',r),y.on('click',r),y.on('wheel',s)),d.keyboard&&x.on('keyup',u.$onKeyUp)}}},u.hide=function(){u.$isShown&&(w.$emit(d.prefixEvent+'.hide.before',u).defaultPrevented||(angular.version.minor<=2?l.leave(x,a):l.leave(x).then(a),d.backdrop&&l.leave(y),u.$isShown=w.$isShown=!1,m(w),d.backdrop&&(x.off('click',r),y.off('click',r),y.off('wheel',s)),d.keyboard&&x.off('keyup',u.$onKeyUp)))},u.toggle=function(){u.$isShown?u.hide():u.show()},u.focus=function(){x[0].focus()},u.$onKeyUp=function(e){27===e.which&&u.$isShown&&(u.hide(),e.stopPropagation())},u}function m(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function p(e,n){return angular.element((n||document).querySelectorAll(e))}function f(e){return w[e]?w[e]:w[e]=r.get(e,{cache:a}).then(function(e){return e.data})}var h=angular.forEach,$=String.prototype.trim,g=n.requestAnimationFrame||n.setTimeout,v=angular.element(n.document.body),b=/ng-bind="/gi,w={};return d}]}).directive('bsModal',['$window','$sce','$modal',function(e,n,t){return{restrict:'EAC',scope:!0,link:function(e,o,i,a){var r={scope:e,element:o,show:!1};angular.forEach(['template','contentTemplate','placement','backdrop','keyboard','html','container','animation','id','prefixEvent','prefixClass'],function(e){angular.isDefined(i[e])&&(r[e]=i[e])});var l=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(i[e])&&l.test(i[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(t){i[t]&&i.$observe(t,function(o,i){e[t]=n.trustAsHtml(o)})}),i.bsModal&&e.$watch(i.bsModal,function(n,t){angular.isObject(n)?angular.extend(e,n):e.content=n},!0);var s=t(r);o.on(i.trigger||'click',s.toggle),e.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]); //# sourceMappingURL=../modules/modal.min.js.map \ No newline at end of file diff --git a/dist/modules/modal.min.js.map b/dist/modules/modal.min.js.map index 124417781..7fb0218d4 100644 --- a/dist/modules/modal.min.js.map +++ b/dist/modules/modal.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/modal.js"],"names":["angular","template","provider","contentTemplate","defaults","container","element","backdrop","keyboard","html","show","this","$get","forEach","trim","requestAnimationFrame","bodyElement","htmlReplaceRegExp","$modal","ModalFactory","config","enterAnimateCallback","scope","promise","$animate","modalElement","leaveAnimateCallback","toggle","$isShown","removeClass","options","prefixClass","focus","evt","target","currentTarget","safeDigest","preventEventDefault","preventDefault","$options","extend","key","trustAsHtml","$scope","$new","$rootScope","$hide","$$postDigest","$id","id","attr","$show","$sce","hide","$promise","templateEl","fetchTemplate","outerHTML","then","modalLinker","backdropElement","position","css","right","z-index","top","left","init","data","replace","$compile","destroy","remove","$destroy","after","isElement","parent","$element","$emit","prefixEvent","defaultPrevented","animation","clonedElement","display","addClass","enter","el","on","hideOnBackdropClick","$onKeyUp","leave","off","which","stopPropagation","fetchPromises","cache","$templateCache","res","$http","get","directive","restrict","body","link","isDefined","falseValueRegExp","$observe","newValue","oldValue","bsModal","$watch","content","modal","trigger","$on"],"mappings":"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","file":"modules/modal.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n template: 'modal/modal.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($window, $rootScope, $compile, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n $modal.$promise = fetchTemplate(options.template);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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 // Support contentTemplate option\n if(options.contentTemplate) {\n $modal.$promise = $modal.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(contentTemplate);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!config.template) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize modal\n var modalLinker, modalElement;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n $modal.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n modalLinker = $compile(template);\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 if(modalElement) {\n modalElement.remove();\n modalElement = null;\n }\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, 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 // Fetch a cloned element linked from template\n modalElement = $modal.$element = modalLinker(scope, function(clonedElement, scope) {});\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: 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 // Support v1.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n var promise = $animate.enter(modalElement, parent, after, enterAnimateCallback);\n if(promise && promise.then) promise.then(enterAnimateCallback);\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 if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\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(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n var promise = $animate.leave(modalElement, leaveAnimateCallback);\n // Support v1.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n if(promise && promise.then) promise.then(leaveAnimateCallback);\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\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\n $modal.$isShown ? $modal.hide() : $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 // Private methods\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', '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(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && 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 // 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"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/modal.js"],"names":["angular","template","provider","contentTemplate","defaults","container","element","backdrop","keyboard","html","show","this","$get","forEach","trim","requestAnimationFrame","bodyElement","htmlReplaceRegExp","$modal","ModalFactory","config","enterAnimateCallback","scope","version","minor","toggle","$isShown","removeClass","options","prefixClass","focus","modalElement","evt","target","currentTarget","safeDigest","preventEventDefault","preventDefault","$options","extend","key","trustAsHtml","$scope","$new","$rootScope","$hide","$$postDigest","$id","id","attr","$show","$sce","hide","$promise","templateEl","fetchTemplate","outerHTML","then","modalLinker","backdropElement","position","css","right","z-index","top","left","init","data","replace","$compile","destroy","remove","$destroy","after","isElement","parent","$element","$emit","prefixEvent","defaultPrevented","animation","clonedElement","display","addClass","$animate","enter","backdropAnimation","el","on","hideOnBackdropClick","$onKeyUp","leave","leaveAnimateCallback","off","which","stopPropagation","fetchPromises","cache","$templateCache","res","$http","get","directive","restrict","body","link","isDefined","falseValueRegExp","$observe","newValue","oldValue","bsModal","$watch","content","modal","trigger","$on"],"mappings":"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","file":"modules/modal.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n template: 'modal/modal.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($window, $rootScope, $compile, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n $modal.$promise = fetchTemplate(options.template);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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 // Support contentTemplate option\n if(options.contentTemplate) {\n $modal.$promise = $modal.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(contentTemplate);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!config.template) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize modal\n var modalLinker, modalElement;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n $modal.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n modalLinker = $compile(template);\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 if(modalElement) {\n modalElement.remove();\n modalElement = null;\n }\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, 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 // Fetch a cloned element linked from template\n modalElement = $modal.$element = modalLinker(scope, function(clonedElement, scope) {});\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: 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 if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\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(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 if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\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\n $modal.$isShown ? $modal.hide() : $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 // Private methods\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', '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(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && 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 // 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"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/modal.tpl.js b/dist/modules/modal.tpl.js index ddef920c4..54d2a29f9 100644 --- a/dist/modules/modal.tpl.js +++ b/dist/modules/modal.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/modal.tpl.min.js b/dist/modules/modal.tpl.min.js index 2461b415b..7d03c8b71 100644 --- a/dist/modules/modal.tpl.min.js +++ b/dist/modules/modal.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/navbar.js b/dist/modules/navbar.js index ad1ce10ae..e70ae9294 100644 --- a/dist/modules/navbar.js +++ b/dist/modules/navbar.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/navbar.min.js b/dist/modules/navbar.min.js index 271343741..83c47059c 100644 --- a/dist/modules/navbar.min.js +++ b/dist/modules/navbar.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/parse-options.js b/dist/modules/parse-options.js index 87736562e..93d1db43d 100644 --- a/dist/modules/parse-options.js +++ b/dist/modules/parse-options.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/parse-options.min.js b/dist/modules/parse-options.min.js index dcfa3d8d8..db6bbacc8 100644 --- a/dist/modules/parse-options.min.js +++ b/dist/modules/parse-options.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/popover.js b/dist/modules/popover.js index 9aa1b124c..7f9be6ffc 100644 --- a/dist/modules/popover.js +++ b/dist/modules/popover.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/popover.min.js b/dist/modules/popover.min.js index 3203521f8..df1441591 100644 --- a/dist/modules/popover.min.js +++ b/dist/modules/popover.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/popover.tpl.js b/dist/modules/popover.tpl.js index 52e688733..516dff2d5 100644 --- a/dist/modules/popover.tpl.js +++ b/dist/modules/popover.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/popover.tpl.min.js b/dist/modules/popover.tpl.min.js index d4c3063ba..06599ec9a 100644 --- a/dist/modules/popover.tpl.min.js +++ b/dist/modules/popover.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/raf.js b/dist/modules/raf.js index 9876343cd..7761c830b 100644 --- a/dist/modules/raf.js +++ b/dist/modules/raf.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/raf.min.js b/dist/modules/raf.min.js index a5f95d34f..ee949af45 100644 --- a/dist/modules/raf.min.js +++ b/dist/modules/raf.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/scrollspy.js b/dist/modules/scrollspy.js index 14eaf094a..69681ea14 100644 --- a/dist/modules/scrollspy.js +++ b/dist/modules/scrollspy.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/scrollspy.min.js b/dist/modules/scrollspy.min.js index b3ba36075..d1b3c8528 100644 --- a/dist/modules/scrollspy.min.js +++ b/dist/modules/scrollspy.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/select.js b/dist/modules/select.js index 4f9cd602c..0044918ed 100644 --- a/dist/modules/select.js +++ b/dist/modules/select.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -87,7 +87,9 @@ angular.module('mgcrea.ngStrap.select', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngSt $select.activate = function(index) { if (options.multiple) { $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index); - if (options.sort) scope.$activeIndex.sort(); + if (options.sort) scope.$activeIndex.sort(function(a, b) { + return a - b; + }); } else { scope.$activeIndex = index; } diff --git a/dist/modules/select.min.js b/dist/modules/select.min.js index 1e9ffeab0..0eea40609 100644 --- a/dist/modules/select.min.js +++ b/dist/modules/select.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$select',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',template:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:' ',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,l,i){function o(t,n,a){var o={},c=angular.extend({},e,a);o=l(t,c);var u=o.$scope;u.$matches=[],u.$activeIndex=c.multiple?[]:-1,u.$isMultiple=c.multiple,u.$showAllNoneButtons=c.allNoneButtons&&c.multiple,u.$iconCheckmark=c.iconCheckmark,u.$allText=c.allText,u.$noneText=c.noneText,u.$activate=function(e){u.$$postDigest(function(){o.activate(e)})},u.$select=function(e,t){u.$$postDigest(function(){o.select(e)})},u.$isVisible=function(){return o.$isVisible()},u.$isActive=function(e){return o.$isActive(e)},u.$selectAll=function(){for(var e=0;e=u.$matches.length&&(u.$activeIndex=c.multiple?[]:0)},o.$isVisible=function(){return c.minLength&&n?u.$matches.length&&n.$viewValue.length>=c.minLength:u.$matches.length},o.$isActive=function(e){return c.multiple?-1!==u.$activeIndex.indexOf(e):u.$activeIndex===e},o.$getIndex=function(e){var t=u.$matches.length,n=t;if(t){for(n=t;n--&&u.$matches[n].value!==e;);if(!(0>n))return n}},o.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),r){var t=angular.element(e.target);t.triggerHandler('click')}},o.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(e.preventDefault(),e.stopPropagation(),c.multiple&&9===e.keyCode?o.hide():c.multiple||13!==e.keyCode&&9!==e.keyCode?void(c.multiple||(38===e.keyCode&&u.$activeIndex>0?u.$activeIndex--:38===e.keyCode&&u.$activeIndex<0?u.$activeIndex=u.$matches.length-1:40===e.keyCode&&u.$activeIndex'),s.after(t)}var $=l(n.bsOptions),d=a(t,o,c),m=$.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(m,function(t,n){$.valuesFn(e,o).then(function(e){d.update(e),o.$render()})}),e.$watch(n.ngModel,function(e,t){d.$updateActiveIndex(),o.$render()},!0),o.$render=function(){var e,n;c.multiple&&angular.isArray(o.$modelValue)?(e=o.$modelValue.map(function(e){return n=d.$getIndex(e),angular.isDefined(n)?d.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(c.maxLength||i.maxLength)?e.length+' '+(c.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=d.$getIndex(o.$modelValue),e=angular.isDefined(n)?d.$scope.$matches[n].label:!1),t.html((e?e:c.placeholder)+(c.caretHtml?c.caretHtml:i.caretHtml))},c.multiple&&(o.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){d&&d.destroy(),c=null,d=null})}}}]); +'use strict';angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$select',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',template:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:' ',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,l,i){function o(t,n,a){var o={},c=angular.extend({},e,a);o=l(t,c);var u=o.$scope;u.$matches=[],u.$activeIndex=c.multiple?[]:-1,u.$isMultiple=c.multiple,u.$showAllNoneButtons=c.allNoneButtons&&c.multiple,u.$iconCheckmark=c.iconCheckmark,u.$allText=c.allText,u.$noneText=c.noneText,u.$activate=function(e){u.$$postDigest(function(){o.activate(e)})},u.$select=function(e,t){u.$$postDigest(function(){o.select(e)})},u.$isVisible=function(){return o.$isVisible()},u.$isActive=function(e){return o.$isActive(e)},u.$selectAll=function(){for(var e=0;e=u.$matches.length&&(u.$activeIndex=c.multiple?[]:0)},o.$isVisible=function(){return c.minLength&&n?u.$matches.length&&n.$viewValue.length>=c.minLength:u.$matches.length},o.$isActive=function(e){return c.multiple?-1!==u.$activeIndex.indexOf(e):u.$activeIndex===e},o.$getIndex=function(e){var t=u.$matches.length,n=t;if(t){for(n=t;n--&&u.$matches[n].value!==e;);if(!(0>n))return n}},o.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),r){var t=angular.element(e.target);t.triggerHandler('click')}},o.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(e.preventDefault(),e.stopPropagation(),c.multiple&&9===e.keyCode?o.hide():c.multiple||13!==e.keyCode&&9!==e.keyCode?void(c.multiple||(38===e.keyCode&&u.$activeIndex>0?u.$activeIndex--:38===e.keyCode&&u.$activeIndex<0?u.$activeIndex=u.$matches.length-1:40===e.keyCode&&u.$activeIndex'),s.after(t)}var $=l(n.bsOptions),d=a(t,o,c),m=$.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(m,function(t,n){$.valuesFn(e,o).then(function(e){d.update(e),o.$render()})}),e.$watch(n.ngModel,function(e,t){d.$updateActiveIndex(),o.$render()},!0),o.$render=function(){var e,n;c.multiple&&angular.isArray(o.$modelValue)?(e=o.$modelValue.map(function(e){return n=d.$getIndex(e),angular.isDefined(n)?d.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(c.maxLength||i.maxLength)?e.length+' '+(c.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=d.$getIndex(o.$modelValue),e=angular.isDefined(n)?d.$scope.$matches[n].label:!1),t.html((e?e:c.placeholder)+(c.caretHtml?c.caretHtml:i.caretHtml))},c.multiple&&(o.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){d&&d.destroy(),c=null,d=null})}}}]); //# sourceMappingURL=../modules/select.min.js.map \ No newline at end of file diff --git a/dist/modules/select.min.js.map b/dist/modules/select.min.js.map index 25fe3ee4f..ccf571ceb 100644 --- a/dist/modules/select.min.js.map +++ b/dist/modules/select.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/select.js"],"names":["angular","trigger","provider","container","this","defaults","keyboard","html","delay","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","bodyEl","isNative","isTouch","SelectFactory","$select","$tooltip","element","options","scope","$activeIndex","config","$isMultiple","$showAllNoneButtons","$allText","$iconCheckmark","activate","index","$$postDigest","select","evt","$isActive","$isVisible","i","$selectNone","$matches","length","matches","$updateActiveIndex","value","controller","hide","$setViewValue","map","$emit","prefixEvent","$modelValue","$getIndex","minLength","$viewValue","l","indexOf","preventDefault","stopPropagation","targetEl","$onMouseDown","keyCode","$digest","_show","isUndefined","show","$element","addClass","$timeout","_hide","on","$onKeyDown","off","directive","$scope","$window","document","link","require","restrict","forEach","attr","falseValueRegExp","isDefined","dataMultiple","key","nodeName","toLowerCase","inputEl","after","test","watchedOptions","$watchCollection","parsedOptions","valuesFn","update","$parseOptions","bsOptions","ngModel","$match","newValue","oldValue","$render","values","selected","isArray","join","label","$isEmpty","$on","destroy"],"mappings":"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","file":"modules/select.min.js","sourcesContent":["'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 template: '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(a|o)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 }\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 $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.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 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(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\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 } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 evt.preventDefault();\n evt.stopPropagation();\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 // 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 && !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(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // 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 // 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 // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(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 });\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, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? 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 = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? 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"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/select.js"],"names":["angular","trigger","provider","container","this","defaults","keyboard","html","delay","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","bodyEl","isNative","isTouch","SelectFactory","$select","$tooltip","element","options","scope","$activeIndex","config","$isMultiple","$showAllNoneButtons","$allText","$iconCheckmark","activate","index","$$postDigest","select","evt","$isActive","$isVisible","i","$selectNone","$matches","length","matches","$updateActiveIndex","b","a","controller","value","hide","$setViewValue","map","$emit","prefixEvent","$modelValue","$getIndex","minLength","$viewValue","l","indexOf","preventDefault","stopPropagation","targetEl","$onMouseDown","keyCode","$digest","_show","isUndefined","show","$element","addClass","$timeout","_hide","on","$onKeyDown","off","directive","$scope","$window","document","link","require","restrict","forEach","attr","falseValueRegExp","isDefined","dataMultiple","key","nodeName","toLowerCase","inputEl","after","test","watchedOptions","$watchCollection","parsedOptions","valuesFn","update","$parseOptions","bsOptions","ngModel","$match","newValue","oldValue","$render","values","selected","isArray","join","label","$isEmpty","$on","destroy"],"mappings":"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","file":"modules/select.min.js","sourcesContent":["'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 template: '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(a|o)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 }\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 $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\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 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(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\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 } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 evt.preventDefault();\n evt.stopPropagation();\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 // 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 && !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(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // 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 // 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 // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(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 });\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, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? 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 = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? 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"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/select.tpl.js b/dist/modules/select.tpl.js index f5a299987..c4c59034e 100644 --- a/dist/modules/select.tpl.js +++ b/dist/modules/select.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/select.tpl.min.js b/dist/modules/select.tpl.min.js index e0c66b1b6..755f352d4 100644 --- a/dist/modules/select.tpl.min.js +++ b/dist/modules/select.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tab.js b/dist/modules/tab.js index 518d3af1f..505475962 100644 --- a/dist/modules/tab.js +++ b/dist/modules/tab.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tab.min.js b/dist/modules/tab.min.js index e5f8e53af..de57775db 100644 --- a/dist/modules/tab.min.js +++ b/dist/modules/tab.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tab.tpl.js b/dist/modules/tab.tpl.js index 39c40b98b..c73d86414 100644 --- a/dist/modules/tab.tpl.js +++ b/dist/modules/tab.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tab.tpl.min.js b/dist/modules/tab.tpl.min.js index 19b7ccfb9..acd4ba026 100644 --- a/dist/modules/tab.tpl.min.js +++ b/dist/modules/tab.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/timepicker.js b/dist/modules/timepicker.js index 764b04781..a11ff183d 100644 --- a/dist/modules/timepicker.js +++ b/dist/modules/timepicker.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -313,18 +313,18 @@ angular.module('mgcrea.ngStrap.timepicker', [ 'mgcrea.ngStrap.helpers.dateParser $timepicker.show = function() { _show(); $timeout(function() { - $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); + $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); if (options.keyboard) { - element.on('keydown', $timepicker.$onKeyDown); + element && element.on('keydown', $timepicker.$onKeyDown); } }, 0, false); }; var _hide = $timepicker.hide; $timepicker.hide = function(blur) { if (!$timepicker.$isShown) return; - $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); + $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); if (options.keyboard) { - element.off('keydown', $timepicker.$onKeyDown); + element && element.off('keydown', $timepicker.$onKeyDown); } _hide(blur); }; diff --git a/dist/modules/timepicker.min.js b/dist/modules/timepicker.min.js index 5d148a8a6..c4b8f9f70 100644 --- a/dist/modules/timepicker.min.js +++ b/dist/modules/timepicker.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.timepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$timepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'timepicker',placement:'bottom-left',template:'timepicker/timepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!0,timeType:'date',timeFormat:'shortTime',timezone:null,modelTimeFormat:null,autoclose:!1,minTime:-(1/0),maxTime:+(1/0),length:5,hourStep:1,minuteStep:5,secondStep:5,roundDisplay:!1,iconUp:'glyphicon glyphicon-chevron-up',iconDown:'glyphicon glyphicon-chevron-down',arrowBehavior:'pager'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','$tooltip','$timeout',function(t,n,a,i,o,r,s){function u(t,n,a){function i(e){var t=6e4*p.minuteStep;return new Date(Math.floor(e.getTime()/t)*t)}function u(e,n){var a=e+n;if(t[0].createTextRange){var i=t[0].createTextRange();i.collapse(!0),i.moveStart('character',e),i.moveEnd('character',a),i.select()}else t[0].setSelectionRange?t[0].setSelectionRange(e,a):angular.isUndefined(t[0].selectionStart)&&(t[0].selectionStart=e,t[0].selectionEnd=a)}function c(){t[0].focus()}var m=r(t,angular.extend({},e,a)),g=a.scope,p=m.$options,$=m.$scope,f=p.lang,h=function(e,t,n){return o.formatDate(e,t,f,n)},v=0,w=p.roundDisplay?i(new Date):new Date,S=n.$dateValue||w,y={hour:S.getHours(),meridian:S.getHours()<12,minute:S.getMinutes(),second:S.getSeconds(),millisecond:S.getMilliseconds()},D=o.getDatetimeFormat(p.timeFormat,f),T=o.hoursFormat(D),V=o.timeSeparator(D),b=o.minutesFormat(D),k=o.secondsFormat(D),M=o.showSeconds(D),x=o.showAM(D);$.$iconUp=p.iconUp,$.$iconDown=p.iconDown,$.$select=function(e,t){m.select(e,t)},$.$moveIndex=function(e,t){m.$moveIndex(e,t)},$.$switchMeridian=function(e){m.switchMeridian(e)},m.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())?(m.$date=e,angular.extend(y,{hour:e.getHours(),minute:e.getMinutes(),second:e.getSeconds(),millisecond:e.getMilliseconds()}),m.$build()):m.$isBuilt||m.$build()},m.select=function(e,t,a){(!n.$dateValue||isNaN(n.$dateValue.getTime()))&&(n.$dateValue=new Date(1970,0,1)),angular.isDate(e)||(e=new Date(e)),0===t?n.$dateValue.setHours(e.getHours()):1===t?n.$dateValue.setMinutes(e.getMinutes()):2===t&&n.$dateValue.setSeconds(e.getSeconds()),n.$setViewValue(angular.copy(n.$dateValue)),n.$render(),p.autoclose&&!a&&s(function(){m.hide(!0)})},m.switchMeridian=function(e){if(n.$dateValue&&!isNaN(n.$dateValue.getTime())){var t=(e||n.$dateValue).getHours();n.$dateValue.setHours(12>t?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},m.$build=function(){var e,t,n=$.midIndex=parseInt(p.length/2,10),a=[];for(e=0;e1*p.maxTime},$.$arrowAction=function(e,t){'picker'===p.arrowBehavior?m.$setTimeByStep(e,t):m.$moveIndex(e,t)},m.$setTimeByStep=function(e,t){{var n=new Date(m.$date),a=n.getHours(),i=(h(n,T).length,n.getMinutes()),o=(h(n,b).length,n.getSeconds());h(n,k).length}0===t?n.setHours(a-parseInt(p.hourStep,10)*e):1===t?n.setMinutes(i-parseInt(p.minuteStep,10)*e):2===t&&n.setSeconds(o-parseInt(p.secondStep,10)*e),m.select(n,t,!0)},m.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,y.hour+e*p.length,y.minute,y.second),angular.extend(y,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,y.hour,y.minute+e*p.length*p.minuteStep,y.second),angular.extend(y,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,y.hour,y.minute,y.second+e*p.length*p.secondStep),angular.extend(y,{second:n.getSeconds()})),m.$build()},m.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},m.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return m.hide(!0);var t=new Date(m.$date),n=t.getHours(),a=h(t,T).length,i=t.getMinutes(),o=h(t,b).length,r=t.getSeconds(),s=h(t,k).length,d=1,l=/(37|39)/.test(e.keyCode),c=2+1*M+1*x;l&&(37===e.keyCode?v=1>v?c-1:v-1:39===e.keyCode&&(v=c-1>v?v+1:0));var $=[0,a],f=0;38===e.keyCode&&(f=-1),40===e.keyCode&&(f=1);var w=2===v&&M,S=2===v&&!M||3===v&&M;0===v?(t.setHours(n+f*parseInt(p.hourStep,10)),a=h(t,T).length,$=[0,a]):1===v?(t.setMinutes(i+f*parseInt(p.minuteStep,10)),o=h(t,b).length,$=[a+d,o]):w?(t.setSeconds(r+f*parseInt(p.secondStep,10)),s=h(t,k).length,$=[a+d+o+d,s]):S&&(l||m.switchMeridian(),$=[a+d+o+d+(s+d)*M,2]),m.select(t,v,!0),u($[0],$[1]),g.$digest()}};var N=m.init;m.init=function(){return d&&p.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(l&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',c)),void N())};var F=m.destroy;m.destroy=function(){d&&p.useNative&&t.off('click',c),F()};var H=m.show;m.show=function(){H(),s(function(){m.$element.on(l?'touchstart':'mousedown',m.$onMouseDown),p.keyboard&&t.on('keydown',m.$onKeyDown)},0,!1)};var I=m.hide;return m.hide=function(e){m.$isShown&&(m.$element.off(l?'touchstart':'mousedown',m.$onMouseDown),p.keyboard&&t.off('keydown',m.$onKeyDown),I(e))},m}var d=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),l='createTouch'in t.document&&d;return e.lang||(e.lang=o.getDefaultLocale()),u.defaults=e,u}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,n,a,i,o){{var r=o.defaults,s=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);e.requestAnimationFrame||e.setTimeout}return{restrict:'EAC',require:'ngModel',link:function(e,t,n,u){function d(e){if(angular.isDate(e)){var t=isNaN(c.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=c.minTime,n=isNaN(c.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=c.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function l(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,c.timeFormat)}var c={scope:e,controller:u};angular.forEach(['placement','container','delay','trigger','keyboard','html','animation','template','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(c[e]=n[e])});var m=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(n[e])&&m.test(n[e])&&(c[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),s&&(c.useNative||r.useNative)&&(c.timeFormat='HH:mm');var g=o(t,u,c);c=g.$options;var p=c.lang,$=function(e,t,n){return a.formatDate(e,t,p,n)},f=i({format:c.timeFormat,lang:p});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){g.$options[e]=f.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),d(u.$dateValue)})}),e.$watch(n.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var n=angular.isDate(e)?e:f.parse(e,u.$dateValue);return!n||isNaN(n.getTime())?void u.$setValidity('date',!1):(d(n),'string'===c.timeType?(t=f.timezoneOffsetAdjust(n,c.timezone,!0),$(t,c.modelTimeFormat||c.timeFormat)):(t=f.timezoneOffsetAdjust(u.$dateValue,c.timezone,!0),'number'===c.timeType?t.getTime():'unix'===c.timeType?t.getTime()/1e3:'iso'===c.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===c.timeType?f.parse(e,null,c.modelTimeFormat):new Date('unix'===c.timeType?1e3*e:e),u.$dateValue=f.timezoneOffsetAdjust(t,c.timezone),l()}),u.$render=function(){t.val(l())},e.$on('$destroy',function(){g&&g.destroy(),c=null,g=null})}}}]); +'use strict';angular.module('mgcrea.ngStrap.timepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$timepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'timepicker',placement:'bottom-left',template:'timepicker/timepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!0,timeType:'date',timeFormat:'shortTime',timezone:null,modelTimeFormat:null,autoclose:!1,minTime:-(1/0),maxTime:+(1/0),length:5,hourStep:1,minuteStep:5,secondStep:5,roundDisplay:!1,iconUp:'glyphicon glyphicon-chevron-up',iconDown:'glyphicon glyphicon-chevron-down',arrowBehavior:'pager'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','$tooltip','$timeout',function(t,n,a,i,o,r,s){function u(t,n,a){function i(e){var t=6e4*p.minuteStep;return new Date(Math.floor(e.getTime()/t)*t)}function u(e,n){var a=e+n;if(t[0].createTextRange){var i=t[0].createTextRange();i.collapse(!0),i.moveStart('character',e),i.moveEnd('character',a),i.select()}else t[0].setSelectionRange?t[0].setSelectionRange(e,a):angular.isUndefined(t[0].selectionStart)&&(t[0].selectionStart=e,t[0].selectionEnd=a)}function c(){t[0].focus()}var m=r(t,angular.extend({},e,a)),g=a.scope,p=m.$options,$=m.$scope,f=p.lang,h=function(e,t,n){return o.formatDate(e,t,f,n)},v=0,w=p.roundDisplay?i(new Date):new Date,S=n.$dateValue||w,y={hour:S.getHours(),meridian:S.getHours()<12,minute:S.getMinutes(),second:S.getSeconds(),millisecond:S.getMilliseconds()},D=o.getDatetimeFormat(p.timeFormat,f),T=o.hoursFormat(D),V=o.timeSeparator(D),b=o.minutesFormat(D),k=o.secondsFormat(D),M=o.showSeconds(D),x=o.showAM(D);$.$iconUp=p.iconUp,$.$iconDown=p.iconDown,$.$select=function(e,t){m.select(e,t)},$.$moveIndex=function(e,t){m.$moveIndex(e,t)},$.$switchMeridian=function(e){m.switchMeridian(e)},m.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())?(m.$date=e,angular.extend(y,{hour:e.getHours(),minute:e.getMinutes(),second:e.getSeconds(),millisecond:e.getMilliseconds()}),m.$build()):m.$isBuilt||m.$build()},m.select=function(e,t,a){(!n.$dateValue||isNaN(n.$dateValue.getTime()))&&(n.$dateValue=new Date(1970,0,1)),angular.isDate(e)||(e=new Date(e)),0===t?n.$dateValue.setHours(e.getHours()):1===t?n.$dateValue.setMinutes(e.getMinutes()):2===t&&n.$dateValue.setSeconds(e.getSeconds()),n.$setViewValue(angular.copy(n.$dateValue)),n.$render(),p.autoclose&&!a&&s(function(){m.hide(!0)})},m.switchMeridian=function(e){if(n.$dateValue&&!isNaN(n.$dateValue.getTime())){var t=(e||n.$dateValue).getHours();n.$dateValue.setHours(12>t?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},m.$build=function(){var e,t,n=$.midIndex=parseInt(p.length/2,10),a=[];for(e=0;e1*p.maxTime},$.$arrowAction=function(e,t){'picker'===p.arrowBehavior?m.$setTimeByStep(e,t):m.$moveIndex(e,t)},m.$setTimeByStep=function(e,t){{var n=new Date(m.$date),a=n.getHours(),i=(h(n,T).length,n.getMinutes()),o=(h(n,b).length,n.getSeconds());h(n,k).length}0===t?n.setHours(a-parseInt(p.hourStep,10)*e):1===t?n.setMinutes(i-parseInt(p.minuteStep,10)*e):2===t&&n.setSeconds(o-parseInt(p.secondStep,10)*e),m.select(n,t,!0)},m.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,y.hour+e*p.length,y.minute,y.second),angular.extend(y,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,y.hour,y.minute+e*p.length*p.minuteStep,y.second),angular.extend(y,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,y.hour,y.minute,y.second+e*p.length*p.secondStep),angular.extend(y,{second:n.getSeconds()})),m.$build()},m.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},m.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return m.hide(!0);var t=new Date(m.$date),n=t.getHours(),a=h(t,T).length,i=t.getMinutes(),o=h(t,b).length,r=t.getSeconds(),s=h(t,k).length,l=1,d=/(37|39)/.test(e.keyCode),c=2+1*M+1*x;d&&(37===e.keyCode?v=1>v?c-1:v-1:39===e.keyCode&&(v=c-1>v?v+1:0));var $=[0,a],f=0;38===e.keyCode&&(f=-1),40===e.keyCode&&(f=1);var w=2===v&&M,S=2===v&&!M||3===v&&M;0===v?(t.setHours(n+f*parseInt(p.hourStep,10)),a=h(t,T).length,$=[0,a]):1===v?(t.setMinutes(i+f*parseInt(p.minuteStep,10)),o=h(t,b).length,$=[a+l,o]):w?(t.setSeconds(r+f*parseInt(p.secondStep,10)),s=h(t,k).length,$=[a+l+o+l,s]):S&&(d||m.switchMeridian(),$=[a+l+o+l+(s+l)*M,2]),m.select(t,v,!0),u($[0],$[1]),g.$digest()}};var N=m.init;m.init=function(){return l&&p.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',c)),void N())};var F=m.destroy;m.destroy=function(){l&&p.useNative&&t.off('click',c),F()};var H=m.show;m.show=function(){H(),s(function(){m.$element&&m.$element.on(d?'touchstart':'mousedown',m.$onMouseDown),p.keyboard&&t&&t.on('keydown',m.$onKeyDown)},0,!1)};var I=m.hide;return m.hide=function(e){m.$isShown&&(m.$element&&m.$element.off(d?'touchstart':'mousedown',m.$onMouseDown),p.keyboard&&t&&t.off('keydown',m.$onKeyDown),I(e))},m}var l=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),d='createTouch'in t.document&&l;return e.lang||(e.lang=o.getDefaultLocale()),u.defaults=e,u}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,n,a,i,o){{var r=o.defaults,s=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);e.requestAnimationFrame||e.setTimeout}return{restrict:'EAC',require:'ngModel',link:function(e,t,n,u){function l(e){if(angular.isDate(e)){var t=isNaN(c.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=c.minTime,n=isNaN(c.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=c.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,c.timeFormat)}var c={scope:e,controller:u};angular.forEach(['placement','container','delay','trigger','keyboard','html','animation','template','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(c[e]=n[e])});var m=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(n[e])&&m.test(n[e])&&(c[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),s&&(c.useNative||r.useNative)&&(c.timeFormat='HH:mm');var g=o(t,u,c);c=g.$options;var p=c.lang,$=function(e,t,n){return a.formatDate(e,t,p,n)},f=i({format:c.timeFormat,lang:p});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){g.$options[e]=f.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),l(u.$dateValue)})}),e.$watch(n.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var n=angular.isDate(e)?e:f.parse(e,u.$dateValue);return!n||isNaN(n.getTime())?void u.$setValidity('date',!1):(l(n),'string'===c.timeType?(t=f.timezoneOffsetAdjust(n,c.timezone,!0),$(t,c.modelTimeFormat||c.timeFormat)):(t=f.timezoneOffsetAdjust(u.$dateValue,c.timezone,!0),'number'===c.timeType?t.getTime():'unix'===c.timeType?t.getTime()/1e3:'iso'===c.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===c.timeType?f.parse(e,null,c.modelTimeFormat):new Date('unix'===c.timeType?1e3*e:e),u.$dateValue=f.timezoneOffsetAdjust(t,c.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),c=null,g=null})}}}]); //# sourceMappingURL=../modules/timepicker.min.js.map \ No newline at end of file diff --git a/dist/modules/timepicker.min.js.map b/dist/modules/timepicker.min.js.map index fce60de3b..78dd4081c 100644 --- a/dist/modules/timepicker.min.js.map +++ b/dist/modules/timepicker.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/timepicker.js"],"names":["angular","container","provider","keyboard","this","defaults","html","delay","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","length","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","bodyEl","isNative","isTouch","timepickerFactory","$get","parentScope","config","scope","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","select","end","start","element","setSelectionRange","isUndefined","collapse","selectionStart","moveStart","selectionEnd","moveEnd","focusElement","focus","_init","$timepicker","init","$tooltip","extend","floorMinutes","time","options","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","controller","$dateValue","hoursFormat","$dateFormatter","$iconUp","$iconDown","$select","$moveIndex","value","index","$switchMeridian","switchMeridian","isDate","isNaN","getMinutes","getTime","$build","minute","$setViewValue","$timeout","keep","hide","Date","setHours","setMinutes","setSeconds","copy","$render","hours","midIndex","push","label","selected","$isSelected","disabled","i","minutes","seconds","minutesFormat","rows","showSeconds","secondsFormat","$isDisabled","showAM","timeSeparator","$date","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","hoursLength","parseInt","targetDate","$onMouseDown","evt","target","nodeName","stopPropagation","targetEl","triggerHandler","preventDefault","$onKeyDown","test","keyCode","secondsLength","sepLength","lateralMove","count","minutesLength","selectRange","incr","isSeconds","isMeridian","createSelection","$digest","createTextRange","prop","attr","_destroy","destroy","off","_show","show","_hide","on","blur","$element","directive","$options","$scope","restrict","forEach","require","link","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","falseValueRegExp","isDefined","bsShow","newValue","oldValue","timepicker","key","dateParser","$dateParser","$observe","validateAgainstMinMaxTime","$watch","ngModel","getTimeForAttribute","parse","timezoneOffsetAdjust","$formatters","modelValue","NaN","$on"],"mappings":"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","file":"modules/timepicker.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n '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 template: '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 bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)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 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 {\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 = {hour: startDate.getHours(), meridian: startDate.getHours() < 12, minute: startDate.getMinutes(), second: startDate.getSeconds(), millisecond: startDate.getMilliseconds()};\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n 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, {hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(), millisecond: date.getMilliseconds()});\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() { $timepicker.hide(true); });\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, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [], 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({date: hour, label: formatDate(hour, hoursFormat), selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), disabled: $timepicker.$isDisabled(hour, 0)});\n }\n var minutes = [], 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({date: minute, label: formatDate(minute, minutesFormat), selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), disabled: $timepicker.$isDisabled(minute, 1)});\n }\n var seconds = [], 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({date: second, label: formatDate(second, secondsFormat), selected: $timepicker.$date && $timepicker.$isSelected(second, 2), disabled: $timepicker.$isDisabled(second, 2)});\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);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), secondsLength = formatDate(newDate, secondsFormat).length;\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n }\n else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n }\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, {hour: targetDate.getHours()});\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, {minute: targetDate.getMinutes()});\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, {second: targetDate.getSeconds()});\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) return $timepicker.hide(true);\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), 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 _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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 $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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, controller: controller};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Visibility binding support\n attr.bsShow && 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 newValue === true ? timepicker.show() : timepicker.hide();\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 // Initialize parser\n var dateParser = $dateParser({format: options.timeFormat, lang: lang});\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\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;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\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 } else {\n return new Date(date);\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 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"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/timepicker.js"],"names":["angular","container","provider","keyboard","this","defaults","html","delay","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","length","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","bodyEl","isNative","isTouch","timepickerFactory","$get","parentScope","config","scope","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","select","end","start","element","setSelectionRange","isUndefined","collapse","selectionStart","moveStart","selectionEnd","moveEnd","focusElement","focus","_init","$timepicker","init","$tooltip","extend","floorMinutes","time","options","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","controller","$dateValue","hoursFormat","$dateFormatter","$iconUp","$iconDown","$select","$moveIndex","value","index","$switchMeridian","switchMeridian","isDate","isNaN","getMinutes","getTime","$build","minute","$setViewValue","$timeout","keep","hide","Date","setHours","setMinutes","setSeconds","copy","$render","hours","midIndex","push","label","selected","$isSelected","disabled","i","minutes","seconds","minutesFormat","rows","showSeconds","secondsFormat","$isDisabled","showAM","timeSeparator","$date","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","hoursLength","parseInt","targetDate","$onMouseDown","evt","target","nodeName","stopPropagation","targetEl","triggerHandler","preventDefault","$onKeyDown","test","keyCode","secondsLength","sepLength","lateralMove","count","minutesLength","selectRange","incr","isSeconds","isMeridian","createSelection","$digest","createTextRange","prop","attr","_destroy","destroy","off","_show","show","_hide","blur","$element","directive","$options","$scope","restrict","forEach","require","link","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","falseValueRegExp","isDefined","bsShow","newValue","oldValue","timepicker","key","dateParser","$dateParser","$observe","validateAgainstMinMaxTime","$watch","ngModel","getTimeForAttribute","parse","timezoneOffsetAdjust","$formatters","modelValue","NaN","$on"],"mappings":"AAOA,YAEAA,SAQMC,OAAW,6BAAA,oCAAA,uCAAA,2BAAAC,SAAA,cAAA,WAPf,GAQIC,GAAUC,KAAAC,UACVC,UAAM,UACNC,YAAO,aAEPC,UAAW,cACXC,SAAU,iCACVC,QAAAA,QACAC,WAAU,EACVC,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACAC,WAAUC,EACVC,SAAQ,OACRC,WAAU,YACVC,SAAAA,KACAC,gBAAY,KACZC,WAAAA,EACAC,UAAQN,EAAAA,GACRO,UAAUP,EAAAA,GACVQ,OAAAA,EARFN,SAAU,EAWVd,WAAK,EAEHgB,WAAIK,EACJJ,cAAIK,EACJJ,OAAIK,iCACJJ,SAAIlB,mCAEJmB,cAASI,QAVbxB,MAaMyB,MAAIC,UAAcC,YAAOC,aAAAA,OAAAA,iBAAAA,WAAAA,WAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GAR7B,QAcMJ,GAAsBK,EAAAA,EAAiBC,GAezC,QAAIC,GAAAA,GAAYC,GAAAA,GAAMC,IAAUC,EAAAA,UAAYC,OAAAA,IAAUF,MAAAA,KAAUC,MAAAA,EAAAA,UAAaE,GAAAA,GA0M/E,QAsCMC,GAASC,EAAAA,GArCb,GAAIC,GAsCKC,EAAGC,CArCZ,IAsCIA,EAAQ,GAAGC,gBAAkBF,CArC/B,GAAIH,GAsCMzC,EAAQ+C,GAAAA,iBAChBF,GAAQG,UAAGC,GACXJ,EAAQK,UAAGC,YAAeR,GArC5BF,EAASW,QAAQ,YAAaT,GAC9BF,EAASC,aAwCFW,GAAAA,GAAAA,kBACPR,EAAQ,GAAGS,kBAAAA,EAAAA,GAtCFtD,QAAQ+C,YAAYF,EAAQ,GAAGI,kBA2CtCM,EAAQC,GAAAA,eAAYC,EACxBD,EAAYC,GAAAA,aAAOd,GAvCrB,QA0CME,KAzCJA,EA0CI,GAAAS,QAhSN,GAAIE,GAAcE,EAASb,EAAS7C,QAAQ2D,UAAWtD,EAAU0B,IAgB/DD,EAAS8B,EAAaC,MAGpBC,EAAYN,EAAYM,SACxB9B,EAAOwB,EAAcO,OAhBrBC,EAAOF,EAAQE,KAqBbC,EAAAA,SAAgBC,EAAAhC,EAAAvB,GACpB,MAAIwD,GAAcL,WAAQzC,EAAeuC,EAAAA,EAAajD,IAE2DyD,EAAkBC,EAAcC,EAAajC,EAAUkC,aAAAA,EAAAA,GAAAA,OAAAA,GAAAA,MAdtKlC,EAAYmC,EAAWC,YAAcN,EAgBnCjC,GAEJE,KAAIsC,EAAcC,WAOlB3C,SAAM4C,EAAUd,WAAQxC,GACxBU,OAAM6C,EAAYf,aAIlB9B,OAAM8C,EAAUT,aACdb,YAAYd,EAAOwB,mBAErBlC,EAAM+C,EAAsBC,kBAAOC,EAAAA,WAAAA,GACjCzB,EAAYuB,EAAkBE,YAAAA,GAAAA,EAAAA,EAAAA,cAAAA,GAAAA,EAAAA,EAAAA,cAAAA,GAAAA,EAAAA,EAAAA,cAAAA,GAAAA,EAAAA,EAAAA,YAAAA,GAAAA,EAAAA,EAAAA,OAAAA,EAxBlCjD,GAAM4C,QAAUd,EAAQxC,OA0BtBU,EAAMkD,UAAAA,EAAkB3D,SAxB1BS,EAyBIwB,QAAY2B,SAAAA,EAAejB,GAxB7BV,EAAYd,OAAOwB,EAAMe,IAE3BjD,EA6BOhC,WAAQoF,SAAOlB,EAAUmB,GA5B9B7B,EA6BIA,WAAoBU,EAAAA,IA3B1BlC,EA4BgCI,gBAAWE,SAAAA,GA3BzCkB,EA2B6DU,eAAKoB,IAzBpE9B,EAyB6Gc,OAAaJ,SAAKK,GAxBzHvE,QAAQoF,OAAOlB,KAAUmB,MAAMnB,EAAKqB,YAyBpC/B,EAAYgC,MAAAA,EAvBdxF,QAwBO2D,OAAIH,GACTA,KAAAA,EAAYgC,WAvBZC,OAAQvB,EAAKoB,aACblB,OAAQF,EAAKG,aA0BjBb,YAAYd,EAAS6B,oBAGnBf,EAAY4B,UACTH,EAAaT,UAGhBA,EAAWkB,UAzBflC,EA4BMmC,OAAS,SAAAzB,EAAAe,EAAAW,KAAapC,EAAYqC,YAAKR,MAAAb,EAAAC,WAAAc,cAAAf,EAAAC,WAAA,GAAAqB,MAAA,KAAA,EAAA,IA1BtC9F,QAAQoF,OAAOlB,KAAOA,EAAO,GAAI4B,MAAK5B,IAC7B,IAAVe,EAAaT,EAAWC,WAAWsB,SAAS7B,EAAK5B,YAAgC,IAAV2C,EAAaT,EAAWC,WAAWuB,WAAW9B,EAAKoB,cAAkC,IAAVL,GAAaT,EAAWC,WAAWwB,WAAW/B,EAAKG,cACzMG,EAAWkB,cAAc1F,QAAQkG,KAAK1B,EAAWC,aA4BjDjB,EAAY2B,UACVrB,EAAKU,YAAWC,GACdkB,EAAA,WA1BAnC,EAAYqC,MAAK,MAIvBrC,EA2BIgB,eAAW2B,SAAAA,GA1Bb,GAAK3B,EAAWC,aAAcY,MAAMb,EAAWC,WAAWc,WAA1D,CAkCE,GAAIa,IAAAA,GAAYhE,EAAAA,YAAAA,UAChBoC,GAAQC,WAAOX,SAAqB,GAAb7C,EAAamF,EAAA,GAAAA,EAAA,IA9BtC5B,EA+BWkB,cAAe1F,QAAMmC,KAAAA,EAAiBkE,aA9BjD7B,EA+BU8B,YA7BZ9C,EA6B8B+C,OAAOtE,WA5BnC,GA4BkEuE,GAA2EhD,EAA3EgD,EAAUhD,EAAAA,SAAqBA,SAAAA,EAAYiD,OAAYrE,EAAAA,IAAUsE,IA1BnI,KAAKC,EAAI,EAAGA,EAAI7C,EAAQ7C,OAAQ0F,IAC9BvE,EAAO,GAAI0D,MAAK,KAAM,EAAG,EAAG3D,EAASC,MAAQiE,EAAWM,GAAK7C,EAAQ5C,UA2BrEkF,EAAIQ,MACJ1C,KAAQ9B,EACNqD,MAASxD,EAASG,EAAMsC,GACxBkC,SAAQN,EAAAA,OAAAA,EAAAA,YAAAA,EAAAA,GAAMpC,SAAMuB,EAAAA,YAAAA,EAAAA,IAtBxB,IAsBuJjC,GAAVkD,IArB7I,KAAKC,EAAI,EAAGA,EAAI7C,EAAQ7C,OAAQ0F,IAC9BlB,EAAS,GAAIK,MAAK,KAAM,EAAG,EAAG,EAAG3D,EAASsD,QAAUY,EAAWM,GAAK7C,EAAQ3C,YAsB5EyF,EAAIC,MACJ3C,KAAQuB,EACNrB,MAASnC,EAASwD,EAASqB,GAC3BD,SAAQP,EAAAA,OAAAA,EAAAA,YAAAA,EAAAA,GAAMpC,SAAME,EAAAA,YAAAA,EAAAA,IAjBxB,IAiBuJZ,GAAVkD,IAhB7I,KAAKC,EAAI,EAAGA,EAAI7C,EAAQ7C,OAAQ0F,IAC9BvC,EAAS,GAAI0B,MAAK,KAAM,EAAG,EAAG,EAAG,EAAG3D,EAASiC,QAAUiC,EAAWM,GAAK7C,EAAQ1C,YAkB/EyF,EAAIE,MACJ7C,KAAQE,EACNmC,MAAIS,EAAa5C,EAAA6C,GACfF,SAAKT,EAAgBM,OAAQD,EAAYA,YAAAA,EAAAA,GAhB3CD,SAiBOlD,EAAA0D,YAAA9C,EAAA,IAdX,IAAI2C,KAkBF/E,KAAAA,EAAM+E,EAAAA,EAAOA,EAAAA,OAAAA,IAEb/E,EAAMmF,KADAH,GACSG,EAAAA,GAAAA,EAAAA,GAAAA,EAAAA,KAETC,EAAgBA,GAAAA,EAAAA,IAIxB5D,GAAAA,KAAYiD,EACVzE,EAAIwB,YAAY6D,EAjBlBrF,EAmBImF,OAAY7E,EAlBhBN,EAAMsF,MAmBMrC,EAAaoC,OAAAjB,EAAAC,GAAAnC,MAAA5B,WAAA,GAlBzBN,EAmBIoF,cAAY9B,EAlBhB9B,EAmBYyB,UAAU,GAjBxBzB,EAAYiD,YAAc,SAASvC,EAAMe,GACvC,MAAKzB,GAAY6D,MAAwC,IAAVpC,EAqB/CzB,EAAY0D,aAAc1D,EAAeyB,MAAAA,WACnCsC,IAAAA,EACDtC,EAAUK,eAAG9B,EAAA6D,MAAA/B,aACCpB,IAAfqD,EACKrD,EAAGe,eAAazB,EAAA6D,MAAAhD,aADrBkD,QAxB2B,GAQjC/D,EAoBM+D,YAAoBhC,SAAAA,EAAYpD,GAnBpC,GAAIoF,EAQJ,OAaSA,KAAPtC,EAnBAsC,EAAerD,EAAKqB,UAA8B,IAAlBpD,EAASsD,OAAiC,IAAlBtD,EAASiC,OAsB9C,IAAfoD,EACJD,EAAY/F,EAAAA,UAA4B,KAAVW,EAAUC,KAAA,IAAAD,EAAAiC,OAC1BqD,IAAZjE,IApBF+D,EAqBOrD,EAAAqB,UAAA,KAAApD,EAAAC,KAAA,IAAAD,EAAAsD,QAnBF8B,EAAiC,EAAlBzD,EAAQhD,SAAeyG,EAAiC,EAAlBzD,EAAQ/C,SAwBpEyC,EAAAA,aAAYiE,SAAiBzC,EAAAC,GACJzB,WAAnBkE,EAAAA,cACJlE,EAAYkE,eAAQpF,EAAYqF,GAEhCnE,EAAckE,WAAQrD,EAAAA,IAnB1Bb,EAuBSiE,eAAiB,SAAAzC,EAAAC,GAtBxB,CAAA,GAuBIyC,GAAQ1B,GAAAA,MAAWY,EAAWgB,OAtB9BxB,EAwBOnB,EAAAA,WACPyC,GADoBzF,EAAAyF,EAAAhD,GAAAzD,OACZgF,EAAWY,cAvBnBA,GAuB+CzF,EAAYsG,EAAM1C,GAAAA,OAvBvD0C,EAAQrD,aAA8BpC,GAAWyF,EAAST,GAAehG,OAyBzEyB,IAAZc,EAvBAkE,EAAQ3B,SAASK,EAAQwB,SAAS9D,EAAQ5C,SAAU,IAAM8D,GA0BhDD,IAAAA,EACV2C,EAAIG,WAAAA,EAAAA,SAAAA,EAAAA,WAAAA,IAAAA,GACY,IAAb5C,GACD4C,EAAAA,WAAiB/B,EAAW8B,SAAMzF,EAASC,WAAgB0B,IAAAA,GAvB/DN,EAwBoCqE,OAAAA,EAAWvF,GAAAA,IAtBjDkB,EAuBWuB,WAAa,SAAGC,EAAAC,GAtBzB,GAuBI4C,EACQlE,KAAR3D,GAtBF6H,EAsBoCA,GAAAA,MAAWvC,KAAAA,EAAAA,EAAAA,EAAAA,KAAAA,EAAAA,EAAAA,OAAAA,EAAAA,OAAAA,EAAAA,QArB/CtF,QAAQ2D,OAAOxB,GACbC,KAqBKyF,EAAavF,cAEHH,IAAPwB,GApBVkE,EAoBoCA,GAAAA,MAAWxD,KAAAA,EAAAA,EAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,EAAAA,OAAAA,EAAAA,WAAAA,EAAAA,QAnB/CrE,QAAQ2D,OAAOxB,GACbsD,OAAQoC,EAAWvC,gBAEF,IAAVL,IAqBXzB,EAAYsE,GAAAA,MAAAA,KAAe,EAAA,EAASC,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,OAAAA,EAAAA,EAAAA,OAAAA,EAAAA,YAElC/H,QAAOgI,OAAOC,GACVC,OAAAA,EAAAA,gBAlBN1E,EAsBO2E,UApBT3E,EAAYsE,aAAe,SAASC,GAGlC,GAoB4B,UAAxBI,EAAAA,OAASC,SAAAA,eAAeL,EAAAM,iBArB5BN,EAAIG,kBACAvG,EAAS,CAwBb6B,GAAAA,GAAY8E,QAAazF,QAASkF,EAAAA,OACaA,YAAxCI,EAAA,GAAAF,SAAmBM,gBACpBF,EAAAA,EAAAA,UAIJF,EAAOK,eAAgB,WAtB3BhF,EA2BQoD,WAAkBtB,SAAAA,GACtB,GAAIuB,mBAAkBxC,KAAAA,EAAAA,WAAcoE,EAAAA,WAAgBxG,EAAWyF,OAA/D,CAGA,GAFAK,EAAIW,iBACJX,EAAIY,kBACY3B,KAAZ4B,EAAAA,QAAY5B,MAAcxD,GAAaqC,MAAA,EAG3C,IAAI8C,GAAAA,GAAa7C,MAAAtC,EAAA6D,OACfjB,EAAOoC,EAAAA,WAAgBvE,EAAgBA,EAAAA,EAAoB2E,GAAY3E,OA5BvE2C,EAAUc,EAAQpC,aAAcuD,EAAgB5G,EAAWyF,EAASZ,GAAe7F,OAiCjF6H,EAAAA,EAAezE,aAAGsD,EAAAA,EAAAA,EAAAA,GAAAA,OAClBoB,EAAO,EACPhB,EAAIS,UAAgBO,KAAQhB,EAAAS,SAC5BT,EAAIS,EAAgBO,EAAhBP,EAAwB,EAAArB,CAC5B6B,KACa/E,KAAbgF,EAAAA,QAAahF,EAAuCA,EAAf+C,EAAe/C,EAAAA,EAAkBA,EAAK+C,EAAAA,KAAAA,EAAAA,UAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GA9BjF,IAgCIU,IAAiBtB,EAAAA,GAEjBuB,EAAAA,CACe,MAAfmB,EAAAA,UAAkBnB,EAAAA,IACV1D,KAjCR8D,EAiCKS,UAAGvE,EAAkB,EAhC9B,IAiCIyD,GAA6BqB,IAArB/C,GAA0B4B,EAElCiB,EAA2BnB,IAA3BmB,IAAoC/B,GAAe7F,IAAAA,GAAAA,CACpC0G,KAAfmB,GAjCFpB,EAkCO3B,SAAGiD,EAAWD,EAAAnB,SAAA9D,EAAA5C,SAAA,KACnBwG,EAAQzB,EAAWY,EAAUkC,GAAcjF,OAE3C2E,GAAgBxG,EAAAA,IACD0F,IAAfmB,GAlCFpB,EAmCO1B,WAAGiD,EAAYF,EAAAnB,SAAA9D,EAAA3C,WAAA,KACpB0H,EAAIF,EAAanF,EAAY2B,GAAAA,OAC7B2D,GAAenB,EAAce,EAAAA,IAlCtBM,GAoCTxF,EAAAA,WAAmBkE,EAASzD,EAAAA,SAAeH,EAAA1C,WAAA,KAC3C8H,EAAgBJ,EAAYpB,EAAIoB,GAAY7H,OAC5Ca,GAAYqH,EAAAA,EAAAA,EAAAA,EAAAA,IAlCHF,IAuCFC,GAAAA,EAAuBjI,iBAC9B6H,GAAkB7H,EAAAA,EAAAA,EAAAA,GAAAA,EAAAA,GAAAA,EAAAA,IApCpBuC,EAsCQf,OAAWI,EAAWuG,GAAAA,GArC9BF,EAsCalG,EAAS,GAAA8F,EAAA,IArCtBhH,EAsCaoB,WAlBf,IA0CML,GAAQwG,EAAK5F,IAzCnBD,GA0Cc8F,KAAK,WAzCjB,MA0CIzG,IAAWiB,EAAST,WAzCtBR,EAAQwG,KAAK,OAAQ,YA2CrB9F,GAAAA,IAAAA,qBAAAA,eAGEgG,IACJ/F,EAAYgG,KAAAA,OAAU,QACpB3G,EAAGnB,KAAAA,WAAoBlB,QACrBqC,EAAQ4G,GAAAA,QAAIpG,QAEdkG,MAGF,IAAIG,GAAQlG,EAAYmG,OACxBnG,GAAYmG,QAAO,WACjBD,GAAAA,EAAAA,WAGA/D,EAAS8D,IAAA,QAAApG,GA5CXkG,IAEF,IAAIG,GAAQlG,EAAYmG,IACxBnG,GA8CUmG,KAAA,WA7CRD,IAgDA/D,EAAIiE,WACJpG,EAAYqC,UAAgBgE,EAAAA,SAAAA,GAAAA,EAAAA,aAAAA,YAAAA,EAAAA,cACtBrG,EAAAA,UACJA,GAAYsG,EAAAA,GAAYtG,UAAYsG,EAAanI,aAE/CkB,GAAAA,GA7CN,IA+CI+G,GAAMC,EAAAA,IAkBRnI,OAhEF8B,GAAYqC,KAAO,SAASgE,GAiDnBrG,EAAAA,WA/CPA,EAAYsG,UAAYtG,EAAYsG,SAASL,IAAI9H,EAAU,aAAe,YAAa6B,EAAYsE,cAmDrGlG,EAAAA,UACAiB,GAAOjB,EAAAA,IAAAA,UAAAA,EAAAA,YAOVmI,EAAUF,KAGLnI,EA5VJ,GAcIA,IADIoC,QAAUN,QAAYwG,EAAAA,SAAAA,MACdxG,8BAAYyG,KAAAA,EAAAA,UAAAA,YAExBtI,EAAWmC,eAAQE,GAAAA,UAAAA,CAgVrBkG,OA/UE7J,GAAI4B,OAAa5B,EAAS6D,KAAMhC,EAAQvB,oBA8U5CiB,EAAAvB,SAAAA,EACE6J,MAvDHH,UAyDS,gBAAkB/H,UAAOa,SAAe2B,KAAAA,iBAAAA,cAAAA,cAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GAxDlD,CAAA,GA2DMnE,GAAIyD,EAAAA,SA1DNpC,EA0DwBM,8BAAAA,KAAAA,EAAAA,UAAAA,UAAmBwC,GAAAA,uBAAAA,EAAAA,WAxD/C,OACE0F,SAwDYC,MAvDZC,QAwDSpK,UAvDTqK,KAAM,SAAkBrI,EAAOa,EAASyG,EAAM9E,GAsC5C,QAsEIA,GAA+B8F,GAE/B,GAAIC,QAAAA,OAASC,GAAb,CAtEF,GAuEMC,GAAApF,MAAAvB,EAAAhD,UAAA,GAAAgF,MAAA0E,EAAAjF,WAAAmF,YAAA,KAAA,EAAA,IAAA5G,EAAAhD,QAtEFwJ,EAAajF,MAAMvB,EAAQ/C,UAAY,GAAI+E,MAAK0E,EAAWjF,WAAWmF,YAAY,KAAM,EAAG,IAAM5G,EAAQ/C,QAwE3GyD,EAAWC,GAAa+F,CAtE1BhG,GAAWmG,aAAa,OAAQJ,GA0EhC/F,EAAWoG,aAASC,MAAQJ,GAE1BjG,EAAIN,aAAAA,MAAAA,GAEA4G,IAxENtG,EAAWC,WAAa+F,IAiD1B,QAASO,KACP,OAAQvG,EAAWC,YAAcY,MAAMb,EAAWC,WAAWc,WAAa,GAAKtD,EAAWuC,EAAWC,WAAYX,EAAQpD,YAxCzH,GAAIsK,IACJhL,MAAQmK,EACN3F,WAAWyG,EAKb3B,SAAK4B,SAAUlJ,YAAasH,YAAa,QAAS6B,UAAUC,WAAAA,OAAAA,YAAAA,WAAAA,YAAAA,WAAAA,aAAAA,WAAAA,kBAAAA,YAAAA,WAAAA,aAAAA,aAAAA,SAAAA,gBAAAA,SAAAA,WAAAA,eAAAA,KAAAA,cAAAA,eAAAA,SAAAA,GAC1DpL,QAAIqL,UAAerL,EAAAA,MAAQiL,EAAUE,GAAW7B,EAAAgC,KA3DpD,IA6DIH,GAAoBE,eA5DxBrL,SAAQmK,SAAU,OAAQ,YAAa,YAAa,YAAa,gBAAkB,SAASmB,GAgEvF5J,QAAAA,UAAaoC,EAAQtD,KAAaH,EAASG,KAAYsD,EAAAA,MAAQpD,EAAa4K,IAAA,KAE/ExH,EAAAA,QAAUuH,EAAWrB,OAAAA,EAAAA,OAAAA,SAAAA,EAAAA,GAEjBhG,GAAeA,QAAAA,UAAAA,KACf/B,QAAAA,SAAakJ,KAAejJ,IAAQvB,EAAAA,MAAAA,2BACtCwK,KAAOxG,EAAAA,EAAe1C,OAAiBC,EAAQ8B,UAI7CuH,IAAaC,EAAAA,WAAAA,EAAAA,aAAAA,EAAAA,WAAAA,QAjEnB,IAiEgCtJ,GAAQ4B,EAAQpD,EAAAA,EAAAA,EAhEhDoD,GAgEkEE,EAAAA,QA/DlE,IAAIA,GAAOF,EAAQE,KAkEjBhE,EAAQmK,SAASjG,EAAWhC,EAAAvB,GAE1BX,MAAAA,GAAkBsJ,WAAcA,EAAKmC,EAASH,EAAK3K,IAhEnD4K,EAkESF,GAjEXnJ,OAkEIwJ,EAAAA,WAjEJ1H,KAAMA,GAsENhC,SAAM2J,SAAYC,UAAS,WAAST,SAAUC,GAE5CC,QAAAA,UAAkB7G,EAAAA,KAAWC,EAAAA,SAAAA,EAAAA,SAAAA,GAC5B4G,EAAArB,SAAAsB,GAAAC,EAAAM,oBAAAP,EAAAH,IAEH9F,MAASqG,EAAAA,SAAAA,KAA0BlB,EAAAA,SACjCkB,EAAoBlB,EAAa/F,gBAnErCzC,EAsEQuI,OAAAA,EAAUE,QAAAA,SAAcH,EAAAA,GAC5B9F,EAAWmG,OAAAA,EAAalG,cACxBD,GAxDJA,EA8EQgG,SAAAA,QAAoBA,SAAAA,GA7E1B,GA8EIhG,EA7EJ,KAgFIsG,EAEAY,MAjFFlH,GAgFOmG,aAAA,QAAA,GACLe,IAGF,IAAG5H,GAAQrD,QAAa2E,OAAA0F,GAAUA,EAAAS,EAAAO,MAAAhB,EAAAtG,EAAAC,WAhFpC,QAiFIP,GAAOqH,MAAWQ,EAAAA,eAClBvH,GAAOvC,aAAiB6B,QAAQlD,IAGlC8K,EAAwBlB,GAEN/J,WAjFhBqD,EAiFQA,UACRI,EAAOA,EAAKqB,qBAAYiF,EAAA1G,EAAAnD,UAAA,GACnBsB,EAAWxB,EAAAA,EAAaG,iBAAOkD,EAAApD,cA/ExCwD,EAiFSqH,EAAAQ,qBAAAvH,EAAAC,WAAAX,EAAAnD,UAAA,GACWuD,WAAhBJ,EAAOrD,SAhFFyD,EAAKqB,UACkB,SAArBzB,EAAQrD,SAoFRuL,EAAAA,UAAiB,IAEtB9H,QAAAA,EAAAA,SACDlE,EAAQ+C,cAEJ,GAAG/C,MAAAA,OAjFdwE,EAoFa+G,YAAWO,KAAMG,SAAAA,GAnF5B,GAAI/H,EAaJ,OAXEA,GAmFEA,QAAOnB,YAASkJ,IAAa,OAAAA,EACxBC,EAAAA,EACElM,QAASiM,OAAAA,GAnFXA,EAuFiBV,WAAb9G,EAAAA,SACJsG,EAAAA,MAAAA,EAAAA,KAAAA,EAAAA,iBAIE5E,GAAAA,MAzFqB,SAArBrC,EAAQrD,SAyFE,IAAV0F,EAtFO8F,GA4FhBzH,EAAQA,WAAWC,EAAcY,qBAAiBZ,EAAWc,EAAAA,UAzFxDwF,MAETvG,EA4FQ6G,QAAYA,WAChBvH,EAAAA,IAAUiH,MAvFd/I,EAAMmK,IAAI,WAAY,WAChBd,GAAYA,EAAW7B,UAC3B1F,EAAU,KACVuH,EAAa","file":"modules/timepicker.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n '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 template: '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 bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)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 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 {\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 = {hour: startDate.getHours(), meridian: startDate.getHours() < 12, minute: startDate.getMinutes(), second: startDate.getSeconds(), millisecond: startDate.getMilliseconds()};\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n 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, {hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(), millisecond: date.getMilliseconds()});\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() { $timepicker.hide(true); });\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, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [], 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({date: hour, label: formatDate(hour, hoursFormat), selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), disabled: $timepicker.$isDisabled(hour, 0)});\n }\n var minutes = [], 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({date: minute, label: formatDate(minute, minutesFormat), selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), disabled: $timepicker.$isDisabled(minute, 1)});\n }\n var seconds = [], 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({date: second, label: formatDate(second, secondsFormat), selected: $timepicker.$date && $timepicker.$isSelected(second, 2), disabled: $timepicker.$isDisabled(second, 2)});\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);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), secondsLength = formatDate(newDate, secondsFormat).length;\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n }\n else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n }\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, {hour: targetDate.getHours()});\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, {minute: targetDate.getMinutes()});\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, {second: targetDate.getSeconds()});\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) return $timepicker.hide(true);\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), 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 _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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 $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if(options.keyboard) {\n 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(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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, controller: controller};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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 // Visibility binding support\n attr.bsShow && 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 newValue === true ? timepicker.show() : timepicker.hide();\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 // Initialize parser\n var dateParser = $dateParser({format: options.timeFormat, lang: lang});\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\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;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\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 } else {\n return new Date(date);\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 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"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/timepicker.tpl.js b/dist/modules/timepicker.tpl.js index 9e39ca2dc..face00b9c 100644 --- a/dist/modules/timepicker.tpl.js +++ b/dist/modules/timepicker.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/timepicker.tpl.min.js b/dist/modules/timepicker.tpl.min.js index 42d120c9c..5908eb382 100644 --- a/dist/modules/timepicker.tpl.min.js +++ b/dist/modules/timepicker.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tooltip.js b/dist/modules/tooltip.js index 6206c6335..f8843d22c 100644 --- a/dist/modules/tooltip.js +++ b/dist/modules/tooltip.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -167,8 +167,11 @@ angular.module('mgcrea.ngStrap.tooltip', [ 'mgcrea.ngStrap.helpers.dimensions' ] $tooltip.$isShown = scope.$isShown = true; safeDigest(scope); $tooltip.$applyPlacement(); - var promise = $animate.enter(tipElement, parent, after, enterAnimateCallback); - if (promise && promise.then) promise.then(enterAnimateCallback); + if (angular.version.minor <= 2) { + $animate.enter(tipElement, parent, after, enterAnimateCallback); + } else { + $animate.enter(tipElement, parent, after).then(enterAnimateCallback); + } safeDigest(scope); $$rAF(function() { if (tipElement) tipElement.css({ @@ -207,8 +210,11 @@ angular.module('mgcrea.ngStrap.tooltip', [ 'mgcrea.ngStrap.helpers.dimensions' ] scope.$emit(options.prefixEvent + '.hide.before', $tooltip); _blur = blur; _tipToHide = tipElement; - var promise = $animate.leave(tipElement, leaveAnimateCallback); - if (promise && promise.then) promise.then(leaveAnimateCallback); + if (angular.version.minor <= 2) { + $animate.leave(tipElement, leaveAnimateCallback); + } else { + $animate.leave(tipElement).then(leaveAnimateCallback); + } $tooltip.$isShown = scope.$isShown = false; safeDigest(scope); if (options.keyboard && tipElement !== null) { diff --git a/dist/modules/tooltip.min.js b/dist/modules/tooltip.min.js index fc652aa10..17c877b9c 100644 --- a/dist/modules/tooltip.min.js +++ b/dist/modules/tooltip.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.helpers.dimensions']).provider('$tooltip',function(){var t=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',template:'tooltip/tooltip.tpl.html',contentTemplate:!1,trigger:'hover focus',keyboard:!1,html:!1,show:!1,title:'',type:'',delay:0,autoClose:!1,bsEnabled:!0,viewport:{selector:'body',padding:0}};this.$get=['$window','$rootScope','$compile','$q','$templateCache','$http','$animate','$sce','dimensions','$$rAF','$timeout',function(e,o,n,i,a,r,l,s,f,c,u){function p(i,a){function r(){M.$emit(K.prefixEvent+'.show',H)}function p(){if(M.$emit(K.prefixEvent+'.hide',H),B===Y){if(R&&'focus'===K.trigger)return i[0].blur();A()}}function b(){var t=K.trigger.split(' ');angular.forEach(t,function(t){'click'===t?i.on('click',H.toggle):'manual'!==t&&(i.on('hover'===t?'mouseenter':'focus',H.enter),i.on('hover'===t?'mouseleave':'blur',H.leave),'button'===N&&'hover'!==t&&i.on($?'touchstart':'mousedown',H.$onFocusElementMouseDown))})}function y(){for(var t=K.trigger.split(' '),e=t.length;e--;){var o=t[e];'click'===o?i.off('click',H.toggle):'manual'!==o&&(i.off('hover'===o?'mouseenter':'focus',H.enter),i.off('hover'===o?'mouseleave':'blur',H.leave),'button'===N&&'hover'!==o&&i.off($?'touchstart':'mousedown',H.$onFocusElementMouseDown))}}function E(){'focus'!==K.trigger?B.on('keyup',H.$onKeyUp):i.on('keyup',H.$onFocusKeyUp)}function k(){'focus'!==K.trigger?B.off('keyup',H.$onKeyUp):i.off('keyup',H.$onFocusKeyUp)}function C(){u(function(){B.on('click',D),w.on('click',H.hide),z=!0},0,!1)}function S(){z&&(B.off('click',D),w.off('click',H.hide),z=!1)}function D(t){t.stopPropagation()}function x(t){t=t||K.target||i;var o=t[0],n='BODY'===o.tagName,a=o.getBoundingClientRect(),r={};for(var l in a)r[l]=a[l];null===r.width&&(r=angular.extend({},r,{width:a.right-a.left,height:a.bottom-a.top}));var s=n?{top:0,left:0}:f.offset(o),c={scroll:n?document.documentElement.scrollTop||document.body.scrollTop:t.prop('scrollTop')||0},u=n?{width:document.documentElement.clientWidth,height:e.innerHeight}:null;return angular.extend({},r,c,u,s)}function T(t,e,o,n){var i,a=t.split('-');switch(a[0]){case'right':i={top:e.top+e.height/2-n/2,left:e.left+e.width};break;case'bottom':i={top:e.top+e.height,left:e.left+e.width/2-o/2};break;case'left':i={top:e.top+e.height/2-n/2,left:e.left-o};break;default:i={top:e.top-n,left:e.left+e.width/2-o/2}}if(!a[1])return i;if('top'===a[0]||'bottom'===a[0])switch(a[1]){case'left':i.left=e.left;break;case'right':i.left=e.left+e.width-o}else if('left'===a[0]||'right'===a[0])switch(a[1]){case'top':i.top=e.top-n;break;case'bottom':i.top=e.top+e.height}return i}function P(t,e){var o=B[0],n=o.offsetWidth,i=o.offsetHeight,a=parseInt(f.css(o,'margin-top'),10),r=parseInt(f.css(o,'margin-left'),10);isNaN(a)&&(a=0),isNaN(r)&&(r=0),t.top=t.top+a,t.left=t.left+r,f.setOffset(o,angular.extend({using:function(t){B.css({top:Math.round(t.top)+'px',left:Math.round(t.left)+'px',right:''})}},t),0);var l=o.offsetWidth,s=o.offsetHeight;if('top'===e&&s!==i&&(t.top=t.top+i-s),!/top-left|top-right|bottom-left|bottom-right/.test(e)){var c=F(e,t,l,s);if(c.left?t.left+=c.left:t.top+=c.top,f.setOffset(o,t),/top|right|bottom|left/.test(e)){var u=/top|bottom/.test(e),p=u?2*c.left-n+l:2*c.top-i+s,h=u?'offsetWidth':'offsetHeight';O(p,o[h],u)}}}function F(t,e,o,n){var i={top:0,left:0},a=K.viewport&&d(K.viewport.selector||K.viewport);if(!a)return i;var r=K.viewport&&K.viewport.padding||0,l=x(a);if(/right|left/.test(t)){var s=e.top-r-l.scroll,f=e.top+r-l.scroll+n;sl.top+l.height&&(i.top=l.top+l.height-f)}else{var c=e.left-r,u=e.left+r+o;cl.width&&(i.left=l.left+l.width-u)}return i}function O(t,e,o){var n=d('.tooltip-arrow, .arrow',B[0]);n.css(o?'left':'top',50*(1-t/e)+'%').css(o?'top':'left','')}function A(){clearTimeout(W),H.$isShown&&null!==B&&(K.autoClose&&S(),K.keyboard&&k()),V&&(V.$destroy(),V=null),B&&(B.remove(),B=H.$element=null)}var H={},N=i[0].nodeName.toLowerCase(),K=H.$options=angular.extend({},t,a);H.$promise=g(K.template);var M=H.$scope=K.scope&&K.scope.$new()||o.$new();if(K.delay&&angular.isString(K.delay)){var U=K.delay.split(',').map(parseFloat);K.delay=U.length>1?{show:U[0],hide:U[1]}:U[0]}H.$id=K.id||i.attr('id')||'',K.title&&(M.title=s.trustAsHtml(K.title)),M.$setEnabled=function(t){M.$$postDigest(function(){H.setEnabled(t)})},M.$hide=function(){M.$$postDigest(function(){H.hide()})},M.$show=function(){M.$$postDigest(function(){H.show()})},M.$toggle=function(){M.$$postDigest(function(){H.toggle()})},H.$isShown=M.$isShown=!1;var W,j;K.contentTemplate&&(H.$promise=H.$promise.then(function(t){var e=angular.element(t);return g(K.contentTemplate).then(function(t){var o=d('[ng-bind="content"]',e[0]);return o.length||(o=d('[ng-bind="title"]',e[0])),o.removeAttr('ng-bind').html(t),e[0].outerHTML})}));var q,B,I,L,V;H.$promise.then(function(t){angular.isObject(t)&&(t=t.data),K.html&&(t=t.replace(v,'ng-bind-html="')),t=m.apply(t),I=t,q=n(t),H.init()}),H.init=function(){K.delay&&angular.isNumber(K.delay)&&(K.delay={show:K.delay,hide:K.delay}),'self'===K.container?L=i:angular.isElement(K.container)?L=K.container:K.container&&(L=d(K.container)),b(),K.target&&(K.target=angular.isElement(K.target)?K.target:d(K.target)),K.show&&M.$$postDigest(function(){'focus'===K.trigger?i[0].focus():H.show()})},H.destroy=function(){y(),A(),M.$destroy()},H.enter=function(){return clearTimeout(W),j='in',K.delay&&K.delay.show?void(W=setTimeout(function(){'in'===j&&H.show()},K.delay.show)):H.show()},H.show=function(){if(K.bsEnabled&&!H.$isShown){M.$emit(K.prefixEvent+'.show.before',H);var t,e;K.container?(t=L,e=L[0].lastChild?angular.element(L[0].lastChild):null):(t=null,e=i),B&&A(),V=H.$scope.$new(),B=H.$element=q(V,function(t,e){}),B.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),K.animation&&B.addClass(K.animation),K.type&&B.addClass(K.prefixClass+'-'+K.type),K.customClass&&B.addClass(K.customClass),e?e.after(B):t.prepend(B),H.$isShown=M.$isShown=!0,h(M),H.$applyPlacement();var o=l.enter(B,t,e,r);o&&o.then&&o.then(r),h(M),c(function(){B&&B.css({visibility:'visible'})}),K.keyboard&&('focus'!==K.trigger&&H.focus(),E()),K.autoClose&&C()}},H.leave=function(){return clearTimeout(W),j='out',K.delay&&K.delay.hide?void(W=setTimeout(function(){'out'===j&&H.hide()},K.delay.hide)):H.hide()};var R,Y;H.hide=function(t){if(H.$isShown){M.$emit(K.prefixEvent+'.hide.before',H),R=t,Y=B;var e=l.leave(B,p);e&&e.then&&e.then(p),H.$isShown=M.$isShown=!1,h(M),K.keyboard&&null!==B&&k(),K.autoClose&&null!==B&&S()}},H.toggle=function(){H.$isShown?H.leave():H.enter()},H.focus=function(){B[0].focus()},H.setEnabled=function(t){K.bsEnabled=t},H.setViewport=function(t){K.viewport=t},H.$applyPlacement=function(){if(B){var e=K.placement,o=/\s?auto?\s?/i,n=o.test(e);n&&(e=e.replace(o,'')||t.placement),B.addClass(K.placement);var a=x(),r=B.prop('offsetWidth'),l=B.prop('offsetHeight');if(n){var s=e,f=K.container?d(K.container):i.parent(),c=x(f);s.indexOf('bottom')>=0&&a.bottom+l>c.bottom?e=s.replace('bottom','top'):s.indexOf('top')>=0&&a.top-lc.width?e='right'===s?'left':e.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&a.left-rl.top+l.height&&(i.top=l.top+l.height-c)}else{var f=e.left-r,u=e.left+r+o;fl.width&&(i.left=l.left+l.width-u)}return i}function O(t,e,o){var n=d('.tooltip-arrow, .arrow',B[0]);n.css(o?'left':'top',50*(1-t/e)+'%').css(o?'top':'left','')}function A(){clearTimeout(W),H.$isShown&&null!==B&&(K.autoClose&&S(),K.keyboard&&k()),V&&(V.$destroy(),V=null),B&&(B.remove(),B=H.$element=null)}var H={},N=i[0].nodeName.toLowerCase(),K=H.$options=angular.extend({},t,a);H.$promise=g(K.template);var M=H.$scope=K.scope&&K.scope.$new()||o.$new();if(K.delay&&angular.isString(K.delay)){var U=K.delay.split(',').map(parseFloat);K.delay=U.length>1?{show:U[0],hide:U[1]}:U[0]}H.$id=K.id||i.attr('id')||'',K.title&&(M.title=s.trustAsHtml(K.title)),M.$setEnabled=function(t){M.$$postDigest(function(){H.setEnabled(t)})},M.$hide=function(){M.$$postDigest(function(){H.hide()})},M.$show=function(){M.$$postDigest(function(){H.show()})},M.$toggle=function(){M.$$postDigest(function(){H.toggle()})},H.$isShown=M.$isShown=!1;var W,j;K.contentTemplate&&(H.$promise=H.$promise.then(function(t){var e=angular.element(t);return g(K.contentTemplate).then(function(t){var o=d('[ng-bind="content"]',e[0]);return o.length||(o=d('[ng-bind="title"]',e[0])),o.removeAttr('ng-bind').html(t),e[0].outerHTML})}));var q,B,I,L,V;H.$promise.then(function(t){angular.isObject(t)&&(t=t.data),K.html&&(t=t.replace(v,'ng-bind-html="')),t=m.apply(t),I=t,q=n(t),H.init()}),H.init=function(){K.delay&&angular.isNumber(K.delay)&&(K.delay={show:K.delay,hide:K.delay}),'self'===K.container?L=i:angular.isElement(K.container)?L=K.container:K.container&&(L=d(K.container)),b(),K.target&&(K.target=angular.isElement(K.target)?K.target:d(K.target)),K.show&&M.$$postDigest(function(){'focus'===K.trigger?i[0].focus():H.show()})},H.destroy=function(){y(),A(),M.$destroy()},H.enter=function(){return clearTimeout(W),j='in',K.delay&&K.delay.show?void(W=setTimeout(function(){'in'===j&&H.show()},K.delay.show)):H.show()},H.show=function(){if(K.bsEnabled&&!H.$isShown){M.$emit(K.prefixEvent+'.show.before',H);var t,e;K.container?(t=L,e=L[0].lastChild?angular.element(L[0].lastChild):null):(t=null,e=i),B&&A(),V=H.$scope.$new(),B=H.$element=q(V,function(t,e){}),B.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),K.animation&&B.addClass(K.animation),K.type&&B.addClass(K.prefixClass+'-'+K.type),K.customClass&&B.addClass(K.customClass),e?e.after(B):t.prepend(B),H.$isShown=M.$isShown=!0,h(M),H.$applyPlacement(),angular.version.minor<=2?l.enter(B,t,e,r):l.enter(B,t,e).then(r),h(M),f(function(){B&&B.css({visibility:'visible'})}),K.keyboard&&('focus'!==K.trigger&&H.focus(),E()),K.autoClose&&C()}},H.leave=function(){return clearTimeout(W),j='out',K.delay&&K.delay.hide?void(W=setTimeout(function(){'out'===j&&H.hide()},K.delay.hide)):H.hide()};var R,Y;H.hide=function(t){H.$isShown&&(M.$emit(K.prefixEvent+'.hide.before',H),R=t,Y=B,angular.version.minor<=2?l.leave(B,p):l.leave(B).then(p),H.$isShown=M.$isShown=!1,h(M),K.keyboard&&null!==B&&k(),K.autoClose&&null!==B&&S())},H.toggle=function(){H.$isShown?H.leave():H.enter()},H.focus=function(){B[0].focus()},H.setEnabled=function(t){K.bsEnabled=t},H.setViewport=function(t){K.viewport=t},H.$applyPlacement=function(){if(B){var e=K.placement,o=/\s?auto?\s?/i,n=o.test(e);n&&(e=e.replace(o,'')||t.placement),B.addClass(K.placement);var a=x(),r=B.prop('offsetWidth'),l=B.prop('offsetHeight');if(n){var s=e,c=K.container?d(K.container):i.parent(),f=x(c);s.indexOf('bottom')>=0&&a.bottom+l>f.bottom?e=s.replace('bottom','top'):s.indexOf('top')>=0&&a.top-lf.width?e='right'===s?'left':e.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&a.left-r 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, hoverState;\n\n // Support contentTemplate option\n if(options.contentTemplate) {\n $tooltip.$promise = $tooltip.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]);\n if(!contentEl.length) contentEl = findElement('[ng-bind=\"title\"]', templateEl[0]);\n contentEl.removeAttr('ng-bind').html(contentTemplate);\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize tooltip\n var tipLinker, tipElement, tipTemplate, tipContainer, tipScope;\n $tooltip.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n tipTemplate = template;\n tipLinker = $compile(template);\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 options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\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, 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 = tipLinker(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 after ? after.after(tipElement) : parent.prepend(tipElement);\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.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n var promise = $animate.enter(tipElement, parent, after, enterAnimateCallback);\n if(promise && promise.then) promise.then(enterAnimateCallback);\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\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\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.3+ $animate\n // https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9\n var promise = $animate.leave(tipElement, leaveAnimateCallback);\n if(promise && promise.then) promise.then(leaveAnimateCallback);\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() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\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 autoToken = /\\s?auto?\\s?/i,\n 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 tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var container = options.container ? findElement(options.container) : element.parent();\n var containerPosition = getPosition(container);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > containerPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < containerPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > containerPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < containerPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : 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 $tooltip.$isShown ? element[0].blur() : element[0].focus();\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') {\n element.on('click', $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 nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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') {\n element.off('click', $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 nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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 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 for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\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 scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n 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 }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n 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 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 arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 },\n $viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n if (!$viewport) {\n return delta;\n }\n\n var viewportPadding = options.viewport && options.viewport.padding || 0,\n viewportDimensions = getPosition($viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll,\n 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 rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.width) { // 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 scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'contentTemplate', '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 // 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 // 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && 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 newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var 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"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/tooltip.js"],"names":["angular","target","provider","placement","this","defaults","template","contentTemplate","trigger","keyboard","html","show","title","type","delay","autoClose","bsEnabled","viewport","selector","padding","$get","String","htmlReplaceRegExp","$body","nodeName","element","toLowerCase","split","enterAnimateCallback","scope","$emit","options","prefixEvent","$tooltip","leaveAnimateCallback","_tipToHide","leave","$isShown","blur","tipElement","forEach","triggers","on","toggle","unbindTriggerEvents","enter","i","length","off","bindKeyboardEvents","$onKeyUp","isTouch","$onFocusElementMouseDown","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","$timeout","hide","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","$element","rect","stopPropagation","width","extend","elRect","height","p","top","left","dimensions","offset","el","scroll","isBody","document","documentElement","$window","getCalculatedOffset","position","actualWidth","actualHeight","outerDims","clientWidth","innerHeight","tip","marginTop","parseInt","using","props","css","isNaN","right","marginLeft","setOffset","delta","getViewportAdjustedDelta","isVertical","replaceArrow","arrowDelta","test","arrowOffsetPosition","viewportPadding","topEdgeOffset","$viewport","viewportDimensions","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","findElement","$arrow","clearTimeout","timeout","tipScope","$destroy","$$phase","$options","config","fetchTemplate","$scope","$new","$rootScope","$id","attr","map","parseFloat","$sce","trustAsHtml","$setEnabled","$$postDigest","id","$hide","setEnabled","isEnabled","$promise","templateEl","contentEl","then","tipLinker","tipTemplate","isObject","init","data","isNumber","container","tipContainer","bindTriggerEvents","isElement","destroyTipElement","hoverState","parent","after","lastChild","display","visibility","clonedElement","safeDigest","version","minor","addClass","animation","$animate","customClass","$$rAF","$applyPlacement","focus","_blur","replace","elementPosition","autoPlace","originalPlacement","containerPosition","indexOf","tipHeight","removeClass","tipPosition","applyPlacement","tipWidth","evt","preventDefault","fetchPromises","cache","$templateCache","res","TooltipFactory","$http","get","directive","restrict","trim","isString","$location","link","falseValueRegExp","transclusion","dataTarget","key","isDefined","hasOwnProperty","oldValue","tooltip","$observe","newValue","bsTooltip","$watch","bsShow","match","setViewport","$on","destroy"],"mappings":"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","file":"modules/tooltip.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.tooltip', ['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 template: 'tooltip/tooltip.tpl.html',\n contentTemplate: 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, $compile, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var nodeName = element[0].nodeName.toLowerCase();\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n $tooltip.$promise = fetchTemplate(options.template);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\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, hoverState;\n\n // Support contentTemplate option\n if(options.contentTemplate) {\n $tooltip.$promise = $tooltip.$promise.then(function(template) {\n var templateEl = angular.element(template);\n return fetchTemplate(options.contentTemplate)\n .then(function(contentTemplate) {\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]);\n if(!contentEl.length) contentEl = findElement('[ng-bind=\"title\"]', templateEl[0]);\n contentEl.removeAttr('ng-bind').html(contentTemplate);\n return templateEl[0].outerHTML;\n });\n });\n }\n\n // Fetch, compile then initialize tooltip\n var tipLinker, tipElement, tipTemplate, tipContainer, tipScope;\n $tooltip.$promise.then(function(template) {\n if(angular.isObject(template)) template = template.data;\n if(options.html) template = template.replace(htmlReplaceRegExp, 'ng-bind-html=\"');\n template = trim.apply(template);\n tipTemplate = template;\n tipLinker = $compile(template);\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 options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\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, 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 = tipLinker(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 after ? after.after(tipElement) : parent.prepend(tipElement);\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\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\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() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\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 autoToken = /\\s?auto?\\s?/i,\n 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 tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var container = options.container ? findElement(options.container) : element.parent();\n var containerPosition = getPosition(container);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > containerPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < containerPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > containerPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < containerPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : 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 $tooltip.$isShown ? element[0].blur() : element[0].focus();\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') {\n element.on('click', $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 nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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') {\n element.off('click', $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 nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\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 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 for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\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 scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n 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 }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n 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 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 arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 },\n $viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n if (!$viewport) {\n return delta;\n }\n\n var viewportPadding = options.viewport && options.viewport.padding || 0,\n viewportDimensions = getPosition($viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll,\n 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 rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.width) { // 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 scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\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}).then(function(res) {\n return res.data;\n }));\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'contentTemplate', '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 // 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 // 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && 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 angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && 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 newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && 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 newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var 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"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/tooltip.tpl.js b/dist/modules/tooltip.tpl.js index 5b25107a9..543e7a000 100644 --- a/dist/modules/tooltip.tpl.js +++ b/dist/modules/tooltip.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tooltip.tpl.min.js b/dist/modules/tooltip.tpl.min.js index ff35d37e5..194061dc9 100644 --- a/dist/modules/tooltip.tpl.min.js +++ b/dist/modules/tooltip.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/typeahead.js b/dist/modules/typeahead.js index c9385a459..66340556f 100644 --- a/dist/modules/typeahead.js +++ b/dist/modules/typeahead.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -106,17 +106,17 @@ angular.module('mgcrea.ngStrap.typeahead', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.n $typeahead.show = function() { show(); $timeout(function() { - $typeahead.$element.on('mousedown', $typeahead.$onMouseDown); + $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown); if (options.keyboard) { - element.on('keydown', $typeahead.$onKeyDown); + element && element.on('keydown', $typeahead.$onKeyDown); } }, 0, false); }; var hide = $typeahead.hide; $typeahead.hide = function() { - $typeahead.$element.off('mousedown', $typeahead.$onMouseDown); + $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown); if (options.keyboard) { - element.off('keydown', $typeahead.$onKeyDown); + element && element.off('keydown', $typeahead.$onKeyDown); } if (!options.autoSelect) $typeahead.activate(-1); hide(); @@ -178,7 +178,11 @@ angular.module('mgcrea.ngStrap.typeahead', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.n }); controller.$formatters.push(function(modelValue) { var displayValue = parsedOptions.displayValue(modelValue); - return displayValue === undefined ? '' : displayValue; + if (displayValue) return displayValue; + if (modelValue && typeof modelValue !== 'object') { + return modelValue; + } + return ''; }); controller.$render = function() { if (controller.$isEmpty(controller.$viewValue)) return element.val(''); diff --git a/dist/modules/typeahead.min.js b/dist/modules/typeahead.min.js index 3573fb435..63c59d67e 100644 --- a/dist/modules/typeahead.min.js +++ b/dist/modules/typeahead.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$typeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',template:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'filter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(t,n,a,i){function o(t,n,o){var r={},l=angular.extend({},e,o);r=a(t,l);var c=o.scope,u=r.$scope;u.$resetMatches=function(){u.$matches=[],u.$activeIndex=l.autoSelect?0:-1},u.$resetMatches(),u.$activate=function(e){u.$$postDigest(function(){r.activate(e)})},u.$select=function(e,t){u.$$postDigest(function(){r.select(e)})},u.$isVisible=function(){return r.$isVisible()},r.update=function(e){u.$matches=e,u.$activeIndex>=e.length&&(u.$activeIndex=l.autoSelect?0:-1),/^(bottom|bottom-left|bottom-right)$/.test(l.placement)||i(r.$applyPlacement)},r.activate=function(e){u.$activeIndex=e},r.select=function(e){if(-1!==e){var t=u.$matches[e].value;n.$setViewValue(t),n.$render(),u.$resetMatches(),c&&c.$digest(),u.$emit(l.prefixEvent+'.select',t,e,r)}},r.$isVisible=function(){return l.minLength&&n?u.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=l.minLength:!!u.$matches.length},r.$getIndex=function(e){var t=u.$matches.length,n=t;if(t){for(n=t;n--&&u.$matches[n].value!==e;);if(!(0>n))return n}},r.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},r.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!r.$isVisible()||13===e.keyCode&&-1===u.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&u.$matches.length?r.select(u.$activeIndex):38===e.keyCode&&u.$activeIndex>0?u.$activeIndex--:40===e.keyCode&&u.$activeIndex0)return void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1));e.length>s&&(e=e.slice(0,s));var n=p.$isVisible();n&&p.update(e),(1!==e.length||e[0].value!==t)&&(!n&&p.update(e),r.$render())})}),r.$formatters.push(function(e){var t=f.displayValue(e);return void 0===t?'':t}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=p.$getIndex(r.$modelValue),n=angular.isDefined(e)?p.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?f.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'';t.val(l.trimValue===!1?a:a.trim())},e.$on('$destroy',function(){p&&p.destroy(),l=null,p=null})}}}]); +'use strict';angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$typeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',template:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'filter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(t,n,a,i){function o(t,n,o){var r={},l=angular.extend({},e,o);r=a(t,l);var c=o.scope,u=r.$scope;u.$resetMatches=function(){u.$matches=[],u.$activeIndex=l.autoSelect?0:-1},u.$resetMatches(),u.$activate=function(e){u.$$postDigest(function(){r.activate(e)})},u.$select=function(e,t){u.$$postDigest(function(){r.select(e)})},u.$isVisible=function(){return r.$isVisible()},r.update=function(e){u.$matches=e,u.$activeIndex>=e.length&&(u.$activeIndex=l.autoSelect?0:-1),/^(bottom|bottom-left|bottom-right)$/.test(l.placement)||i(r.$applyPlacement)},r.activate=function(e){u.$activeIndex=e},r.select=function(e){if(-1!==e){var t=u.$matches[e].value;n.$setViewValue(t),n.$render(),u.$resetMatches(),c&&c.$digest(),u.$emit(l.prefixEvent+'.select',t,e,r)}},r.$isVisible=function(){return l.minLength&&n?u.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=l.minLength:!!u.$matches.length},r.$getIndex=function(e){var t=u.$matches.length,n=t;if(t){for(n=t;n--&&u.$matches[n].value!==e;);if(!(0>n))return n}},r.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},r.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!r.$isVisible()||13===e.keyCode&&-1===u.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&u.$matches.length?r.select(u.$activeIndex):38===e.keyCode&&u.$activeIndex>0?u.$activeIndex--:40===e.keyCode&&u.$activeIndex0)return void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1));e.length>s&&(e=e.slice(0,s));var n=m.$isVisible();n&&m.update(e),(1!==e.length||e[0].value!==t)&&(!n&&m.update(e),r.$render())})}),r.$formatters.push(function(e){var t=f.displayValue(e);return t?t:e&&'object'!=typeof e?e:''}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=m.$getIndex(r.$modelValue),n=angular.isDefined(e)?m.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?f.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'';t.val(l.trimValue===!1?a:a.trim())},e.$on('$destroy',function(){m&&m.destroy(),l=null,m=null})}}}]); //# sourceMappingURL=../modules/typeahead.min.js.map \ No newline at end of file diff --git a/dist/modules/typeahead.min.js.map b/dist/modules/typeahead.min.js.map index e72e98684..92811c35f 100644 --- a/dist/modules/typeahead.min.js.map +++ b/dist/modules/typeahead.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/typeahead.js"],"names":["angular","trigger","provider","container","this","defaults","keyboard","html","delay","minLength","filter","limit","autoSelect","comparator","trimValue","$get","bodyEl","$typeahead","options","scope","$scope","$matches","extend","config","$resetMatches","$$postDigest","activate","$activeIndex","select","index","$select","evt","matches","$isVisible","update","test","placement","$timeout","value","controller","$render","$emit","prefixEvent","parentScope","length","l","isString","$viewValue","i","preventDefault","stopPropagation","keyCode","$digest","show","$element","$onMouseDown","hide","on","$onKeyDown","TypeaheadFactory","directive","$window","document","body","link","require","restrict","falseValueRegExp","element","attr","key","bsOptions","parsedOptions","$parseOptions","typeahead","watchOptions","watchedOptions","$watchCollection","values","$match","replace","trim","$watch","ngModel","newValue","oldValue","$modelValue","valuesFn","selectMode","isVisible","slice","$formatters","displayValue","undefined","selected","isDefined","isObject","toString","$on","$isEmpty","val","destroy","label"],"mappings":"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","file":"modules/typeahead.min.js","sourcesContent":["'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 template: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'filter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\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 // When the placement is not one of the bottom placements, re-calc the positioning\n // so the results render correctly.\n if (/^(bottom|bottom-left|bottom-right)$/.test(options.placement)) return;\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n $timeout($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 l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 }\n\n // Navigate with keyboard\n else if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\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 // 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 imediately.\n $timeout(function() {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $typeahead.$onKeyDown);\n }\n if(!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n element.attr('autocomplete' ,'off');\n\n // Build proper bsOptions\n var 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) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\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 var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if(values.length === 1 && values[0].value === newValue) return;\n !isVisible && 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 return displayValue === undefined ? '' : displayValue;\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)) return element.val('');\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? 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"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/typeahead.js"],"names":["angular","trigger","provider","container","this","defaults","keyboard","html","delay","minLength","filter","limit","autoSelect","comparator","trimValue","$get","bodyEl","$typeahead","options","scope","$scope","$matches","extend","config","$resetMatches","$$postDigest","activate","$activeIndex","select","index","$select","evt","matches","$isVisible","update","test","placement","$timeout","value","controller","$render","$emit","prefixEvent","parentScope","length","l","isString","$viewValue","i","preventDefault","stopPropagation","keyCode","$digest","show","$element","$onMouseDown","hide","on","$onKeyDown","TypeaheadFactory","directive","$window","document","body","link","require","restrict","falseValueRegExp","element","attr","key","bsOptions","parsedOptions","$parseOptions","typeahead","watchOptions","watchedOptions","$watchCollection","values","$match","replace","trim","$watch","ngModel","newValue","oldValue","$modelValue","valuesFn","selectMode","isVisible","slice","$formatters","displayValue","modelValue","push","$getIndex","selected","$on","$isEmpty","val","destroy","isDefined","label","isObject","toString"],"mappings":"AAOA,YAEAA,SAGMC,OAAS,4BAAA,yBAAA,wCAAAC,SAAA,aAAA,WAFb,GAGIC,GAAWC,KAAAC,UACXC,UAAU,UACVC,YAAM,YACNC,YAAO,aACPC,UAAW,cACXC,SAAQ,+BACRC,QAAO,QACPC,WAAAA,EACAC,UAAAA,EACAC,MAAAA,EAFFN,MAAO,EAKPJ,UAAKW,EAEHL,OAAIM,SAEJL,MAAA,EALFC,YAOQK,EANRJ,WASQK,GARRJ,WAUIG,EARNb,MAUMW,MAAII,UAAQF,aAAWG,WAAAA,WAAAA,SAAAA,EAAAA,EAAAA,EAAAA,GAR3B,QAWMD,GAAME,EAAAA,EAAAA,GAVV,GAWIF,MAVAD,EAAUlB,QAAQsB,UAAWjB,EAAUkB,EAYzCJ,GAAMK,EAAAA,EAAAA,EAENL,IAAAA,GAAkBI,EAAAJ,MAChBA,EAAMM,EAAaL,MAXvBD,GAYMF,cAAWS,WAXfP,EAAME,YACNF,EAAMQ,aAAeT,EAAQN,WAAa,EAAI,IAEhDO,EAaIA,gBAZJA,EAaMF,UAAWW,SAAOC,GAZtBV,EAAMM,aAAa,WACjBR,EAAWS,SAASG,MAGxBV,EAAMW,QAAU,SAASD,EAAOE,GAkB9Bd,EAAAA,aAAoB,WAClBE,EAAME,OAAWW,MAdrBb,EAAMc,WAAa,WAqBf,MAAIhB,GAAAgB,cAlBRhB,EAAWiB,OAAS,SAASF,GAyB3Bf,EAAAA,SAAWS,EACTP,EAAMQ,cAAeE,EAAAA,SAvBrBV,EAAMQ,aAAeT,EAAQN,WAAa,EAAI,IA2B3CiB,sCAAcM,KAAAjB,EAAAkB,YACjBC,EAAIC,EAAcjB,kBAvBtBJ,EA0BIsB,SAAWC,SAAAA,GACXrB,EAAMK,aAAAA,GAxBVP,EA2BUwB,OAAMvB,SAAQwB,GA1BtB,GAAc,KAAVb,EAAJ,CA+BAZ,GAAAA,GAAWgB,EAAAA,SAAaJ,GAAAS,KACtBC,GAAIrB,cAAQT,GA7Bd8B,EA8BapB,UA7BbA,EAAMK,gBAgCJmB,GAAatB,EAASuB,UA9BxBzB,EAAMsB,MAAMvB,EAAQwB,YAAc,UAAWJ,EAAOT,EAAOZ,KAE7DA,EAgCYE,WAAME,WACd,MAAIwB,GAAGpC,WAAA8B,EA7BFpB,EAAME,SAASuB,QAAU5C,QAAQ8C,SAASP,EAAWQ,aAAeR,EAAWQ,WAAWH,QAAU1B,EAAQT,YA8BzGoC,EAAGG,SAAMJ,QA5BrB3B,EAgCW+B,UAAAA,SAAAA,GA/BT,GAAIH,GAAI1B,EAAME,SAASuB,OAAQI,EAAIH,CAkCnC5B,IAAAA,EAAAA,CAEEc,IAAIkB,EAAAA,EAAAA,KACAC,EAAAA,SAAAA,GAAAA,QAAAA,IAGNjC,KAAAA,EAAAA,GACE,MAAI+B,KAjCR/B,EAqCUgC,aAAAA,SAAAA,GApCRlB,EAqCIA,iBApCJA,EAAImB,mBAENjC,EAuCMA,WAAkBE,SAAMQ,GAtCvB,aA0CSwB,KAAAA,EAAYA,YAGxBhC,EAAMiC,cAAAA,KAAAA,EAAAA,SAAAA,KAAAA,EAAAA,eA3CNrB,EAAIkB,iBAgDFI,EAAAA,mBAEFA,KAAAA,EAAAA,SAAAA,EAAAA,SAAAA,OAGAhB,EAAST,OAAAT,EAAAQ,cACgBV,KAAvBA,EAAWqC,SAAYrC,EAAWqC,aAAY,EAAAnC,EAAaF,eAAWsC,KAAAA,EAAAA,SAAAA,EAAAA,aAAAA,EAAAA,SAAAA,OAAAA,EAAAA,EAAAA,eAAAA,QAAAA,YAAAA,EAAAA,gBAAAA,EAAAA,aAAAA,GAhD1EpC,EAiDOD,WA/CT,IAAImC,GAAOpC,EAAWoC,IACtBpC,GAiDUoC,KAAA,WAhDRA,IAmDAhB,EAAWpB,WACXA,EAAWuC,UAAOvC,EAAAqC,SAAAG,GAAA,YAAAxC,EAAAsC,cAChBtC,EAAWqC,UACRpC,GAAQZ,EAAUmD,GAAA,UAAAxC,EAAAyC,aAhDpB,GAAG,GAER,IAmDIF,GAAAA,EAAAA,IAkBN,OApEEvC,GAAWuC,KAAO,WAqDhBvC,EAAOA,UAAAA,EAAAA,SAAAA,IAAAA,YAAAA,EAAAA,cAnDHC,EAAQZ,UAuDdqD,GAAiBtD,EAAAA,IAAWA,UAAAA,EAAAA,YApDrBa,EAAQN,YAAYK,EAAWS,SAAS,IA2DlDkC,KAIC3C,EA/IUO,QAAAA,QAAgBqC,EAAAC,SAAAC,KAkJxBC,OADAC,GAAS5D,SAAAA,EACHsD,MA1DTC,UA6DoBzC,eAAOA,UAAAA,SAAAA,KAAAA,aAAAA,gBAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GA5D5B,GAAId,GAAWY,EAAWZ,QAC1B,QACE6D,SA4DSlE,MA3DTiE,QAAS,UACTD,KA8DQG,SAAAA,EAAmBC,EAAAC,EAAA9B,GACvBvC,GAAAA,IACEmB,MAAGnB,EAILoE,SAAQC,SAAK,YAAgB,YAAA,QAAA,UAAA,WAAA,OAAA,YAAA,WAAA,SAAA,QAAA,YAAA,eAAA,aAAA,aAAA,aAAA,KAAA,cAAA,eAAA,SAAAC,GAGzB5D,QAASQ,UAAQR,EAAAA,MAAUL,EAASK,GAAAA,EAAAA,KAExC,IAAIG,GAAaK,eAEjBlB,SAAIuE,SAAYF,OAAKE,YAAAA,aAAAA,SAAAA,GAClB7D,QAAQ6D,UAAAA,EAAaD,KAAQ5D,EAASyB,KAAAkC,EAAAC,MAAApD,EAAAoD,IAAA,KAEzCF,EAAGzD,KAAO4D,eAAa,MACvB,IAAIC,GAAAA,EAAgBC,QAAAA,EAAcF,OAG9BG,EAAAA,EAAYzD,OAAWmD,EAAS7B,MAGjCrB,EAAQyD,EAAAA,YAActE,EAAAQ,WAEvB0D,EAAIK,EAAAA,SACJzD,KAAM0D,GAAiBD,MAAAA,EAAgB,eAErCJ,IAAAA,GAAuBrD,IAAOoB,GAxEhC5B,IAyEI+D,GAAiBI,cAAAA,EAxEzB,IAAIN,GAyEehC,EAAAA,GAxEfkC,EAAYzD,EAAWmD,EAAS7B,EAAYrB,EAChD,IAAIA,EAAQyD,aAAc,CACxB,GAAIC,GAAiBJ,EAAcO,OAAO,GAAGC,QAAQ,OAAQ,IAAIA,QAAQ,UAAW,IAAIC,MA4ExF9D,GAAM+D,iBAAYC,EAAkBC,SAAUC,EAAAA,GAE5ClE,EAAMmE,SAAcF,EAAAA,GAAAA,KAAAA,SAAAA,GACpBZ,EAAce,OAAAA,GAIZhD,EAAWiD,cA3EjBrE,EA+EM+D,OAAGJ,EAAOlC,QAASjC,SAAOmE,EAASA,GA9EvC3D,EA+EQsE,YAAYf,EA9EpBF,EA+EIiB,SAAaf,EAAUxC,GAAO4C,KAAAA,SAAAA,GAE9B,GAAGA,EAAOlC,aAAgBkC,EAAOlC,QAAGN,EAAU8C,OAAU,EAGxD7C,WAFCkD,GAAAA,cAAuBvD,EAAO4C,WAAAA,UAAAA,EAAAA,EAAAA,WAAAA,OAAAA,GA7E7BA,GAAOlC,OAASjC,IAAOmE,EAASA,EAAOY,MAAM,EAAG/E,GAoFtD4B,IAAAA,GAAWoD,EAAiB1D,YAE1BwD,IAAIG,EAAepB,OAAAA,IAGD,IAAdoB,EAAAA,QAAqBA,EAAAA,GAAAA,QAAAA,MAIzBH,GAAII,EAAqBA,OAAAA,GACvBtD,EAAOsD,eAtFbtD,EAAWoD,YAAYG,KAAK,SAASD,GA4FnCtD,GAAAA,GAAqBiC,EAAAoB,aAAAC,EAEnB,OAAGtD,GAAoBA,EACnBV,GAA4BU,gBAAVwD,GAClBC,EAEA1D,KA1FRC,EAAWC,QAAU,WA+FnBrB,GAAM8E,EAAIC,SAAY3D,EAAAQ,YAAA,MAAAqB,GAAA+B,IAAA,GACpB,IAAIzB,GAAAA,EAAWA,UAAU0B,EAAAA,aACzBlF,EAAUlB,QAAAqG,UAAAxE,GAAA6C,EAAAtD,OAAAC,SAAAQ,GAAAyE,MAAA/D,EAAAQ,UACV2B,GAAAA,QAAY6B,SAAAP,GAAAxB,EAAAoB,aAAAI,GAAAA,CA7Fd,IAAI1D,GAAQ0D,EAAWA,EAASQ,WAAWxB,QAAQ,iBAAkB,IAAM,EAC3EZ,GAAQ+B,IAAIjF,EAAQJ,aAAc,EAAQwB,EAAQA,EAAM2C,SAE1D9D,EAAM8E,IAAI,WAAY,WAChBvB,GAAWA,EAAU0B,UACzBlF,EAAU,KACVwD,EAAY","file":"modules/typeahead.min.js","sourcesContent":["'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 template: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'filter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\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 // When the placement is not one of the bottom placements, re-calc the positioning\n // so the results render correctly.\n if (/^(bottom|bottom-left|bottom-right)$/.test(options.placement)) return;\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n $timeout($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 l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\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 }\n\n // Navigate with keyboard\n else if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\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 // 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 $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element && element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if(options.keyboard) {\n element && element.off('keydown', $typeahead.$onKeyDown);\n }\n if(!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\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 // Directive options\n var options = {scope: scope};\n angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', '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'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n element.attr('autocomplete' ,'off');\n\n // Build proper bsOptions\n var 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) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\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 var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if(values.length === 1 && values[0].value === newValue) return;\n !isVisible && 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) return displayValue;\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 (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)) return element.val('');\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? 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"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/typeahead.tpl.js b/dist/modules/typeahead.tpl.js index 7630d6dac..60421471b 100644 --- a/dist/modules/typeahead.tpl.js +++ b/dist/modules/typeahead.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/typeahead.tpl.min.js b/dist/modules/typeahead.tpl.min.js index dc7b52f19..d89edc160 100644 --- a/dist/modules/typeahead.tpl.min.js +++ b/dist/modules/typeahead.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.2.3 - 2015-05-20 + * @version v2.2.4 - 2015-05-28 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/docs/scripts/app.js b/docs/scripts/app.js index 27d3e3bfe..582b9a160 100644 --- a/docs/scripts/app.js +++ b/docs/scripts/app.js @@ -4,7 +4,7 @@ angular.module('mgcrea.ngStrapDocs', ['mgcrea.ngStrap', 'mgcrea.ngPlunkr', 'ngRoute', 'ngAnimate']) -.constant('version', 'v2.2.3') +.constant('version', 'v2.2.4') .config(function($plunkrProvider, version) { diff --git a/package.json b/package.json index 9ad8f5dfc..0ead328b3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "angular-strap", "description": "AngularStrap - AngularJS directives for Bootstrap", - "version": "2.2.3", + "version": "2.2.4", "keywords": [ "angular", "bootstrap" @@ -32,14 +32,14 @@ ], "dependencies": {}, "devDependencies": { - "del": "^1.1.1", - "factory-angular-channels": "^0.7.1", + "del": "^1.2.0", + "factory-angular-channels": "^0.7.2", "gulp": "gulpjs/gulp#4.0", - "gulp-jshint": "^1.10.0", + "gulp-jshint": "^1.11.0", "gulp-util": "^3.0.4", "jasmine-core": "^2.3.4", - "jshint-stylish": "^1.0.2", - "karma": "^0.12.31", + "jshint-stylish": "^2.0.0", + "karma": "^0.12.33", "karma-chrome-launcher": "^0.1.12", "karma-coverage": "^0.3.1", "karma-jasmine": "^0.3.5",