text: 
  /**
   * @ngdoc overview
   * @name ui.bootstrap.tabs
   *
   * @description
   * AngularJS version of the tabs directive.
   */
  
  angular.module('ui.bootstrap.tabs', [])
  
  .directive('tabs', function() {
    return function() {
      throw new Error("The `tabs` directive is deprecated, please migrate to `tabset`. Instructions can be found at http://github.com/angular-ui/bootstrap/tree/master/CHANGELOG.md");
    };
  })
  
  .controller('TabsetController', ['$scope', '$element', 
  function TabsetCtrl($scope, $element) {
    var ctrl = this,
      tabs = ctrl.tabs = $scope.tabs = [];
  
    ctrl.select = function(tab) {
      angular.forEach(tabs, function(tab) {
        tab.active = false;
      });  
      tab.active = true;
    };
  
    ctrl.addTab = function addTab(tab) {
      tabs.push(tab);
      if (tabs.length == 1) {
        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 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.
   *
   * @example
  <example module="ui.bootstrap">
    <file name="index.html">
      <tabset>
        <tab heading="Vertical Tab 1"><b>First</b> Content!</tab>
        <tab heading="Vertical 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>
    </file>
  </example>
   */
  .directive('tabset', function() {
    return {
      restrict: 'EA',
      transclude: true,
      scope: {},
      controller: 'TabsetController',
      templateUrl: 'template/tabs/tabset.html',
      link: function(scope, element, attrs) {
        scope.vertical = angular.isDefined(attrs.vertical) ? scope.$eval(attrs.vertical) : false;
        scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs';
      }
    };
  })
  
  /**
   * @ngdoc directive
   * @name ui.bootstrap.tabs.directive:tab
   * @restrict EA
   *
   * @param {string=} heading The visible heading, or title, of the tab. Set HTML headings with {@link 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 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 ui.bootstrap.tabs.directive:tabHeading
   * @restrict EA
   *
   * @description
   * Creates an HTML heading for a {@link 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', '$http', '$templateCache', '$compile',
  function($parse, $http, $templateCache, $compile) {
    return {
      require: '^tabset',
      restrict: 'EA',
      replace: true,
      templateUrl: 'template/tabs/tab.html',
      transclude: true,
      scope: {
        heading: '@',
        onSelect: '&select' //This callback is called in contentHeadingTransclude
                            //once it inserts the tab's content into the dom
      },
      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) {
          var getActive, setActive;
          scope.active = false; // default value
          if (attrs.active) {
            getActive = $parse(attrs.active);
            setActive = getActive.assign;
            scope.$parent.$watch(getActive, function updateActive(value) {
              if ( !!value && scope.disabled ) {
                setActive(scope.$parent, false); // Prevent active assignment
              } else {
                scope.active = !!value;
              }
            });
          } else {
            setActive = getActive = angular.noop;
          }
  
          scope.$watch('active', function(active) {
            setActive(scope.$parent, active);
            if (active) {
              tabsetCtrl.select(scope);
              scope.onSelect();
            }
          });
  
          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);
          });
          //If the tabset sets this tab to active, set the parent scope's active
          //binding too.  We do this so the watch for the parent's initial active
          //value won't overwrite what is initially set by the tabset
          if (scope.active) {
            setActive(scope.$parent, true);
          } 
  
          //Transclude the collection of sibling elements. Use forEach to find
          //the heading if it exists. We don't use a directive for tab-heading
          //because it is problematic. Discussion @ http://git.io/MSNPwQ
          transclude(scope.$parent, function(clone) {
            //Look at every element in the clone collection. If it's tab-heading,
            //mark it as that.  If it's not tab-heading, mark it as tab contents
            var contents = [], heading;
            angular.forEach(clone, function(el) {
              //See if it's a tab-heading attr or element directive
              //First make sure it's a normal element, one that has a tagName
              if (el.tagName &&
                  (el.hasAttribute("tab-heading") || 
                   el.hasAttribute("data-tab-heading") ||
                   el.tagName.toLowerCase() == "tab-heading" ||
                   el.tagName.toLowerCase() == "data-tab-heading"
                  )) {
                heading = el;
              } else {
                contents.push(el);
              }
            });
            //Share what we found on the scope, so our tabHeadingTransclude and
            //tabContentTransclude directives can find out what the heading and
            //contents are.
            if (heading) { 
              scope.headingElement = angular.element(heading);
            }
            scope.contentElement = angular.element(contents);
          });
        };
      }
    };
  }])
  
  .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', ['$parse', function($parse) {
    return {
      restrict: 'A',
      require: '^tabset',
      link: function(scope, elm, attrs, tabsetCtrl) {
        scope.$watch($parse(attrs.tabContentTransclude), function(tab) {
          elm.html('');
          if (tab) {
            elm.append(tab.contentElement);
          }
        });
      }
    };
  }])
  
  ;
  
  