text: /**
   * Durandal 2.2.0 Copyright (c) 2010-2016 Blue Spire Consulting, Inc. All Rights Reserved.
   * Available via the MIT license.
   * see: http://durandaljs.com or https://github.com/BlueSpire/Durandal for details.
   */
  /**
   * The app module controls app startup, plugin loading/configuration and root visual display.
   * @module app
   * @requires system
   * @requires viewEngine
   * @requires composition
   * @requires events
   * @requires jquery
   */
  define(['durandal/system', 'durandal/viewEngine', 'durandal/composition', 'durandal/events', 'jquery'], function(system, viewEngine, composition, Events, $) {
      var app,
          allPluginIds = [],
          allPluginConfigs = [];
  
      function loadPlugins(){
          return system.defer(function(dfd){
              if(allPluginIds.length == 0){
                  dfd.resolve();
                  return;
              }
  
              system.acquire(allPluginIds).then(function(loaded){
                  for(var i = 0; i < loaded.length; i++){
                      var currentModule = loaded[i];
  
                      if(currentModule.install){
                          var config = allPluginConfigs[i];
                          if(!system.isObject(config)){
                              config = {};
                          }
  
                          currentModule.install(config);
                          system.log('Plugin:Installed ' + allPluginIds[i]);
                      }else{
                          system.log('Plugin:Loaded ' + allPluginIds[i]);
                      }
                  }
  
                  dfd.resolve();
              }).fail(function(err){
                  system.error('Failed to load plugin(s). Details: ' + err.message);
              });
          }).promise();
      }
  
      /**
       * @class AppModule
       * @static
       * @uses Events
       */
      app = {
          /**
           * The title of your application.
           * @property {string} title
           */
          title: 'Application',
          /**
           * Configures one or more plugins to be loaded and installed into the application.
           * @method configurePlugins
           * @param {object} config Keys are plugin names. Values can be truthy, to simply install the plugin, or a configuration object to pass to the plugin.
           * @param {string} [baseUrl] The base url to load the plugins from.
           */
          configurePlugins:function(config, baseUrl){
              var pluginIds = system.keys(config);
              baseUrl = baseUrl || 'plugins/';
  
              if(baseUrl.indexOf('/', baseUrl.length - 1) === -1){
                  baseUrl += '/';
              }
  
              for(var i = 0; i < pluginIds.length; i++){
                  var key = pluginIds[i];
                  allPluginIds.push(baseUrl + key);
                  allPluginConfigs.push(config[key]);
              }
          },
          /**
           * Starts the application.
           * @method start
           * @return {promise}
           */
          start: function() {
              system.log('Application:Starting');
  
              if (this.title) {
                  document.title = this.title;
              }
  
              return system.defer(function (dfd) {
                  $(function() {
                      loadPlugins().then(function(){
                          dfd.resolve();
                          system.log('Application:Started');
                      });
                  });
              }).promise();
          },
          /**
           * Sets the root module/view for the application.
           * @method setRoot
           * @param {string} root The root view or module.
           * @param {string} [transition] The transition to use from the previous root (or splash screen) into the new root.
           * @param {string} [applicationHost] The application host element or id. By default the id 'applicationHost' will be used.
           */
          setRoot: function(root, transition, applicationHost) {
              var hostElement, settings = { activate:true, transition: transition };
  
              if (!applicationHost || system.isString(applicationHost)) {
                  hostElement = document.getElementById(applicationHost || 'applicationHost');
              } else {
                  hostElement = applicationHost;
              }
  
              if (system.isString(root)) {
                  if (viewEngine.isViewUrl(root)) {
                      settings.view = root;
                  } else {
                      settings.model = root;
                  }
              } else {
                  settings.model = root;
              }
  
              function finishComposition() {
                  if(settings.model) {
                      if (settings.model.canActivate) {
                          try {
                              var result = settings.model.canActivate();
                              if (result && result.then) {
                                  result.then(function (actualResult) {
                                      if (actualResult) {
                                          composition.compose(hostElement, settings);
                                      }
                                  }).fail(function (err) {
                                      system.error(err);
                                  });
                              } else if (result) {
                                  composition.compose(hostElement, settings);
                              }
                          } catch (er) {
                              system.error(er);
                          }
                      } else {
                          composition.compose(hostElement, settings);
                      }
                  } else {
                      composition.compose(hostElement, settings);
                  }
              }
  
              if(system.isString(settings.model)) {
                  system.acquire(settings.model).then(function(module) {
                      settings.model = system.resolveObject(module);
                      finishComposition();
                  }).fail(function(err) {
                      system.error('Failed to load root module (' + settings.model + '). Details: ' + err.message);
                  });
              } else {
                  finishComposition();
              }
          }
      };
  
      Events.includeIn(app);
  
      return app;
  });
  