/*
 * ark-ui-bootstrap
 * http://ark.genesys.com

 * Version: 1.0.1-4 - 2019-01-16
 * License: LicenseRef-LICENSE
 */
angular.module("ark-ui-bootstrap", ["ark-ui-bootstrap.tpls", "ark-ui-bootstrap.transition","ark-ui-bootstrap.collapse","ark-ui-bootstrap.accordion","ark-ui-bootstrap.bindHtml","ark-ui-bootstrap.buttons","ark-ui-bootstrap.position","ark-ui-bootstrap.dropdown","ark-ui-bootstrap.modal","ark-ui-bootstrap.tooltip","ark-ui-bootstrap.popover","ark-ui-bootstrap.tabs"]);
angular.module("ark-ui-bootstrap.tpls", ["template/accordion/accordion-group.html","template/accordion/accordion.html","template/modal/backdrop.html","template/modal/window-new.html","template/modal/window.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover-html-unsafe-popup.html","template/popover/popover.html","template/tabs/tab.html","template/tabs/tabset.html"]);
angular.module('ark-ui-bootstrap.transition', [])

/**
 * $transition service provides a consistent interface to trigger CSS 3 transitions and to be informed when they complete.
 * @param  {DOMElement} element  The DOMElement that will be animated.
 * @param  {string|object|function} trigger  The thing that will cause the transition to start:
 *   - As a string, it represents the css class to be added to the element.
 *   - As an object, it represents a hash of style attributes to be applied to the element.
 *   - As a function, it represents a function to be called that will cause the transition to occur.
 * @return {Promise}  A promise that is resolved when the transition finishes.
 */
.factory('$transition', ['$q', '$timeout', '$rootScope', function($q, $timeout, $rootScope) {

  var $transition = function(element, trigger, options) {
    options = options || {};
    var deferred = $q.defer();
    var endEventName = $transition[options.animation ? 'animationEndEventName' : 'transitionEndEventName'];

    var transitionEndHandler = function(event) {
      $rootScope.$apply(function() {
        element.unbind(endEventName, transitionEndHandler);
        deferred.resolve(element);
      });
    };

    if (endEventName) {
      element.bind(endEventName, transitionEndHandler);
    }

    // Wrap in a timeout to allow the browser time to update the DOM before the transition is to occur
    $timeout(function() {
      if ( angular.isString(trigger) ) {
        element.addClass(trigger);
      } else if ( angular.isFunction(trigger) ) {
        trigger(element);
      } else if ( angular.isObject(trigger) ) {
        element.css(trigger);
      }
      //If browser does not support transitions, instantly resolve
      if ( !endEventName ) {
        deferred.resolve(element);
      }
    });

    // Add our custom cancel function to the promise that is returned
    // We can call this if we are about to run a new transition, which we know will prevent this transition from ending,
    // i.e. it will therefore never raise a transitionEnd event for that transition
    deferred.promise.cancel = function() {
      if ( endEventName ) {
        element.unbind(endEventName, transitionEndHandler);
      }
      deferred.reject('Transition cancelled');
    };

    return deferred.promise;
  };

  // Work out the name of the transitionEnd event
  var transElement = document.createElement('trans');
  var transitionEndEventNames = {
    'WebkitTransition': 'webkitTransitionEnd',
    'MozTransition': 'transitionend',
    'OTransition': 'oTransitionEnd',
    'transition': 'transitionend'
  };
  var animationEndEventNames = {
    'WebkitTransition': 'webkitAnimationEnd',
    'MozTransition': 'animationend',
    'OTransition': 'oAnimationEnd',
    'transition': 'animationend'
  };
  function findEndEventName(endEventNames) {
    for (var name in endEventNames){
      if (transElement.style[name] !== undefined) {
        return endEventNames[name];
      }
    }
  }
  $transition.transitionEndEventName = findEndEventName(transitionEndEventNames);
  $transition.animationEndEventName = findEndEventName(animationEndEventNames);
  return $transition;
}]);

angular.module('ark-ui-bootstrap.collapse', ['ark-ui-bootstrap.transition'])

  .directive('collapse', ['$transition', function ($transition) {

    return {
      link: function (scope, element, attrs) {

        var initialAnimSkip = true;
        var currentTransition;

        function doTransition(change) {
          var newTransition = $transition(element, change);
          if (currentTransition) {
            currentTransition.cancel();
          }
          currentTransition = newTransition;
          newTransition.then(newTransitionDone, newTransitionDone);
          return newTransition;

          function newTransitionDone() {
            // Make sure it's this transition, otherwise, leave it alone.
            if (currentTransition === newTransition) {
              currentTransition = undefined;
            }
          }
        }

        function expand() {
          if (initialAnimSkip) {
            initialAnimSkip = false;
            expandDone();
          } else {
            element.removeClass('collapse').addClass('collapsing');
            doTransition({ height: element[0].scrollHeight + 'px' }).then(expandDone);
          }
        }

        function expandDone() {
          element.removeClass('collapsing');
          element.addClass('collapse in');
          element.css({height: 'auto'});
        }

        function collapse() {
          if (initialAnimSkip) {
            initialAnimSkip = false;
            collapseDone();
            element.css({height: 0});
          } else {
            // CSS transitions don't work with height: auto, so we have to manually change the height to a specific value
            element.css({ height: element[0].scrollHeight + 'px' });
            //trigger reflow so a browser realizes that height was updated from auto to a specific value
            var x = element[0].offsetWidth;

            element.removeClass('collapse in').addClass('collapsing');

            doTransition({ height: 0 }).then(collapseDone);
          }
        }

        function collapseDone() {
          element.removeClass('collapsing');
          element.addClass('collapse');
        }

        scope.$watch(attrs.collapse, function (shouldCollapse) {
          if (shouldCollapse) {
            collapse();
          } else {
            expand();
          }
        });
      }
    };
  }]);

angular.module('ark-ui-bootstrap.accordion', ['ark-ui-bootstrap.collapse'])

.constant('accordionConfig', {
  closeOthers: true
})

.controller('AccordionController', ['$scope', '$attrs', 'accordionConfig', function ($scope, $attrs, accordionConfig) {

  // This array keeps track of the accordion groups
  this.groups = [];

  // Ensure that all the groups in this accordion are closed, unless close-others explicitly says not to
  this.closeOthers = function(openGroup) {
    var closeOthers = angular.isDefined($attrs.closeOthers) ? $scope.$eval($attrs.closeOthers) : accordionConfig.closeOthers;
    if ( closeOthers ) {
      angular.forEach(this.groups, function (group) {
        if ( group !== openGroup ) {
          group.isOpen = false;
        }
      });
    }
  };

  // This is called from the accordion-group directive to add itself to the accordion
  this.addGroup = function(groupScope) {
    var that = this;
    this.groups.push(groupScope);

    groupScope.$on('$destroy', function (event) {
      that.removeGroup(groupScope);
    });
  };

  // This is called from the accordion-group directive when to remove itself
  this.removeGroup = function(group) {
    var index = this.groups.indexOf(group);
    if ( index !== -1 ) {
      this.groups.splice(index, 1);
    }
  };

}])

// The accordion directive simply sets up the directive controller
// and adds an accordion CSS class to itself element.
.directive('accordion', function () {
  return {
    restrict:'EA',
    controller:'AccordionController',
    transclude: true,
    replace: false,
    templateUrl: 'template/accordion/accordion.html'
  };
})

// The accordion-group directive indicates a block of html that will expand and collapse in an accordion
.directive('accordionGroup', function() {
  return {
    require:'^accordion',         // We need this directive to be inside an accordion
    restrict:'EA',
    transclude:true,              // It transcludes the contents of the directive into the template
    replace: true,                // The element containing the directive will be replaced with the template
    templateUrl:'template/accordion/accordion-group.html',
    scope: {
      heading: '@',               // Interpolate the heading attribute onto this scope
      isOpen: '=?',
      isDisabled: '=?'
    },
    controller: function() {
      this.setHeading = function(element) {
        this.heading = element;
      };
    },
    link: function(scope, element, attrs, accordionCtrl) {
      accordionCtrl.addGroup(scope);

      scope.$watch('isOpen', function(value) {
        if ( value ) {
          accordionCtrl.closeOthers(scope);
        }
      });

      scope.toggleOpen = function() {
        if ( !scope.isDisabled ) {
          scope.isOpen = !scope.isOpen;
        }
      };
    }
  };
})

// Use accordion-heading below an accordion-group to provide a heading containing HTML
// <accordion-group>
//   <accordion-heading>Heading containing HTML - <img src="..."></accordion-heading>
// </accordion-group>
.directive('accordionHeading', function() {
  return {
    restrict: 'EA',
    transclude: true,   // Grab the contents to be used as the heading
    template: '',       // In effect remove this element!
    replace: true,
    require: '^accordionGroup',
    link: function(scope, element, attr, accordionGroupCtrl, transclude) {
      // Pass the heading to the accordion-group controller
      // so that it can be transcluded into the right place in the template
      // [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
      accordionGroupCtrl.setHeading(transclude(scope, function() {}));
    }
  };
})

// Use in the accordion-group template to indicate where you want the heading to be transcluded
// You must provide the property on the accordion-group controller that will hold the transcluded element
// <div class="accordion-group">
//   <div class="accordion-heading" ><a ... accordion-transclude="heading">...</a></div>
//   ...
// </div>
.directive('accordionTransclude', function() {
  return {
    require: '^accordionGroup',
    link: function(scope, element, attr, controller) {
      scope.$watch(function() { return controller[attr.accordionTransclude]; }, function(heading) {
        if ( heading ) {
          element.html('');
          element.append(heading);
        }
      });
    }
  };
});

