lib/angular/js/Angular.js
function bootstrap(element, modules, config) {
  if (!isObject(config)) config = {};
  var defaultConfig = {
    strictDi: false
  };
  config = extend(defaultConfig, config);
  var doBootstrap = function() {
    element = jqLite(element);

    if (element.injector()) {
      var tag = (element[0] === document) ? 'document' : startingTag(element);
      throw ngMinErr('btstrpd', "App Already Bootstrapped with this Element '{0}'", tag);
    }

    modules = modules || [];
    modules.unshift(['$provide', function($provide) {
      $provide.value('$rootElement', element);
    }]);
    modules.unshift('ng');
    var injector = createInjector(modules, config.strictDi);
    injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
       function(scope, element, compile, injector) {
        scope.$apply(function() {
          element.data('$injector', injector);
          compile(element)(scope);
        });
      }]
    );
    return injector;
  };

  var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;

  if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
    return doBootstrap();
  }

  window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
  angular.resumeBootstrap = function(extraModules) {
    forEach(extraModules, function(module) {
      modules.push(module);
    });
    doBootstrap();
  };
}
function bootstrap(element, modules, config) {
  if (!isObject(config)) config = {};
  var defaultConfig = {
    strictDi: false
  };
  config = extend(defaultConfig, config);
  var doBootstrap = function() {
    element = jqLite(element);

    if (element.injector()) {
      var tag = (element[0] === document) ? 'document' : startingTag(element);
      throw ngMinErr('btstrpd', "App Already Bootstrapped with this Element '{0}'", tag);
    }

    modules = modules || [];
    modules.unshift(['$provide', function($provide) {
      $provide.value('$rootElement', element);
    }]);
    modules.unshift('ng');
    var injector = createInjector(modules, config.strictDi);
    injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
       function(scope, element, compile, injector) {
        scope.$apply(function() {
          element.data('$injector', injector);
          compile(element)(scope);
        });
      }]
    );
    return injector;
  };

  var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;

  if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
    return doBootstrap();
  }

  window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
  angular.resumeBootstrap = function(extraModules) {
    forEach(extraModules, function(module) {
      modules.push(module);
    });
    doBootstrap();
  };
}
function bootstrap ( element , modules , config ) { if ( ! isObject ( config ) ) config = { } ; var defaultConfig = { strictDi : false } ; config = extend ( defaultConfig , config ) ; var doBootstrap = function ( ) { element = jqLite ( element ) ; if ( element . injector ( ) ) { var tag = ( element [ 0 ] === document ) ? 'document' : startingTag ( element ) ; throw ngMinErr ( 'btstrpd' , "App Already Bootstrapped with this Element '{0}'" , tag ) ; } modules = modules || [ ] ; modules . unshift ( [ '$provide' , function ( $provide ) { $provide . value ( '$rootElement' , element ) ; } ] ) ; modules . unshift ( 'ng' ) ; var injector = createInjector ( modules , config . strictDi ) ; injector . invoke ( [ '$rootScope' , '$rootElement' , '$compile' , '$injector' , function ( scope , element , compile , injector ) { scope . $apply ( function ( ) { element . data ( '$injector' , injector ) ; compile ( element ) ( scope ) ; } ) ; } ] ) ; return injector ; } ; var NG_DEFER_BOOTSTRAP = / ^NG_DEFER_BOOTSTRAP! / ; if ( window && ! NG_DEFER_BOOTSTRAP . test ( window . name ) ) { return doBootstrap ( ) ; } window . name = window . name . replace ( NG_DEFER_BOOTSTRAP , '' ) ; angular . resumeBootstrap = function ( extraModules ) { forEach ( extraModules , function ( module ) { modules . push ( module ) ; } ) ; doBootstrap ( ) ; } ; }
@ngdoc function
@name angular.bootstrap
@module ng
@description
Use this function to manually start up angular application.

See: {@link guide/bootstrap Bootstrap}

Note that Protractor based end-to-end tests cannot use this function to bootstrap manually.
They must use {@link ng.directive:ngApp ngApp}.

Angular will detect if it has been loaded into the browser more than once and only allow the
first loaded script to be bootstrapped and will report a warning to the browser console for
each of the subsequent scripts. This prevents strange results in applications, where otherwise
multiple instances of Angular try to work on the DOM.

```html
<!doctype html>
<html>
<body>
<div ng-controller="WelcomeController">
{{greeting}}
</div>

<script src="angular.js"></script>
<script>
var app = angular.module('demo', [])
.controller('WelcomeController', function($scope) {
$scope.greeting = 'Welcome!';
});
angular.bootstrap(document, ['demo']);
</script>
</body>
</html>
```

@param {DOMElement} element DOM element which is the root of angular application.
@param {Array<String|Function|Array>=} modules an array of modules to load into the application.
Each item in the array should be the name of a predefined module or a (DI annotated)
function that will be invoked by the injector as a run block.
See: {@link angular.module modules}
@param {Object=} config an object for defining configuration options for the application. The
following keys are supported:

- `strictDi`: disable automatic function annotation for the application. This is meant to
assist in finding bugs which break minified code.

@returns {auto.$injector} Returns the newly created injector for this app.
@ngdoc function @name angular . bootstrap @module ng @description Use this function to manually start up angular application .