From 68e291e5008513fa83853684b3496b1338a276b5 Mon Sep 17 00:00:00 2001 From: Olivier Louvignes Date: Thu, 29 Oct 2015 18:59:53 +0100 Subject: [PATCH] chore(release): cut the 2.3.5 release --- bower.json | 2 +- dist/angular-strap.compat.js | 415 +++++++++++++++-------------- dist/angular-strap.compat.min.js | 6 +- dist/angular-strap.js | 415 +++++++++++++++-------------- dist/angular-strap.min.js | 8 +- dist/angular-strap.min.js.map | 2 +- dist/angular-strap.tpl.js | 4 +- dist/angular-strap.tpl.min.js | 4 +- 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/compiler.js | 8 +- dist/modules/compiler.min.js | 4 +- dist/modules/compiler.min.js.map | 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 | 63 +++-- dist/modules/dropdown.min.js | 4 +- dist/modules/dropdown.min.js.map | 2 +- dist/modules/dropdown.tpl.js | 4 +- dist/modules/dropdown.tpl.min.js | 4 +- dist/modules/modal.js | 2 +- dist/modules/modal.min.js | 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 | 2 +- dist/modules/select.min.js | 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 | 2 +- dist/modules/timepicker.min.js | 2 +- dist/modules/timepicker.tpl.js | 2 +- dist/modules/timepicker.tpl.min.js | 2 +- dist/modules/tooltip.js | 2 +- dist/modules/tooltip.min.js | 2 +- dist/modules/tooltip.tpl.js | 2 +- dist/modules/tooltip.tpl.min.js | 2 +- dist/modules/typeahead.js | 2 +- dist/modules/typeahead.min.js | 2 +- dist/modules/typeahead.tpl.js | 2 +- dist/modules/typeahead.tpl.min.js | 2 +- docs/dev.html | 4 +- docs/scripts/app.js | 2 +- package.json | 2 +- 81 files changed, 559 insertions(+), 520 deletions(-) diff --git a/bower.json b/bower.json index f7a0a67ac..467abbce4 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "angular-strap", "description": "AngularStrap - AngularJS directives for Bootstrap", - "version": "2.3.4", + "version": "2.3.5", "keywords": [ "angular", "bootstrap" diff --git a/dist/angular-strap.compat.js b/dist/angular-strap.compat.js index cb0e36336..935421a20 100644 --- a/dist/angular-strap.compat.js +++ b/dist/angular-strap.compat.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -1359,179 +1359,6 @@ } }; } ]); - angular.module('mgcrea.ngStrap.scrollspy', [ 'mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$bsScrollspy', function() { - var spies = this.$$spies = {}; - var defaults = this.defaults = { - debounce: 150, - throttle: 100, - offset: 100 - }; - this.$get = ["$window", "$document", "$rootScope", "bsDimensions", "bsDebounce", "bsThrottle", function($window, $document, $rootScope, dimensions, debounce, throttle) { - var windowEl = angular.element($window); - var docEl = angular.element($document.prop('documentElement')); - var bodyEl = angular.element($window.document.body); - function nodeName(element, name) { - return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase(); - } - function ScrollSpyFactory(config) { - var options = angular.extend({}, defaults, config); - if (!options.element) options.element = bodyEl; - var isWindowSpy = nodeName(options.element, 'body'); - var scrollEl = isWindowSpy ? windowEl : options.element; - var scrollId = isWindowSpy ? 'window' : options.id; - if (spies[scrollId]) { - spies[scrollId].$$count++; - return spies[scrollId]; - } - var $scrollspy = {}; - var unbindViewContentLoaded, unbindIncludeContentLoaded; - var trackedElements = $scrollspy.$trackedElements = []; - var sortedElements = []; - var activeTarget; - var debouncedCheckPosition; - var throttledCheckPosition; - var debouncedCheckOffsets; - var viewportHeight; - var scrollTop; - $scrollspy.init = function() { - this.$$count = 1; - debouncedCheckPosition = debounce(this.checkPosition, options.debounce); - throttledCheckPosition = throttle(this.checkPosition, options.throttle); - scrollEl.on('click', this.checkPositionWithEventLoop); - windowEl.on('resize', debouncedCheckPosition); - scrollEl.on('scroll', throttledCheckPosition); - debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce); - unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets); - unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets); - debouncedCheckOffsets(); - if (scrollId) { - spies[scrollId] = $scrollspy; - } - }; - $scrollspy.destroy = function() { - this.$$count--; - if (this.$$count > 0) { - return; - } - scrollEl.off('click', this.checkPositionWithEventLoop); - windowEl.off('resize', debouncedCheckPosition); - scrollEl.off('scroll', throttledCheckPosition); - unbindViewContentLoaded(); - unbindIncludeContentLoaded(); - if (scrollId) { - delete spies[scrollId]; - } - }; - $scrollspy.checkPosition = function() { - if (!sortedElements.length) return; - scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0; - viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight')); - if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) { - return $scrollspy.$activateElement(sortedElements[0]); - } - for (var i = sortedElements.length; i--; ) { - if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue; - if (activeTarget === sortedElements[i].target) continue; - if (scrollTop < sortedElements[i].offsetTop) continue; - if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue; - return $scrollspy.$activateElement(sortedElements[i]); - } - }; - $scrollspy.checkPositionWithEventLoop = function() { - setTimeout($scrollspy.checkPosition, 1); - }; - $scrollspy.$activateElement = function(element) { - if (activeTarget) { - var activeElement = $scrollspy.$getTrackedElement(activeTarget); - if (activeElement) { - activeElement.source.removeClass('active'); - if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) { - activeElement.source.parent().parent().removeClass('active'); - } - } - } - activeTarget = element.target; - element.source.addClass('active'); - if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) { - element.source.parent().parent().addClass('active'); - } - }; - $scrollspy.$getTrackedElement = function(target) { - return trackedElements.filter(function(obj) { - return obj.target === target; - })[0]; - }; - $scrollspy.checkOffsets = function() { - angular.forEach(trackedElements, function(trackedElement) { - var targetElement = document.querySelector(trackedElement.target); - trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null; - if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1; - }); - sortedElements = trackedElements.filter(function(el) { - return el.offsetTop !== null; - }).sort(function(a, b) { - return a.offsetTop - b.offsetTop; - }); - debouncedCheckPosition(); - }; - $scrollspy.trackElement = function(target, source) { - trackedElements.push({ - target: target, - source: source - }); - }; - $scrollspy.untrackElement = function(target, source) { - var toDelete; - for (var i = trackedElements.length; i--; ) { - if (trackedElements[i].target === target && trackedElements[i].source === source) { - toDelete = i; - break; - } - } - trackedElements = trackedElements.splice(toDelete, 1); - }; - $scrollspy.activate = function(i) { - trackedElements[i].addClass('active'); - }; - $scrollspy.init(); - return $scrollspy; - } - return ScrollSpyFactory; - } ]; - }).directive('bsScrollspy', ["$rootScope", "bsDebounce", "bsDimensions", "$bsScrollspy", function($rootScope, debounce, dimensions, $scrollspy) { - return { - restrict: 'EAC', - link: function postLink(scope, element, attr) { - var options = { - scope: scope - }; - angular.forEach([ 'offset', 'target' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var scrollspy = $scrollspy(options); - scrollspy.trackElement(options.target, element); - scope.$on('$destroy', function() { - if (scrollspy) { - scrollspy.untrackElement(options.target, element); - scrollspy.destroy(); - } - options = null; - scrollspy = null; - }); - } - }; - } ]).directive('bsScrollspyList', ["$rootScope", "bsDebounce", "bsDimensions", "$bsScrollspy", function($rootScope, debounce, dimensions, $scrollspy) { - return { - restrict: 'A', - compile: function postLink(element, attr) { - var children = element[0].querySelectorAll('li > a[href]'); - angular.forEach(children, function(child) { - var childEl = angular.element(child); - childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href')); - }); - } - }; - } ]); angular.module('mgcrea.ngStrap.select', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions' ]).provider('$bsSelect', function() { var defaults = this.defaults = { animation: 'am-fade', @@ -1816,6 +1643,179 @@ } }; } ]); + angular.module('mgcrea.ngStrap.scrollspy', [ 'mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$bsScrollspy', function() { + var spies = this.$$spies = {}; + var defaults = this.defaults = { + debounce: 150, + throttle: 100, + offset: 100 + }; + this.$get = ["$window", "$document", "$rootScope", "bsDimensions", "bsDebounce", "bsThrottle", function($window, $document, $rootScope, dimensions, debounce, throttle) { + var windowEl = angular.element($window); + var docEl = angular.element($document.prop('documentElement')); + var bodyEl = angular.element($window.document.body); + function nodeName(element, name) { + return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase(); + } + function ScrollSpyFactory(config) { + var options = angular.extend({}, defaults, config); + if (!options.element) options.element = bodyEl; + var isWindowSpy = nodeName(options.element, 'body'); + var scrollEl = isWindowSpy ? windowEl : options.element; + var scrollId = isWindowSpy ? 'window' : options.id; + if (spies[scrollId]) { + spies[scrollId].$$count++; + return spies[scrollId]; + } + var $scrollspy = {}; + var unbindViewContentLoaded, unbindIncludeContentLoaded; + var trackedElements = $scrollspy.$trackedElements = []; + var sortedElements = []; + var activeTarget; + var debouncedCheckPosition; + var throttledCheckPosition; + var debouncedCheckOffsets; + var viewportHeight; + var scrollTop; + $scrollspy.init = function() { + this.$$count = 1; + debouncedCheckPosition = debounce(this.checkPosition, options.debounce); + throttledCheckPosition = throttle(this.checkPosition, options.throttle); + scrollEl.on('click', this.checkPositionWithEventLoop); + windowEl.on('resize', debouncedCheckPosition); + scrollEl.on('scroll', throttledCheckPosition); + debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce); + unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets); + unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets); + debouncedCheckOffsets(); + if (scrollId) { + spies[scrollId] = $scrollspy; + } + }; + $scrollspy.destroy = function() { + this.$$count--; + if (this.$$count > 0) { + return; + } + scrollEl.off('click', this.checkPositionWithEventLoop); + windowEl.off('resize', debouncedCheckPosition); + scrollEl.off('scroll', throttledCheckPosition); + unbindViewContentLoaded(); + unbindIncludeContentLoaded(); + if (scrollId) { + delete spies[scrollId]; + } + }; + $scrollspy.checkPosition = function() { + if (!sortedElements.length) return; + scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0; + viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight')); + if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) { + return $scrollspy.$activateElement(sortedElements[0]); + } + for (var i = sortedElements.length; i--; ) { + if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue; + if (activeTarget === sortedElements[i].target) continue; + if (scrollTop < sortedElements[i].offsetTop) continue; + if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue; + return $scrollspy.$activateElement(sortedElements[i]); + } + }; + $scrollspy.checkPositionWithEventLoop = function() { + setTimeout($scrollspy.checkPosition, 1); + }; + $scrollspy.$activateElement = function(element) { + if (activeTarget) { + var activeElement = $scrollspy.$getTrackedElement(activeTarget); + if (activeElement) { + activeElement.source.removeClass('active'); + if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) { + activeElement.source.parent().parent().removeClass('active'); + } + } + } + activeTarget = element.target; + element.source.addClass('active'); + if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) { + element.source.parent().parent().addClass('active'); + } + }; + $scrollspy.$getTrackedElement = function(target) { + return trackedElements.filter(function(obj) { + return obj.target === target; + })[0]; + }; + $scrollspy.checkOffsets = function() { + angular.forEach(trackedElements, function(trackedElement) { + var targetElement = document.querySelector(trackedElement.target); + trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null; + if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1; + }); + sortedElements = trackedElements.filter(function(el) { + return el.offsetTop !== null; + }).sort(function(a, b) { + return a.offsetTop - b.offsetTop; + }); + debouncedCheckPosition(); + }; + $scrollspy.trackElement = function(target, source) { + trackedElements.push({ + target: target, + source: source + }); + }; + $scrollspy.untrackElement = function(target, source) { + var toDelete; + for (var i = trackedElements.length; i--; ) { + if (trackedElements[i].target === target && trackedElements[i].source === source) { + toDelete = i; + break; + } + } + trackedElements = trackedElements.splice(toDelete, 1); + }; + $scrollspy.activate = function(i) { + trackedElements[i].addClass('active'); + }; + $scrollspy.init(); + return $scrollspy; + } + return ScrollSpyFactory; + } ]; + }).directive('bsScrollspy', ["$rootScope", "bsDebounce", "bsDimensions", "$bsScrollspy", function($rootScope, debounce, dimensions, $scrollspy) { + return { + restrict: 'EAC', + link: function postLink(scope, element, attr) { + var options = { + scope: scope + }; + angular.forEach([ 'offset', 'target' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var scrollspy = $scrollspy(options); + scrollspy.trackElement(options.target, element); + scope.$on('$destroy', function() { + if (scrollspy) { + scrollspy.untrackElement(options.target, element); + scrollspy.destroy(); + } + options = null; + scrollspy = null; + }); + } + }; + } ]).directive('bsScrollspyList', ["$rootScope", "bsDebounce", "bsDimensions", "$bsScrollspy", function($rootScope, debounce, dimensions, $scrollspy) { + return { + restrict: 'A', + compile: function postLink(element, attr) { + var children = element[0].querySelectorAll('li > a[href]'); + angular.forEach(children, function(child) { + var childEl = angular.element(child); + childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href')); + }); + } + }; + } ]); angular.module('mgcrea.ngStrap.popover', [ 'mgcrea.ngStrap.tooltip' ]).provider('$bsPopover', function() { var defaults = this.defaults = { animation: 'am-fade', @@ -2729,10 +2729,12 @@ } }); angular.extend(resolve, locals); - if (templateUrl) { + if (template) { + resolve.$template = $q.when(template); + } else if (templateUrl) { resolve.$template = fetchTemplate(templateUrl); } else { - resolve.$template = $q.when(template); + throw new Error('Missing `template` / `templateUrl` option.'); } if (options.contentTemplate) { resolve.$template = $q.all([ resolve.$template, fetchTemplate(options.contentTemplate) ]).then(function(templates) { @@ -2822,7 +2824,6 @@ }; var show = $dropdown.show; $dropdown.show = function() { - if (!scope.content) return; show(); $timeout(function() { options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown); @@ -2855,31 +2856,43 @@ return { restrict: 'EAC', scope: true, - link: function postLink(scope, element, attr, transclusion) { - var options = { - scope: scope + compile: function(tElement, tAttrs) { + var options = {}; + if (!tAttrs.bsDropdown) { + var nextSibling = tElement[0].nextSibling; + while (nextSibling && nextSibling.nodeType !== 1) { + nextSibling = nextSibling.nextSibling; + } + if (nextSibling.classList.contains('dropdown-menu')) { + options.template = nextSibling.outerHTML; + options.templateUrl = undefined; + nextSibling.parentNode.removeChild(nextSibling); + } + } + return function postLink(scope, element, attr) { + options.scope = scope; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id' ], function(key) { + if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) { + scope.content = newValue; + }, true); + attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!dropdown || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i); + newValue === true ? dropdown.show() : dropdown.hide(); + }); + var dropdown = $dropdown(element, options); + scope.$on('$destroy', function() { + if (dropdown) dropdown.destroy(); + options = null; + dropdown = null; + }); }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'html', 'container' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; - }); - attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) { - scope.content = newValue; - }, true); - attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { - if (!dropdown || !angular.isDefined(newValue)) return; - if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i); - newValue === true ? dropdown.show() : dropdown.hide(); - }); - var dropdown = $dropdown(element, options); - scope.$on('$destroy', function() { - if (dropdown) dropdown.destroy(); - options = null; - dropdown = null; - }); } }; } ]); diff --git a/dist/angular-strap.compat.min.js b/dist/angular-strap.compat.min.js index 5e833f6ce..d456a5ea5 100644 --- a/dist/angular-strap.compat.min.js +++ b/dist/angular-strap.compat.min.js @@ -1,3 +1,3 @@ -!function(e,t,n){'use strict';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;return angular.forEach(d,function(e,t){angular.isString(e)?d[t]=a.get(e):d[t]=a.invoke(e)}),angular.extend(d,f),n?d.$template=l(n):d.$template=e.when(r),t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$bsTypeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$bsTooltip','$$rAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex0?void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1)):(e.length>c&&(e=e.slice(0,c)),g.update(e),void 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})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$bsTooltip',function(){var e=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',templateUrl:'tooltip/tooltip.tpl.html',template:'',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','$bsCompiler','$q','$templateCache','$http','$animate','$sce','bsDimensions','$$rAF','$timeout',function(n,a,o,i,r,s,l,u,c,d,f){function p(i,r){function s(){P.$emit(V.prefixEvent+'.show',F)}function p(){if(P.$emit(V.prefixEvent+'.hide',F),R===j){if(z&&'focus'===V.trigger)return i[0].blur();A()}}function v(){var e=V.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',F.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',F.enter),i.on('hover'===e?'mouseleave':'blur',F.leave),'button'===I&&'hover'!==e&&i.on($?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function w(){for(var e=V.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',F.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',F.enter),i.off('hover'===n?'mouseleave':'blur',F.leave),'button'===I&&'hover'!==n&&i.off($?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function y(){'focus'!==V.trigger?R.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function b(){'focus'!==V.trigger?R.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function D(){f(function(){R.on('click',k),h.on('click',F.hide),K=!0},0,!1)}function S(){K&&(R.off('click',k),h.off('click',F.hide),K=!1)}function k(e){e.stopPropagation()}function x(e){e=e||V.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 T(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 C(e,t){var n=R[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){R.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=M(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';E(f,n[p],d)}}}function M(e,t,n,a){var o={top:0,left:0};if(!F.$viewport)return o;var i=V.viewport&&V.viewport.padding||0,r=x(F.$viewport);if(/right|left/.test(e)){var s=t.top-i-r.scroll,l=t.top+i-r.scroll+a;sr.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;ur.right&&(o.left=r.left+r.width-c)}return o}function E(e,t,n){var a=m('.tooltip-arrow, .arrow',R[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(H),F.$isShown&&null!==R&&(V.autoClose&&S(),V.keyboard&&b()),q&&(q.$destroy(),q=null),R&&(R.remove(),R=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),O=F.$promise=o.compile(V),P=F.$scope=V.scope&&V.scope.$new()||a.$new(),I=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var N=V.delay.split(',').map(parseFloat);V.delay=N.length>1?{show:N[0],hide:N[1]}:N[0]}F.$id=V.id||i.attr('id')||'',V.title&&(P.title=u.trustAsHtml(V.title)),P.$setEnabled=function(e){P.$$postDigest(function(){F.setEnabled(e)})},P.$hide=function(){P.$$postDigest(function(){F.hide()})},P.$show=function(){P.$$postDigest(function(){F.show()})},P.$toggle=function(){P.$$postDigest(function(){F.toggle()})},F.$isShown=P.$isShown=!1;var H,L,U,R,Y,q;O.then(function(e){U=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?Y=i:angular.isElement(V.container)?Y=V.container:V.container&&(Y=m(V.container)),v(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&P.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),A(),P.$destroy()},F.enter=function(){return clearTimeout(H),L='in',V.delay&&V.delay.show?void(H=setTimeout(function(){'in'===L&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){P.$emit(V.prefixEvent+'.show.before',F);var e,t;V.container?(e=Y,t=Y[0].lastChild?angular.element(Y[0].lastChild):null):(e=null,t=i),R&&A(),q=F.$scope.$new(),R=F.$element=U.link(q,function(e,t){}),R.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&R.addClass(V.animation),V.type&&R.addClass(V.prefixClass+'-'+V.type),V.customClass&&R.addClass(V.customClass),t?t.after(R):e.prepend(R),F.$isShown=P.$isShown=!0,g(P),F.$applyPlacement(),angular.version.minor<=2?l.enter(R,e,t,s):l.enter(R,e,t).then(s),g(P),d(function(){R&&R.css({visibility:'visible'}),V.keyboard&&('focus'!==V.trigger&&F.focus(),y())}),V.autoClose&&D()}},F.leave=function(){return clearTimeout(H),L='out',V.delay&&V.delay.hide?void(H=setTimeout(function(){'out'===L&&F.hide()},V.delay.hide)):F.hide()};var z,j;F.hide=function(e){F.$isShown&&(P.$emit(V.prefixEvent+'.hide.before',F),z=e,j=R,angular.version.minor<=2?l.leave(R,p):l.leave(R).then(p),F.$isShown=P.$isShown=!1,g(P),V.keyboard&&null!==R&&b(),V.autoClose&&null!==R&&S())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){R[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(R){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),R.addClass(V.placement);var o=x(),i=R.prop('offsetWidth'),r=R.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);s.indexOf('bottom')>=0&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):s.indexOf('top')>=0&&o.top-rl.width?t='right'===s?'left':t.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&o.left-it?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||y),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();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 void f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,S).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,S).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(){!c&&t.attr('readonly')||t.attr('disabled')||(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=/(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','$bsDateFormatter','$bsDateParser','$bsTimepicker',function(e,t,a,o,i,r){var s=r.defaults,l=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.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,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)},h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),c(u.$dateValue)})}),e.$watch(a.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 a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):'unix'===f.timeType?new Date(1e3*e):new Date(e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$bsTab',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&&t0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',y),m.off('scroll',b),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(C.length){if(k=(g?a.pageYOffset:m.prop('scrollTop'))||0,S=Math.max(a.innerHeight,f.prop('clientHeight')),kC[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','bsDebounce','bsDimensions','$bsScrollspy',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','bsDebounce','bsDimensions','$bsScrollspy',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('$bsSelect',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',templateUrl:'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','$bsTooltip','$timeout',function(t,n,a,o,i){function r(a,r,s){var u={},c=angular.extend({},e,s);u=o(a,c);var d=u.$scope;d.$matches=[],c.multiple?d.$activeIndex=[]:d.$activeIndex=-1,d.$isMultiple=c.multiple,d.$showAllNoneButtons=c.allNoneButtons&&c.multiple,d.$iconCheckmark=c.iconCheckmark,d.$allText=c.allText,d.$noneText=c.noneText,d.$activate=function(e){d.$$postDigest(function(){u.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){u.select(e)})},d.$isVisible=function(){return u.$isVisible()},d.$isActive=function(e){return u.$isActive(e)},d.$selectAll=function(){for(var e=0;e=c.minLength:d.$matches.length},u.$isActive=function(e){return c.multiple?-1!==d.$activeIndex.indexOf(e):d.$activeIndex===e},u.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},u.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),c.multiple&&9===e.keyCode?u.hide():c.multiple||13!==e.keyCode&&9!==e.keyCode?void(c.multiple||(38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:38===e.keyCode&&d.$activeIndex<0?d.$activeIndex=d.$matches.length-1:40===e.keyCode&&d.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},u.$selectScrollFix=function(e){'UL'===n[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var f=u.show;u.show=function(){f(),c.multiple&&u.$element.addClass('select-multiple'),i(function(){u.$element.on(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.on('keydown',u.$onKeyDown)},0,!1)};var p=u.hide;return u.hide=function(){!c.multiple&&angular.isUndefined(r.$modelValue)&&(d.$activeIndex=-1),u.$element.off(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.off('keydown',u.$onKeyDown),p(!0)},u}var s=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),l='createTouch'in t.document&&s;return r.defaults=e,r}]}).directive('bsSelect',['$window','$parse','$q','$bsSelect','$bsParseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(l.test(u)?s.multiple=!1:s.multiple=u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element(''),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s);f.$isIE()&&t[0].addEventListener('blur',f.$selectScrollFix);var 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.popover',['mgcrea.ngStrap.tooltip']).provider('$bsPopover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$bsTooltip',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','$bsPopover',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','templateUrl','controller','controllerAs','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)&&(s.test(l)?r.target=!1:r.target=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.navbar',[]).provider('$bsNavbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$bsNavbar',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.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$bsModal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$bsCompiler','$animate','$timeout','$sce','bsDimensions',function(n,a,o,i,r,s,l){function u(t){function n(){S.$emit(b.prefixEvent+'.show',y)}function r(){S.$emit(b.prefixEvent+'.hide',y),g.removeClass(b.prefixClass+'-open'),b.animation&&g.removeClass(b.prefixClass+'-with-'+b.animation)}function l(){b.backdrop&&(x.on('click',h),C.on('click',h),C.on('wheel',v))}function u(){b.backdrop&&(x.off('click',h),C.off('click',h),C.off('wheel',v))}function m(){b.keyboard&&x.on('keyup',y.$onKeyUp)}function $(){b.keyboard&&x.off('keyup',y.$onKeyUp)}function h(e){e.target===e.currentTarget&&('static'===b.backdrop?y.focus():y.hide())}function v(e){e.preventDefault()}function w(){y.$isShown&&null!==x&&(u(),$()),T&&(T.$destroy(),T=null),x&&(x.remove(),x=y.$element=null)}var y={},b=y.$options=angular.extend({},e,t),D=y.$promise=o.compile(b),S=y.$scope=b.scope&&b.scope.$new()||a.$new();b.element||b.container||(b.container='body'),y.$id=b.id||b.element&&b.element.attr('id')||'',f(['title','content'],function(e){b[e]&&(S[e]=s.trustAsHtml(b[e]))}),S.$hide=function(){S.$$postDigest(function(){y.hide()})},S.$show=function(){S.$$postDigest(function(){y.show()})},S.$toggle=function(){S.$$postDigest(function(){y.toggle()})},y.$isShown=S.$isShown=!1;var k,x,T,C=angular.element('
');return C.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),D.then(function(e){k=e,y.init()}),y.init=function(){b.show&&S.$$postDigest(function(){y.show()})},y.destroy=function(){w(),C&&(C.remove(),C=null),S.$destroy()},y.show=function(){if(!y.$isShown){var e,t;if(angular.isElement(b.container)?(e=b.container,t=b.container[0].lastChild?angular.element(b.container[0].lastChild):null):b.container?(e=d(b.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=b.element),x&&w(),T=y.$scope.$new(),x=y.$element=k.link(T,function(e,t){}),!S.$emit(b.prefixEvent+'.show.before',y).defaultPrevented){x.css({display:'block'}).addClass(b.placement),b.animation&&(b.backdrop&&C.addClass(b.backdropAnimation),x.addClass(b.animation)),b.backdrop&&i.enter(C,g,null),angular.version.minor<=2?i.enter(x,e,t,n):i.enter(x,e,t).then(n),y.$isShown=S.$isShown=!0,c(S);var a=x[0];p(function(){a.focus()}),g.addClass(b.prefixClass+'-open'),b.animation&&g.addClass(b.prefixClass+'-with-'+b.animation),l(),m()}}},y.hide=function(){y.$isShown&&(S.$emit(b.prefixEvent+'.hide.before',y).defaultPrevented||(angular.version.minor<=2?i.leave(x,r):i.leave(x).then(r),b.backdrop&&i.leave(C),y.$isShown=S.$isShown=!1,c(S),u(),$()))},y.toggle=function(){y.$isShown?y.hide():y.show()},y.focus=function(){x[0].focus()},y.$onKeyUp=function(e){27===e.which&&y.$isShown&&(y.hide(),e.stopPropagation())},y}function c(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function d(e,n){return angular.element((n||t).querySelectorAll(e))}var f=angular.forEach,p=(String.prototype.trim,n.requestAnimationFrame||n.setTimeout),g=angular.element(n.document.body);return u}]}).directive('bsModal',['$window','$sce','$bsModal',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','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation','backdropAnimation','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.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.helpers.parseOptions',[]).provider('$bsParseOptions',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 angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('bsDimensions',['$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.debounce',[]).factory('bsDebounce',['$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('bsThrottle',['$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.dateParser',[]).provider('$bsDateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;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;t=1*e&&2===e.length?this.setFullYear(2e3+1*e):this.setFullYear(1*e)}};return m.init=function(){m.$format=e.DATETIME_FORMATS[g.format]||g.format,f=d(m.$format),p=u(m.$format)},m.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):f.test(e)},m.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||m.$format,i));var r=o?d(o):f,l=o?u(o):p,c=r.exec(n);if(!c)return!1;for(var g=a&&!isNaN(a.getTime())?(new t).fromDate(a):(new t).fromDate(new Date(1970,0,1,0)),$=0;$12?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.dateFormatter',[]).service('$bsDateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$bsDropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$bsTooltip','$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),d=u.$scope=c.scope&&c.scope.$new()||n.$new();u=a(t,c);var f=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&&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 void(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(){!d&&t.attr('readonly')||t.attr('disabled')||(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=/(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','$bsDateFormatter','$bsDateParser','$bsDatepicker',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};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(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)});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});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())}),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)})}),angular.isDefined(n.dateFormat)&&n.$observe('dateFormat',function(e){p.$options.dateFormat=e}),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?NaN:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):'unix'===d.dateType?new Date(1e3*e):new Date(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('bsDatepickerViews',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=['$bsDateFormatter','$bsDateParser','$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.collapse',[]).provider('$bsCollapse',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;n=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 S=0;S<1*f.offsetParent-1;S++)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,'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'))),o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')))},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',['$bsAffix','$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',['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'])}(window,document); \ No newline at end of file +!function(e,t,n){'use strict';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;if(angular.forEach(d,function(e,t){angular.isString(e)?d[t]=a.get(e):d[t]=a.invoke(e)}),angular.extend(d,f),r)d.$template=e.when(r);else{if(!n)throw new Error('Missing `template` / `templateUrl` option.');d.$template=l(n)}return t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$bsTypeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$bsTooltip','$$rAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex0?void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1)):(e.length>c&&(e=e.slice(0,c)),g.update(e),void 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})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$bsTooltip',function(){var e=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',templateUrl:'tooltip/tooltip.tpl.html',template:'',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','$bsCompiler','$q','$templateCache','$http','$animate','$sce','bsDimensions','$$rAF','$timeout',function(n,a,o,i,r,s,l,u,c,d,f){function p(i,r){function s(){P.$emit(V.prefixEvent+'.show',F)}function p(){if(P.$emit(V.prefixEvent+'.hide',F),R===j){if(z&&'focus'===V.trigger)return i[0].blur();A()}}function v(){var e=V.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',F.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',F.enter),i.on('hover'===e?'mouseleave':'blur',F.leave),'button'===I&&'hover'!==e&&i.on($?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function w(){for(var e=V.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',F.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',F.enter),i.off('hover'===n?'mouseleave':'blur',F.leave),'button'===I&&'hover'!==n&&i.off($?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function b(){'focus'!==V.trigger?R.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function y(){'focus'!==V.trigger?R.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function D(){f(function(){R.on('click',k),h.on('click',F.hide),K=!0},0,!1)}function S(){K&&(R.off('click',k),h.off('click',F.hide),K=!1)}function k(e){e.stopPropagation()}function x(e){e=e||V.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 T(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 C(e,t){var n=R[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){R.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=M(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';E(f,n[p],d)}}}function M(e,t,n,a){var o={top:0,left:0};if(!F.$viewport)return o;var i=V.viewport&&V.viewport.padding||0,r=x(F.$viewport);if(/right|left/.test(e)){var s=t.top-i-r.scroll,l=t.top+i-r.scroll+a;sr.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;ur.right&&(o.left=r.left+r.width-c)}return o}function E(e,t,n){var a=m('.tooltip-arrow, .arrow',R[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(H),F.$isShown&&null!==R&&(V.autoClose&&S(),V.keyboard&&y()),q&&(q.$destroy(),q=null),R&&(R.remove(),R=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),O=F.$promise=o.compile(V),P=F.$scope=V.scope&&V.scope.$new()||a.$new(),I=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var N=V.delay.split(',').map(parseFloat);V.delay=N.length>1?{show:N[0],hide:N[1]}:N[0]}F.$id=V.id||i.attr('id')||'',V.title&&(P.title=u.trustAsHtml(V.title)),P.$setEnabled=function(e){P.$$postDigest(function(){F.setEnabled(e)})},P.$hide=function(){P.$$postDigest(function(){F.hide()})},P.$show=function(){P.$$postDigest(function(){F.show()})},P.$toggle=function(){P.$$postDigest(function(){F.toggle()})},F.$isShown=P.$isShown=!1;var H,L,U,R,Y,q;O.then(function(e){U=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?Y=i:angular.isElement(V.container)?Y=V.container:V.container&&(Y=m(V.container)),v(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&P.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),A(),P.$destroy()},F.enter=function(){return clearTimeout(H),L='in',V.delay&&V.delay.show?void(H=setTimeout(function(){'in'===L&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){P.$emit(V.prefixEvent+'.show.before',F);var e,t;V.container?(e=Y,t=Y[0].lastChild?angular.element(Y[0].lastChild):null):(e=null,t=i),R&&A(),q=F.$scope.$new(),R=F.$element=U.link(q,function(e,t){}),R.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&R.addClass(V.animation),V.type&&R.addClass(V.prefixClass+'-'+V.type),V.customClass&&R.addClass(V.customClass),t?t.after(R):e.prepend(R),F.$isShown=P.$isShown=!0,g(P),F.$applyPlacement(),angular.version.minor<=2?l.enter(R,e,t,s):l.enter(R,e,t).then(s),g(P),d(function(){R&&R.css({visibility:'visible'}),V.keyboard&&('focus'!==V.trigger&&F.focus(),b())}),V.autoClose&&D()}},F.leave=function(){return clearTimeout(H),L='out',V.delay&&V.delay.hide?void(H=setTimeout(function(){'out'===L&&F.hide()},V.delay.hide)):F.hide()};var z,j;F.hide=function(e){F.$isShown&&(P.$emit(V.prefixEvent+'.hide.before',F),z=e,j=R,angular.version.minor<=2?l.leave(R,p):l.leave(R).then(p),F.$isShown=P.$isShown=!1,g(P),V.keyboard&&null!==R&&y(),V.autoClose&&null!==R&&S())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){R[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(R){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),R.addClass(V.placement);var o=x(),i=R.prop('offsetWidth'),r=R.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);s.indexOf('bottom')>=0&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):s.indexOf('top')>=0&&o.top-rl.width?t='right'===s?'left':t.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&o.left-it?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||b),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();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,y.hour+e*g.length,y.minute,y.second),angular.extend(y,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,y.hour,y.minute+e*g.length*g.minuteStep,y.second),angular.extend(y,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,y.hour,y.minute,y.second+e*g.length*g.secondStep),angular.extend(y,{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 void f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,S).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,b=2===v&&!C||3===v&&C;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,S).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]):b&&(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(){!c&&t.attr('readonly')||t.attr('disabled')||(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=/(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','$bsDateFormatter','$bsDateParser','$bsTimepicker',function(e,t,a,o,i,r){var s=r.defaults,l=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.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,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)},h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),c(u.$dateValue)})}),e.$watch(a.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 a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):'unix'===f.timeType?new Date(1e3*e):new Date(e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$bsTab',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&&t',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$bsTooltip','$timeout',function(t,n,a,o,i){function r(a,r,s){var u={},c=angular.extend({},e,s);u=o(a,c);var d=u.$scope;d.$matches=[],c.multiple?d.$activeIndex=[]:d.$activeIndex=-1,d.$isMultiple=c.multiple,d.$showAllNoneButtons=c.allNoneButtons&&c.multiple,d.$iconCheckmark=c.iconCheckmark,d.$allText=c.allText,d.$noneText=c.noneText,d.$activate=function(e){d.$$postDigest(function(){u.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){u.select(e)})},d.$isVisible=function(){return u.$isVisible()},d.$isActive=function(e){return u.$isActive(e)},d.$selectAll=function(){for(var e=0;e=c.minLength:d.$matches.length},u.$isActive=function(e){return c.multiple?-1!==d.$activeIndex.indexOf(e):d.$activeIndex===e},u.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},u.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),c.multiple&&9===e.keyCode?u.hide():c.multiple||13!==e.keyCode&&9!==e.keyCode?void(c.multiple||(38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:38===e.keyCode&&d.$activeIndex<0?d.$activeIndex=d.$matches.length-1:40===e.keyCode&&d.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},u.$selectScrollFix=function(e){'UL'===n[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var f=u.show;u.show=function(){f(),c.multiple&&u.$element.addClass('select-multiple'),i(function(){u.$element.on(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.on('keydown',u.$onKeyDown)},0,!1)};var p=u.hide;return u.hide=function(){!c.multiple&&angular.isUndefined(r.$modelValue)&&(d.$activeIndex=-1),u.$element.off(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.off('keydown',u.$onKeyDown),p(!0)},u}var s=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),l='createTouch'in t.document&&s;return r.defaults=e,r}]}).directive('bsSelect',['$window','$parse','$q','$bsSelect','$bsParseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(l.test(u)?s.multiple=!1:s.multiple=u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element(''),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s);f.$isIE()&&t[0].addEventListener('blur',f.$selectScrollFix);var 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.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$bsScrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','bsDimensions','bsDebounce','bsThrottle',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,b,y,D,S,k,x={},T=x.$trackedElements=[],C=[];return x.init=function(){this.$$count=1,b=s(this.checkPosition,c.debounce),y=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',b),m.on('scroll',y),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',b),m.off('scroll',y),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(C.length){if(k=(g?a.pageYOffset:m.prop('scrollTop'))||0,S=Math.max(a.innerHeight,f.prop('clientHeight')),kC[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}),b()},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','bsDebounce','bsDimensions','$bsScrollspy',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','bsDebounce','bsDimensions','$bsScrollspy',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.popover',['mgcrea.ngStrap.tooltip']).provider('$bsPopover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$bsTooltip',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','$bsPopover',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','templateUrl','controller','controllerAs','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)&&(s.test(l)?r.target=!1:r.target=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.navbar',[]).provider('$bsNavbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$bsNavbar',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.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$bsModal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$bsCompiler','$animate','$timeout','$sce','bsDimensions',function(n,a,o,i,r,s,l){function u(t){function n(){S.$emit(y.prefixEvent+'.show',b)}function r(){S.$emit(y.prefixEvent+'.hide',b),g.removeClass(y.prefixClass+'-open'),y.animation&&g.removeClass(y.prefixClass+'-with-'+y.animation)}function l(){y.backdrop&&(x.on('click',h),C.on('click',h),C.on('wheel',v))}function u(){y.backdrop&&(x.off('click',h),C.off('click',h),C.off('wheel',v))}function m(){y.keyboard&&x.on('keyup',b.$onKeyUp)}function $(){y.keyboard&&x.off('keyup',b.$onKeyUp)}function h(e){e.target===e.currentTarget&&('static'===y.backdrop?b.focus():b.hide())}function v(e){e.preventDefault()}function w(){b.$isShown&&null!==x&&(u(),$()),T&&(T.$destroy(),T=null),x&&(x.remove(),x=b.$element=null)}var b={},y=b.$options=angular.extend({},e,t),D=b.$promise=o.compile(y),S=b.$scope=y.scope&&y.scope.$new()||a.$new();y.element||y.container||(y.container='body'),b.$id=y.id||y.element&&y.element.attr('id')||'',f(['title','content'],function(e){y[e]&&(S[e]=s.trustAsHtml(y[e]))}),S.$hide=function(){S.$$postDigest(function(){b.hide()})},S.$show=function(){S.$$postDigest(function(){b.show()})},S.$toggle=function(){S.$$postDigest(function(){b.toggle()})},b.$isShown=S.$isShown=!1;var k,x,T,C=angular.element('
');return C.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),D.then(function(e){k=e,b.init()}),b.init=function(){y.show&&S.$$postDigest(function(){b.show()})},b.destroy=function(){w(),C&&(C.remove(),C=null),S.$destroy()},b.show=function(){if(!b.$isShown){var e,t;if(angular.isElement(y.container)?(e=y.container,t=y.container[0].lastChild?angular.element(y.container[0].lastChild):null):y.container?(e=d(y.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=y.element),x&&w(),T=b.$scope.$new(),x=b.$element=k.link(T,function(e,t){}),!S.$emit(y.prefixEvent+'.show.before',b).defaultPrevented){x.css({display:'block'}).addClass(y.placement),y.animation&&(y.backdrop&&C.addClass(y.backdropAnimation),x.addClass(y.animation)),y.backdrop&&i.enter(C,g,null),angular.version.minor<=2?i.enter(x,e,t,n):i.enter(x,e,t).then(n),b.$isShown=S.$isShown=!0,c(S);var a=x[0];p(function(){a.focus()}),g.addClass(y.prefixClass+'-open'),y.animation&&g.addClass(y.prefixClass+'-with-'+y.animation),l(),m()}}},b.hide=function(){b.$isShown&&(S.$emit(y.prefixEvent+'.hide.before',b).defaultPrevented||(angular.version.minor<=2?i.leave(x,r):i.leave(x).then(r),y.backdrop&&i.leave(C),b.$isShown=S.$isShown=!1,c(S),u(),$()))},b.toggle=function(){b.$isShown?b.hide():b.show()},b.focus=function(){x[0].focus()},b.$onKeyUp=function(e){27===e.which&&b.$isShown&&(b.hide(),e.stopPropagation())},b}function c(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function d(e,n){return angular.element((n||t).querySelectorAll(e))}var f=angular.forEach,p=(String.prototype.trim,n.requestAnimationFrame||n.setTimeout),g=angular.element(n.document.body);return u}]}).directive('bsModal',['$window','$sce','$bsModal',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','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation','backdropAnimation','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.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.helpers.parseOptions',[]).provider('$bsParseOptions',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 angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('bsDimensions',['$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.debounce',[]).factory('bsDebounce',['$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('bsThrottle',['$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.dateParser',[]).provider('$bsDateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;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;t=1*e&&2===e.length?this.setFullYear(2e3+1*e):this.setFullYear(1*e)}};return m.init=function(){m.$format=e.DATETIME_FORMATS[g.format]||g.format,f=d(m.$format),p=u(m.$format)},m.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):f.test(e)},m.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||m.$format,i));var r=o?d(o):f,l=o?u(o):p,c=r.exec(n);if(!c)return!1;for(var g=a&&!isNaN(a.getTime())?(new t).fromDate(a):(new t).fromDate(new Date(1970,0,1,0)),$=0;$12?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.dateFormatter',[]).service('$bsDateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$bsDropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$bsTooltip','$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&&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 void(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 b=u.show;u.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(b(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1))};var y=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),y(e))},u}var c=/(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','$bsDateFormatter','$bsDateParser','$bsDatepicker',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};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(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)});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});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())}),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)})}),angular.isDefined(n.dateFormat)&&n.$observe('dateFormat',function(e){p.$options.dateFormat=e}),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?NaN:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):'unix'===d.dateType?new Date(1e3*e):new Date(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('bsDatepickerViews',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=['$bsDateFormatter','$bsDateParser','$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.collapse',[]).provider('$bsCollapse',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;n=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,b=null,y=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var S=0;S<1*f.offsetParent-1;S++)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(y,t,n);b!==r&&(b=r,'top'===r?(y=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(y=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'))):(y=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))),o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')))},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',['$bsAffix','$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',['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'])}(window,document); \ No newline at end of file diff --git a/dist/angular-strap.js b/dist/angular-strap.js index a406dc82d..88d922bc9 100644 --- a/dist/angular-strap.js +++ b/dist/angular-strap.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -1359,179 +1359,6 @@ } }; } ]); - angular.module('mgcrea.ngStrap.scrollspy', [ 'mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$scrollspy', function() { - var spies = this.$$spies = {}; - var defaults = this.defaults = { - debounce: 150, - throttle: 100, - offset: 100 - }; - this.$get = [ '$window', '$document', '$rootScope', 'dimensions', 'debounce', 'throttle', function($window, $document, $rootScope, dimensions, debounce, throttle) { - var windowEl = angular.element($window); - var docEl = angular.element($document.prop('documentElement')); - var bodyEl = angular.element($window.document.body); - function nodeName(element, name) { - return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase(); - } - function ScrollSpyFactory(config) { - var options = angular.extend({}, defaults, config); - if (!options.element) options.element = bodyEl; - var isWindowSpy = nodeName(options.element, 'body'); - var scrollEl = isWindowSpy ? windowEl : options.element; - var scrollId = isWindowSpy ? 'window' : options.id; - if (spies[scrollId]) { - spies[scrollId].$$count++; - return spies[scrollId]; - } - var $scrollspy = {}; - var unbindViewContentLoaded, unbindIncludeContentLoaded; - var trackedElements = $scrollspy.$trackedElements = []; - var sortedElements = []; - var activeTarget; - var debouncedCheckPosition; - var throttledCheckPosition; - var debouncedCheckOffsets; - var viewportHeight; - var scrollTop; - $scrollspy.init = function() { - this.$$count = 1; - debouncedCheckPosition = debounce(this.checkPosition, options.debounce); - throttledCheckPosition = throttle(this.checkPosition, options.throttle); - scrollEl.on('click', this.checkPositionWithEventLoop); - windowEl.on('resize', debouncedCheckPosition); - scrollEl.on('scroll', throttledCheckPosition); - debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce); - unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets); - unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets); - debouncedCheckOffsets(); - if (scrollId) { - spies[scrollId] = $scrollspy; - } - }; - $scrollspy.destroy = function() { - this.$$count--; - if (this.$$count > 0) { - return; - } - scrollEl.off('click', this.checkPositionWithEventLoop); - windowEl.off('resize', debouncedCheckPosition); - scrollEl.off('scroll', throttledCheckPosition); - unbindViewContentLoaded(); - unbindIncludeContentLoaded(); - if (scrollId) { - delete spies[scrollId]; - } - }; - $scrollspy.checkPosition = function() { - if (!sortedElements.length) return; - scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0; - viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight')); - if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) { - return $scrollspy.$activateElement(sortedElements[0]); - } - for (var i = sortedElements.length; i--; ) { - if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue; - if (activeTarget === sortedElements[i].target) continue; - if (scrollTop < sortedElements[i].offsetTop) continue; - if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue; - return $scrollspy.$activateElement(sortedElements[i]); - } - }; - $scrollspy.checkPositionWithEventLoop = function() { - setTimeout($scrollspy.checkPosition, 1); - }; - $scrollspy.$activateElement = function(element) { - if (activeTarget) { - var activeElement = $scrollspy.$getTrackedElement(activeTarget); - if (activeElement) { - activeElement.source.removeClass('active'); - if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) { - activeElement.source.parent().parent().removeClass('active'); - } - } - } - activeTarget = element.target; - element.source.addClass('active'); - if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) { - element.source.parent().parent().addClass('active'); - } - }; - $scrollspy.$getTrackedElement = function(target) { - return trackedElements.filter(function(obj) { - return obj.target === target; - })[0]; - }; - $scrollspy.checkOffsets = function() { - angular.forEach(trackedElements, function(trackedElement) { - var targetElement = document.querySelector(trackedElement.target); - trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null; - if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1; - }); - sortedElements = trackedElements.filter(function(el) { - return el.offsetTop !== null; - }).sort(function(a, b) { - return a.offsetTop - b.offsetTop; - }); - debouncedCheckPosition(); - }; - $scrollspy.trackElement = function(target, source) { - trackedElements.push({ - target: target, - source: source - }); - }; - $scrollspy.untrackElement = function(target, source) { - var toDelete; - for (var i = trackedElements.length; i--; ) { - if (trackedElements[i].target === target && trackedElements[i].source === source) { - toDelete = i; - break; - } - } - trackedElements = trackedElements.splice(toDelete, 1); - }; - $scrollspy.activate = function(i) { - trackedElements[i].addClass('active'); - }; - $scrollspy.init(); - return $scrollspy; - } - return ScrollSpyFactory; - } ]; - }).directive('bsScrollspy', [ '$rootScope', 'debounce', 'dimensions', '$scrollspy', function($rootScope, debounce, dimensions, $scrollspy) { - return { - restrict: 'EAC', - link: function postLink(scope, element, attr) { - var options = { - scope: scope - }; - angular.forEach([ 'offset', 'target' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var scrollspy = $scrollspy(options); - scrollspy.trackElement(options.target, element); - scope.$on('$destroy', function() { - if (scrollspy) { - scrollspy.untrackElement(options.target, element); - scrollspy.destroy(); - } - options = null; - scrollspy = null; - }); - } - }; - } ]).directive('bsScrollspyList', [ '$rootScope', 'debounce', 'dimensions', '$scrollspy', function($rootScope, debounce, dimensions, $scrollspy) { - return { - restrict: 'A', - compile: function postLink(element, attr) { - var children = element[0].querySelectorAll('li > a[href]'); - angular.forEach(children, function(child) { - var childEl = angular.element(child); - childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href')); - }); - } - }; - } ]); angular.module('mgcrea.ngStrap.select', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions' ]).provider('$select', function() { var defaults = this.defaults = { animation: 'am-fade', @@ -1816,6 +1643,179 @@ } }; } ]); + angular.module('mgcrea.ngStrap.scrollspy', [ 'mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$scrollspy', function() { + var spies = this.$$spies = {}; + var defaults = this.defaults = { + debounce: 150, + throttle: 100, + offset: 100 + }; + this.$get = [ '$window', '$document', '$rootScope', 'dimensions', 'debounce', 'throttle', function($window, $document, $rootScope, dimensions, debounce, throttle) { + var windowEl = angular.element($window); + var docEl = angular.element($document.prop('documentElement')); + var bodyEl = angular.element($window.document.body); + function nodeName(element, name) { + return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase(); + } + function ScrollSpyFactory(config) { + var options = angular.extend({}, defaults, config); + if (!options.element) options.element = bodyEl; + var isWindowSpy = nodeName(options.element, 'body'); + var scrollEl = isWindowSpy ? windowEl : options.element; + var scrollId = isWindowSpy ? 'window' : options.id; + if (spies[scrollId]) { + spies[scrollId].$$count++; + return spies[scrollId]; + } + var $scrollspy = {}; + var unbindViewContentLoaded, unbindIncludeContentLoaded; + var trackedElements = $scrollspy.$trackedElements = []; + var sortedElements = []; + var activeTarget; + var debouncedCheckPosition; + var throttledCheckPosition; + var debouncedCheckOffsets; + var viewportHeight; + var scrollTop; + $scrollspy.init = function() { + this.$$count = 1; + debouncedCheckPosition = debounce(this.checkPosition, options.debounce); + throttledCheckPosition = throttle(this.checkPosition, options.throttle); + scrollEl.on('click', this.checkPositionWithEventLoop); + windowEl.on('resize', debouncedCheckPosition); + scrollEl.on('scroll', throttledCheckPosition); + debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce); + unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets); + unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets); + debouncedCheckOffsets(); + if (scrollId) { + spies[scrollId] = $scrollspy; + } + }; + $scrollspy.destroy = function() { + this.$$count--; + if (this.$$count > 0) { + return; + } + scrollEl.off('click', this.checkPositionWithEventLoop); + windowEl.off('resize', debouncedCheckPosition); + scrollEl.off('scroll', throttledCheckPosition); + unbindViewContentLoaded(); + unbindIncludeContentLoaded(); + if (scrollId) { + delete spies[scrollId]; + } + }; + $scrollspy.checkPosition = function() { + if (!sortedElements.length) return; + scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0; + viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight')); + if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) { + return $scrollspy.$activateElement(sortedElements[0]); + } + for (var i = sortedElements.length; i--; ) { + if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue; + if (activeTarget === sortedElements[i].target) continue; + if (scrollTop < sortedElements[i].offsetTop) continue; + if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue; + return $scrollspy.$activateElement(sortedElements[i]); + } + }; + $scrollspy.checkPositionWithEventLoop = function() { + setTimeout($scrollspy.checkPosition, 1); + }; + $scrollspy.$activateElement = function(element) { + if (activeTarget) { + var activeElement = $scrollspy.$getTrackedElement(activeTarget); + if (activeElement) { + activeElement.source.removeClass('active'); + if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) { + activeElement.source.parent().parent().removeClass('active'); + } + } + } + activeTarget = element.target; + element.source.addClass('active'); + if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) { + element.source.parent().parent().addClass('active'); + } + }; + $scrollspy.$getTrackedElement = function(target) { + return trackedElements.filter(function(obj) { + return obj.target === target; + })[0]; + }; + $scrollspy.checkOffsets = function() { + angular.forEach(trackedElements, function(trackedElement) { + var targetElement = document.querySelector(trackedElement.target); + trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null; + if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1; + }); + sortedElements = trackedElements.filter(function(el) { + return el.offsetTop !== null; + }).sort(function(a, b) { + return a.offsetTop - b.offsetTop; + }); + debouncedCheckPosition(); + }; + $scrollspy.trackElement = function(target, source) { + trackedElements.push({ + target: target, + source: source + }); + }; + $scrollspy.untrackElement = function(target, source) { + var toDelete; + for (var i = trackedElements.length; i--; ) { + if (trackedElements[i].target === target && trackedElements[i].source === source) { + toDelete = i; + break; + } + } + trackedElements = trackedElements.splice(toDelete, 1); + }; + $scrollspy.activate = function(i) { + trackedElements[i].addClass('active'); + }; + $scrollspy.init(); + return $scrollspy; + } + return ScrollSpyFactory; + } ]; + }).directive('bsScrollspy', [ '$rootScope', 'debounce', 'dimensions', '$scrollspy', function($rootScope, debounce, dimensions, $scrollspy) { + return { + restrict: 'EAC', + link: function postLink(scope, element, attr) { + var options = { + scope: scope + }; + angular.forEach([ 'offset', 'target' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var scrollspy = $scrollspy(options); + scrollspy.trackElement(options.target, element); + scope.$on('$destroy', function() { + if (scrollspy) { + scrollspy.untrackElement(options.target, element); + scrollspy.destroy(); + } + options = null; + scrollspy = null; + }); + } + }; + } ]).directive('bsScrollspyList', [ '$rootScope', 'debounce', 'dimensions', '$scrollspy', function($rootScope, debounce, dimensions, $scrollspy) { + return { + restrict: 'A', + compile: function postLink(element, attr) { + var children = element[0].querySelectorAll('li > a[href]'); + angular.forEach(children, function(child) { + var childEl = angular.element(child); + childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href')); + }); + } + }; + } ]); angular.module('mgcrea.ngStrap.popover', [ 'mgcrea.ngStrap.tooltip' ]).provider('$popover', function() { var defaults = this.defaults = { animation: 'am-fade', @@ -2729,10 +2729,12 @@ } }); angular.extend(resolve, locals); - if (templateUrl) { + if (template) { + resolve.$template = $q.when(template); + } else if (templateUrl) { resolve.$template = fetchTemplate(templateUrl); } else { - resolve.$template = $q.when(template); + throw new Error('Missing `template` / `templateUrl` option.'); } if (options.contentTemplate) { resolve.$template = $q.all([ resolve.$template, fetchTemplate(options.contentTemplate) ]).then(function(templates) { @@ -2822,7 +2824,6 @@ }; var show = $dropdown.show; $dropdown.show = function() { - if (!scope.content) return; show(); $timeout(function() { options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown); @@ -2855,31 +2856,43 @@ return { restrict: 'EAC', scope: true, - link: function postLink(scope, element, attr, transclusion) { - var options = { - scope: scope + compile: function(tElement, tAttrs) { + var options = {}; + if (!tAttrs.bsDropdown) { + var nextSibling = tElement[0].nextSibling; + while (nextSibling && nextSibling.nodeType !== 1) { + nextSibling = nextSibling.nextSibling; + } + if (nextSibling.classList.contains('dropdown-menu')) { + options.template = nextSibling.outerHTML; + options.templateUrl = undefined; + nextSibling.parentNode.removeChild(nextSibling); + } + } + return function postLink(scope, element, attr) { + options.scope = scope; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id' ], function(key) { + if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) { + scope.content = newValue; + }, true); + attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!dropdown || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i); + newValue === true ? dropdown.show() : dropdown.hide(); + }); + var dropdown = $dropdown(element, options); + scope.$on('$destroy', function() { + if (dropdown) dropdown.destroy(); + options = null; + dropdown = null; + }); }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'html', 'container' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; - }); - attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) { - scope.content = newValue; - }, true); - attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { - if (!dropdown || !angular.isDefined(newValue)) return; - if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i); - newValue === true ? dropdown.show() : dropdown.hide(); - }); - var dropdown = $dropdown(element, options); - scope.$on('$destroy', function() { - if (dropdown) dropdown.destroy(); - options = null; - dropdown = null; - }); } }; } ]); diff --git a/dist/angular-strap.min.js b/dist/angular-strap.min.js index ff2258cd1..b2152425d 100644 --- a/dist/angular-strap.min.js +++ b/dist/angular-strap.min.js @@ -1,11 +1,11 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;return angular.forEach(d,function(e,t){angular.isString(e)?d[t]=a.get(e):d[t]=a.invoke(e)}),angular.extend(d,f),n?d.$template=l(n):d.$template=e.when(r),t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}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',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$tooltip','$$rAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex0?void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1)):(e.length>c&&(e=e.slice(0,c)),g.update(e),void 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})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','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',templateUrl:'tooltip/tooltip.tpl.html',template:'',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','$bsCompiler','$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(){I.$emit(V.prefixEvent+'.show',F)}function p(){if(I.$emit(V.prefixEvent+'.hide',F),R===j){if(z&&'focus'===V.trigger)return i[0].blur();A()}}function v(){var e=V.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',F.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',F.enter),i.on('hover'===e?'mouseleave':'blur',F.leave),'button'===N&&'hover'!==e&&i.on($?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function w(){for(var e=V.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',F.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',F.enter),i.off('hover'===n?'mouseleave':'blur',F.leave),'button'===N&&'hover'!==n&&i.off($?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function y(){'focus'!==V.trigger?R.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function b(){'focus'!==V.trigger?R.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function D(){f(function(){R.on('click',S),h.on('click',F.hide),K=!0},0,!1)}function k(){K&&(R.off('click',S),h.off('click',F.hide),K=!1)}function S(e){e.stopPropagation()}function x(e){e=e||V.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 T(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 C(e,t){var n=R[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){R.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=E(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';M(f,n[p],d)}}}function E(e,t,n,a){var o={top:0,left:0};if(!F.$viewport)return o;var i=V.viewport&&V.viewport.padding||0,r=x(F.$viewport);if(/right|left/.test(e)){var s=t.top-i-r.scroll,l=t.top+i-r.scroll+a;sr.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;ur.right&&(o.left=r.left+r.width-c)}return o}function M(e,t,n){var a=m('.tooltip-arrow, .arrow',R[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(H),F.$isShown&&null!==R&&(V.autoClose&&k(),V.keyboard&&b()),q&&(q.$destroy(),q=null),R&&(R.remove(),R=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),O=F.$promise=o.compile(V),I=F.$scope=V.scope&&V.scope.$new()||a.$new(),N=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var P=V.delay.split(',').map(parseFloat);V.delay=P.length>1?{show:P[0],hide:P[1]}:P[0]}F.$id=V.id||i.attr('id')||'',V.title&&(I.title=u.trustAsHtml(V.title)),I.$setEnabled=function(e){I.$$postDigest(function(){F.setEnabled(e)})},I.$hide=function(){I.$$postDigest(function(){F.hide()})},I.$show=function(){I.$$postDigest(function(){F.show()})},I.$toggle=function(){I.$$postDigest(function(){F.toggle()})},F.$isShown=I.$isShown=!1;var H,L,U,R,Y,q;O.then(function(e){U=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?Y=i:angular.isElement(V.container)?Y=V.container:V.container&&(Y=m(V.container)),v(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&I.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),A(),I.$destroy()},F.enter=function(){return clearTimeout(H),L='in',V.delay&&V.delay.show?void(H=setTimeout(function(){'in'===L&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){I.$emit(V.prefixEvent+'.show.before',F);var e,t;V.container?(e=Y,t=Y[0].lastChild?angular.element(Y[0].lastChild):null):(e=null,t=i),R&&A(),q=F.$scope.$new(),R=F.$element=U.link(q,function(e,t){}),R.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&R.addClass(V.animation),V.type&&R.addClass(V.prefixClass+'-'+V.type),V.customClass&&R.addClass(V.customClass),t?t.after(R):e.prepend(R),F.$isShown=I.$isShown=!0,g(I),F.$applyPlacement(),angular.version.minor<=2?l.enter(R,e,t,s):l.enter(R,e,t).then(s),g(I),d(function(){R&&R.css({visibility:'visible'}),V.keyboard&&('focus'!==V.trigger&&F.focus(),y())}),V.autoClose&&D()}},F.leave=function(){return clearTimeout(H),L='out',V.delay&&V.delay.hide?void(H=setTimeout(function(){'out'===L&&F.hide()},V.delay.hide)):F.hide()};var z,j;F.hide=function(e){F.$isShown&&(I.$emit(V.prefixEvent+'.hide.before',F),z=e,j=R,angular.version.minor<=2?l.leave(R,p):l.leave(R).then(p),F.$isShown=I.$isShown=!1,g(I),V.keyboard&&null!==R&&b(),V.autoClose&&null!==R&&k())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){R[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(R){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),R.addClass(V.placement);var o=x(),i=R.prop('offsetWidth'),r=R.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);s.indexOf('bottom')>=0&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):s.indexOf('top')>=0&&o.top-rl.width?t='right'===s?'left':t.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&o.left-it?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||y),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();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 void 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*E;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 M=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 M())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(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=/(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,a,o,i,r){var s=r.defaults,l=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.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,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)},h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),c(u.$dateValue)})}),e.$watch(a.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 a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):'unix'===f.timeType?new Date(1e3*e):new Date(e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=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&&t0||(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',templateUrl:'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(a,r,s){var u={},c=angular.extend({},e,s);u=o(a,c);var d=u.$scope;d.$matches=[],c.multiple?d.$activeIndex=[]:d.$activeIndex=-1,d.$isMultiple=c.multiple,d.$showAllNoneButtons=c.allNoneButtons&&c.multiple,d.$iconCheckmark=c.iconCheckmark,d.$allText=c.allText,d.$noneText=c.noneText,d.$activate=function(e){d.$$postDigest(function(){u.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){u.select(e)})},d.$isVisible=function(){return u.$isVisible()},d.$isActive=function(e){return u.$isActive(e)},d.$selectAll=function(){for(var e=0;e=c.minLength:d.$matches.length},u.$isActive=function(e){return c.multiple?-1!==d.$activeIndex.indexOf(e):d.$activeIndex===e},u.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},u.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),c.multiple&&9===e.keyCode?u.hide():c.multiple||13!==e.keyCode&&9!==e.keyCode?void(c.multiple||(38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:38===e.keyCode&&d.$activeIndex<0?d.$activeIndex=d.$matches.length-1:40===e.keyCode&&d.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},u.$selectScrollFix=function(e){'UL'===n[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var f=u.show;u.show=function(){f(),c.multiple&&u.$element.addClass('select-multiple'),i(function(){u.$element.on(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.on('keydown',u.$onKeyDown)},0,!1)};var p=u.hide;return u.hide=function(){!c.multiple&&angular.isUndefined(r.$modelValue)&&(d.$activeIndex=-1),u.$element.off(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.off('keydown',u.$onKeyDown),p(!0)},u}var s=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),l='createTouch'in t.document&&s;return r.defaults=e,r}]}).directive('bsSelect',['$window','$parse','$q','$select','$parseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(l.test(u)?s.multiple=!1:s.multiple=u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element(''),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s);f.$isIE()&&t[0].addEventListener('blur',f.$selectScrollFix);var 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.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'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','templateUrl','controller','controllerAs','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)&&(s.test(l)?r.target=!1:r.target=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.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.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$bsCompiler','$animate','$timeout','$sce','dimensions',function(n,a,o,i,r,s,l){function u(t){function n(){k.$emit(b.prefixEvent+'.show',y)}function r(){k.$emit(b.prefixEvent+'.hide',y),g.removeClass(b.prefixClass+'-open'),b.animation&&g.removeClass(b.prefixClass+'-with-'+b.animation)}function l(){b.backdrop&&(x.on('click',h),C.on('click',h),C.on('wheel',v))}function u(){b.backdrop&&(x.off('click',h),C.off('click',h),C.off('wheel',v))}function m(){b.keyboard&&x.on('keyup',y.$onKeyUp)}function $(){b.keyboard&&x.off('keyup',y.$onKeyUp)}function h(e){e.target===e.currentTarget&&('static'===b.backdrop?y.focus():y.hide())}function v(e){e.preventDefault()}function w(){y.$isShown&&null!==x&&(u(),$()),T&&(T.$destroy(),T=null),x&&(x.remove(),x=y.$element=null)}var y={},b=y.$options=angular.extend({},e,t),D=y.$promise=o.compile(b),k=y.$scope=b.scope&&b.scope.$new()||a.$new();b.element||b.container||(b.container='body'),y.$id=b.id||b.element&&b.element.attr('id')||'',f(['title','content'],function(e){b[e]&&(k[e]=s.trustAsHtml(b[e]))}),k.$hide=function(){k.$$postDigest(function(){y.hide()})},k.$show=function(){k.$$postDigest(function(){y.show()})},k.$toggle=function(){k.$$postDigest(function(){y.toggle()})},y.$isShown=k.$isShown=!1;var S,x,T,C=angular.element('
');return C.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),D.then(function(e){S=e,y.init()}),y.init=function(){b.show&&k.$$postDigest(function(){y.show()})},y.destroy=function(){w(),C&&(C.remove(),C=null),k.$destroy()},y.show=function(){if(!y.$isShown){var e,t;if(angular.isElement(b.container)?(e=b.container,t=b.container[0].lastChild?angular.element(b.container[0].lastChild):null):b.container?(e=d(b.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=b.element),x&&w(),T=y.$scope.$new(),x=y.$element=S.link(T,function(e,t){}),!k.$emit(b.prefixEvent+'.show.before',y).defaultPrevented){x.css({display:'block'}).addClass(b.placement),b.animation&&(b.backdrop&&C.addClass(b.backdropAnimation),x.addClass(b.animation)),b.backdrop&&i.enter(C,g,null),angular.version.minor<=2?i.enter(x,e,t,n):i.enter(x,e,t).then(n),y.$isShown=k.$isShown=!0,c(k);var a=x[0];p(function(){a.focus()}),g.addClass(b.prefixClass+'-open'),b.animation&&g.addClass(b.prefixClass+'-with-'+b.animation),l(),m()}}},y.hide=function(){y.$isShown&&(k.$emit(b.prefixEvent+'.hide.before',y).defaultPrevented||(angular.version.minor<=2?i.leave(x,r):i.leave(x).then(r),b.backdrop&&i.leave(C),y.$isShown=k.$isShown=!1,c(k),u(),$()))},y.toggle=function(){y.$isShown?y.hide():y.show()},y.focus=function(){x[0].focus()},y.$onKeyUp=function(e){27===e.which&&y.$isShown&&(y.hide(),e.stopPropagation())},y}function c(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function d(e,n){return angular.element((n||t).querySelectorAll(e))}var f=angular.forEach,p=(String.prototype.trim,n.requestAnimationFrame||n.setTimeout),g=angular.element(n.document.body);return u}]}).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','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation','backdropAnimation','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.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.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 angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),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.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.dateParser',[]).provider('$dateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;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;t=1*e&&2===e.length?this.setFullYear(2e3+1*e):this.setFullYear(1*e)}};return m.init=function(){m.$format=e.DATETIME_FORMATS[g.format]||g.format,f=d(m.$format),p=u(m.$format)},m.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):f.test(e)},m.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||m.$format,i));var r=o?d(o):f,l=o?u(o):p,c=r.exec(n);if(!c)return!1;for(var g=a&&!isNaN(a.getTime())?(new t).fromDate(a):(new t).fromDate(new Date(1970,0,1,0)),$=0;$12?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.dateFormatter',[]).service('$dateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],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',templateUrl:'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),d=u.$scope=c.scope&&c.scope.$new()||n.$new();u=a(t,c);var f=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&&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 void(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(){!d&&t.attr('readonly')||t.attr('disabled')||(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=/(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};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(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)});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});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())}),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)})}),angular.isDefined(n.dateFormat)&&n.$observe('dateFormat',function(e){p.$options.dateFormat=e}),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?NaN:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):'unix'===d.dateType?new Date(1e3*e):new Date(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.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;n=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,'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'))),o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')))},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',['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'])}(window,document); +!function(e,t,n){'use strict';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;if(angular.forEach(d,function(e,t){angular.isString(e)?d[t]=a.get(e):d[t]=a.invoke(e)}),angular.extend(d,f),r)d.$template=e.when(r);else{if(!n)throw new Error('Missing `template` / `templateUrl` option.');d.$template=l(n)}return t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}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',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$tooltip','$$rAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex0?void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1)):(e.length>c&&(e=e.slice(0,c)),g.update(e),void 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})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','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',templateUrl:'tooltip/tooltip.tpl.html',template:'',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','$bsCompiler','$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(){I.$emit(V.prefixEvent+'.show',F)}function p(){if(I.$emit(V.prefixEvent+'.hide',F),R===j){if(z&&'focus'===V.trigger)return i[0].blur();A()}}function v(){var e=V.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',F.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',F.enter),i.on('hover'===e?'mouseleave':'blur',F.leave),'button'===N&&'hover'!==e&&i.on($?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function w(){for(var e=V.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',F.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',F.enter),i.off('hover'===n?'mouseleave':'blur',F.leave),'button'===N&&'hover'!==n&&i.off($?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function y(){'focus'!==V.trigger?R.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function b(){'focus'!==V.trigger?R.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function D(){f(function(){R.on('click',S),h.on('click',F.hide),K=!0},0,!1)}function k(){K&&(R.off('click',S),h.off('click',F.hide),K=!1)}function S(e){e.stopPropagation()}function x(e){e=e||V.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 T(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 C(e,t){var n=R[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){R.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=E(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';M(f,n[p],d)}}}function E(e,t,n,a){var o={top:0,left:0};if(!F.$viewport)return o;var i=V.viewport&&V.viewport.padding||0,r=x(F.$viewport);if(/right|left/.test(e)){var s=t.top-i-r.scroll,l=t.top+i-r.scroll+a;sr.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;ur.right&&(o.left=r.left+r.width-c)}return o}function M(e,t,n){var a=m('.tooltip-arrow, .arrow',R[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(H),F.$isShown&&null!==R&&(V.autoClose&&k(),V.keyboard&&b()),q&&(q.$destroy(),q=null),R&&(R.remove(),R=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),O=F.$promise=o.compile(V),I=F.$scope=V.scope&&V.scope.$new()||a.$new(),N=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var P=V.delay.split(',').map(parseFloat);V.delay=P.length>1?{show:P[0],hide:P[1]}:P[0]}F.$id=V.id||i.attr('id')||'',V.title&&(I.title=u.trustAsHtml(V.title)),I.$setEnabled=function(e){I.$$postDigest(function(){F.setEnabled(e)})},I.$hide=function(){I.$$postDigest(function(){F.hide()})},I.$show=function(){I.$$postDigest(function(){F.show()})},I.$toggle=function(){I.$$postDigest(function(){F.toggle()})},F.$isShown=I.$isShown=!1;var H,L,U,R,Y,q;O.then(function(e){U=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?Y=i:angular.isElement(V.container)?Y=V.container:V.container&&(Y=m(V.container)),v(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&I.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),A(),I.$destroy()},F.enter=function(){return clearTimeout(H),L='in',V.delay&&V.delay.show?void(H=setTimeout(function(){'in'===L&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){I.$emit(V.prefixEvent+'.show.before',F);var e,t;V.container?(e=Y,t=Y[0].lastChild?angular.element(Y[0].lastChild):null):(e=null,t=i),R&&A(),q=F.$scope.$new(),R=F.$element=U.link(q,function(e,t){}),R.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&R.addClass(V.animation),V.type&&R.addClass(V.prefixClass+'-'+V.type),V.customClass&&R.addClass(V.customClass),t?t.after(R):e.prepend(R),F.$isShown=I.$isShown=!0,g(I),F.$applyPlacement(),angular.version.minor<=2?l.enter(R,e,t,s):l.enter(R,e,t).then(s),g(I),d(function(){R&&R.css({visibility:'visible'}),V.keyboard&&('focus'!==V.trigger&&F.focus(),y())}),V.autoClose&&D()}},F.leave=function(){return clearTimeout(H),L='out',V.delay&&V.delay.hide?void(H=setTimeout(function(){'out'===L&&F.hide()},V.delay.hide)):F.hide()};var z,j;F.hide=function(e){F.$isShown&&(I.$emit(V.prefixEvent+'.hide.before',F),z=e,j=R,angular.version.minor<=2?l.leave(R,p):l.leave(R).then(p),F.$isShown=I.$isShown=!1,g(I),V.keyboard&&null!==R&&b(),V.autoClose&&null!==R&&k())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){R[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(R){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),R.addClass(V.placement);var o=x(),i=R.prop('offsetWidth'),r=R.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);s.indexOf('bottom')>=0&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):s.indexOf('top')>=0&&o.top-rl.width?t='right'===s?'left':t.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&o.left-it?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||y),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();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 void 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*E;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 M=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 M())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(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=/(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,a,o,i,r){var s=r.defaults,l=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.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,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)},h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),c(u.$dateValue)})}),e.$watch(a.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 a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):'unix'===f.timeType?new Date(1e3*e):new Date(e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=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&&t',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(a,r,s){var u={},c=angular.extend({},e,s);u=o(a,c);var d=u.$scope;d.$matches=[],c.multiple?d.$activeIndex=[]:d.$activeIndex=-1,d.$isMultiple=c.multiple,d.$showAllNoneButtons=c.allNoneButtons&&c.multiple,d.$iconCheckmark=c.iconCheckmark,d.$allText=c.allText,d.$noneText=c.noneText,d.$activate=function(e){d.$$postDigest(function(){u.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){u.select(e)})},d.$isVisible=function(){return u.$isVisible()},d.$isActive=function(e){return u.$isActive(e)},d.$selectAll=function(){for(var e=0;e=c.minLength:d.$matches.length},u.$isActive=function(e){return c.multiple?-1!==d.$activeIndex.indexOf(e):d.$activeIndex===e},u.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},u.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),c.multiple&&9===e.keyCode?u.hide():c.multiple||13!==e.keyCode&&9!==e.keyCode?void(c.multiple||(38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:38===e.keyCode&&d.$activeIndex<0?d.$activeIndex=d.$matches.length-1:40===e.keyCode&&d.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},u.$selectScrollFix=function(e){'UL'===n[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var f=u.show;u.show=function(){f(),c.multiple&&u.$element.addClass('select-multiple'),i(function(){u.$element.on(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.on('keydown',u.$onKeyDown)},0,!1)};var p=u.hide;return u.hide=function(){!c.multiple&&angular.isUndefined(r.$modelValue)&&(d.$activeIndex=-1),u.$element.off(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.off('keydown',u.$onKeyDown),p(!0)},u}var s=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),l='createTouch'in t.document&&s;return r.defaults=e,r}]}).directive('bsSelect',['$window','$parse','$q','$select','$parseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(l.test(u)?s.multiple=!1:s.multiple=u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element(''),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s);f.$isIE()&&t[0].addEventListener('blur',f.$selectScrollFix);var 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.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.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'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','templateUrl','controller','controllerAs','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)&&(s.test(l)?r.target=!1:r.target=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.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.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$bsCompiler','$animate','$timeout','$sce','dimensions',function(n,a,o,i,r,s,l){function u(t){function n(){k.$emit(b.prefixEvent+'.show',y)}function r(){k.$emit(b.prefixEvent+'.hide',y),g.removeClass(b.prefixClass+'-open'),b.animation&&g.removeClass(b.prefixClass+'-with-'+b.animation)}function l(){b.backdrop&&(x.on('click',h),C.on('click',h),C.on('wheel',v))}function u(){b.backdrop&&(x.off('click',h),C.off('click',h),C.off('wheel',v))}function m(){b.keyboard&&x.on('keyup',y.$onKeyUp)}function $(){b.keyboard&&x.off('keyup',y.$onKeyUp)}function h(e){e.target===e.currentTarget&&('static'===b.backdrop?y.focus():y.hide())}function v(e){e.preventDefault()}function w(){y.$isShown&&null!==x&&(u(),$()),T&&(T.$destroy(),T=null),x&&(x.remove(),x=y.$element=null)}var y={},b=y.$options=angular.extend({},e,t),D=y.$promise=o.compile(b),k=y.$scope=b.scope&&b.scope.$new()||a.$new();b.element||b.container||(b.container='body'),y.$id=b.id||b.element&&b.element.attr('id')||'',f(['title','content'],function(e){b[e]&&(k[e]=s.trustAsHtml(b[e]))}),k.$hide=function(){k.$$postDigest(function(){y.hide()})},k.$show=function(){k.$$postDigest(function(){y.show()})},k.$toggle=function(){k.$$postDigest(function(){y.toggle()})},y.$isShown=k.$isShown=!1;var S,x,T,C=angular.element('
');return C.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),D.then(function(e){S=e,y.init()}),y.init=function(){b.show&&k.$$postDigest(function(){y.show()})},y.destroy=function(){w(),C&&(C.remove(),C=null),k.$destroy()},y.show=function(){if(!y.$isShown){var e,t;if(angular.isElement(b.container)?(e=b.container,t=b.container[0].lastChild?angular.element(b.container[0].lastChild):null):b.container?(e=d(b.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=b.element),x&&w(),T=y.$scope.$new(),x=y.$element=S.link(T,function(e,t){}),!k.$emit(b.prefixEvent+'.show.before',y).defaultPrevented){x.css({display:'block'}).addClass(b.placement),b.animation&&(b.backdrop&&C.addClass(b.backdropAnimation),x.addClass(b.animation)),b.backdrop&&i.enter(C,g,null),angular.version.minor<=2?i.enter(x,e,t,n):i.enter(x,e,t).then(n),y.$isShown=k.$isShown=!0,c(k);var a=x[0];p(function(){a.focus()}),g.addClass(b.prefixClass+'-open'),b.animation&&g.addClass(b.prefixClass+'-with-'+b.animation),l(),m()}}},y.hide=function(){y.$isShown&&(k.$emit(b.prefixEvent+'.hide.before',y).defaultPrevented||(angular.version.minor<=2?i.leave(x,r):i.leave(x).then(r),b.backdrop&&i.leave(C),y.$isShown=k.$isShown=!1,c(k),u(),$()))},y.toggle=function(){y.$isShown?y.hide():y.show()},y.focus=function(){x[0].focus()},y.$onKeyUp=function(e){27===e.which&&y.$isShown&&(y.hide(),e.stopPropagation())},y}function c(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function d(e,n){return angular.element((n||t).querySelectorAll(e))}var f=angular.forEach,p=(String.prototype.trim,n.requestAnimationFrame||n.setTimeout),g=angular.element(n.document.body);return u}]}).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','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation','backdropAnimation','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.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.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 angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),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.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.dateParser',[]).provider('$dateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;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;t=1*e&&2===e.length?this.setFullYear(2e3+1*e):this.setFullYear(1*e)}};return m.init=function(){m.$format=e.DATETIME_FORMATS[g.format]||g.format,f=d(m.$format),p=u(m.$format)},m.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):f.test(e)},m.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||m.$format,i));var r=o?d(o):f,l=o?u(o):p,c=r.exec(n);if(!c)return!1;for(var g=a&&!isNaN(a.getTime())?(new t).fromDate(a):(new t).fromDate(new Date(1970,0,1,0)),$=0;$12?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.dateFormatter',[]).service('$dateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],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',templateUrl:'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&&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 void(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(){!d&&t.attr('readonly')||t.attr('disabled')||(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=/(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};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(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)});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});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())}),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)})}),angular.isDefined(n.dateFormat)&&n.$observe('dateFormat',function(e){p.$options.dateFormat=e}),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?NaN:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):'unix'===d.dateType?new Date(1e3*e):new Date(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.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;n=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,'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'))),o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')))},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',['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'])}(window,document); //# sourceMappingURL=angular-strap.min.js.map diff --git a/dist/angular-strap.min.js.map b/dist/angular-strap.min.js.map index 853d4a8af..a23cba617 100644 --- a/dist/angular-strap.min.js.map +++ b/dist/angular-strap.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["angular-strap.js","typeahead/typeahead.js","helpers/compiler.js","dropdown/dropdown.js","tooltip/tooltip.js","timepicker/timepicker.js","tab/tab.js","scrollspy/scrollspy.js","select/select.js","popover/popover.js","navbar/navbar.js","modal/modal.js","helpers/raf.js","helpers/parse-options.js","helpers/dimensions.js","helpers/debounce.js","helpers/date-parser.js","helpers/date-formatter.js","datepicker/datepicker.js","collapse/collapse.js","button/button.js","aside/aside.js","alert/alert.js","affix/affix.js","module.js"],"names":["placement","document","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","bsCompilerService","$inject","$http","get","angular","module","defaults","this","animation","data","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","contentEl","findElement","outerHTML","contentTemplate","all","templateEl","removeAttr","html","templates","replace","next","remove","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","trigger","provider","container","keyboard","delay","minLength","filter","limit","autoSelect","comparator","trimValue","$get","bodyEl","$typeahead","$scope","$matches","config","$resetMatches","$$postDigest","activate","$activeIndex","select","index","$select","evt","matches","$isVisible","safeDigest","update","$$rAF","$render","$emit","prefixEvent","parentScope","length","l","$viewValue","i","preventDefault","stopPropagation","keyCode","$digest","show","$timeout","$element","$onMouseDown","hide","on","$onKeyDown","TypeaheadFactory","array","isFunction","$$phase","$window","body","$filter","expression","directive","results","restrict","require","falseValueRegExp","attr","bsOptions","test","parsedOptions","$parseOptions","typeahead","watchOptions","watchedOptions","$watchCollection","values","$match","$watch","ngModel","newValue","oldValue","$modelValue","valuesFn","selectMode","$setViewValue","substring","displayValue","slice","$formatters","push","modelValue","selected","val","destroy","isDefined","label","toString","$on","target","title","type","autoClose","bsEnabled","viewport","selector","padding","String","htmlReplaceRegExp","$body","$tooltip","split","enterAnimateCallback","leaveAnimateCallback","_tipToHide","leave","$isShown","blur","tipElement","nodeName","triggers","toggle","unbindTriggerEvents","enter","off","bindKeyboardEvents","$onKeyUp","isTouch","$onFocusElementMouseDown","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","rect","width","elRect","height","p","top","left","dimensions","offset","el","scroll","isBody","documentElement","getCalculatedOffset","position","actualWidth","actualHeight","outerDims","clientWidth","innerHeight","tip","marginTop","parseInt","using","props","css","isNaN","right","marginLeft","setOffset","delta","getViewportAdjustedDelta","isVertical","replaceArrow","arrowDelta","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","clearTimeout","timeout","tipScope","$destroy","$options","$promise","$bsCompiler","$new","$rootScope","toLowerCase","$id","map","parseFloat","$sce","trustAsHtml","$setEnabled","id","$hide","setEnabled","isEnabled","compileData","promise","init","tipContainer","bindTriggerEvents","isElement","destroyTipElement","hoverState","parent","after","lastChild","display","visibility","clonedElement","version","minor","addClass","$animate","customClass","$applyPlacement","focus","_blur","elementPosition","autoPlace","autoToken","viewportPosition","originalPlacement","indexOf","tipHeight","removeClass","tipPosition","applyPlacement","tipWidth","$location","transclusion","dataTarget","hasOwnProperty","tooltip","$observe","bsTooltip","bsShow","match","setViewport","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","isNative","$timepicker","timepickerFactory","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","end","start","setSelectionRange","isUndefined","collapse","selectionStart","moveStart","selectionEnd","moveEnd","focusElement","_init","floorMinutes","time","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","$dateValue","hoursFormat","$dateFormatter","$iconUp","$iconDown","$moveIndex","$switchMeridian","switchMeridian","isDate","getMinutes","getTime","$build","minute","keep","Date","setHours","setMinutes","setSeconds","hours","midIndex","$isSelected","disabled","minutes","seconds","minutesFormat","rows","showSeconds","secondsFormat","$isDisabled","showAM","timeSeparator","$date","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","targetDate","targetEl","triggerHandler","sepLength","lateralMove","count","minutesLength","selectRange","hoursLength","incr","isSeconds","isMeridian","secondsLength","createSelection","createTextRange","prop","_destroy","_show","_hide","navigator","userAgent","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","timepicker","dateParser","$dateParser","validateAgainstMinMaxTime","getTimeForAttribute","parse","timezoneOffsetAdjust","NaN","self","navClass","activeClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$active","$attrs","$navClass","$remove","active","activeIndex","splice","$setActive","name","fn","$pane","$tab","transclude","postLink","ngModelCtrl","bsTabsCtrl","attrs","bsActivePane","parsedBsActivePane","assign","$parse","render","$isActive","spies","debounce","$document","windowEl","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","$trackedElements","sortedElements","activeTarget","debouncedCheckPosition","viewportHeight","throttledCheckPosition","debouncedCheckOffsets","scrollTop","checkPositionWithEventLoop","checkOffsets","checkPosition","docEl","$activateElement","offsetTop","setTimeout","activeElement","source","$getTrackedElement","targetElement","querySelector","trackedElement","b","trackElement","toDelete","untrackElement","scrollspy","childEl","querySelectorAll","child","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$isMultiple","$showAllNoneButtons","$iconCheckmark","$allText","$activate","$selectNone","$updateActiveIndex","a","$apply","isArray","$getIndex","$selectScrollFix","$isIE","stopImmediatePropagation","ua","tagName","e","dataMultiple","inputEl","addEventListener","join","$isEmpty","content","$popover","PopoverFactory","requestAnimationFrame","popover","bsPopover","routeAttr","$navbar","liElements","li","liElement","pattern","path","RegExp","regexp","backdrop","bodyElement","ModalFactory","$modal","prefixClass","modalElement","unbindBackdropEvents","hideOnBackdropClick","backdropElement","preventEventDefault","destroyModalElement","modalScope","$show","bottom","z-index","defaultPrevented","backdropAnimation","bindBackdropEvents","which","$root","query","bsModal","modal","cancelAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","raf","timer","$values","displayFn","valueName","valueFn","ParseOptionsFactory","groupByFn","keyName","jqLite","currentStyle","window","getComputedStyle","extra","boxRect","getBoundingClientRect","style","offsetHeight","docElement","ownerDocument","curPosition","curLeft","curCSSTop","pageYOffset","clientTop","pageXOffset","scrollLeft","clientLeft","curCSSLeft","calculatePosition","curTop","curOffset","curElem","call","offsetParentRect","offsetParentElement","offsetParent","offsetWidth","outer","func","immediate","factory","context","args","cancel","callNow","leading","trailing","wait","year","$localeProvider","milliseconds","ParseDate","prototype","isNumeric","n","isFinite","indexOfCaseInsensitive","len","str","strict","DateParserFactory","day","month","getFullYear","getMonth","proto","noop","toDate","regExpMap","sss","$locale","dateFilter","mm","keys","setFnMap","clonedFormat","search","v","sortedMap","regExpForFormat","re","text","Object","escapeReservedSymbols","regex","m","HH","H","hh","h","EEEE","EEE","DATETIME_FORMATS","SHORTDAY","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","s","setDate","setMonth","setMap","setMapForFormat","$format","baseDate","formatRegex","formatSetMap","exec","fromDate","getDate","today","getDateForAttribute","substr","daylightSavingAdjust","undo","getDefaultLocale","getDatetimeFormat","weekdaysShort","splitTimeFormat","service","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","parentEl","hasClass","bsDropdown","dropdown","dateType","dateFormat","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","minDate","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","DatepickerFactory","$datepicker","pickerViews","views","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","$toggleMode","setMode","updateDisabledDates","disabledDateRanges","dateRanges","mode","pristine","$updateSelected","built","$setDisabledEl","isDisabled","steps","getUTCFullYear","getUTCMonth","UTC","getUTCDate","shiftKey","altKey","onKeyDown","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","parsedDate","getDateFormattedString","validateAgainstMinMaxDate","disabledDates","daySplit","arr","mod","arrays","size","weekDaysMin","weekDaysLabelsHtml","picker","weekDaysLabels","concat","firstDayOfMonth","firstDate","getDay","firstDateOffset","build","days","isToday","toDateString","muted","showLabels","labels","isSelected","firstMonth","months","lastDate","actualMonth","firstYear","years","actualYear","setYear","startCollapsed","allowMultiple","activeIndexes","$targets","activeItems","activateItem","$collapse","$viewChangeListeners","$registerToggle","$toggles","$unregisterToggle","$unregisterTarget","deactivateItem","fixActiveItemIndexes","disallowToggle","isActive","$activeIndexes","bsCollapseCtrl","controllers","bsCollapseToggle","$registerTarget","action","toggleEvent","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","equals","checked","bind","toggleClass","AsideFactory","$aside","bsAside","aside","duration","dismissable","AlertFactory","$alert","bsAlert","alert","AffixFactory","$affix","inlineStyles","reset","setWidth","initialAffixTop","getRequiredAffixClass","unpin","getScrollTop","scrollHeight","getScrollHeight","initialOffsetTop","offsetBottom","affixed","$parseOffsets","affix","elementHeight","offsetUnpin","$onResize","$debouncedOnResize","initialPosition","affixTarget","option"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\n\n// Source: typeahead/typeahead.js\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n 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 // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function(index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function(index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function() {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function(value) {\n var l = scope.$matches.length,\n 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 // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function($filter) {\n return function(array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function(results) {\n return $filter('filter')(results, expression, comparator);\n });\n } else {\n return $filter('filter')(array, expression, comparator);\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 = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = 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 typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = 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// Source: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n 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, $bsCompiler, $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 options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n 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 = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n 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 // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n });\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\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 // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.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 > viewportPosition.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 < viewportPosition.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 // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n 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', 'templateUrl', 'controller', 'controllerAs', '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: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n 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, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $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\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // 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({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n 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 undefined;\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: 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: 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 templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(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 if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(options.multiple) {\n if(angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if(angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } 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 // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function() {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function(e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && angular.isUndefined(controller.$modelValue)) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // 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 if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$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: popover/popover.js\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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: 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: modal/modal.js\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $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\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(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 bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\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 function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement() {\n if($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if(modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if(modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n 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 return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass'], 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: 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: 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 if(!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function(modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues(values, scope) {\n return values.map(function(match, index) {\n var locals = {}, 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/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/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/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/date-formatter.js\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function() {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function(format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function(lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat(format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function(timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function(date, format, lang, timezone){\n return dateFilter(date, format, timezone);\n };\n\n });\n\n// Source: helpers/compiler.js\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n\n// Source: dropdown/dropdown.js\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n if(!scope.content) return;\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(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', '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: datepicker/datepicker.js\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // Uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var isNative = /(ip(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 $datepicker.hide(true);\n } else {\n scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if (!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if (!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(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};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Visibility binding support\n 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 // 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 // Observe date format\n angular.isDefined(attr.dateFormat) && attr.$observe('dateFormat', function(newValue) {\n datepicker.$options.dateFormat = newValue;\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: collapse/collapse.js\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function(key) {\n if(angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = value;\n }\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 && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .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: 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: aside/aside.js\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n 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', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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: alert/alert.js\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function($modal, $timeout) {\n\n function AlertFactory(config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if(options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if(options.duration) {\n $alert.show = function() {\n show();\n $timeout(function() {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function($window, $sce, $alert) {\n\n 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', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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: 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 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 // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function() {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function() {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles){\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if(options.offsetTop) {\n if(options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if(options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if(options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n }\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: module.js\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n\n})(window, document);\n","'use strict';\n\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n 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 // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function(index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function(index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function() {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function(value) {\n var l = scope.$matches.length,\n 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 // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function($filter) {\n return function(array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function(results) {\n return $filter('filter')(results, expression, comparator);\n });\n } else {\n return $filter('filter')(array, expression, comparator);\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 = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = 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 typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = 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","'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n if(!scope.content) return;\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(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', '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.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n 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, $bsCompiler, $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 options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n 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 = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n 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 // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n });\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\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 // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.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 > viewportPosition.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 < viewportPosition.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 // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n 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', 'templateUrl', 'controller', 'controllerAs', '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.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n 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, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $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\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // 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({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n 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 undefined;\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.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.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 templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(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 if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(options.multiple) {\n if(angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if(angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } 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 // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function() {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function(e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && angular.isUndefined(controller.$modelValue)) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // 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 if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$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.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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.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.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $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\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(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 bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\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 function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement() {\n if($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if(modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if(modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n 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 return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass'], 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\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.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 if(!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function(modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues(values, scope) {\n return values.map(function(match, index) {\n var locals = {}, 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\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.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.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.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.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // Uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var isNative = /(ip(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 $datepicker.hide(true);\n } else {\n scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if (!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if (!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(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};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Visibility binding support\n 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 // 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 // Observe date format\n angular.isDefined(attr.dateFormat) && attr.$observe('dateFormat', function(newValue) {\n datepicker.$options.dateFormat = newValue;\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.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function(key) {\n if(angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = value;\n }\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 && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .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.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.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n 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', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function($modal, $timeout) {\n\n function AlertFactory(config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if(options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if(options.duration) {\n $alert.show = function() {\n show();\n $timeout(function() {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function($window, $sce, $alert) {\n\n 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', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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.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 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 // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function() {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function() {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles){\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if(options.offsetTop) {\n if(options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if(options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if(options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n }\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","\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["angular-strap.js","typeahead/typeahead.js","helpers/compiler.js","dropdown/dropdown.js","tooltip/tooltip.js","timepicker/timepicker.js","tab/tab.js","select/select.js","scrollspy/scrollspy.js","popover/popover.js","navbar/navbar.js","modal/modal.js","helpers/raf.js","helpers/parse-options.js","helpers/dimensions.js","helpers/debounce.js","helpers/date-parser.js","helpers/date-formatter.js","datepicker/datepicker.js","collapse/collapse.js","button/button.js","aside/aside.js","alert/alert.js","affix/affix.js","module.js"],"names":["placement","document","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","bsCompilerService","$inject","$http","get","angular","module","defaults","this","animation","data","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","all","templateEl","contentEl","findElement","contentTemplate","removeAttr","html","templates","replace","next","remove","outerHTML","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","trigger","provider","container","keyboard","delay","minLength","filter","limit","autoSelect","comparator","trimValue","$get","bodyEl","$typeahead","$scope","$matches","config","$resetMatches","$$postDigest","activate","$activeIndex","select","index","$select","evt","matches","$isVisible","safeDigest","update","$$rAF","$render","$emit","prefixEvent","parentScope","length","l","$viewValue","i","preventDefault","stopPropagation","keyCode","$digest","show","$timeout","$element","$onMouseDown","hide","on","$onKeyDown","TypeaheadFactory","array","isFunction","$$phase","$window","body","$filter","expression","directive","results","restrict","require","falseValueRegExp","attr","bsOptions","test","parsedOptions","$parseOptions","typeahead","watchOptions","watchedOptions","$watchCollection","values","$match","$watch","ngModel","newValue","oldValue","$modelValue","valuesFn","selectMode","$setViewValue","substring","displayValue","slice","$formatters","push","modelValue","selected","val","destroy","isDefined","label","toString","$on","target","title","type","autoClose","bsEnabled","viewport","selector","padding","String","htmlReplaceRegExp","$body","$tooltip","split","enterAnimateCallback","leaveAnimateCallback","_tipToHide","leave","$isShown","blur","tipElement","nodeName","triggers","toggle","unbindTriggerEvents","enter","off","bindKeyboardEvents","$onKeyUp","isTouch","$onFocusElementMouseDown","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","rect","width","elRect","height","p","top","left","dimensions","offset","el","scroll","isBody","documentElement","getCalculatedOffset","position","actualWidth","actualHeight","outerDims","clientWidth","innerHeight","tip","marginTop","parseInt","using","props","css","isNaN","right","marginLeft","setOffset","delta","getViewportAdjustedDelta","isVertical","replaceArrow","arrowDelta","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","clearTimeout","timeout","tipScope","$destroy","$options","$promise","$bsCompiler","$new","$rootScope","toLowerCase","$id","map","parseFloat","$sce","trustAsHtml","$setEnabled","id","$hide","setEnabled","isEnabled","compileData","promise","init","tipContainer","bindTriggerEvents","isElement","destroyTipElement","hoverState","parent","after","lastChild","display","visibility","clonedElement","version","minor","addClass","$animate","customClass","$applyPlacement","focus","_blur","elementPosition","autoPlace","autoToken","viewportPosition","originalPlacement","indexOf","tipHeight","removeClass","tipPosition","applyPlacement","tipWidth","$location","transclusion","dataTarget","hasOwnProperty","tooltip","$observe","bsTooltip","bsShow","match","setViewport","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","isNative","$timepicker","timepickerFactory","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","end","start","setSelectionRange","isUndefined","collapse","selectionStart","moveStart","selectionEnd","moveEnd","focusElement","_init","floorMinutes","time","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","$dateValue","hoursFormat","$dateFormatter","$iconUp","$iconDown","$moveIndex","$switchMeridian","switchMeridian","isDate","getMinutes","getTime","$build","minute","keep","Date","setHours","setMinutes","setSeconds","hours","midIndex","$isSelected","disabled","minutes","seconds","minutesFormat","rows","showSeconds","secondsFormat","$isDisabled","showAM","timeSeparator","$date","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","targetDate","targetEl","triggerHandler","sepLength","lateralMove","count","minutesLength","selectRange","hoursLength","incr","isSeconds","isMeridian","secondsLength","createSelection","createTextRange","prop","_destroy","_show","_hide","navigator","userAgent","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","timepicker","dateParser","$dateParser","validateAgainstMinMaxTime","getTimeForAttribute","parse","timezoneOffsetAdjust","NaN","self","navClass","activeClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$active","$attrs","$navClass","$remove","active","activeIndex","splice","$setActive","name","fn","$pane","$tab","transclude","postLink","ngModelCtrl","bsTabsCtrl","attrs","bsActivePane","parsedBsActivePane","assign","$parse","render","$isActive","prefixClass","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$isMultiple","$showAllNoneButtons","$iconCheckmark","$allText","$activate","$selectNone","$updateActiveIndex","b","a","$apply","isArray","$getIndex","$selectScrollFix","$isIE","stopImmediatePropagation","ua","activeElement","tagName","e","dataMultiple","inputEl","addEventListener","join","$isEmpty","spies","$document","windowEl","debounce","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","$trackedElements","sortedElements","activeTarget","debouncedCheckPosition","viewportHeight","throttledCheckPosition","debouncedCheckOffsets","scrollTop","checkPositionWithEventLoop","checkOffsets","checkPosition","docEl","$activateElement","offsetTop","setTimeout","source","$getTrackedElement","targetElement","querySelector","trackedElement","trackElement","toDelete","untrackElement","scrollspy","childEl","querySelectorAll","child","content","$popover","PopoverFactory","requestAnimationFrame","popover","bsPopover","routeAttr","$navbar","liElements","li","liElement","pattern","path","RegExp","regexp","backdrop","bodyElement","ModalFactory","$modal","modalElement","unbindBackdropEvents","hideOnBackdropClick","backdropElement","preventEventDefault","destroyModalElement","modalScope","$show","bottom","z-index","defaultPrevented","backdropAnimation","bindBackdropEvents","which","$root","query","bsModal","modal","cancelAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","raf","timer","$values","displayFn","valueName","valueFn","ParseOptionsFactory","groupByFn","keyName","jqLite","currentStyle","window","getComputedStyle","extra","boxRect","getBoundingClientRect","style","offsetHeight","docElement","ownerDocument","curPosition","curLeft","curCSSTop","pageYOffset","clientTop","pageXOffset","scrollLeft","clientLeft","curCSSLeft","calculatePosition","curTop","curOffset","curElem","call","offsetParentRect","offsetParentElement","offsetParent","offsetWidth","outer","func","immediate","factory","context","args","cancel","callNow","leading","trailing","wait","year","$localeProvider","milliseconds","ParseDate","prototype","isNumeric","n","isFinite","indexOfCaseInsensitive","len","str","strict","DateParserFactory","day","month","getFullYear","getMonth","proto","noop","toDate","regExpMap","sss","$locale","dateFilter","mm","keys","setFnMap","clonedFormat","search","v","sortedMap","regExpForFormat","re","text","Object","escapeReservedSymbols","regex","m","HH","H","hh","h","EEEE","EEE","DATETIME_FORMATS","SHORTDAY","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","s","setDate","setMonth","setMap","setMapForFormat","$format","baseDate","formatRegex","formatSetMap","exec","fromDate","getDate","today","getDateForAttribute","substr","daylightSavingAdjust","undo","getDefaultLocale","getDatetimeFormat","weekdaysShort","splitTimeFormat","service","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","parentEl","hasClass","nextSibling","tElement","classList","parentNode","removeChild","nodeType","tAttrs","bsDropdown","dropdown","dateType","dateFormat","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","minDate","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","DatepickerFactory","$datepicker","pickerViews","views","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","$toggleMode","setMode","updateDisabledDates","disabledDateRanges","dateRanges","mode","pristine","$updateSelected","built","$setDisabledEl","isDisabled","steps","getUTCFullYear","getUTCMonth","UTC","getUTCDate","shiftKey","altKey","onKeyDown","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","parsedDate","getDateFormattedString","validateAgainstMinMaxDate","disabledDates","daySplit","arr","mod","arrays","size","weekDaysMin","weekDaysLabelsHtml","picker","weekDaysLabels","concat","firstDayOfMonth","firstDate","getDay","firstDateOffset","build","days","isToday","toDateString","muted","showLabels","labels","isSelected","firstMonth","months","lastDate","actualMonth","firstYear","years","actualYear","setYear","startCollapsed","allowMultiple","activeIndexes","$targets","activeItems","activateItem","$collapse","$viewChangeListeners","$registerToggle","$toggles","$unregisterToggle","$unregisterTarget","deactivateItem","fixActiveItemIndexes","disallowToggle","isActive","$activeIndexes","bsCollapseCtrl","controllers","bsCollapseToggle","$registerTarget","action","toggleEvent","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","equals","checked","bind","toggleClass","AsideFactory","$aside","bsAside","aside","duration","dismissable","AlertFactory","$alert","bsAlert","alert","AffixFactory","$affix","inlineStyles","reset","setWidth","initialAffixTop","getRequiredAffixClass","unpin","getScrollTop","scrollHeight","getScrollHeight","initialOffsetTop","offsetBottom","affixed","$parseOffsets","affix","elementHeight","offsetUnpin","$onResize","$debouncedOnResize","initialPosition","affixTarget","option"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\n\n// Source: typeahead/typeahead.js\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n 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 // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function(index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function(index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function() {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function(value) {\n var l = scope.$matches.length,\n 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 // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function($filter) {\n return function(array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function(results) {\n return $filter('filter')(results, expression, comparator);\n });\n } else {\n return $filter('filter')(array, expression, comparator);\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 = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = 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 typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = 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// Source: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n 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, $bsCompiler, $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 options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n 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 = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n 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 // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n });\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\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 // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.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 > viewportPosition.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 < viewportPosition.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 // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n 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', 'templateUrl', 'controller', 'controllerAs', '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: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n 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, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $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\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // 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({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n 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 undefined;\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: 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: select/select.js\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(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 if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(options.multiple) {\n if(angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if(angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } 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 // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function() {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function(e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && angular.isUndefined(controller.$modelValue)) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // 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 if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$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: 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: popover/popover.js\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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: 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: modal/modal.js\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $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\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(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 bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\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 function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement() {\n if($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if(modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if(modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n 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 return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass'], 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: 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: 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 if(!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function(modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues(values, scope) {\n return values.map(function(match, index) {\n var locals = {}, 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/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/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/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/date-formatter.js\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function() {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function(format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function(lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat(format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function(timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function(date, format, lang, timezone){\n return dateFilter(date, format, timezone);\n };\n\n });\n\n// Source: helpers/compiler.js\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n\n// Source: dropdown/dropdown.js\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n 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 compile: function(tElement, tAttrs) {\n\n // Directive options\n var options = {};\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling.classList.contains('dropdown-menu')) {\n options.template = nextSibling.outerHTML;\n options.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink(scope, element, attr) {\n\n // Directive options\n options.scope = scope;\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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\n// Source: datepicker/datepicker.js\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // Uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var isNative = /(ip(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 $datepicker.hide(true);\n } else {\n scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if (!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if (!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(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};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Visibility binding support\n 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 // 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 // Observe date format\n angular.isDefined(attr.dateFormat) && attr.$observe('dateFormat', function(newValue) {\n datepicker.$options.dateFormat = newValue;\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: collapse/collapse.js\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function(key) {\n if(angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = value;\n }\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 && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .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: 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: aside/aside.js\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n 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', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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: alert/alert.js\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function($modal, $timeout) {\n\n function AlertFactory(config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if(options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if(options.duration) {\n $alert.show = function() {\n show();\n $timeout(function() {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function($window, $sce, $alert) {\n\n 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', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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: 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 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 // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function() {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function() {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles){\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if(options.offsetTop) {\n if(options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if(options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if(options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n }\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: module.js\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n\n})(window, document);\n","'use strict';\n\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n 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 // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function(index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function(index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function() {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function(value) {\n var l = scope.$matches.length,\n 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 // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function($filter) {\n return function(array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function(results) {\n return $filter('filter')(results, expression, comparator);\n });\n } else {\n return $filter('filter')(array, expression, comparator);\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 = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = 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 typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = 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","'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n 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 compile: function(tElement, tAttrs) {\n\n // Directive options\n var options = {};\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling.classList.contains('dropdown-menu')) {\n options.template = nextSibling.outerHTML;\n options.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink(scope, element, attr) {\n\n // Directive options\n options.scope = scope;\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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","'use strict';\n\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n 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, $bsCompiler, $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 options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n 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 = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n 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 // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n });\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\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 // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.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 > viewportPosition.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 < viewportPosition.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 // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n 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', 'templateUrl', 'controller', 'controllerAs', '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.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n 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, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $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\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // 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({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n 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 undefined;\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.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.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(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 if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(options.multiple) {\n if(angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if(angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } 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 // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function() {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function(e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && angular.isUndefined(controller.$modelValue)) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // 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 if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$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.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.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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.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.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $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\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(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 bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\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 function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement() {\n if($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if(modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if(modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n 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 return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass'], 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\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.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 if(!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function(modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues(values, scope) {\n return values.map(function(match, index) {\n var locals = {}, 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\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.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.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.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.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // Uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var isNative = /(ip(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 $datepicker.hide(true);\n } else {\n scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if (!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if (!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(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};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Visibility binding support\n 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 // 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 // Observe date format\n angular.isDefined(attr.dateFormat) && attr.$observe('dateFormat', function(newValue) {\n datepicker.$options.dateFormat = newValue;\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.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function(key) {\n if(angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = value;\n }\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 && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .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.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.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n 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', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function($modal, $timeout) {\n\n function AlertFactory(config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if(options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if(options.duration) {\n $alert.show = function() {\n show();\n $timeout(function() {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function($window, $sce, $alert) {\n\n 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', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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.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 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 // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function() {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function() {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles){\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if(options.offsetTop) {\n if(options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if(options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if(options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n }\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","\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/angular-strap.tpl.js b/dist/angular-strap.tpl.js index 3dd79cca5..e2e5fccff 100644 --- a/dist/angular-strap.tpl.js +++ b/dist/angular-strap.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -17,7 +17,7 @@ $templateCache.put('datepicker/datepicker.tpl.html', ''); } ]); angular.module('mgcrea.ngStrap.dropdown').run([ '$templateCache', function($templateCache) { - $templateCache.put('dropdown/dropdown.tpl.html', ''); + $templateCache.put('dropdown/dropdown.tpl.html', ''); } ]); angular.module('mgcrea.ngStrap.modal').run([ '$templateCache', function($templateCache) { $templateCache.put('modal/modal.tpl.html', ''); diff --git a/dist/angular-strap.tpl.min.js b/dist/angular-strap.tpl.min.js index 1a1841479..c2c268fe5 100644 --- a/dist/angular-strap.tpl.min.js +++ b/dist/angular-strap.tpl.min.js @@ -1,8 +1,8 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -!function(t,e,n){'use strict';angular.module('mgcrea.ngStrap.alert').run(['$templateCache',function(t){t.put('alert/alert.tpl.html','
 
')}]),angular.module('mgcrea.ngStrap.aside').run(['$templateCache',function(t){t.put('aside/aside.tpl.html','')}]),angular.module('mgcrea.ngStrap.datepicker').run(['$templateCache',function(t){t.put('datepicker/datepicker.tpl.html','')}]),angular.module('mgcrea.ngStrap.dropdown').run(['$templateCache',function(t){t.put('dropdown/dropdown.tpl.html','')}]),angular.module('mgcrea.ngStrap.modal').run(['$templateCache',function(t){t.put('modal/modal.tpl.html','')}]),angular.module('mgcrea.ngStrap.popover').run(['$templateCache',function(t){t.put('popover/popover.tpl.html','

')}]),angular.module('mgcrea.ngStrap.select').run(['$templateCache',function(t){t.put('select/select.tpl.html','')}]),angular.module('mgcrea.ngStrap.tab').run(['$templateCache',function(t){t.put('tab/tab.tpl.html','
')}]),angular.module('mgcrea.ngStrap.timepicker').run(['$templateCache',function(t){t.put('timepicker/timepicker.tpl.html','')}]),angular.module('mgcrea.ngStrap.tooltip').run(['$templateCache',function(t){t.put('tooltip/tooltip.tpl.html','
')}]),angular.module('mgcrea.ngStrap.typeahead').run(['$templateCache',function(t){t.put('typeahead/typeahead.tpl.html','')}])}(window,document); \ No newline at end of file +!function(t,e,n){'use strict';angular.module('mgcrea.ngStrap.alert').run(['$templateCache',function(t){t.put('alert/alert.tpl.html','
 
')}]),angular.module('mgcrea.ngStrap.aside').run(['$templateCache',function(t){t.put('aside/aside.tpl.html','')}]),angular.module('mgcrea.ngStrap.datepicker').run(['$templateCache',function(t){t.put('datepicker/datepicker.tpl.html','')}]),angular.module('mgcrea.ngStrap.dropdown').run(['$templateCache',function(t){t.put('dropdown/dropdown.tpl.html','')}]),angular.module('mgcrea.ngStrap.modal').run(['$templateCache',function(t){t.put('modal/modal.tpl.html','')}]),angular.module('mgcrea.ngStrap.popover').run(['$templateCache',function(t){t.put('popover/popover.tpl.html','

')}]),angular.module('mgcrea.ngStrap.select').run(['$templateCache',function(t){t.put('select/select.tpl.html','')}]),angular.module('mgcrea.ngStrap.tab').run(['$templateCache',function(t){t.put('tab/tab.tpl.html','
')}]),angular.module('mgcrea.ngStrap.timepicker').run(['$templateCache',function(t){t.put('timepicker/timepicker.tpl.html','')}]),angular.module('mgcrea.ngStrap.tooltip').run(['$templateCache',function(t){t.put('tooltip/tooltip.tpl.html','
')}]),angular.module('mgcrea.ngStrap.typeahead').run(['$templateCache',function(t){t.put('typeahead/typeahead.tpl.html','')}])}(window,document); \ No newline at end of file diff --git a/dist/modules/affix.js b/dist/modules/affix.js index 94cf8cce6..df62e9d13 100644 --- a/dist/modules/affix.js +++ b/dist/modules/affix.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 80f8bd6c1..b6c210ca7 100644 --- a/dist/modules/affix.min.js +++ b/dist/modules/affix.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 eba046c54..8d1313cba 100644 --- a/dist/modules/alert.js +++ b/dist/modules/alert.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 cf1cfa2a5..94ac8b608 100644 --- a/dist/modules/alert.min.js +++ b/dist/modules/alert.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 b1861042b..861acbe6c 100644 --- a/dist/modules/alert.tpl.js +++ b/dist/modules/alert.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 2b20cc039..b9f3710b0 100644 --- a/dist/modules/alert.tpl.min.js +++ b/dist/modules/alert.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 42e6547ff..62c38447d 100644 --- a/dist/modules/aside.js +++ b/dist/modules/aside.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 1d78596c1..6d7cd72df 100644 --- a/dist/modules/aside.min.js +++ b/dist/modules/aside.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 7e06f81a2..3460e50a7 100644 --- a/dist/modules/aside.tpl.js +++ b/dist/modules/aside.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 cd1de277a..48725c076 100644 --- a/dist/modules/aside.tpl.min.js +++ b/dist/modules/aside.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 3ee12d6fa..fadedd395 100644 --- a/dist/modules/button.js +++ b/dist/modules/button.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 c515e8765..7c5b1ba51 100644 --- a/dist/modules/button.min.js +++ b/dist/modules/button.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 ccd406d02..0131aea46 100644 --- a/dist/modules/collapse.js +++ b/dist/modules/collapse.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 98ddf870a..d144c202f 100644 --- a/dist/modules/collapse.min.js +++ b/dist/modules/collapse.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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/compiler.js b/dist/modules/compiler.js index a85a301ee..7f0728e3a 100644 --- a/dist/modules/compiler.js +++ b/dist/modules/compiler.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -32,10 +32,12 @@ function bsCompilerService($q, $http, $injector, $compile, $controller, $templat } }); angular.extend(resolve, locals); - if (templateUrl) { + if (template) { + resolve.$template = $q.when(template); + } else if (templateUrl) { resolve.$template = fetchTemplate(templateUrl); } else { - resolve.$template = $q.when(template); + throw new Error('Missing `template` / `templateUrl` option.'); } if (options.contentTemplate) { resolve.$template = $q.all([ resolve.$template, fetchTemplate(options.contentTemplate) ]).then(function(templates) { diff --git a/dist/modules/compiler.min.js b/dist/modules/compiler.min.js index c155074d8..a3b954d99 100644 --- a/dist/modules/compiler.min.js +++ b/dist/modules/compiler.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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';function bsCompilerService(e,t,n,l,r,a){function o(e,t){return angular.element((t||document).querySelectorAll(e))}function i(e){return c[e]?c[e]:c[e]=t.get(e,{cache:a}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var a=t.templateUrl,c=t.template||'',m=t.controller,p=t.controllerAs,u=angular.copy(t.resolve||{}),s=angular.copy(t.locals||{}),g=t.transformTemplate||angular.identity,d=t.bindToController;return angular.forEach(u,function(e,t){angular.isString(e)?u[t]=n.get(e):u[t]=n.invoke(e)}),angular.extend(u,s),a?u.$template=i(a):u.$template=e.when(c),t.contentTemplate&&(u.$template=e.all([u.$template,i(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),l=o('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||l.next().remove(),n[0].outerHTML})),e.all(u).then(function(e){var n=g(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),o=l(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,m){var n=r(m,e,!0);d&&angular.extend(n.instance,e);var l=angular.isObject(n)?n:n();a.data('$ngControllerController',l),a.children().data('$ngControllerController',l),p&&(t[p]=l)}return o.apply(null,arguments)}}})};var c={}}angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',bsCompilerService),bsCompilerService.$inject=['$q','$http','$injector','$compile','$controller','$templateCache']; +'use strict';function bsCompilerService(e,t,n,l,r,a){function o(e,t){return angular.element((t||document).querySelectorAll(e))}function i(e){return c[e]?c[e]:c[e]=t.get(e,{cache:a}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var a=t.templateUrl,c=t.template||'',m=t.controller,p=t.controllerAs,u=angular.copy(t.resolve||{}),s=angular.copy(t.locals||{}),g=t.transformTemplate||angular.identity,d=t.bindToController;if(angular.forEach(u,function(e,t){angular.isString(e)?u[t]=n.get(e):u[t]=n.invoke(e)}),angular.extend(u,s),c)u.$template=e.when(c);else{if(!a)throw new Error('Missing `template` / `templateUrl` option.');u.$template=i(a)}return t.contentTemplate&&(u.$template=e.all([u.$template,i(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),l=o('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||l.next().remove(),n[0].outerHTML})),e.all(u).then(function(e){var n=g(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),o=l(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,m){var n=r(m,e,!0);d&&angular.extend(n.instance,e);var l=angular.isObject(n)?n:n();a.data('$ngControllerController',l),a.children().data('$ngControllerController',l),p&&(t[p]=l)}return o.apply(null,arguments)}}})};var c={}}angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',bsCompilerService),bsCompilerService.$inject=['$q','$http','$injector','$compile','$controller','$templateCache']; //# sourceMappingURL=compiler.min.js.map diff --git a/dist/modules/compiler.min.js.map b/dist/modules/compiler.min.js.map index ccc99eb7e..25a55f118 100644 --- a/dist/modules/compiler.min.js.map +++ b/dist/modules/compiler.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/compiler.js"],"names":["templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","$http","get","bsCompilerService","data","this","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","angular","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","contentEl","findElement","outerHTML","contentTemplate","all","templateEl","removeAttr","html","templates","replace","next","remove","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","service","$inject"],"mappings":"AAOA,YAIA,SAmEQA,mBAAcC,EAAQD,EAAAA,EAAAA,EAAAA,EAAAA,GAF5B,QA4FyDE,GAAOC,EAAAA,GA3F9D,MA4FGC,SAAKC,SAASC,GAAAA,UAAAA,iBAAAA,IAzFnB,QAASC,GAAcC,GACrB,MAAIC,GAAcD,GAAkBC,EAAcD,GAC3CC,EAAcD,GAAYE,EAAMC,IAAIH,GA6F/CI,MAAAA,IA3FOR,KAAK,SAASE,GACf,MAAOA,GAAIO,OAzEfC,KAmEEC,QAAIP,SAAWP,GACXe,EAAAA,UAAaf,UAAQe,KAAAA,EAAAA,YACzBC,QAAIC,KAAAA,oGACJjB,EAAIkB,YAAkBC,EAAKnB,SAC3BA,EAAIoB,SAAiBD,GAErB,IAAIE,GAAAA,EAAmBrB,YAKvBsB,EAAQC,EAAQL,UAAkBM,GAChCT,EAAYU,EAASD,WACnBN,EAAeQ,EAAAA,aAtEfR,EAuEKI,QAAAH,KAAAnB,EAAAkB,aACLA,EAAQS,QAAOD,KAAAA,EAAUE,YAtEzBC,EAAoB7B,EAAQ6B,mBAAqBP,QAAQQ,SACzDT,EAAmBrB,EAAQqB,gBAsB/B,OAoDAC,SAAQS,QAAOb,EAASE,SAAAA,EAAAA,GAEpBrB,QAAAA,SAAayB,GACfN,EAAQc,GAAAA,EAAY1B,IAAAA,GAEpBY,EAAQc,GAAAA,EAAeC,OAAK1B,KAvE9Be,QA4EEJ,OAAQc,EAAYE,GAEhBnC,EA5EJmB,EA6EQiB,UAAYC,EAAYrC,GA3EhCmB,EA8EIc,UAAkBE,EAAGG,KAAAA,GA5EvBrC,EAAQsC,kBAiFZpB,EAAUqB,UAAIrB,EAASf,KAAKe,EAASE,UAAAA,EAAAA,EAAAA,mBAAAA,KAAAA,SAAAA,GAEnC,GAAIb,GAAWsB,QAAAA,QAAkBT,EAAOY,IACpChC,EAAcoC,EAAA,sBAAAI,EAAA,IAAAC,WAAA,WAAAC,KAAAC,EAAA,GA/EhB,OAgFApC,GAAWA,aAASqC,EAAQC,OAAeC,SAhFpCN,EAAW,GAAGH,aAuFvBH,EAAAK,IAAArB,GAAAf,KAAA,SAAAiB,GAnFA,GAoFEA,GAAQA,EAAAA,EAAAA,UACRhB,GAASA,OACT2C,EAAMxC,EAAcyC,QAAAA,cAAAA,kBAlFtB,IAsFI5C,GAAIW,QAAYX,QAAA,SAAAsC,KAAAnC,EAAA0C,QAAAC,WArFhBC,EAsFMC,EAAAA,EArFV,QACEhC,OAsFME,EArFNlB,QAASA,EACT2C,KAuFI,SAAWzB,GArFb,GADAF,EAwFEhB,OAAa4C,EACb5C,EAAQiD,CAER,GAAIpC,GAAAA,EAAcF,EAAAK,GAAA,EAChB4B,IAxFA1B,QAAQS,OAAOqB,EAAWE,SAAUlC,EA4FxC,IAAAmC,GAAOJ,QAAaK,SAAMC,GAAAA,EAAAA,GAzFxBrD,GAAQQ,KAAK,0BAA2B2C,GACxCnD,EAAQiD,WAAWzC,KAAK,0BAA2B2C,GAC/CtC,IACF+B,EAAM/B,GAAgBsC,GAG1B,MAAOJ,GAAOO,MAAM,KAAMD,eAQlC,IAAIjD,MAtENc,QAkEMtB,OAAQO,0BAAWoD,QAAA,cAAAhD,mBAezBA,kBAAkBiD,SAAY,KAAM,QAAS,YAAa,WAAY,cAAe","file":"modules/compiler.min.js","sourcesContent":["'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/compiler.js"],"names":["templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","$http","get","bsCompilerService","data","this","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","angular","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","all","templateEl","contentEl","findElement","contentTemplate","removeAttr","html","templates","replace","next","remove","outerHTML","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","service","$inject"],"mappings":"AAOA,YAIA,SAmEQA,mBAAcC,EAAQD,EAAAA,EAAAA,EAAAA,EAAAA,GAA5B,QA4FyDE,GAAOC,EAAAA,GA3F9D,MA4FGC,SAAKC,SAASC,GAAAA,UAAAA,iBAAAA,IAzFnB,QAASC,GAAcC,GACrB,MAAIC,GAAcD,GAAkBC,EAAcD,GAC3CC,EAAcD,GAAYE,EAAMC,IAAIH,GA6F/CI,MAAAA,IA3FOR,KAAK,SAASE,GACf,MAAOA,GAAIO,OA3EfC,KAmEEC,QAAIP,SAAWP,GACXe,EAAAA,UAAaf,UAAQe,KAAAA,EAAAA,YACzBC,QAAIC,KAAAA,oGACJjB,EAAIkB,YAAkBC,EAAKnB,SAC3BA,EAAIoB,SAAiBD,GAErB,IAAIE,GAAAA,EAAmBrB,YAKvBsB,EAAQC,EAAQL,UAAkBM,GAChCT,EAAYU,EAASD,WACnBN,EAAeQ,EAAAA,aAtEfR,EAuEKI,QAAAH,KAAAnB,EAAAkB,aACLA,EAAQS,QAAOD,KAAAA,EAAUE,YAtEzBC,EAAoB7B,EAAQ6B,mBAAqBP,QAAQQ,SACzDT,EAAmBrB,EAAQqB,gBAoF/B,IAVAC,QAAQS,QAAOb,EAASE,SAAAA,EAAAA,GAEpBb,QAAUkB,SAAAD,GACZN,EAAQc,GAAAA,EAAeC,IAAK1B,GAE5BW,EAAQc,GAAAA,EAAY1B,OAAcP,KAvEpCuB,QAAQS,OAAOb,EAASE,GA4EpBpB,EAEFkB,EAAQc,UAAYE,EAAGC,KAAAA,OAEnB,CAAA,IAAIC,EA1ER,KA8EI,IAAOA,OAAAA,6CAhFXlB,GA6EQmB,UAAYC,EAAYvC,GAjElC,MARIC,GAAQuC,kBAiFZrB,EAAUiB,UAAIjB,EAASf,KAAKe,EAASE,UAAAA,EAAAA,EAAAA,mBAAAA,KAAAA,SAAAA,GAEnC,GAAIb,GAAWsB,QAAAA,QAAkBT,EAAOY,IACpChC,EAAcsC,EAAA,sBAAAF,EAAA,IAAAI,WAAA,WAAAC,KAAAC,EAAA,GA/EhB,OAgFAnC,GAAWA,aAASoC,EAAQC,OAAeC,SAhFpCT,EAAW,GAAGU,aAuFvBZ,EAAAC,IAAAjB,GAAAf,KAAA,SAAAiB,GAnFA,GAoFEA,GAAQA,EAAAA,EAAAA,UACRhB,GAASA,OACT2C,EAAMxC,EAAcyC,QAAAA,cAAAA,kBAlFtB,IAsFI5C,GAAIW,QAAYX,QAAA,SAAAqC,KAAAlC,EAAA0C,QAAAC,WArFhBC,EAsFMC,EAAAA,EArFV,QACEhC,OAsFME,EArFNlB,QAASA,EACT2C,KAuFI,SAAWzB,GArFb,GADAF,EAwFEhB,OAAa4C,EACb5C,EAAQiD,CAER,GAAIpC,GAAAA,EAAcF,EAAAK,GAAA,EAChB4B,IAxFA1B,QAAQS,OAAOqB,EAAWE,SAAUlC,EA4FxC,IAAAmC,GAAOJ,QAAaK,SAAMC,GAAAA,EAAAA,GAzFxBrD,GAAQQ,KAAK,0BAA2B2C,GACxCnD,EAAQiD,WAAWzC,KAAK,0BAA2B2C,GAC/CtC,IACF+B,EAAM/B,GAAgBsC,GAG1B,MAAOJ,GAAOO,MAAM,KAAMD,eAQlC,IAAIjD,MAxENc,QAkEMtB,OAAQO,0BAAWoD,QAAA,cAAAhD,mBAiBzBA,kBAAkBiD,SAAY,KAAM,QAAS,YAAa,WAAY,cAAe","file":"modules/compiler.min.js","sourcesContent":["'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/date-formatter.js b/dist/modules/date-formatter.js index cad43e1cf..bea988200 100644 --- a/dist/modules/date-formatter.js +++ b/dist/modules/date-formatter.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 4d2be6051..017c353df 100644 --- a/dist/modules/date-formatter.min.js +++ b/dist/modules/date-formatter.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 7d11adc2f..00740771d 100644 --- a/dist/modules/date-parser.js +++ b/dist/modules/date-parser.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 ce9e6e446..40d2c1e62 100644 --- a/dist/modules/date-parser.min.js +++ b/dist/modules/date-parser.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 9d972580c..975e6b190 100644 --- a/dist/modules/datepicker.js +++ b/dist/modules/datepicker.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 adcff072e..53fce7b73 100644 --- a/dist/modules/datepicker.min.js +++ b/dist/modules/datepicker.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 d7d94a324..468c859b6 100644 --- a/dist/modules/datepicker.tpl.js +++ b/dist/modules/datepicker.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 e76745663..31bba4e2d 100644 --- a/dist/modules/datepicker.tpl.min.js +++ b/dist/modules/datepicker.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 41c1f3be9..146873025 100644 --- a/dist/modules/debounce.js +++ b/dist/modules/debounce.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 fb3fc4c27..eebad6c27 100644 --- a/dist/modules/debounce.min.js +++ b/dist/modules/debounce.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 33d3ed052..5850c9ac7 100644 --- a/dist/modules/dimensions.js +++ b/dist/modules/dimensions.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 f8859d6c3..552e446a0 100644 --- a/dist/modules/dimensions.min.js +++ b/dist/modules/dimensions.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 bb18e81b6..cbdac3662 100644 --- a/dist/modules/dropdown.js +++ b/dist/modules/dropdown.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -44,7 +44,6 @@ angular.module('mgcrea.ngStrap.dropdown', [ 'mgcrea.ngStrap.tooltip' ]).provider }; var show = $dropdown.show; $dropdown.show = function() { - if (!scope.content) return; show(); $timeout(function() { options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown); @@ -77,31 +76,43 @@ angular.module('mgcrea.ngStrap.dropdown', [ 'mgcrea.ngStrap.tooltip' ]).provider return { restrict: 'EAC', scope: true, - link: function postLink(scope, element, attr, transclusion) { - var options = { - scope: scope + compile: function(tElement, tAttrs) { + var options = {}; + if (!tAttrs.bsDropdown) { + var nextSibling = tElement[0].nextSibling; + while (nextSibling && nextSibling.nodeType !== 1) { + nextSibling = nextSibling.nextSibling; + } + if (nextSibling.classList.contains('dropdown-menu')) { + options.template = nextSibling.outerHTML; + options.templateUrl = undefined; + nextSibling.parentNode.removeChild(nextSibling); + } + } + return function postLink(scope, element, attr) { + options.scope = scope; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id' ], function(key) { + if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) { + scope.content = newValue; + }, true); + attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!dropdown || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i); + newValue === true ? dropdown.show() : dropdown.hide(); + }); + var dropdown = $dropdown(element, options); + scope.$on('$destroy', function() { + if (dropdown) dropdown.destroy(); + options = null; + dropdown = null; + }); }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'html', 'container' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; - }); - attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) { - scope.content = newValue; - }, true); - attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { - if (!dropdown || !angular.isDefined(newValue)) return; - if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i); - newValue === true ? dropdown.show() : dropdown.hide(); - }); - var dropdown = $dropdown(element, options); - scope.$on('$destroy', function() { - if (dropdown) dropdown.destroy(); - options = null; - dropdown = null; - }); } }; } ]); \ No newline at end of file diff --git a/dist/modules/dropdown.min.js b/dist/modules/dropdown.min.js index 28b5c7c66..fe84c8a60 100644 --- a/dist/modules/dropdown.min.js +++ b/dist/modules/dropdown.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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',templateUrl:'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),p=d.$scope=s.scope&&s.scope.$new()||n.$new();d=t(o,s);var u=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){i&&i.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 if(!scope.content) return;\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(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', '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","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","nextSibling","tElement","restrict","compile","classList","templateUrl","parentNode","removeChild","nodeType","outerHTML","tAttrs","isDefined","key","falseValueRegExp","attr","bsDropdown","$watch","newValue","oldValue","content","dropdown","isString","match","bsShow","$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 templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n 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 compile: function(tElement, tAttrs) {\n\n // Directive options\n var options = {};\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling.classList.contains('dropdown-menu')) {\n options.template = nextSibling.outerHTML;\n options.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink(scope, element, attr) {\n\n // Directive options\n options.scope = scope;\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\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"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/dropdown.tpl.js b/dist/modules/dropdown.tpl.js index ab0686162..7b4e83ac8 100644 --- a/dist/modules/dropdown.tpl.js +++ b/dist/modules/dropdown.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -8,5 +8,5 @@ 'use strict'; angular.module('mgcrea.ngStrap.dropdown').run([ '$templateCache', function($templateCache) { - $templateCache.put('dropdown/dropdown.tpl.html', ''); + $templateCache.put('dropdown/dropdown.tpl.html', ''); } ]); \ No newline at end of file diff --git a/dist/modules/dropdown.tpl.min.js b/dist/modules/dropdown.tpl.min.js index 637fcace4..792779f3f 100644 --- a/dist/modules/dropdown.tpl.min.js +++ b/dist/modules/dropdown.tpl.min.js @@ -1,8 +1,8 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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').run(['$templateCache',function(e){e.put('dropdown/dropdown.tpl.html','')}]); \ No newline at end of file +'use strict';angular.module('mgcrea.ngStrap.dropdown').run(['$templateCache',function(e){e.put('dropdown/dropdown.tpl.html','')}]); \ No newline at end of file diff --git a/dist/modules/modal.js b/dist/modules/modal.js index be08b0e5a..63a100eff 100644 --- a/dist/modules/modal.js +++ b/dist/modules/modal.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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.min.js b/dist/modules/modal.min.js index abe42327d..f37555d03 100644 --- a/dist/modules/modal.min.js +++ b/dist/modules/modal.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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.js b/dist/modules/modal.tpl.js index 5b58601f0..e123a7620 100644 --- a/dist/modules/modal.tpl.js +++ b/dist/modules/modal.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 d3e8adaa6..79e5d38fa 100644 --- a/dist/modules/modal.tpl.min.js +++ b/dist/modules/modal.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 fe8a480fc..b5c2543a2 100644 --- a/dist/modules/navbar.js +++ b/dist/modules/navbar.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 ee5b052de..76fb644fc 100644 --- a/dist/modules/navbar.min.js +++ b/dist/modules/navbar.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 24d79c65e..907568c3b 100644 --- a/dist/modules/parse-options.js +++ b/dist/modules/parse-options.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 faaa3e55d..b3ad138bc 100644 --- a/dist/modules/parse-options.min.js +++ b/dist/modules/parse-options.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 84e60ad05..96c71d25b 100644 --- a/dist/modules/popover.js +++ b/dist/modules/popover.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 1c96701d6..a6663608f 100644 --- a/dist/modules/popover.min.js +++ b/dist/modules/popover.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 5ea64f621..a348a4293 100644 --- a/dist/modules/popover.tpl.js +++ b/dist/modules/popover.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 fffd4d7de..028618cfa 100644 --- a/dist/modules/popover.tpl.min.js +++ b/dist/modules/popover.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 bf5d47754..6f6d9dd55 100644 --- a/dist/modules/raf.js +++ b/dist/modules/raf.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 6814325dc..0b1de934d 100644 --- a/dist/modules/raf.min.js +++ b/dist/modules/raf.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 d751b28eb..ad47de1a5 100644 --- a/dist/modules/scrollspy.js +++ b/dist/modules/scrollspy.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 f3dab3ddd..8b0d77f95 100644 --- a/dist/modules/scrollspy.min.js +++ b/dist/modules/scrollspy.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 304034fac..b0c441436 100644 --- a/dist/modules/select.js +++ b/dist/modules/select.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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.min.js b/dist/modules/select.min.js index d8ab182aa..ffc747497 100644 --- a/dist/modules/select.min.js +++ b/dist/modules/select.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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.js b/dist/modules/select.tpl.js index c985d810a..96aa1d9bc 100644 --- a/dist/modules/select.tpl.js +++ b/dist/modules/select.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 5aa057752..10127a76d 100644 --- a/dist/modules/select.tpl.min.js +++ b/dist/modules/select.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 40dedfd2d..ef3a4270f 100644 --- a/dist/modules/tab.js +++ b/dist/modules/tab.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 c4531622b..10f9b46e0 100644 --- a/dist/modules/tab.min.js +++ b/dist/modules/tab.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 f893b6dec..130eaf4e1 100644 --- a/dist/modules/tab.tpl.js +++ b/dist/modules/tab.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 ef9b4e93c..93dae91a6 100644 --- a/dist/modules/tab.tpl.min.js +++ b/dist/modules/tab.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 6d2b7184f..df09f2012 100644 --- a/dist/modules/timepicker.js +++ b/dist/modules/timepicker.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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.min.js b/dist/modules/timepicker.min.js index 4d328b0af..59c385256 100644 --- a/dist/modules/timepicker.min.js +++ b/dist/modules/timepicker.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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.js b/dist/modules/timepicker.tpl.js index ca9e7c9ae..bde6f14b9 100644 --- a/dist/modules/timepicker.tpl.js +++ b/dist/modules/timepicker.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 4dbf6bed1..3b0bc1ac9 100644 --- a/dist/modules/timepicker.tpl.min.js +++ b/dist/modules/timepicker.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 dabc5fa30..e59b92d69 100644 --- a/dist/modules/tooltip.js +++ b/dist/modules/tooltip.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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.min.js b/dist/modules/tooltip.min.js index 706ad2268..b0e260297 100644 --- a/dist/modules/tooltip.min.js +++ b/dist/modules/tooltip.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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.js b/dist/modules/tooltip.tpl.js index d78d2b3d6..7c15481f0 100644 --- a/dist/modules/tooltip.tpl.js +++ b/dist/modules/tooltip.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 447c9e2c0..44e3c454b 100644 --- a/dist/modules/tooltip.tpl.min.js +++ b/dist/modules/tooltip.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 3f5486f4b..9cd98582b 100644 --- a/dist/modules/typeahead.js +++ b/dist/modules/typeahead.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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.min.js b/dist/modules/typeahead.min.js index 2bffd5e97..d7bb899c9 100644 --- a/dist/modules/typeahead.min.js +++ b/dist/modules/typeahead.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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.js b/dist/modules/typeahead.tpl.js index 80543dfc2..28861f3f5 100644 --- a/dist/modules/typeahead.tpl.js +++ b/dist/modules/typeahead.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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 80a8e3954..59d3e09c8 100644 --- a/dist/modules/typeahead.tpl.min.js +++ b/dist/modules/typeahead.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.4 - 2015-10-25 + * @version v2.3.5 - 2015-10-29 * @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/dev.html b/docs/dev.html index b08fbbf5a..891a38b5b 100644 --- a/docs/dev.html +++ b/docs/dev.html @@ -51,14 +51,14 @@ -
+ - +
diff --git a/docs/scripts/app.js b/docs/scripts/app.js index c6a0d37e6..497fb7236 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.3.4') +.constant('version', 'v2.3.5') .constant('ngVersion', angular.version.full) .config(function($plunkrProvider, version) { diff --git a/package.json b/package.json index b5299448d..3d3f3c352 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "angular-strap", "description": "AngularStrap - AngularJS directives for Bootstrap", - "version": "2.3.4", + "version": "2.3.5", "keywords": [ "angular", "bootstrap"