angular.module('ark-ui-bootstrap.bindHtml', [])

  .directive('bindHtmlUnsafe', function () {
    return function (scope, element, attr) {
      element.addClass('ng-binding').data('$binding', attr.bindHtmlUnsafe);
      scope.$watch(attr.bindHtmlUnsafe, function bindHtmlUnsafeWatchAction(value) {
        element.html(value || '');
      });
    };
  });
angular.module('ark-ui-bootstrap.buttons', [])

.constant('buttonConfig', {
  activeClass: 'active',
  toggleEvent: 'click'
})

.controller('ButtonsController', ['buttonConfig', function(buttonConfig) {
  this.activeClass = buttonConfig.activeClass || 'active';
  this.toggleEvent = buttonConfig.toggleEvent || 'click';
}])

.directive('btnRadio', function () {
  return {
    require: ['btnRadio', 'ngModel'],
    controller: 'ButtonsController',
    link: function (scope, element, attrs, ctrls) {
      var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];

      //model -> UI
      ngModelCtrl.$render = function () {
        element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, scope.$eval(attrs.btnRadio)));
      };

      //ui->model
      element.bind(buttonsCtrl.toggleEvent, function () {
        var isActive = element.hasClass(buttonsCtrl.activeClass);

        if (!isActive || angular.isDefined(attrs.uncheckable)) {
          scope.$apply(function () {
            ngModelCtrl.$setViewValue(isActive ? null : scope.$eval(attrs.btnRadio));
            ngModelCtrl.$render();
          });
        }
      });
    }
  };
})

.directive('btnCheckbox', function () {
  return {
    require: ['btnCheckbox', 'ngModel'],
    controller: 'ButtonsController',
    link: function (scope, element, attrs, ctrls) {
      var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];

      function getTrueValue() {
        return getCheckboxValue(attrs.btnCheckboxTrue, true);
      }

      function getFalseValue() {
        return getCheckboxValue(attrs.btnCheckboxFalse, false);
      }

      function getCheckboxValue(attributeValue, defaultValue) {
        var val = scope.$eval(attributeValue);
        return angular.isDefined(val) ? val : defaultValue;
      }

      //model -> UI
      ngModelCtrl.$render = function () {
        element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, getTrueValue()));
      };

      //ui->model
      element.bind(buttonsCtrl.toggleEvent, function () {
        scope.$apply(function () {
          ngModelCtrl.$setViewValue(element.hasClass(buttonsCtrl.activeClass) ? getFalseValue() : getTrueValue());
          ngModelCtrl.$render();
        });
      });
    }
  };
});

angular.module('ark-ui-bootstrap.position', [])

/**
 * A set of utility methods that can be use to retrieve position of DOM elements.
 * It is meant to be used where we need to absolute-position DOM elements in
 * relation to other, existing elements (this is the case for tooltips, popovers,
 * typeahead suggestions etc.).
 */
  .factory('$position', ['$document', '$window', function ($document, $window) {

    function getStyle(el, cssprop) {
      if (el.currentStyle) { //IE
        return el.currentStyle[cssprop];
      } else if ($window.getComputedStyle) {
        return $window.getComputedStyle(el)[cssprop];
      }
      // finally try and get inline style
      return el.style[cssprop];
    }

    /**
     * Checks if a given element is statically positioned
     * @param element - raw DOM element
     */
    function isStaticPositioned(element) {
      return (getStyle(element, 'position') || 'static' ) === 'static';
    }

    /**
     * returns the closest, non-statically positioned parentOffset of a given element
     * @param element
     */
    var parentOffsetEl = function (element) {
      var docDomEl = $document[0];
      var offsetParent = element.offsetParent || docDomEl;
      while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent) ) {
        offsetParent = offsetParent.offsetParent;
      }
      return offsetParent || docDomEl;
    };

    return {
      /**
       * Provides read-only equivalent of jQuery's position function:
       * http://api.jquery.com/position/
       */
      position: function (element) {
        var elBCR = this.offset(element);
        var offsetParentBCR = { top: 0, left: 0 };
        var offsetParentEl = parentOffsetEl(element[0]);
        if (offsetParentEl != $document[0]) {
          offsetParentBCR = this.offset(angular.element(offsetParentEl));
          offsetParentBCR.top += offsetParentEl.clientTop - offsetParentEl.scrollTop;
          offsetParentBCR.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft;
        }

        var boundingClientRect = element[0].getBoundingClientRect();
        return {
          width: boundingClientRect.width || element.prop('offsetWidth'),
          height: boundingClientRect.height || element.prop('offsetHeight'),
          top: elBCR.top - offsetParentBCR.top,
          left: elBCR.left - offsetParentBCR.left
        };
      },

      /**
       * Provides read-only equivalent of jQuery's offset function:
       * http://api.jquery.com/offset/
       */
      offset: function (element) {
        var boundingClientRect = element[0].getBoundingClientRect();
        return {
          width: boundingClientRect.width || element.prop('offsetWidth'),
          height: boundingClientRect.height || element.prop('offsetHeight'),
          top: boundingClientRect.top + ($window.pageYOffset || $document[0].documentElement.scrollTop),
          left: boundingClientRect.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft)
        };
      },

      /**
       * Provides coordinates for the targetEl in relation to hostEl
       */
      positionElements: function (hostEl, targetEl, positionStr, appendToBody, hostEvent) {

        var positionStrParts = positionStr.split('-');
        var pos0 = positionStrParts[0], pos1 = positionStrParts[1] || 'center';

        var hostElPos,
          targetElWidth,
          targetElHeight,
          targetElPos;

        hostElPos = appendToBody ? this.offset(hostEl) : this.position(hostEl);

        targetElWidth = targetEl.prop('offsetWidth');
        targetElHeight = targetEl.prop('offsetHeight');

        var shiftWidth = {
          center: function () {
            return hostElPos.left + hostElPos.width / 2 - targetElWidth / 2;
          },
          left: function () {
            return hostElPos.left;
          },
          right: function () {
            return hostElPos.left + hostElPos.width;
          }
        };

        var shiftHeight = {
          center: function () {
            return hostElPos.top + hostElPos.height / 2 - targetElHeight / 2;
          },
          top: function () {
            return hostElPos.top;
          },
          bottom: function () {
            return hostElPos.top + hostElPos.height;
          }
        };

        switch (pos0) {
          case 'right':
            targetElPos = {
              top: shiftHeight[pos1](),
              left: shiftWidth[pos0]()
            };
            break;
          case 'left':
            targetElPos = {
              top: shiftHeight[pos1](),
              left: hostElPos.left - targetElWidth
            };
            break;
          case 'bottom':
            targetElPos = {
              top: shiftHeight[pos0](),
              left: shiftWidth[pos1]()
            };
            break;
          case 'top':
            targetElPos = {
              top: hostElPos.top - targetElHeight,
              left: shiftWidth[pos1]()
            };
            break;
          default:
            if (hostEvent && appendToBody && hostEvent.pageY && hostEvent.pageX){
              targetEl.css({'position' : 'absolute',
                            'margin-top' : '15px',
                            'margin-left' : '15px'});

              targetElPos = {
                top: hostEvent.pageY,
                left: hostEvent.pageX
              };
            } else {
              targetElPos = {
                top: hostElPos.top - targetElHeight,
                left: shiftWidth[pos1]()
              };
              break;
            }
        }

        return targetElPos;
      }
    };
  }]);

angular.module('ark-ui-bootstrap.dropdown', ['ark-ui-bootstrap.position'])

.constant('dropdownConfig', {
  openClass: 'open active'
})

.service('dropdownService', ['$document', '$rootScope', function($document, $rootScope) {
  var openScope = null;

  this.open = function(dropdownScope) {
    if (!openScope) {
      $document.bind('click', closeDropdown);
      $document.bind('keydown', keybindFilter);
    }

    if (openScope && openScope !== dropdownScope) {
      openScope.isOpen = false;
    }

    openScope = dropdownScope;
  };

  this.close = function(dropdownScope) {
    if (openScope === dropdownScope) {
      openScope = null;
      $document.unbind('click', closeDropdown);
      $document.unbind('keydown', keybindFilter);
    }
  };

  var closeDropdown = function(evt) {
    // This method may still be called during the same mouse event that
    // unbound this event handler. So check openScope before proceeding.
    if (!openScope) {
      return;
    }

    if (evt && openScope.getAutoClose() === 'disabled') {
      return;
    }

    var toggleElement = openScope.getToggleElement();
    if (evt && toggleElement && toggleElement[0].contains(evt.target)) {
      return;
    }

    var dropdownElement = openScope.getDropdownElement();
    if (evt && openScope.getAutoClose() === 'outsideClick' &&
      dropdownElement && dropdownElement[0].contains(evt.target)) {
      return;
    }

    openScope.isOpen = false;

    if (!$rootScope.$$phase) {
      openScope.$apply();
    }
  };

  var keybindFilter = function(evt) {
    if (evt.which === 27) {
      openScope.focusToggleElement();
      closeDropdown();
    } else if (openScope.isKeynavEnabled() && /(38|40)/.test(evt.which) && openScope.isOpen) {
      evt.preventDefault();
      evt.stopPropagation();
      openScope.focusDropdownEntry(evt.which);
    }
  };
}])

.controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', '$position', '$document', '$compile', '$templateRequest', '$window', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate, $position, $document, $compile, $templateRequest, $window) {
  var self = this,
    scope = $scope.$new(), // create a child scope so we are not polluting original one
    templateScope,
    openClass = dropdownConfig.openClass,
    getIsOpen,
    setIsOpen = angular.noop,
    toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop,
    appendToBody = false,
    keynavEnabled = false,
    selectedOption = null,
    dropdownUp = false,
    dropdownTemplateHeight = null;

  // dynamically sets position of dropdown menu when it is appended to body
  var setAppendedPosition = function() {
    var pos = $position.positionElements(self.$element, self.dropdownMenu, 'bottom-left', true);

    if (dropdownUp && !self.$element.hasClass('ark-no-dropup')) {
      self.dropdownMenu.css('display', 'inline-block');
      pos.top = pos.top - self.$element[0].offsetHeight - self.dropdownMenu[0].offsetHeight - 6;
      self.dropdownMenu.attr('style', '');
    }
    var css = {
      top: pos.top + 'px',
      display: scope.isOpen ? 'block' : 'none'
    };

    var rightalign = self.dropdownMenu.hasClass('dropdown-menu-right');
    if (!rightalign) {
      css.left = pos.left + 'px';
      css.right = 'auto';
    } else {
      css.left = 'auto';
      css.right = (window.innerWidth - (pos.left + self.$element.prop('offsetWidth'))) + 'px';
    }

    self.dropdownMenu.css(css);
  };

  this.init = function(element) {
    self.$element = element;
    self.dropdownMenu = element.find('ul');

    var windowElement = angular.element($window),
      toggleDropdownUp = _.debounce(function() {
        if (!(element.hasClass('ark-no-dropup'))) {
          self.dropdownMenu.css('display', 'inline-block');
          var dropdownMenuHeight = dropdownTemplateHeight ?
            dropdownTemplateHeight :
            (self.dropdownMenu[0] && self.dropdownMenu[0].offsetHeight);
          dropdownUp = $window.pageYOffset <=
            $position.offset(self.$element).top - $window.innerHeight + self.$element[0].offsetHeight + dropdownMenuHeight + 10;
          self.dropdownMenu.attr('style', '');
          self.$element.toggleClass('dropup', dropdownUp);
          if (appendToBody && self.dropdownMenu && !self.$element.hasClass('ark-no-dropup')) {
            setAppendedPosition();
          }
          $scope.$apply();
        }
      }, 600);

    if ($attrs.isOpen) {
      getIsOpen = $parse($attrs.isOpen);
      setIsOpen = getIsOpen.assign;

      $scope.$watch(getIsOpen, function(value) {
        scope.isOpen = !!value;
      });
    }

    appendToBody = angular.isDefined($attrs.dropdownAppendToBody);
    keynavEnabled = angular.isDefined($attrs.keyboardNav);

    if (appendToBody && self.dropdownMenu) {
      $document.find('body').append(self.dropdownMenu);
      windowElement.bind('resize', setAppendedPosition);
      element.on('$destroy', function() {
        self.dropdownMenu.remove();
      });
    }

    // compiles and stores height of dropdown template to allow dropdown/up functionality when closed
    if (self.dropdownMenuTemplateUrl) {
      $templateRequest(self.dropdownMenuTemplateUrl).then(function(tplContent) {
        templateScope = scope.$new();
        $compile(tplContent.trim())(templateScope, function(dropdownElement) {
          var newEl = dropdownElement;
          self.dropdownMenu.replaceWith(newEl);
          self.dropdownMenu = newEl;
          self.dropdownMenu.css('display', 'inline-block');
          dropdownTemplateHeight = self.dropdownMenu[0].offsetHeight;
        });
        templateScope.$destroy();
        newEl = angular.element('<ul class="dropdown-menu"></ul>');
        self.dropdownMenu.replaceWith(newEl);
        self.dropdownMenu = newEl;
      });
    }

    toggleDropdownUp(); // runs on init
    windowElement.bind('scroll', toggleDropdownUp);

    $scope.$on('$destroy', function() {
      windowElement.unbind('scroll', toggleDropdownUp);
      windowElement.unbind('resize', setAppendedPosition);
    });
  };

  this.toggle = function(open) {
    return scope.isOpen = arguments.length ? !!open : !scope.isOpen;
  };

  // Allow other directives to watch status
  this.isOpen = function() {
    return scope.isOpen;
  };

  scope.getToggleElement = function() {
    return self.toggleElement;
  };

  scope.getAutoClose = function() {
    return $attrs.autoClose || 'always'; //or 'outsideClick' or 'disabled'
  };

  scope.getElement = function() {
    return self.$element;
  };

  scope.isKeynavEnabled = function() {
    return keynavEnabled;
  };

  scope.focusDropdownEntry = function(keyCode) {
    var elems = self.dropdownMenu ? //If append to body is used.
      (angular.element(self.dropdownMenu).find('a')) :
      (angular.element(self.$element).find('ul').eq(0).find('a'));

    switch (keyCode) {
      case (40):
        {
          if (!angular.isNumber(self.selectedOption)) {
            self.selectedOption = 0;
          } else {
            self.selectedOption = (self.selectedOption === elems.length - 1 ?
              self.selectedOption :
              self.selectedOption + 1);
          }
          break;
        }
      case (38):
        {
          if (!angular.isNumber(self.selectedOption)) {
            return;
          } else {
            self.selectedOption = (self.selectedOption === 0 ?
              0 :
              self.selectedOption - 1);
          }
          break;
        }
    }
    elems[self.selectedOption].focus();
  };

  scope.getDropdownElement = function() {
    return self.dropdownMenu;
  };

  scope.focusToggleElement = function() {
    if (self.toggleElement) {
      self.toggleElement[0].focus();
    }
  };

  scope.$watch('isOpen', function(isOpen, wasOpen) {
    if (appendToBody && self.dropdownMenu) {
      setAppendedPosition();
    }

    $animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass).then(function() {
      if (angular.isDefined(isOpen) && isOpen !== wasOpen) {
        toggleInvoker($scope, {
          open: !!isOpen
        });
      }
    });

    if (isOpen) {
      if (self.dropdownMenuTemplateUrl) {
        $templateRequest(self.dropdownMenuTemplateUrl).then(function(tplContent) {
          templateScope = scope.$new();
          $compile(tplContent.trim())(templateScope, function(dropdownElement) {
            var newEl = dropdownElement;
            self.dropdownMenu.replaceWith(newEl);
            self.dropdownMenu = newEl;
          });
        });
      }

      scope.focusToggleElement();
      dropdownService.open(scope);
    } else {
      if (self.dropdownMenuTemplateUrl) {
        if (templateScope) {
          templateScope.$destroy();
        }
        var newEl = angular.element('<ul class="dropdown-menu"></ul>');
        self.dropdownMenu.replaceWith(newEl);
        self.dropdownMenu = newEl;
      }

      dropdownService.close(scope);
      self.selectedOption = null;
    }

    if (angular.isFunction(setIsOpen)) {
      setIsOpen($scope, isOpen);
    }
  });

  $scope.$on('$locationChangeSuccess', function() {
    if (scope.getAutoClose() !== 'disabled') {
      scope.isOpen = false;
    }
  });

  $scope.$on('$destroy', function() {
    scope.$destroy();
  });
}])

.directive('arkDropdown', function() {
  return {
    restrict: 'CA',
    controller: 'DropdownController',
    link: function(scope, element, attrs, dropdownCtrl) {
      dropdownCtrl.init(element);
    }
  };
})

.directive('dropdownMenu', function() {
  return {
    restrict: 'AC',
    require: '?^arkDropdown',
    link: function(scope, element, attrs, dropdownCtrl) {
      if (!dropdownCtrl) {
        return;
      }
      var tplUrl = attrs.templateUrl;
      if (tplUrl) {
        dropdownCtrl.dropdownMenuTemplateUrl = tplUrl;
      }
      if (!dropdownCtrl.dropdownMenu) {
        dropdownCtrl.dropdownMenu = element;
      }
    }
  };
})

.directive('keyboardNav', function() {
  return {
    restrict: 'A',
    require: '?^arkDropdown',
    link: function(scope, element, attrs, dropdownCtrl) {

      element.bind('keydown', function(e) {

        if ([38, 40].indexOf(e.which) !== -1) {

          e.preventDefault();
          e.stopPropagation();

          var elems = angular.element(element).find('a');

          switch (e.keyCode) {
            case (40):
              { // Down
                if (!angular.isNumber(dropdownCtrl.selectedOption)) {
                  dropdownCtrl.selectedOption = 0;
                } else {
                  dropdownCtrl.selectedOption = (dropdownCtrl.selectedOption === elems.length - 1 ? dropdownCtrl.selectedOption : dropdownCtrl.selectedOption + 1);
                }

              }
              break;
            case (38):
              { // Up
                dropdownCtrl.selectedOption = (dropdownCtrl.selectedOption === 0 ? 0 : dropdownCtrl.selectedOption - 1);
              }
              break;
          }
          elems[dropdownCtrl.selectedOption].focus();
        }
      });
    }

  };
})

.directive('arkDropdownToggle', function() {
  return {
    restrict: 'CA',
    require: '?^arkDropdown',
    link: function(scope, element, attrs, dropdownCtrl) {
      if (!dropdownCtrl) {
        return;
      }

      element.addClass('dropdown-toggle');

      dropdownCtrl.toggleElement = element;

      var toggleDropdown = function(event) {
        event.preventDefault();

        if (!element.hasClass('disabled') && !attrs.disabled) {
          scope.$apply(function() {
            dropdownCtrl.toggle();
          });
        }
      };

      element.bind('click', toggleDropdown);

      // WAI-ARIA
      element.attr({
        'aria-haspopup': true,
        'aria-expanded': false
      });
      scope.$watch(dropdownCtrl.isOpen, function(isOpen) {
        element.attr('aria-expanded', !!isOpen);
      });

      scope.$on('$destroy', function() {
        element.unbind('click', toggleDropdown);
      });
    }
  };
});

angular.module('ark-ui-bootstrap.modal', ['ark-ui-bootstrap.transition'])

/**
 * A helper, internal data structure that acts as a map but also allows getting / removing
 * elements in the LIFO order
 */
  .factory('$$stackedMap', function () {
    return {
      createNew: function () {
        var stack = [];

        return {
          add: function (key, value) {
            stack.push({
              key: key,
              value: value
            });
          },
          get: function (key) {
            for (var i = 0; i < stack.length; i++) {
              if (key == stack[i].key) {
                return stack[i];
              }
            }
          },
          keys: function() {
            var keys = [];
            for (var i = 0; i < stack.length; i++) {
              keys.push(stack[i].key);
            }
            return keys;
          },
          top: function () {
            return stack[stack.length - 1];
          },
          remove: function (key) {
            var idx = -1;
            for (var i = 0; i < stack.length; i++) {
              if (key == stack[i].key) {
                idx = i;
                break;
              }
            }
            return stack.splice(idx, 1)[0];
          },
          removeTop: function () {
            return stack.splice(stack.length - 1, 1)[0];
          },
          length: function () {
            return stack.length;
          }
        };
      }
    };
  })

/**
 * A helper directive for the $modal service. It creates a backdrop element.
 */
  .directive('modalBackdrop', ['$timeout', function ($timeout) {
    return {
      restrict: 'EA',
      replace: true,
      templateUrl: 'template/modal/backdrop.html',
      link: function (scope, element, attrs) {
        scope.backdropClass = attrs.backdropClass || '';

        scope.animate = false;

        //trigger CSS transitions
        $timeout(function () {
          scope.animate = true;
        });
      }
    };
  }])

  .directive('modalWindow', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
    return {
      restrict: 'EA',
      scope: {
        index: '@',
        animate: '='
      },
      replace: true,
      transclude: true,
      templateUrl: function(tElement, tAttrs) {
        if (tAttrs.newStyle === 'true') {
          return tAttrs.templateUrl || 'template/modal/window-new.html';
        }
        else {
          return tAttrs.templateUrl || 'template/modal/window.html';
        }
      },
      link: function (scope, element, attrs) {
        element.addClass(attrs.windowClass || '');
        scope.size = attrs.size;

        $timeout(function () {
          // trigger CSS transitions
          scope.animate = true;
          // focus a freshly-opened modal
          element[0].focus();
        });

        scope.close = function (evt) {
          var modal = $modalStack.getTop();
          if (modal && modal.value.backdrop && modal.value.backdrop != 'static' && (evt.target === evt.currentTarget)) {
            evt.preventDefault();
            evt.stopPropagation();
            $modalStack.dismiss(modal.key, 'backdrop click');
          }
        };
      }
    };
  }])

  .directive('modalTransclude', function () {
    return {
      link: function($scope, $element, $attrs, controller, $transclude) {
        $transclude($scope.$parent, function(clone) {
          $element.empty();
          $element.append(clone);
        });
      }
    };
  })

  .factory('$modalStack', ['$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap',
    function ($transition, $timeout, $document, $compile, $rootScope, $$stackedMap) {

      var OPENED_MODAL_CLASS = 'modal-open';

      var backdropDomEl, backdropScope;
      var openedWindows = $$stackedMap.createNew();
      var $modalStack = {};

      function backdropIndex() {
        var topBackdropIndex = -1;
        var opened = openedWindows.keys();
        for (var i = 0; i < opened.length; i++) {
          if (openedWindows.get(opened[i]).value.backdrop) {
            topBackdropIndex = i;
          }
        }
        return topBackdropIndex;
      }

      $rootScope.$watch(backdropIndex, function(newBackdropIndex){
        if (backdropScope) {
          backdropScope.index = newBackdropIndex;
        }
      });

      function removeModalWindow(modalInstance) {

        var body = $document.find('body').eq(0);
        var modalWindow = openedWindows.get(modalInstance).value;

        //clean up the stack
        openedWindows.remove(modalInstance);

        //remove window DOM element
        removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, 300, function() {
          modalWindow.modalScope.$destroy();
          body.toggleClass(OPENED_MODAL_CLASS, openedWindows.length() > 0);
          checkRemoveBackdrop();
        });
      }

      function checkRemoveBackdrop() {
          //remove backdrop if no longer needed
          if (backdropDomEl && backdropIndex() == -1) {
            var backdropScopeRef = backdropScope;
            removeAfterAnimate(backdropDomEl, backdropScope, 150, function () {
              backdropScopeRef.$destroy();
              backdropScopeRef = null;
            });
            backdropDomEl = undefined;
            backdropScope = undefined;
          }
      }

      function removeAfterAnimate(domEl, scope, emulateTime, done) {
        // Closing animation
        scope.animate = false;

        var transitionEndEventName = $transition.transitionEndEventName;
        if (transitionEndEventName) {
          // transition out
          var timeout = $timeout(afterAnimating, emulateTime);

          domEl.bind(transitionEndEventName, function () {
            $timeout.cancel(timeout);
            afterAnimating();
            scope.$apply();
          });
        } else {
          // Ensure this call is async
          $timeout(afterAnimating);
        }

        function afterAnimating() {
          if (afterAnimating.done) {
            return;
          }
          afterAnimating.done = true;

          domEl.remove();
          if (done) {
            done();
          }
        }
      }

      $document.bind('keydown', function (evt) {
        var modal;

        if (evt.which === 27) {
          modal = openedWindows.top();
          if (modal && modal.value.keyboard) {
            evt.preventDefault();
            $rootScope.$apply(function () {
              $modalStack.dismiss(modal.key, 'escape key press');
            });
          }
        }
      });

      $modalStack.open = function (modalInstance, modal) {

        openedWindows.add(modalInstance, {
          deferred: modal.deferred,
          modalScope: modal.scope,
          backdrop: modal.backdrop,
          keyboard: modal.keyboard
        });

        var body = $document.find('body').eq(0),
            currBackdropIndex = backdropIndex();

        if (currBackdropIndex >= 0 && !backdropDomEl) {
          backdropScope = $rootScope.$new(true);
          backdropScope.index = currBackdropIndex;
          var angularBackgroundDomEl = angular.element('<div modal-backdrop></div>');
          angularBackgroundDomEl.attr('backdrop-class', modal.backdropClass);
          backdropDomEl = $compile(angularBackgroundDomEl)(backdropScope);
          body.append(backdropDomEl);
        }

        var angularDomEl = angular.element('<div modal-window></div>');
        angularDomEl.attr({
          'template-url': modal.windowTemplateUrl,
          'window-class': modal.windowClass,
          'size': modal.size,
          'index': openedWindows.length() - 1,
          'animate': 'animate',
          'new-style': modal.newStyle
        }).html(modal.content);

        var modalDomEl = $compile(angularDomEl)(modal.scope);
        openedWindows.top().value.modalDomEl = modalDomEl;
        body.append(modalDomEl);
        body.addClass(OPENED_MODAL_CLASS);
      };

      $modalStack.close = function (modalInstance, result) {
        var modalWindow = openedWindows.get(modalInstance);
        if (modalWindow) {
          modalWindow.value.deferred.resolve(result);
          removeModalWindow(modalInstance);
        }
      };

      $modalStack.dismiss = function (modalInstance, reason) {
        var modalWindow = openedWindows.get(modalInstance);
        if (modalWindow) {
          modalWindow.value.deferred.reject(reason);
          removeModalWindow(modalInstance);
        }
      };

      $modalStack.dismissAll = function (reason) {
        var topModal = this.getTop();
        while (topModal) {
          this.dismiss(topModal.key, reason);
          topModal = this.getTop();
        }
      };

      $modalStack.getTop = function () {
        return openedWindows.top();
      };

      return $modalStack;
    }])

  .provider('$modal', function () {

    var $modalProvider = {
      options: {
        backdrop: true, //can be also false or 'static'
        keyboard: true
      },
      $get: ['$injector', '$rootScope', '$q', '$http', '$templateCache', '$controller', '$modalStack',
        function ($injector, $rootScope, $q, $http, $templateCache, $controller, $modalStack) {

          var $modal = {};

          function getTemplatePromise(options) {
            return options.template ? $q.when(options.template) :
              $http.get(angular.isFunction(options.templateUrl) ? (options.templateUrl)() : options.templateUrl,
                {cache: $templateCache}).then(function (result) {
                  return result.data;
              });
          }

          function getResolvePromises(resolves) {
            var promisesArr = [];
            angular.forEach(resolves, function (value) {
              if (angular.isFunction(value) || angular.isArray(value)) {
                promisesArr.push($q.when($injector.invoke(value)));
              }
            });
            return promisesArr;
          }

          $modal.open = function (modalOptions) {

            var modalResultDeferred = $q.defer();
            var modalOpenedDeferred = $q.defer();

            //prepare an instance of a modal to be injected into controllers and returned to a caller
            var modalInstance = {
              result: modalResultDeferred.promise,
              opened: modalOpenedDeferred.promise,
              close: function (result) {
                $modalStack.close(modalInstance, result);
              },
              dismiss: function (reason) {
                $modalStack.dismiss(modalInstance, reason);
              }
            };

            //merge and clean up options
            modalOptions = angular.extend({}, $modalProvider.options, modalOptions);
            modalOptions.resolve = modalOptions.resolve || {};

            //verify options
            if (!modalOptions.template && !modalOptions.templateUrl) {
              throw new Error('One of template or templateUrl options is required.');
            }

            var templateAndResolvePromise =
              $q.all([getTemplatePromise(modalOptions)].concat(getResolvePromises(modalOptions.resolve)));


            templateAndResolvePromise.then(function resolveSuccess(tplAndVars) {

              var modalScope = (modalOptions.scope || $rootScope).$new();
              modalScope.$close = modalInstance.close;
              modalScope.$dismiss = modalInstance.dismiss;

              var ctrlInstance, ctrlLocals = {};
              var resolveIter = 1;

              //controllers
              if (modalOptions.controller) {
                ctrlLocals.$scope = modalScope;
                ctrlLocals.$modalInstance = modalInstance;
                angular.forEach(modalOptions.resolve, function (value, key) {
                  ctrlLocals[key] = tplAndVars[resolveIter++];
                });

                ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
                if (modalOptions.controller) {
                  modalScope[modalOptions.controllerAs] = ctrlInstance;
                }
              }

              $modalStack.open(modalInstance, {
                scope: modalScope,
                deferred: modalResultDeferred,
                content: tplAndVars[0],
                backdrop: modalOptions.backdrop,
                keyboard: modalOptions.keyboard,
                backdropClass: modalOptions.backdropClass,
                windowClass: modalOptions.windowClass,
                windowTemplateUrl: modalOptions.windowTemplateUrl,
                newStyle: modalOptions.newStyle,
                size: modalOptions.size
              });

            }, function resolveError(reason) {
              modalResultDeferred.reject(reason);
            });

            templateAndResolvePromise.then(function () {
              modalOpenedDeferred.resolve(true);
            }, function () {
              modalOpenedDeferred.reject(false);
            });

            return modalInstance;
          };

          return $modal;
        }]
    };

    return $modalProvider;
  });

/**
 * The following features are still outstanding: animation as a
 * function, placement as a function, inside, support for more triggers than
 * just mouse enter/leave, html tooltips, and selector delegation.
 */
angular.module('ark-ui-bootstrap.tooltip', ['ark-ui-bootstrap.position', 'ark-ui-bootstrap.bindHtml'])

/**
 * The $tooltip service creates tooltip- and popover-like directives as well as
 * houses global options for them.
 */
.provider('$tooltip', function() {
  // The default options tooltip and popover.
  var defaultOptions = {
    placement: 'default',
    animation: true,
    popupDelay: 0,
    appendToBody: true,
    keepInsideViewport: true
  };

  // Default hide triggers for each show trigger
  var triggerMap = {
    'mouseenter': 'mouseleave',
    'mousemove': 'mouseleave',
    'click': 'click',
    'focus': 'blur'
  };

  // The options specified to the provider globally.
  var globalOptions = {};

  /**
   * `options({})` allows global configuration of all tooltips in the
   * application.
   *
   *   var app = angular.module( 'App', ['ark-ui-bootstrap.tooltip'], function( $tooltipProvider ) {
   *     // place tooltips left instead of top by default
   *     $tooltipProvider.options( { placement: 'left' } );
   *   });
   */
  this.options = function(value) {
    angular.extend(globalOptions, value);
  };

  /**
   * This allows you to extend the set of trigger mappings available. E.g.:
   *
   *   $tooltipProvider.setTriggers( 'openTrigger': 'closeTrigger' );
   */
  this.setTriggers = function setTriggers(triggers) {
    angular.extend(triggerMap, triggers);
  };

  /**
   * This is a helper function for translating camel-case to snake-case.
   */
  function snake_case(name) {
    var regexp = /[A-Z]/g;
    var separator = '-';
    return name.replace(regexp, function(letter, pos) {
      return (pos ? separator : '') + letter.toLowerCase();
    });
  }

  /**
   * Returns the actual instance of the $tooltip service.
   * TODO support multiple triggers
   */
  this.$get = ['$window', '$compile', '$timeout', '$parse', '$document', '$position', '$interpolate',
    function($window, $compile, $timeout, $parse, $document, $position, $interpolate) {
      return function $tooltip(type, prefix, defaultTriggerShow, customOptions) {
        var options = angular.extend({}, defaultOptions, globalOptions, customOptions);

        /**
         * Returns an object of show and hide triggers.
         *
         * If a trigger is supplied,
         * it is used to show the tooltip; otherwise, it will use the `trigger`
         * option passed to the `$tooltipProvider.options` method; else it will
         * default to the trigger supplied to this directive factory.
         *
         * The hide trigger is based on the show trigger. If the `trigger` option
         * was passed to the `$tooltipProvider.options` method, it will use the
         * mapped trigger from `triggerMap` or the passed trigger if the map is
         * undefined; otherwise, it uses the `triggerMap` value of the show
         * trigger; else it will just use the show trigger.
         */
        function getTriggers(trigger) {
          var show = trigger || options.trigger || defaultTriggerShow;
          var hide = triggerMap[show] || show;
          return {
            show: show,
            hide: hide
          };
        }

        var directiveName = snake_case(type);

        var startSym = $interpolate.startSymbol();
        var endSym = $interpolate.endSymbol();
        var template =
          '<div ' + directiveName + '-popup ' +
          'title="' + startSym + 'tt_title' + endSym + '" ' +
          'content="' + startSym + 'tt_content' + endSym + '" ' +
          'placement="' + startSym + 'tt_placement' + endSym + '" ' +
          'animation="tt_animation" ' +
          'is-open="tt_isOpen"' +
          '>' +
          '</div>';

        return {
          restrict: 'EA',
          scope: true,
          compile: function(tElem, tAttrs) {
            var tooltipLinker = $compile(template);

            return function link(scope, element, attrs) {
              var tooltip;
              var tooltipLinkedScope;
              var transitionTimeout;
              var popupTimeout;
              var appendToBody = angular.isDefined(options.appendToBody) ? options.appendToBody : false;
              var keepInsideViewport = angular.isDefined(options.keepInsideViewport) ? options.keepInsideViewport : true;
              var triggers = getTriggers(undefined);
              var hasEnableExp = angular.isDefined(attrs[prefix + 'Enable']);

              var popoverAddArrowClass = function(popover, popoverPos, arrowPos) {
                var arrow = angular.element(popover[0].querySelector('.arrow'));

                //default case is bottom
                switch (popoverPos) {

                  case 'right':
                    arrowPos = (arrowPos) ? arrowPos : 'top';
                    if (arrowPos == 'top') {
                      arrow.addClass('top');
                    } else if (arrowPos == 'bottom') {
                      arrow.addClass('bottom');
                    }
                    break;
                  case 'bottom':
                    arrowPos = (arrowPos) ? arrowPos : 'left';
                    if (arrowPos == 'left') {
                      arrow.addClass('left');
                    } else if (arrowPos == 'right') {
                      arrow.addClass('right');
                    }
                    break;

                  case 'left':
                    arrowPos = (arrowPos) ? arrowPos : 'top';
                    if (arrowPos == 'top') {
                      arrow.addClass('top');
                    } else if (arrowPos == 'bottom') {
                      arrow.addClass('bottom');
                    }
                    break;

                  default: //'top'
                    arrowPos = (arrowPos) ? arrowPos : 'left';
                    if (arrowPos == 'left') {
                      arrow.addClass('left');
                    } else if (arrowPos == 'right') {
                      arrow.addClass('right');
                    }
                    break;
                    //votebad[1].append();
                }
              };

              var popoverArrowReposition = function(arrowPos, height, width, pos) {
                switch (arrowPos) {
                  case 'top':
                    return {
                      top: pos.top + (height / 2 - 30),
                      left: pos.left
                    };
                  case 'bottom':
                    return {
                      top: pos.top - (height / 2 - 30),
                      left: pos.left
                    };
                  case 'left':
                    return {
                      top: pos.top,
                      left: pos.left + (width / 2 - 30)
                    };
                  case 'right':
                    return {
                      top: pos.top,
                      left: pos.left - (width / 2 - 30)
                    };
                }
              };

              var popoverWithinViewport = function(pos, boundaries) {
                return pos.top >= boundaries.minY && pos.top <= boundaries.maxY && pos.left >= boundaries.minX && pos.left <= boundaries.maxX;
              };

              var popoverReposition = function(element, popover, pos, boundaries, event) {
                var poHeight = popover[0].offsetHeight;
                var poWidth = popover[0].offsetWidth;
                var arrowPos = attrs.arrowPlacement;
                var popoverPos = attrs.popoverPlacement;
                var elOffset = $position.offset(element);
                var elWidth = elOffset.width;
                var elHeight = elOffset.height;
                var positions = ['top', 'bottom', 'left', 'right'];
                var arrows = {
                  'top': ['left', 'right'],
                  'bottom': ['left', 'right'],
                  'left': ['top', 'bottom'],
                  'right': ['top', 'bottom']
                };
                var placement, arrow, tempPos;

                if (popoverPos !== 'bottom' && popoverPos !== 'left' && popoverPos !== 'right') {
                  popoverPos = 'top';
                }
                if (arrowPos !== arrows[popoverPos][1]) {
                  arrowPos = arrows[popoverPos][0];
                }

                // we'll try current popover placement first
                var result = popoverMinorRepositioning(boundaries, elWidth, elHeight, arrowPos, popoverPos, poWidth, poHeight, pos);
                if (result !== null) {
                  return result;
                }

                // Looping through all possible
                for (var j = 0; j < positions.length; j++) {
                  placement = positions[j];
                  tempPos = $position.positionElements(element, popover, placement, appendToBody, event);
                  for (var i = 0; i <= 1; i++) {
                    result = popoverMinorRepositioning(boundaries, elWidth, elHeight, arrows[placement][i], placement, poWidth, poHeight, tempPos);
                    if (result !== null) {
                      return result;
                    }
                  }
                }

                // really, nothing works.  we'll go with the original
                tempPos = popoverArrowReposition(arrowPos, poHeight, poWidth, pos);
                return {
                  top: tempPos.top,
                  left: tempPos.left,
                  arrowPlacement: arrowPos,
                  popoverPlacement: popoverPos
                };
              };

              var popoverMinorRepositioning = function(boundaries, elWidth, elHeight, arrowPos, popoverPos, poWidth, poHeight, pos) {

                // 1. check if the popover is within viewport
                var adjPos = popoverArrowReposition(arrowPos, poHeight, poWidth, pos);
                if (popoverWithinViewport(adjPos, boundaries)) {
                  return {
                    top: adjPos.top,
                    left: adjPos.left,
                    popoverPlacement: popoverPos,
                    arrowPlacement: arrowPos
                  };
                }
                var opposites = {
                  top: 'bottom',
                  bottom: 'top',
                  left: 'right',
                  right: 'left'
                };


                // 2. OK, it's not within viewport. Can we slide it, keeping the direction of popover placement infact?
                if (popoverSlidable(popoverPos, adjPos, boundaries)) {
                  switch (arrowPos) {
                    case 'left':
                    case 'right':
                      if (adjPos.left > boundaries.maxX && adjPos.left - elWidth / 2 <= boundaries.maxX) {
                        return {
                          top: adjPos.top,
                          left: boundaries.maxX,
                          popoverPlacement: popoverPos,
                          arrowPlacement: arrowPos
                        };
                      } else if (adjPos.left < boundaries.minX && adjPos.left + elWidth / 2 >= boundaries.minX) {
                        return {
                          top: adjPos.top,
                          left: boundaries.minX,
                          popoverPlacement: popoverPos,
                          arrowPlacement: arrowPos
                        };
                      } else {
                        adjPos = popoverArrowReposition(opposites[arrowPos], poHeight, poWidth, pos);
                        if (popoverWithinViewport(adjPos, boundaries)) {
                          return {
                            top: adjPos.top,
                            left: adjPos.left,
                            popoverPlacement: popoverPos,
                            arrowPlacement: opposites[arrowPos]
                          };
                        } else if (adjPos.left < boundaries.minX && adjPos.left + elWidth / 2 >= boundaries.minX) {
                          return {
                            top: adjPos.top,
                            left: boundaries.minX,
                            popoverPlacement: popoverPos,
                            arrowPlacement: opposites[arrowPos]
                          };
                        } else if (adjPos.left > boundaries.maxX && adjPos.left - elWidth / 2 <= boundaries.maxX) {
                          return {
                            top: adjPos.top,
                            left: boundaries.maxX,
                            popoverPlacement: popoverPos,
                            arrowPlacement: opposites[arrowPos]
                          };
                        }
                      }
                      break;
                    case 'top':
                    case 'bottom':
                      if (adjPos.top > boundaries.maxY && adjPos.top - elHeight / 2 <= boundaries.maxY) {
                        return {
                          top: boundaries.maxY,
                          left: adjPos.left,
                          popoverPlacement: popoverPos,
                          arrowPlacement: arrowPos
                        };
                      } else if (adjPos.top < boundaries.minY && adjPos.top + elHeight / 2 >= boundaries.minY) {
                        return {
                          top: boundaries.minY,
                          left: adjPos.left,
                          popoverPlacement: popoverPos,
                          arrowPlacement: arrowPos
                        };
                      } else {
                        adjPos = popoverArrowReposition(opposites[arrowPos], poHeight, poWidth, pos);
                        if (popoverWithinViewport(adjPos, boundaries)) {
                          return {
                            top: adjPos.top,
                            left: adjPos.left,
                            popoverPlacement: popoverPos,
                            arrowPlacement: opposites[arrowPos]
                          };
                        } else if (adjPos.top < boundaries.minY && adjPos.top + elHeight / 2 >= boundaries.minY) {
                          return {
                            top: boundaries.minY,
                            left: adjPos.left,
                            popoverPlacement: popoverPos,
                            arrowPlacement: opposites[arrowPos]
                          };
                        } else if (adjPos.top > boundaries.maxY && adjPos.top - elHeight / 2 <= boundaries.maxY) {
                          return {
                            top: boundaries.maxY,
                            left: adjPos.left,
                            popoverPlacement: popoverPos,
                            arrowPlacement: opposites[arrowPos]
                          };
                        }
                      }
                      break;
                  }
                }

                // nothing worked.  return null
                return null;
              };

              var popoverSlidable = function(popoverPos, pos, boundaries) {
                return (popoverPos === 'top' && pos.top >= boundaries.minY) || (popoverPos === 'bottom' && pos.top <= boundaries.maxY) ||
                  (popoverPos === 'left' && pos.left >= boundaries.minX) || (popoverPos === 'right' && pos.left <= boundaries.maxX);
              };

              var getViewportBoundaries = function(element, tooltip, appendToBody) {
                var elOffset = $position.offset(element);
                var minX = window.pageXOffset - (appendToBody ? 0 : elOffset.left);
                var minY = window.pageYOffset - (appendToBody ? 0 : elOffset.top);
                var ttWidth = tooltip.prop('offsetWidth');
                var ttHeight = tooltip.prop('offsetHeight');
                var maxX = minX + window.innerWidth - ttWidth;
                var maxY = minY + window.innerHeight - ttHeight;

                // give some buffer around the edges
                return {
                  'minX': minX + 10,
                  'minY': minY + 10,
                  'maxX': maxX - 10,
                  'maxY': maxY - 10
                };
              };

              // This logic was originally added to $position.positionElements() for tooltip
              // repositioning.  It's moved to tooltip.
              var repositionTooltip = function(boundaries, pos) {
                var minX = boundaries.minX;
                var minY = boundaries.minY;
                var maxX = boundaries.maxX;
                var maxY = boundaries.maxY;
                return {
                  top: (pos.top < minY) ? minY : (pos.top > maxY) ? maxY : pos.top,
                  left: (pos.left < minX) ? minX : (pos.left > maxX) ? maxX : pos.left
                };
              };

              var positionTooltip = function(event) {
                var isPopover = tooltip.hasClass('popover');
                var ttPosition = $position.positionElements(element, tooltip, scope.tt_placement, appendToBody, event);

                // Get the boundaries of the viewport.
                var boundaries = getViewportBoundaries(element, tooltip, appendToBody, ttPosition);

                // For a popover, position the tooltip according to the arrow placement
                // Center the arrow on the correct side
                if (isPopover) {
                  ttPosition = popoverReposition(element, tooltip, ttPosition, boundaries, event);
                  popoverAddArrowClass(tooltip, ttPosition.popoverPlacement, ttPosition.arrowPlacement);
                  scope.tt_placement = ttPosition.popoverPlacement;
                  attrs.popoverPlacement = ttPosition.popoverPlacement;
                  attrs.arrowPlacement = ttPosition.arrowPlacement;
                } else {
                  ttPosition = repositionTooltip(boundaries, ttPosition);
                }

                ttPosition.top += 'px';
                ttPosition.left += 'px';

                tooltip.css(ttPosition);
              };

              // By default, the tooltip is not open.
              // TODO add ability to start tooltip opened
              scope.tt_isOpen = false;

              function toggleTooltipBind() {
                if (!scope.tt_isOpen) {
                  showTooltipBind();
                } else {
                  hideTooltipBind();
                }
              }
              scope.toggleTooltipBind = function() {
                toggleTooltipBind();
              };

              scope.getButtonElement = function() {
                return element;
              };
              scope.getButtonAttributes = function() {
                return attrs;
              };

              // Show the tooltip with delay if specified, otherwise show it immediately
              function showTooltipBind(event) {
                if (event) {
                  scope.showEvent = event;
                }

                prepareTooltip();

                if (hasEnableExp && !scope.$eval(attrs[prefix + 'Enable'])) {
                  return;
                }
                if (scope.tt_popupDelay) {
                  // Do nothing if the tooltip was already scheduled to pop-up.
                  // This happens if show is triggered multiple times before any hide is triggered.
                  if (!popupTimeout) {
                    popupTimeout = $timeout(show, scope.tt_popupDelay, false);
                    popupTimeout.then(function(reposition) {
                      reposition(scope.showEvent);
                    });
                  }
                } else {
                  show()(scope.showEvent);
                }
              }

              function hideTooltipBind() {
                scope.$apply(function() {
                  hide();
                });
              }

              // Show the tooltip popup element.
              function show() {

                popupTimeout = null;

                // If there is a pending remove transition, we must cancel it, lest the
                // tooltip be mysteriously removed.
                if (transitionTimeout) {
                  $timeout.cancel(transitionTimeout);
                  transitionTimeout = null;
                }

                // Don't show empty tooltips.
                if (!scope.tt_content) {
                  return angular.noop;
                }

                createTooltip();

                // Set the initial positioning.
                tooltip.css({
                  top: 0,
                  left: 0,
                  display: 'block',
                  border: '1px solid #DAE1E8',
                  background: '#FDFDFD',
                  boxShadow: '0px 0px 2px rgba(34,37,41,.24)',
                  borderRadius: '2px'
                });

                // Now we add it to the DOM because need some info about it. But it's not
                // visible yet anyway.
                if (appendToBody) {
                  $document.find('body').append(tooltip);
                } else {
                  element.after(tooltip);
                }

                positionTooltip(scope.showEvent);

                // And show the tooltip.
                scope.tt_isOpen = true;
                scope.$digest(); // digest required as $apply is not called

                // Return positioning function as promise callback for correct
                // positioning after draw.
                return positionTooltip;
              }

              // Hide the tooltip popup element.
              function hide() {
                // First things first: we don't show it anymore.
                scope.tt_isOpen = false;

                //if tooltip is going to be shown after delay, we must cancel this
                $timeout.cancel(popupTimeout);
                popupTimeout = null;

                // And now we remove it from the DOM. However, if we have animation, we
                // need to wait for it to expire beforehand.
                // FIXME: this is a placeholder for a port of the transitions library.
                if (scope.tt_animation) {
                  if (!transitionTimeout) {
                    transitionTimeout = $timeout(removeTooltip, 500);
                  }
                } else {
                  removeTooltip();
                }
              }

              function createTooltip() {
                // There can only be one tooltip element per directive shown at once.
                if (tooltip) {
                  removeTooltip();
                }
                tooltipLinkedScope = scope.$new();
                tooltip = tooltipLinker(tooltipLinkedScope, function() {});

                // Get contents rendered into the tooltip
                scope.$digest();
              }

              function removeTooltip() {
                transitionTimeout = null;
                if (tooltip) {
                  tooltip.remove();
                  tooltip = null;
                }
                if (tooltipLinkedScope) {
                  tooltipLinkedScope.$destroy();
                  tooltipLinkedScope = null;
                }
              }

              function prepareTooltip() {
                prepPlacement();
                prepPopupDelay();
              }

              function updatePosition(event) {
                scope.showEvent = event;
              }

              /**
               * Observe the relevant attributes.
               */
              attrs.$observe(type, function(val) {
                scope.tt_content = val;

                if (!val && scope.tt_isOpen) {
                  hide();
                }
              });

              attrs.$observe(prefix + 'Title', function(val) {
                scope.tt_title = val;
              });

              attrs.$observe(prefix + 'Placement', function(val) {
                if (scope.tt_isOpen) {
                  $timeout(function() {
                    prepPlacement();
                    show()();
                  }, 0, false);
                }
              });

              function prepPlacement() {
                var val = attrs[prefix + 'Placement'];
                scope.tt_placement = angular.isDefined(val) ? val : options.placement;
              }

              function prepPopupDelay() {
                var val = attrs[prefix + 'PopupDelay'];
                var delay = parseInt(val, 10);
                scope.tt_popupDelay = !isNaN(delay) ? delay : options.popupDelay;
              }

              var unregisterTriggers = function() {
                element.unbind(triggers.show, showTooltipBind);
                element.unbind(triggers.hide, hideTooltipBind);
              };

              function prepTriggers() {
                var val = attrs[prefix + 'Trigger'];
                unregisterTriggers();

                triggers = getTriggers(val);

                if (triggers.show === triggers.hide) {
                  element.bind(triggers.show, toggleTooltipBind);
                } else {
                  element.bind(triggers.show, showTooltipBind);
                  if (triggers.show === 'mouseenter') {
                    element.bind('mousemove', updatePosition);
                  }
                  element.bind(triggers.hide, hideTooltipBind);
                }
              }
              prepTriggers();

              var animation = scope.$eval(attrs[prefix + 'Animation']);
              scope.tt_animation = angular.isDefined(animation) ? !!animation : options.animation;

              attrs.$observe(prefix + 'AppendToBody', function(val) {
                appendToBody = angular.isDefined(val) ? $parse(val)(scope) : appendToBody;
              });

              // if a tooltip is attached to <body> we need to remove it on
              // location change as its parent scope will probably not be destroyed
              // by the change.
              if (appendToBody) {
                scope.$on('$locationChangeSuccess', function closeTooltipOnLocationChangeSuccess() {
                  if (scope.tt_isOpen) {
                    hide();
                  }
                });
              }

              // Make sure tooltip is destroyed and removed.
              scope.$on('$destroy', function onDestroyTooltip() {
                $timeout.cancel(transitionTimeout);
                $timeout.cancel(popupTimeout);
                unregisterTriggers();
                removeTooltip();
                scope = null;
              });
            };
          }
        };
      };
    }
  ];
})

.directive('tooltipPopup', function() {
  return {
    restrict: 'EA',
    replace: true,
    scope: {
      content: '@',
      placement: '@',
      animation: '&',
      isOpen: '&'
    },
    templateUrl: 'template/tooltip/tooltip-popup.html'
  };
})

.directive('tooltip', ['$tooltip',
  function($tooltip) {
    return $tooltip('tooltip', 'tooltip', 'mouseenter');
  }
])

.directive('tooltipHtmlUnsafePopup', function() {
  return {
    restrict: 'EA',
    replace: true,
    scope: {
      content: '@',
      placement: '@',
      animation: '&',
      isOpen: '&'
    },
    templateUrl: 'template/tooltip/tooltip-html-unsafe-popup.html'
  };
})

.directive('tooltipHtmlUnsafe', ['$tooltip',
  function($tooltip) {
    return $tooltip('tooltipHtmlUnsafe', 'tooltip', 'mouseenter');
  }
]);

/**
 * The following features are still outstanding: popup delay, animation as a
 * function, placement as a function, inside, support for more triggers than
 * just mouse enter/leave, html popovers, and selector delegatation.
 */
angular.module('ark-ui-bootstrap.popover', ['ark-ui-bootstrap.tooltip'])

.directive('popoverPopup', function() {
  return {
    restrict: 'EA',
    replace: true,
    scope: {
      title: '@',
      content: '@',
      placement: '@',
      animation: '&',
      isOpen: '&'
    },
    templateUrl: 'template/popover/popover.html',
    link: function(scope, element, attrs) {
      angular.element(element[0].querySelector('.popover-close-btn')).on('click', function() {
        scope.$parent.toggleTooltipBind();
      });
    }
  };
})

.directive('popover', ['$tooltip',
  function($tooltip) {
    return $tooltip('popover', 'popover', 'click', {
      appendToBody: false,
      placement: 'top'
    });
  }
])

.directive('popoverHtmlUnsafePopup', function() {
  return {
    restrict: 'EA',
    replace: true,
    scope: {
      title: '@',
      content: '@',
      placement: '@',
      animation: '&',
      isOpen: '&'
    },
    templateUrl: 'template/popover/popover-html-unsafe-popup.html',
    link: function(scope, element, attrs) {
      angular.element(element[0].querySelector('.popover-close-btn')).on('click', function() {
        scope.$parent.toggleTooltipBind();
      });
    }
  };
})

.directive('popoverHtmlUnsafe', ['$tooltip',
  function($tooltip) {
    return $tooltip('popoverHtmlUnsafe', 'popover', 'click', {
      appendToBody: false,
      placement: 'top'
    });
  }
]);


/**
 * @ngdoc overview
 * @name ark-ui-bootstrap.tabs
 *
 * @description
 * AngularJS version of the tabs directive.
 */

angular.module('ark-ui-bootstrap.tabs', [])

.controller('TabsetController', ['$scope', function TabsetCtrl($scope) {
  var ctrl = this,
      tabs = ctrl.tabs = $scope.tabs = [];

  ctrl.select = function(selectedTab) {
    angular.forEach(tabs, function(tab) {
      if (tab.active && tab !== selectedTab) {
        tab.active = false;
        tab.onDeselect();
      }
    });
    selectedTab.active = true;
    selectedTab.onSelect();
  };

  ctrl.addTab = function addTab(tab) {
    tabs.push(tab);
    // we can't run the select function on the first tab
    // since that would select it twice
    if (tabs.length === 1) {
      tab.active = true;
    } else if (tab.active) {
      ctrl.select(tab);
    }
  };

  ctrl.removeTab = function removeTab(tab) {
    var index = tabs.indexOf(tab);
    //Select a new tab if the tab to be removed is selected
    if (tab.active && tabs.length > 1) {
      //If this is the last tab, select the previous tab. else, the next tab.
      var newActiveIndex = index == tabs.length - 1 ? index - 1 : index + 1;
      ctrl.select(tabs[newActiveIndex]);
    }
    tabs.splice(index, 1);
  };
}])

/**
 * @ngdoc directive
 * @name ark-ui-bootstrap.tabs.directive:tabset
 * @restrict EA
 *
 * @description
 * Tabset is the outer container for the tabs directive
 *
 * @param {boolean=} vertical Whether or not to use vertical styling for the tabs.
 * @param {boolean=} justified Whether or not to use justified styling for the tabs.
 *
 * @example
<example module="ui.bootstrap">
  <file name="index.html">
    <tabset>
      <tab heading="Tab 1"><b>First</b> Content!</tab>
      <tab heading="Tab 2"><i>Second</i> Content!</tab>
    </tabset>
    <hr />
    <tabset vertical="true">
      <tab heading="Vertical Tab 1"><b>First</b> Vertical Content!</tab>
      <tab heading="Vertical Tab 2"><i>Second</i> Vertical Content!</tab>
    </tabset>
    <tabset justified="true">
      <tab heading="Justified Tab 1"><b>First</b> Justified Content!</tab>
      <tab heading="Justified Tab 2"><i>Second</i> Justified Content!</tab>
    </tabset>
  </file>
</example>
 */
.directive('tabset', function() {
  return {
    restrict: 'EA',
    transclude: true,
    replace: true,
    scope: {
      type: '@'
    },
    controller: 'TabsetController',
    templateUrl: 'template/tabs/tabset.html',
    link: function(scope, element, attrs) {
      scope.vertical = angular.isDefined(attrs.vertical) ? scope.$parent.$eval(attrs.vertical) : false;
      scope.justified = angular.isDefined(attrs.justified) ? scope.$parent.$eval(attrs.justified) : false;
    }
  };
})

/**
 * @ngdoc directive
 * @name ark-ui-bootstrap.tabs.directive:tab
 * @restrict EA
 *
 * @param {string=} heading The visible heading, or title, of the tab. Set HTML headings with {@link ark-ui-bootstrap.tabs.directive:tabHeading tabHeading}.
 * @param {string=} select An expression to evaluate when the tab is selected.
 * @param {boolean=} active A binding, telling whether or not this tab is selected.
 * @param {boolean=} disabled A binding, telling whether or not this tab is disabled.
 *
 * @description
 * Creates a tab with a heading and content. Must be placed within a {@link ark-ui-bootstrap.tabs.directive:tabset tabset}.
 *
 * @example
<example module="ui.bootstrap">
  <file name="index.html">
    <div ng-controller="TabsDemoCtrl">
      <button class="btn btn-small" ng-click="items[0].active = true">
        Select item 1, using active binding
      </button>
      <button class="btn btn-small" ng-click="items[1].disabled = !items[1].disabled">
        Enable/disable item 2, using disabled binding
      </button>
      <br />
      <tabset>
        <tab heading="Tab 1">First Tab</tab>
        <tab select="alertMe()">
          <tab-heading><i class="icon-bell"></i> Alert me!</tab-heading>
          Second Tab, with alert callback and html heading!
        </tab>
        <tab ng-repeat="item in items"
          heading="{{item.title}}"
          disabled="item.disabled"
          active="item.active">
          {{item.content}}
        </tab>
      </tabset>
    </div>
  </file>
  <file name="script.js">
    function TabsDemoCtrl($scope) {
      $scope.items = [
        { title:"Dynamic Title 1", content:"Dynamic Item 0" },
        { title:"Dynamic Title 2", content:"Dynamic Item 1", disabled: true }
      ];

      $scope.alertMe = function() {
        setTimeout(function() {
          alert("You've selected the alert tab!");
        });
      };
    };
  </file>
</example>
 */

/**
 * @ngdoc directive
 * @name ark-ui-bootstrap.tabs.directive:tabHeading
 * @restrict EA
 *
 * @description
 * Creates an HTML heading for a {@link ark-ui-bootstrap.tabs.directive:tab tab}. Must be placed as a child of a tab element.
 *
 * @example
<example module="ui.bootstrap">
  <file name="index.html">
    <tabset>
      <tab>
        <tab-heading><b>HTML</b> in my titles?!</tab-heading>
        And some content, too!
      </tab>
      <tab>
        <tab-heading><i class="icon-heart"></i> Icon heading?!?</tab-heading>
        That's right.
      </tab>
    </tabset>
  </file>
</example>
 */
.directive('tab', ['$parse', function($parse) {
  return {
    require: '^tabset',
    restrict: 'EA',
    replace: true,
    templateUrl: 'template/tabs/tab.html',
    transclude: true,
    scope: {
      active: '=?',
      heading: '@',
      onSelect: '&select', //This callback is called in contentHeadingTransclude
                          //once it inserts the tab's content into the dom
      onDeselect: '&deselect'
    },
    controller: function() {
      //Empty controller so other directives can require being 'under' a tab
    },
    compile: function(elm, attrs, transclude) {
      return function postLink(scope, elm, attrs, tabsetCtrl) {
        scope.$watch('active', function(active) {
          if (active) {
            tabsetCtrl.select(scope);
          }
        });

        scope.disabled = false;
        if ( attrs.disabled ) {
          scope.$parent.$watch($parse(attrs.disabled), function(value) {
            scope.disabled = !! value;
          });
        }

        scope.select = function() {
          if ( !scope.disabled ) {
            scope.active = true;
          }
        };

        tabsetCtrl.addTab(scope);
        scope.$on('$destroy', function() {
          tabsetCtrl.removeTab(scope);
        });

        //We need to transclude later, once the content container is ready.
        //when this link happens, we're inside a tab heading.
        scope.$transcludeFn = transclude;
      };
    }
  };
}])

.directive('tabHeadingTransclude', [function() {
  return {
    restrict: 'A',
    require: '^tab',
    link: function(scope, elm, attrs, tabCtrl) {
      scope.$watch('headingElement', function updateHeadingElement(heading) {
        if (heading) {
          elm.html('');
          elm.append(heading);
        }
      });
    }
  };
}])

.directive('tabContentTransclude', function() {
  return {
    restrict: 'A',
    require: '^tabset',
    link: function(scope, elm, attrs) {
      var tab = scope.$eval(attrs.tabContentTransclude);

      //Now our tab is ready to be transcluded: both the tab heading area
      //and the tab content area are loaded.  Transclude 'em both.
      tab.$transcludeFn(tab.$parent, function(contents) {
        angular.forEach(contents, function(node) {
          if (isTabHeading(node)) {
            //Let tabHeadingTransclude know.
            tab.headingElement = node;
          } else {
            elm.append(node);
          }
        });
      });
    }
  };
  function isTabHeading(node) {
    return node.tagName &&  (
      node.hasAttribute('tab-heading') ||
      node.hasAttribute('data-tab-heading') ||
      node.tagName.toLowerCase() === 'tab-heading' ||
      node.tagName.toLowerCase() === 'data-tab-heading'
    );
  }
})

;

angular.module("template/accordion/accordion-group.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/accordion/accordion-group.html",
    "<div class=\"accordion-group\">\n" +
    "  <div class=\"panel accordion-heading\" ng-click=\"toggleOpen()\" style=\"cursor: pointer;\">\n" +
    "    <h3 class=\"accordion-title \">\n" +
    "      <a class=\"accordion-toggle\" accordion-transclude=\"heading\"><span ng-class=\"{'text-muted': isDisabled}\">{{heading}}</span></a>\n" +
    "    </h3>\n" +
    "    <span class=\"pull-right accordion-fonticon\" ng-class=\"{'icon-iw-circle-no-chevron-down': !isOpen, 'icon-iw-circle-no-chevron-up': isOpen}\"></span>\n" +
    "  </div>\n" +
    "  <div class=\"panel-collapse accordion-collapse\" collapse=\"!isOpen\">\n" +
    "    <div class=\"panel-body\" ng-transclude></div>\n" +
    "  </div>\n" +
    "</div>\n" +
    "");
}]);

angular.module("template/accordion/accordion.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/accordion/accordion.html",
    "<div class=\"panel-group\" ng-transclude></div>");
}]);

angular.module("template/modal/backdrop.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/modal/backdrop.html",
    "<div class=\"modal-backdrop fade {{ backdropClass }}\"\n" +
    "     ng-class=\"{in: animate}\"\n" +
    "     ng-style=\"{'z-index': 1040 + (index && 1 || 0) + index*10}\"\n" +
    "></div>\n" +
    "");
}]);

angular.module("template/modal/window-new.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/modal/window-new.html",
    "<div tabindex=\"-1\" role=\"dialog\" class=\"modal fade\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\" ng-click=\"close($event)\">\n" +
    "    <div class=\"modal-dialog\" ng-class=\"{'modal-sm': size == 'sm', 'modal-lg': size == 'lg'}\"><div class=\"modal-content-new\" modal-transclude></div></div>\n" +
    "</div>");
}]);

angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/modal/window.html",
    "<div tabindex=\"-1\" role=\"dialog\" class=\"modal fade\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\" ng-click=\"close($event)\">\n" +
    "    <div class=\"modal-dialog\" ng-class=\"{'modal-sm': size == 'sm', 'modal-lg': size == 'lg'}\"><div class=\"modal-content\" modal-transclude></div></div>\n" +
    "</div>");
}]);

angular.module("template/tooltip/tooltip-html-unsafe-popup.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/tooltip/tooltip-html-unsafe-popup.html",
    "<div class=\"tooltip {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
    "  <div class=\"tooltip-arrow\"></div>\n" +
    "  <div class=\"tooltip-inner\" bind-html-unsafe=\"content\"></div>\n" +
    "</div>\n" +
    "");
}]);

angular.module("template/tooltip/tooltip-popup.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/tooltip/tooltip-popup.html",
    "<div class=\"tooltip {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
    "  <div class=\"tooltip-arrow\"></div>\n" +
    "  <div class=\"tooltip-inner\" ng-bind=\"content\"></div>\n" +
    "</div>\n" +
    "");
}]);

angular.module("template/popover/popover-html-unsafe-popup.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/popover/popover-html-unsafe-popup.html",
    "<div class=\"popover {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
    "	<div class=\"arrow\"></div>\n" +
    "\n" +
    "	<div class=\"popover-inner popover-container\">\n" +
    "		<span class=\"popover-close-btn fonticon icon-close\"></span>\n" +
    "		<div class=\"popover-body\">\n" +
    "			<h3 class=\"popover-title\" ng-bind=\"title\" ng-show=\"title\">{{title}}</h3>\n" +
    "			<div class=\"popover-content\" bind-html-unsafe=\"content\"></div>\n" +
    "		</div>\n" +
    "	</div>\n" +
    "</div>");
}]);

angular.module("template/popover/popover.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/popover/popover.html",
    "<div class=\"popover {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
    "	<div class=\"arrow\"></div>\n" +
    "\n" +
    "	<div class='popover-inner popover-container'>\n" +
    "		<span class=\"popover-close-btn fonticon icon-close\"></span>\n" +
    "		<div class=\"popover-body\">\n" +
    "			<h3 class=\"popover-title\" ng-bind=\"title\" ng-show=\"title\"></h3>\n" +
    "			<div class=\"popover-content\" ng-bind=\"content\"></div>\n" +
    "		</div>\n" +
    "	</div>	\n" +
    "</div>\n" +
    "\n" +
    "");
}]);

angular.module("template/tabs/tab.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/tabs/tab.html",
    "<li ng-class=\"{active: active, disabled: disabled}\">\n" +
    "  <a ng-click=\"select()\" tab-heading-transclude>{{heading}}</a>\n" +
    "</li>\n" +
    "");
}]);

angular.module("template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/tabs/tabset.html",
    "<div>\n" +
    "  <ul class=\"nav nav-{{type || 'tabs'}}\" ng-class=\"{'nav-stacked': vertical, 'nav-justified': justified}\" ng-transclude></ul>\n" +
    "  <div class=\"tab-content\">\n" +
    "    <div class=\"tab-pane\" \n" +
    "         ng-repeat=\"tab in tabs\" \n" +
    "         ng-class=\"{active: tab.active}\"\n" +
    "         tab-content-transclude=\"tab\">\n" +
    "    </div>\n" +
    "  </div>\n" +
    "</div>\n" +
    "");
}]);
