Merge "Moved config to ngConstant to mount that from outside the container"
diff --git a/conf/app/README.md b/conf/app/README.md
new file mode 100644
index 0000000..bdc361a
--- /dev/null
+++ b/conf/app/README.md
@@ -0,0 +1,47 @@
+# XOS-GUI Config
+
+### Note that the configurations defined in this folder are for development only, they are most likely to be overrided by a volume mount defined in `service-profile`
+
+## App Config
+
+This configuration will specifiy the rest API base url and the Websocket address.
+Here is it's structure:
+
+```
+angular.module('app')
+  .constant('AppConfig', {
+    apiEndpoint: '/spa/api',
+    websocketClient: '/'
+  });
+
+```
+
+## Style Config
+
+This configuration will contain branding information, such as title, logo and navigation items.
+Here is it's structure:
+
+```
+angular.module('app')
+  .constant('StyleConfig', {
+    projectName: 'CORD',
+    favicon: 'cord-favicon.png',
+    background: 'cord-bg.jpg',
+    payoff: 'Your VNF orchestrator',
+    logo: 'cord-logo.png',
+    routes: [
+        {
+            label: 'Slices',
+            state: 'xos.core.slices'
+        },
+        {
+            label: 'Instances',
+            state: 'xos.core.instances'
+        },
+        {
+            label: 'Nodes',
+            state: 'xos.core.nodes'
+        }
+    ]
+});
+```
\ No newline at end of file
diff --git a/conf/app/app.config.dev.js b/conf/app/app.config.dev.js
new file mode 100644
index 0000000..5c620d7
--- /dev/null
+++ b/conf/app/app.config.dev.js
@@ -0,0 +1,5 @@
+angular.module('app')
+  .constant('AppConfig', {
+    apiEndpoint: 'http://xos.dev:3000/api',
+    websocketClient: 'http://xos.dev:3000'
+  });
diff --git a/conf/app/app.config.dev.ts b/conf/app/app.config.dev.ts
deleted file mode 100644
index 50570d7..0000000
--- a/conf/app/app.config.dev.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import {IAppConfig} from './interfaces';
-export const AppConfig: IAppConfig = {
-    apiEndpoint: 'http://xos.dev:3000/api',
-    websocketClient: 'http://xos.dev:3000'
-};
diff --git a/conf/app/app.config.production.js b/conf/app/app.config.production.js
new file mode 100644
index 0000000..8f5bd5a
--- /dev/null
+++ b/conf/app/app.config.production.js
@@ -0,0 +1,5 @@
+angular.module('app')
+  .constant('AppConfig', {
+    apiEndpoint: '/spa/api',
+    websocketClient: '/'
+  });
diff --git a/conf/app/app.config.production.ts b/conf/app/app.config.production.ts
deleted file mode 100644
index 63c19f3..0000000
--- a/conf/app/app.config.production.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import {IAppConfig} from './interfaces';
-export const AppConfig: IAppConfig = {
-    apiEndpoint: '/spa/api',
-    websocketClient: '/'
-};
diff --git a/conf/app/app.config.remote.ts b/conf/app/app.config.remote.ts
deleted file mode 100644
index 24aa42d..0000000
--- a/conf/app/app.config.remote.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import {IAppConfig} from './interfaces';
-export const AppConfig: IAppConfig = {
-    apiEndpoint: 'http://clnode031.clemson.cloudlab.us:8080/api',
-    websocketClient: 'http://clnode031.clemson.cloudlab.us:8080'
-};
diff --git a/conf/app/app.config.test.js b/conf/app/app.config.test.js
new file mode 100644
index 0000000..86cfcb1
--- /dev/null
+++ b/conf/app/app.config.test.js
@@ -0,0 +1,5 @@
+angular.module('app')
+  .constant('AppConfig', {
+      apiEndpoint: 'http://xos-test:3000/api',
+      websocketClient: 'http://xos-test:3000'
+  });
diff --git a/conf/app/app.config.test.ts b/conf/app/app.config.test.ts
deleted file mode 100644
index 109776c..0000000
--- a/conf/app/app.config.test.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import {IAppConfig} from './interfaces';
-export const AppConfig: IAppConfig = {
-    apiEndpoint: 'http://xos-test:3000/api',
-    websocketClient: 'http://xos-test:3000'
-};
diff --git a/conf/app/interfaces.ts b/conf/app/interfaces.ts
deleted file mode 100644
index 39f085d..0000000
--- a/conf/app/interfaces.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import {IXosNavigationRoute} from '../../src/app/core/services/navigation';
-export interface IStyleConfig {
-  projectName: string;
-  payoff: string;
-  favicon: string;
-  background: string;
-  logo: string;
-  routes: IXosNavigationRoute[];
-}
-
-export interface IAppConfig {
-  apiEndpoint: string;
-  websocketClient: string;
-}
diff --git a/conf/app/style.config.cord.ts b/conf/app/style.config.cord.js
similarity index 82%
rename from conf/app/style.config.cord.ts
rename to conf/app/style.config.cord.js
index c43cac8..6f7ebab 100644
--- a/conf/app/style.config.cord.ts
+++ b/conf/app/style.config.cord.js
@@ -1,5 +1,5 @@
-import {IStyleConfig} from './interfaces';
-export const StyleConfig: IStyleConfig = {
+angular.module('app')
+  .constant('StyleConfig', {
     projectName: 'CORD',
     favicon: 'cord-favicon.png',
     background: 'cord-bg.jpg',
@@ -19,4 +19,4 @@
             state: 'xos.core.nodes'
         }
     ]
-};
+});
diff --git a/conf/app/style.config.opencloud.ts b/conf/app/style.config.opencloud.js
similarity index 75%
rename from conf/app/style.config.opencloud.ts
rename to conf/app/style.config.opencloud.js
index c001344..9693c5d 100644
--- a/conf/app/style.config.opencloud.ts
+++ b/conf/app/style.config.opencloud.js
@@ -1,5 +1,5 @@
-import {IStyleConfig} from './interfaces';
-export const StyleConfig: IStyleConfig = {
+angular.module('app')
+  .constant('StyleConfig', {
     projectName: 'OpenCloud',
     favicon: 'opencloud-favicon.png',
     background: 'opencloud-bg.jpg',
@@ -11,4 +11,4 @@
             state: 'xos.core.slices'
         }
     ]
-};
+});
diff --git a/conf/webpack-dist.conf.js b/conf/webpack-dist.conf.js
index 8945790..54ac67e 100644
--- a/conf/webpack-dist.conf.js
+++ b/conf/webpack-dist.conf.js
@@ -7,6 +7,9 @@
 const pkg = require('../package.json');
 const autoprefixer = require('autoprefixer');
 const BaseHrefWebpackPlugin = require('base-href-webpack-plugin').BaseHrefWebpackPlugin;
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const env = process.env.NODE_ENV || 'production';
+const brand = process.env.BRAND || 'cord';
 
 module.exports = {
   module: {
@@ -47,9 +50,14 @@
     ]
   },
   plugins: [
+    new CopyWebpackPlugin([
+      { from: `./conf/app/app.config.${env}.js`, to: `app.config.js` },
+      { from: `./conf/app/style.config.${brand}.js`, to: `style.config.js` },
+    ]),
     new webpack.optimize.OccurrenceOrderPlugin(),
     new webpack.NoErrorsPlugin(),
     new HtmlWebpackPlugin({
+      inject: true,
       template: conf.path.src('index.html')
     }),
     new webpack.optimize.UglifyJsPlugin({
@@ -64,7 +72,7 @@
     }),
     new BaseHrefWebpackPlugin({
       baseHref: '/spa/'
-    })
+    }),
   ],
   postcss: () => [autoprefixer],
   output: {
diff --git a/conf/webpack.conf.js b/conf/webpack.conf.js
index 7991b97..544b2c5 100644
--- a/conf/webpack.conf.js
+++ b/conf/webpack.conf.js
@@ -4,6 +4,9 @@
 
 const HtmlWebpackPlugin = require('html-webpack-plugin');
 const autoprefixer = require('autoprefixer');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const env = process.env.NODE_ENV || 'production';
+const brand = process.env.BRAND || 'cord';
 
 module.exports = {
   module: {
@@ -54,6 +57,10 @@
     ]
   },
   plugins: [
+    new CopyWebpackPlugin([
+      { from: `./conf/app/app.config.${env}.js`, to: `app.config.js` },
+      { from: `./conf/app/style.config.${brand}.js`, to: `style.config.js` },
+    ]),
     new webpack.optimize.OccurrenceOrderPlugin(),
     new webpack.NoErrorsPlugin(),
     new HtmlWebpackPlugin({
diff --git a/gulp_tasks/misc.js b/gulp_tasks/misc.js
index 0e6a3fd..d766d14 100644
--- a/gulp_tasks/misc.js
+++ b/gulp_tasks/misc.js
@@ -7,14 +7,9 @@
 const replace = require('gulp-replace');
 
 const conf = require('../conf/gulp.conf');
-const cfgFolder = path.join(conf.paths.src, 'app/config');
 
 gulp.task('clean', clean);
 gulp.task('other', other);
-gulp.task('brand', styleConfig);
-gulp.task('appConfig', appConfig);
-gulp.task('copyCfgInterfaces', copyCfgInterfaces);
-gulp.task('config', gulp.series('copyCfgInterfaces', 'brand', 'appConfig'));
 
 function clean() {
   return del([conf.paths.dist, conf.paths.tmp]);
@@ -31,32 +26,6 @@
     .pipe(gulp.dest(conf.paths.dist));
 }
 
-function appConfig() {
-  const env = process.env.NODE_ENV || 'production';
-  return gulp.src([
-    path.join(conf.paths.appConfig, `app.config.${env}.ts`)
-  ])
-    .pipe(rename('app.config.ts'))
-    .pipe(gulp.dest(cfgFolder));
-}
-
-function styleConfig() {
-  const env = process.env.BRAND || 'cord';
-  return gulp.src([
-    path.join(conf.paths.appConfig, `style.config.${env}.ts`)
-  ])
-    .pipe(rename('style.config.ts'))
-    .pipe(gulp.dest(cfgFolder));
-}
-
-function copyCfgInterfaces() {
-  return gulp.src([
-    path.join(conf.paths.appConfig, `interfaces.ts`)
-  ])
-    .pipe(replace('../../src/app/core/services/navigation', '../core/services/navigation'))
-    .pipe(gulp.dest(cfgFolder));
-}
-
 function other() {
   const fileFilter = filter(file => file.stat.isFile());
 
diff --git a/gulpfile.js b/gulpfile.js
index 479273b..541d6e4 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -10,11 +10,11 @@
 // Tell gulp to use the tasks just loaded
 gulp.registry(hub);
 
-gulp.task('build', gulp.series('config', gulp.parallel('other', 'webpack:dist')));
-gulp.task('test', gulp.series('config', 'karma:single-run'));
+gulp.task('build', gulp.series(gulp.parallel('other', 'webpack:dist')));
+gulp.task('test', gulp.series('karma:single-run'));
 gulp.task('test:auto', gulp.series('karma:auto-run'));
-gulp.task('serve', gulp.series('config', 'webpack:watch', 'watch', 'browsersync'));
-gulp.task('serve:dist', gulp.series('config', 'default', 'browsersync:dist'));
+gulp.task('serve', gulp.series('webpack:watch', 'watch', 'browsersync'));
+gulp.task('serve:dist', gulp.series('default', 'browsersync:dist'));
 gulp.task('default', gulp.series('clean', 'build'));
 gulp.task('watch', watch);
 
diff --git a/package.json b/package.json
index fefda25..e119053 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
     "base-href-webpack-plugin": "^1.0.0",
     "browser-sync": "^2.9.11",
     "browser-sync-spa": "^1.0.3",
+    "copy-webpack-plugin": "^4.0.1",
     "css-loader": "^0.23.1",
     "del": "^2.0.2",
     "es6-shim": "^0.35.0",
diff --git a/src/app/config/.gitignore b/src/app/config/.gitignore
deleted file mode 100644
index d6b7ef3..0000000
--- a/src/app/config/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
diff --git a/src/app/core/footer/footer.spec.ts b/src/app/core/footer/footer.spec.ts
index 06c1044..4193bc9 100644
--- a/src/app/core/footer/footer.spec.ts
+++ b/src/app/core/footer/footer.spec.ts
@@ -3,13 +3,18 @@
 import * as angular from 'angular';
 import 'angular-mocks';
 import {xosFooter} from './footer';
-import {StyleConfig} from '../../config/style.config';
+
+const MockStyleConfig = {
+  projectName: 'CORD'
+};
 
 describe('footer component', () => {
   beforeEach(() => {
     angular
       .module('xosFooter', ['app/core/footer/footer.html'])
-      .component('xosFooter', xosFooter);
+      .component('xosFooter', xosFooter)
+      .constant('StyleConfig', MockStyleConfig);
+
     angular.mock.module('xosFooter');
   });
 
@@ -17,6 +22,6 @@
     const element = $compile('<xos-footer></xos-footer>')($rootScope);
     $rootScope.$digest();
     const footer = element.find('a');
-    expect(footer.html().trim()).toEqual(`${StyleConfig.projectName} Team`);
+    expect(footer.html().trim()).toEqual(`${MockStyleConfig.projectName} Team`);
   }));
 });
diff --git a/src/app/core/footer/footer.ts b/src/app/core/footer/footer.ts
index 77a223b..e5fbe3f 100644
--- a/src/app/core/footer/footer.ts
+++ b/src/app/core/footer/footer.ts
@@ -1,11 +1,15 @@
-import {StyleConfig} from '../../config/style.config';
-
+import {IXosStyleConfig} from '../../../index';
 class FooterCtrl {
+
+  static $inject = ['StyleConfig'];
+
   public brand: string;
 
   /** @ngInject */
-  constructor() {
-    this.brand = StyleConfig.projectName;
+  constructor(
+    private StyleConfig: IXosStyleConfig
+  ) {
+    this.brand = this.StyleConfig.projectName;
   }
 }
 
diff --git a/src/app/core/header/header.spec.ts b/src/app/core/header/header.spec.ts
index 864c5a4..62fa368 100644
--- a/src/app/core/header/header.spec.ts
+++ b/src/app/core/header/header.spec.ts
@@ -51,7 +51,11 @@
       .value('toastr', MockToastr)
       .value('toastrConfig', MockToastrConfig)
       .value('AuthService', MockAuth)
-      .value('NavigationService', {});
+      .value('NavigationService', {})
+      .value('StyleConfig', {
+        logo: 'cord-logo.png',
+      });
+
     angular.mock.module('xosHeader');
   });
 
diff --git a/src/app/core/header/header.ts b/src/app/core/header/header.ts
index 88562ea..0a98494 100644
--- a/src/app/core/header/header.ts
+++ b/src/app/core/header/header.ts
@@ -1,5 +1,4 @@
 import './header.scss';
-import {StyleConfig} from '../../config/style.config';
 import {IWSEvent} from '../../datasources/websocket/global';
 import {IStoreService} from '../../datasources/stores/synchronizer.store';
 import {IXosAuthService} from '../../datasources/rest/auth.rest';
@@ -7,13 +6,14 @@
 import {IStateService} from 'angular-ui-router';
 import * as _ from 'lodash';
 import * as $ from 'jquery';
+import {IXosStyleConfig} from '../../../index';
 
 export interface INotification extends IWSEvent {
   viewed?: boolean;
 }
 
 class HeaderController {
-  static $inject = ['$scope', '$rootScope', '$state', 'AuthService', 'SynchronizerStore', 'toastr', 'toastrConfig', 'NavigationService'];
+  static $inject = ['$scope', '$rootScope', '$state', 'AuthService', 'SynchronizerStore', 'toastr', 'toastrConfig', 'NavigationService', 'StyleConfig'];
   public notifications: INotification[] = [];
   public newNotifications: INotification[] = [];
   public version: string;
@@ -30,7 +30,8 @@
     private syncStore: IStoreService,
     private toastr: ng.toastr.IToastrService,
     private toastrConfig: ng.toastr.IToastrConfig,
-    private NavigationService: IXosNavigationService
+    private NavigationService: IXosNavigationService,
+    private StyleConfig: IXosStyleConfig
   ) {
     this.version = require('../../../../package.json').version;
     angular.extend(this.toastrConfig, {
@@ -107,7 +108,7 @@
   }
 
   public getLogo(): string {
-    return require(`../../images/brand/${StyleConfig.logo}`);
+    return require(`../../images/brand/${this.StyleConfig.logo}`);
   }
 
   // TODO display a list of notification in the template (if it make sense)
diff --git a/src/app/core/login/login.ts b/src/app/core/login/login.ts
index cd588d4..a08c17d 100644
--- a/src/app/core/login/login.ts
+++ b/src/app/core/login/login.ts
@@ -1,27 +1,28 @@
 import {AuthService} from '../../datasources/rest/auth.rest';
-import {StyleConfig} from '../../config/style.config';
 import './login.scss';
 import {IXosModelSetupService} from '../services/helpers/model-setup.helpers';
+import {IXosStyleConfig} from '../../../index';
 
 class LoginCtrl {
-  static $inject = ['AuthService', '$state', 'ModelSetup'];
+  static $inject = ['AuthService', '$state', 'ModelSetup', 'StyleConfig'];
   public loginStyle: any;
   public img: string;
   /** @ngInject */
   constructor(
     private authService: AuthService,
     private $state: angular.ui.IStateService,
-    private ModelSetup: IXosModelSetupService
+    private ModelSetup: IXosModelSetupService,
+    private StyleConfig: IXosStyleConfig
   ) {
 
     if (this.authService.isAuthenticated()) {
       this.$state.go('xos.dashboard');
     }
 
-    this.img = this.getImg(StyleConfig.background);
+    this.img = this.getImg(this.StyleConfig.background);
 
     this.loginStyle = {
-      'background-image': `url('${this.getImg(StyleConfig.background)}')`
+      'background-image': `url('${this.getImg(this.StyleConfig.background)}')`
     };
   }
 
diff --git a/src/app/core/nav/nav.spec.ts b/src/app/core/nav/nav.spec.ts
index 28cd3e1..fafec7d 100644
--- a/src/app/core/nav/nav.spec.ts
+++ b/src/app/core/nav/nav.spec.ts
@@ -30,7 +30,8 @@
       .module('xosNav', ['app/core/nav/nav.html', 'ui.router'])
       .component('xosNav', xosNav)
       .service('NavigationService', NavigationService)
-      .value('AuthService', AuthMock);
+      .value('AuthService', AuthMock)
+      .value('StyleConfig', {});
     angular.mock.module('xosNav');
   });
 
diff --git a/src/app/core/nav/nav.ts b/src/app/core/nav/nav.ts
index 6c26635..c100c42 100644
--- a/src/app/core/nav/nav.ts
+++ b/src/app/core/nav/nav.ts
@@ -1,10 +1,10 @@
 import './nav.scss';
 import {IXosNavigationService, IXosNavigationRoute} from '../services/navigation';
-import {StyleConfig} from '../../config/style.config';
 import {IXosAuthService} from '../../datasources/rest/auth.rest';
+import {IXosStyleConfig} from '../../../index';
 
 class NavCtrl {
-  static $inject = ['$scope', '$state', 'NavigationService', 'AuthService'];
+  static $inject = ['$scope', '$state', 'NavigationService', 'AuthService', 'StyleConfig'];
   public routes: IXosNavigationRoute[];
   public navSelected: string;
   public appName: string;
@@ -14,7 +14,8 @@
     private $scope: ng.IScope,
     private $state: angular.ui.IStateService,
     private navigationService: IXosNavigationService,
-    private authService: IXosAuthService
+    private authService: IXosAuthService,
+    private StyleConfig: IXosStyleConfig
   ) {
     // NOTE we'll need to have:
     // - Base routes (defined from configuration based on BRAND)
@@ -24,8 +25,8 @@
     this.$scope.$watch(() => this.navigationService.query(), (routes) => {
       this.routes = routes;
     });
-    this.appName = StyleConfig.projectName;
-    this.payoff = StyleConfig.payoff;
+    this.appName = this.StyleConfig.projectName;
+    this.payoff = this.StyleConfig.payoff;
   }
 
   activateRoute(route: IXosNavigationRoute) {
diff --git a/src/app/core/services/navigation.spec.ts b/src/app/core/services/navigation.spec.ts
index c5fb85d..62e8d3c 100644
--- a/src/app/core/services/navigation.spec.ts
+++ b/src/app/core/services/navigation.spec.ts
@@ -8,15 +8,46 @@
 
 let defaultRoutes: IXosNavigationRoute[];
 
+const mockRoutes = [
+  {
+    label: 'Slices',
+    state: 'xos.core.slices'
+  },
+  {
+    label: 'Instances',
+    state: 'xos.core.instances'
+  },
+  {
+    label: 'Nodes',
+    state: 'xos.core.nodes'
+  }
+];
+
 describe('The Navigation service', () => {
 
-  beforeEach(angular.mock.module(xosCore));
+  beforeEach(() => {
+    angular.module(xosCore)
+      .value('StyleConfig', {
+        routes: mockRoutes
+      });
+
+    angular.mock.module(xosCore);
+  });
 
   beforeEach(angular.mock.inject((
     NavigationService: IXosNavigationService,
   ) => {
     service = NavigationService;
-    defaultRoutes = angular.copy(service.query());
+    defaultRoutes = [
+      {
+        label: 'Home',
+        state: 'xos.dashboard'
+      },
+      {
+        label: 'Core',
+        state: 'xos.core'
+      }
+    ].concat(mockRoutes);
   }));
 
   it('should return navigation routes', () => {
diff --git a/src/app/core/services/navigation.ts b/src/app/core/services/navigation.ts
index d184fc2..31f2b4e 100644
--- a/src/app/core/services/navigation.ts
+++ b/src/app/core/services/navigation.ts
@@ -1,7 +1,7 @@
 /// <reference path="../../../../typings/index.d.ts" />
 
 import * as _ from 'lodash';
-import {StyleConfig} from '../../config/style.config';
+import {IXosStyleConfig} from '../../../index';
 
 export interface IXosNavigationRoute {
   label: string;
@@ -18,9 +18,12 @@
 }
 
 export class NavigationService {
+  static $inject = ['StyleConfig'];
   private routes: IXosNavigationRoute[];
 
-  constructor() {
+  constructor(
+    private StyleConfig: IXosStyleConfig
+  ) {
     const defaultRoutes = [
       {
         label: 'Home',
@@ -34,7 +37,7 @@
     // adding configuration defined routes
     // this.routes = StyleConfig.routes.concat(defaultRoutes).reverse();
     this.routes = defaultRoutes;
-    StyleConfig.routes.forEach(r => {
+    this.StyleConfig.routes.forEach(r => {
       this.add(r);
     });
   }
diff --git a/src/app/core/services/page-title.spec.ts b/src/app/core/services/page-title.spec.ts
index 0959e57..9e6f519 100644
--- a/src/app/core/services/page-title.spec.ts
+++ b/src/app/core/services/page-title.spec.ts
@@ -4,12 +4,20 @@
 import {xosCore} from '../index';
 import {IXosPageTitleService} from './page-title';
 import IWindowService = angular.IWindowService;
-import {StyleConfig} from '../../config/style.config';
 
 let service: IXosPageTitleService, $window: IWindowService;
+
+const MockStyleConfig = {
+  projectName: 'CORD'
+};
+
 describe('The PageTitle service', () => {
 
-  beforeEach(angular.mock.module(xosCore));
+  beforeEach(() => {
+    angular.module(xosCore)
+      .constant('StyleConfig', MockStyleConfig);
+    angular.mock.module(xosCore);
+  });
 
   beforeEach(angular.mock.inject((
     PageTitle: IXosPageTitleService,
@@ -26,11 +34,11 @@
 
   it('should set a page title', () => {
     service.set('sample');
-    expect($window.document.title).toEqual(`${StyleConfig.projectName} - sample`);
+    expect($window.document.title).toEqual(`${MockStyleConfig.projectName} - sample`);
   });
 
   it('should convert dots to >', () => {
     service.set('core.sample.bread.crumb');
-    expect($window.document.title).toEqual(`${StyleConfig.projectName} - core > sample > bread > crumb`);
+    expect($window.document.title).toEqual(`${MockStyleConfig.projectName} - core > sample > bread > crumb`);
   });
 });
diff --git a/src/app/core/services/page-title.ts b/src/app/core/services/page-title.ts
index 865149d..e3b8d42 100644
--- a/src/app/core/services/page-title.ts
+++ b/src/app/core/services/page-title.ts
@@ -1,4 +1,4 @@
-import {StyleConfig} from '../../config/style.config';
+import {IXosStyleConfig} from '../../../index';
 export interface IXosPageTitleService {
   get(): string;
   set(title: string): void;
@@ -6,10 +6,11 @@
 }
 
 export class PageTitle {
-  static $inject = ['$window', '$transitions'];
+  static $inject = ['$window', '$transitions', 'StyleConfig'];
   constructor(
     private $window: angular.IWindowService,
-    private $transitions: any // missing definition
+    private $transitions: any, // missing definition
+    private StyleConfig: IXosStyleConfig
   ) {
     this.$transitions.onSuccess({ to: '**' }, (transtion) => {
       this.set(transtion.$to().name);
@@ -21,7 +22,7 @@
   }
 
   set(title: string) {
-    this.$window.document.title = `${StyleConfig.projectName} - ${this.formatStateName(title)}`;
+    this.$window.document.title = `${this.StyleConfig.projectName} - ${this.formatStateName(title)}`;
   }
 
   private formatStateName(stateName: string): string {
diff --git a/src/app/datasources/helpers/store.helpers.spec.ts b/src/app/datasources/helpers/store.helpers.spec.ts
index adc654b..2cb1eaf 100644
--- a/src/app/datasources/helpers/store.helpers.spec.ts
+++ b/src/app/datasources/helpers/store.helpers.spec.ts
@@ -21,7 +21,8 @@
       .service('ConfigHelpers', ConfigHelpers) // NOTE evaluate mock
       .service('ModelRest', ModelRest) // NOTE evaluate mock
       .service('StoreHelpers', StoreHelpers)
-      .service('AuthService', AuthService);
+      .service('AuthService', AuthService)
+      .value('AppConfig', {});
 
     angular.mock.module('test');
   });
diff --git a/src/app/datasources/rest/auth.rest.spec.ts b/src/app/datasources/rest/auth.rest.spec.ts
index 16c0f8d..483bcfc 100644
--- a/src/app/datasources/rest/auth.rest.spec.ts
+++ b/src/app/datasources/rest/auth.rest.spec.ts
@@ -3,7 +3,6 @@
 import 'angular-resource';
 import 'angular-cookies';
 import {xosDataSources} from '../index';
-import {AppConfig} from '../../config/app.config';
 import {IXosAuthService} from './auth.rest';
 
 let service: IXosAuthService;
@@ -11,11 +10,20 @@
 let $scope;
 let $cookies;
 
+const MockAppCfg = {
+  apiEndpoint: 'http://xos-test:3000/api',
+  websocketClient: 'http://xos-test:3000'
+};
+
 describe('The AuthService service', () => {
 
   beforeEach(angular.mock.module(xosDataSources));
 
   beforeEach(() => {
+
+    angular.module(xosDataSources)
+      .constant('AppConfig', MockAppCfg);
+
     angular.mock.module(xosDataSources);
   });
 
@@ -34,7 +42,7 @@
 
   describe('when logging in', () => {
     beforeEach(() => {
-      httpBackend.expectPOST(`${AppConfig.apiEndpoint}/utility/login/`)
+      httpBackend.expectPOST(`${MockAppCfg.apiEndpoint}/utility/login/`)
         .respond({
           user: JSON.stringify({usernane: 'test@xos.org'}),
           xoscsrftoken: 'token',
@@ -59,7 +67,7 @@
 
   describe('when logging out', () => {
     beforeEach(() => {
-      httpBackend.expectPOST(`${AppConfig.apiEndpoint}/utility/logout/`)
+      httpBackend.expectPOST(`${MockAppCfg.apiEndpoint}/utility/logout/`)
         .respond({
           user: JSON.stringify({usernane: 'test@xos.org'}),
           xoscsrftoken: 'token',
diff --git a/src/app/datasources/rest/auth.rest.ts b/src/app/datasources/rest/auth.rest.ts
index edf7705..2979bf1 100644
--- a/src/app/datasources/rest/auth.rest.ts
+++ b/src/app/datasources/rest/auth.rest.ts
@@ -1,5 +1,5 @@
-import {AppConfig} from '../../config/app.config';
 import IHttpPromiseCallbackArg = angular.IHttpPromiseCallbackArg;
+import {IXosAppConfig} from '../../../index';
 export interface IAuthRequestData {
   username: string;
   password: string;
@@ -30,17 +30,18 @@
   constructor(
     private $http: angular.IHttpService,
     private $q: angular.IQService,
-    private $cookies: angular.cookies.ICookiesService
+    private $cookies: angular.cookies.ICookiesService,
+    private AppConfig: IXosAppConfig
   ) {
   }
 
   public login(data: IAuthRequestData): Promise<any> {
     const d = this.$q.defer();
-    this.$http.post(`${AppConfig.apiEndpoint}/utility/login/`, data)
+    this.$http.post(`${this.AppConfig.apiEndpoint}/utility/login/`, data)
       .then((res: IAuthResponseData) => {
-        this.$cookies.put('xoscsrftoken', res.data.xoscsrftoken);
-        this.$cookies.put('xossessionid', res.data.xossessionid);
-        this.$cookies.put('xosuser', res.data.user);
+        this.$cookies.put('xoscsrftoken', res.data.xoscsrftoken, {path: '/'});
+        this.$cookies.put('xossessionid', res.data.xossessionid, {path: '/'});
+        this.$cookies.put('xosuser', res.data.user, {path: '/'});
         res.data.user = JSON.parse(res.data.user);
         d.resolve(res.data);
       })
@@ -52,7 +53,7 @@
 
   public logout(): Promise<any> {
     const d = this.$q.defer();
-    this.$http.post(`${AppConfig.apiEndpoint}/utility/logout/`, {
+    this.$http.post(`${this.AppConfig.apiEndpoint}/utility/logout/`, {
       xoscsrftoken: this.$cookies.get('xoscsrftoken'),
       xossessionid: this.$cookies.get('xossessionid')
     })
@@ -67,9 +68,9 @@
   }
 
   public clearUser(): void {
-    this.$cookies.remove('xoscsrftoken');
-    this.$cookies.remove('xossessionid');
-    this.$cookies.remove('xosuser');
+    this.$cookies.remove('xoscsrftoken', {path: '/'});
+    this.$cookies.remove('xossessionid', {path: '/'});
+    this.$cookies.remove('xosuser', {path: '/'});
   }
 
   public getUser(): IXosUser {
diff --git a/src/app/datasources/rest/model.rest.spec.ts b/src/app/datasources/rest/model.rest.spec.ts
index f57c0c8..9d5b4f3 100644
--- a/src/app/datasources/rest/model.rest.spec.ts
+++ b/src/app/datasources/rest/model.rest.spec.ts
@@ -4,7 +4,6 @@
 import 'angular-cookies';
 import {IXosResourceService} from './model.rest';
 import {xosDataSources} from '../index';
-import {AppConfig} from '../../config/app.config';
 
 let service: IXosResourceService;
 let resource: ng.resource.IResourceClass<any>;
@@ -12,11 +11,20 @@
 let $resource;
 let $scope;
 
+const MockAppCfg = {
+  apiEndpoint: 'http://xos-test:3000/api',
+  websocketClient: 'http://xos-test:3000'
+};
+
 describe('The ModelRest service', () => {
 
   beforeEach(angular.mock.module(xosDataSources));
 
   beforeEach(() => {
+
+    angular.module(xosDataSources)
+      .constant('AppConfig', MockAppCfg);
+
     angular.mock.module(xosDataSources);
   });
 
@@ -39,7 +47,7 @@
   });
 
   it('should have a query method', (done) => {
-    httpBackend.expectGET(`${AppConfig.apiEndpoint}/core/test`)
+    httpBackend.expectGET(`${MockAppCfg.apiEndpoint}/core/test`)
       .respond([
         {status: 'ok'}
       ]);
@@ -57,7 +65,7 @@
   });
 
   it('should have a get method', (done) => {
-    httpBackend.expectGET(`${AppConfig.apiEndpoint}/core/test/1`)
+    httpBackend.expectGET(`${MockAppCfg.apiEndpoint}/core/test/1`)
       .respond([
         {status: 'ok'}
       ]);
diff --git a/src/app/datasources/rest/model.rest.ts b/src/app/datasources/rest/model.rest.ts
index 8bd2c1f..12590af 100644
--- a/src/app/datasources/rest/model.rest.ts
+++ b/src/app/datasources/rest/model.rest.ts
@@ -1,21 +1,21 @@
-import {AppConfig} from '../../config/app.config';
-
+import {IXosAppConfig} from '../../../index';
 export interface IXosResourceService {
   getResource(url: string): ng.resource.IResourceClass<any>;
 }
 
 export class ModelRest implements IXosResourceService {
-  static $inject = ['$resource'];
+  static $inject = ['$resource', 'AppConfig'];
 
   /** @ngInject */
   constructor(
-    private $resource: ng.resource.IResourceService
+    private $resource: ng.resource.IResourceService,
+    private AppConfig: IXosAppConfig
   ) {
 
   }
 
   public getResource(url: string): ng.resource.IResourceClass<ng.resource.IResource<any>> {
-    const resource: angular.resource.IResourceClass<any> = this.$resource(`${AppConfig.apiEndpoint}${url}/:id/`, {id: '@id'}, {
+    const resource: angular.resource.IResourceClass<any> = this.$resource(`${this.AppConfig.apiEndpoint}${url}/:id/`, {id: '@id'}, {
       update: { method: 'PUT' }
     });
 
diff --git a/src/app/datasources/rest/modeldefs.rest.spec.ts b/src/app/datasources/rest/modeldefs.rest.spec.ts
index 6469cca..9dc4025 100644
--- a/src/app/datasources/rest/modeldefs.rest.spec.ts
+++ b/src/app/datasources/rest/modeldefs.rest.spec.ts
@@ -3,18 +3,26 @@
 import 'angular-resource';
 import 'angular-cookies';
 import {xosDataSources} from '../index';
-import {AppConfig} from '../../config/app.config';
 import {IModeldefsService} from './modeldefs.rest';
 
 let service: IModeldefsService;
 let httpBackend: ng.IHttpBackendService;
 let $scope;
 
+const MockAppCfg = {
+  apiEndpoint: 'http://xos-test:3000/api',
+  websocketClient: 'http://xos-test:3000'
+};
+
 describe('The ModelDefs service', () => {
 
   beforeEach(angular.mock.module(xosDataSources));
 
   beforeEach(() => {
+
+    angular.module(xosDataSources)
+      .constant('AppConfig', MockAppCfg);
+
     angular.mock.module(xosDataSources);
   });
 
@@ -31,7 +39,7 @@
   }));
 
   it('should have a get method', (done) => {
-    httpBackend.expectGET(`${AppConfig.apiEndpoint}/utility/modeldefs/`)
+    httpBackend.expectGET(`${MockAppCfg.apiEndpoint}/utility/modeldefs/`)
       .respond([
         {name: 'ok'}
       ]);
diff --git a/src/app/datasources/rest/modeldefs.rest.ts b/src/app/datasources/rest/modeldefs.rest.ts
index d5a5541..d927f8c 100644
--- a/src/app/datasources/rest/modeldefs.rest.ts
+++ b/src/app/datasources/rest/modeldefs.rest.ts
@@ -1,5 +1,5 @@
-import {AppConfig} from '../../config/app.config';
 import {IXosModelDefsField} from '../../core/services/helpers/config.helpers';
+import {IXosAppConfig} from '../../../index';
 
 export interface IModeldef {
   fields: IXosModelDefsField[];
@@ -12,15 +12,19 @@
 }
 
 export class ModeldefsService {
+
+  static $inject = ['$http', '$q', 'AppConfig'];
+
   constructor(
     private $http: angular.IHttpService,
     private $q: angular.IQService,
+    private AppConfig: IXosAppConfig
   ) {
   }
 
   public get(): Promise<any> {
     const d = this.$q.defer();
-    this.$http.get(`${AppConfig.apiEndpoint}/utility/modeldefs/`)
+    this.$http.get(`${this.AppConfig.apiEndpoint}/utility/modeldefs/`)
       .then((res) => {
         d.resolve(res.data);
       })
diff --git a/src/app/datasources/stores/model.store.spec.ts b/src/app/datasources/stores/model.store.spec.ts
index 5bdc498..97ce890 100644
--- a/src/app/datasources/stores/model.store.spec.ts
+++ b/src/app/datasources/stores/model.store.spec.ts
@@ -6,7 +6,6 @@
 import {IWSEvent} from '../websocket/global';
 import {StoreHelpers} from '../helpers/store.helpers';
 import {ModelRest} from '../rest/model.rest';
-import {AppConfig} from '../../config/app.config';
 import {ConfigHelpers} from '../../core/services/helpers/config.helpers';
 import {AuthService} from '../rest/auth.rest';
 
@@ -34,6 +33,11 @@
   {id: 1, name: 'bar'}
 ];
 
+const MockAppCfg = {
+  apiEndpoint: 'http://xos-test:3000/api',
+  websocketClient: 'http://xos-test:3000'
+};
+
 describe('The ModelStore service', () => {
 
   beforeEach(() => {
@@ -44,7 +48,8 @@
       .service('ModelRest', ModelRest) // TODO mock
       .service('ModelStore', ModelStore)
       .service('ConfigHelpers', ConfigHelpers) // TODO mock
-      .service('AuthService', AuthService);
+      .service('AuthService', AuthService)
+      .constant('AppConfig', MockAppCfg);
 
     angular.mock.module('ModelStore');
   });
@@ -61,7 +66,7 @@
     WebSocket = _WebSocket_;
 
     // ModelRest will call the backend
-    httpBackend.whenGET(`${AppConfig.apiEndpoint}/core/samples`)
+    httpBackend.whenGET(`${MockAppCfg.apiEndpoint}/core/samples`)
       .respond(queryData);
   }));
 
@@ -122,11 +127,11 @@
   describe('when multiple stores are requested', () => {
 
     beforeEach(() => {
-      httpBackend.expectGET(`${AppConfig.apiEndpoint}/core/firsts`)
+      httpBackend.expectGET(`${MockAppCfg.apiEndpoint}/core/firsts`)
         .respond([
           {first: 'foo'}
         ]);
-      httpBackend.expectGET(`${AppConfig.apiEndpoint}/core/seconds`)
+      httpBackend.expectGET(`${MockAppCfg.apiEndpoint}/core/seconds`)
         .respond([
           {second: 'foo'}
         ]);
diff --git a/src/app/datasources/websocket/global.ts b/src/app/datasources/websocket/global.ts
index 89a8607..a5852c8 100644
--- a/src/app/datasources/websocket/global.ts
+++ b/src/app/datasources/websocket/global.ts
@@ -1,6 +1,6 @@
 import * as io from 'socket.io-client';
 import {Subject, Observable} from 'rxjs/Rx';
-import {AppConfig} from '../../config/app.config';
+import {IXosAppConfig} from '../../../index';
 
 export interface IWSEvent {
   model: string;
@@ -16,10 +16,15 @@
 }
 
 export class WebSocketEvent {
+
+  static $inject = ['AppConfig'];
+
   private _events: Subject<IWSEvent> = new Subject<IWSEvent>();
     private socket;
-    constructor() {
-      this.socket = io(AppConfig.websocketClient);
+    constructor(
+      private AppConfig: IXosAppConfig
+    ) {
+      this.socket = io(this.AppConfig.websocketClient);
       this.socket.on('event', (data: IWSEvent): void => {
           this._events.next(data);
         });
diff --git a/src/index.html b/src/index.html
index 8cf67ce..2f5ee65 100644
--- a/src/index.html
+++ b/src/index.html
@@ -15,4 +15,6 @@
   <body class="{{class}}">
     <ui-view></ui-view>
   </body>
+  <script type="text/javascript" src="./app.config.js"></script>
+  <script type="text/javascript" src="./style.config.js"></script>
 </html>
diff --git a/src/index.ts b/src/index.ts
index 916730e..0be6245 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -22,14 +22,28 @@
 } from './interceptors';
 import {IXosCrudData} from './app/views/crud/crud';
 import {IXosPageTitleService} from './app/core/services/page-title';
-import {StyleConfig} from './app/config/style.config';
 import {IXosAuthService} from './app/datasources/rest/auth.rest';
 import {IXosModelSetupService} from './app/core/services/helpers/model-setup.helpers';
+import {IXosNavigationRoute} from './app/core/services/navigation';
 
 export interface IXosState extends angular.ui.IState {
   data: IXosCrudData;
 };
 
+export interface IXosAppConfig {
+  apiEndpoint: string;
+  websocketClient: string;
+}
+
+export interface IXosStyleConfig {
+  projectName: string;
+  payoff: string;
+  favicon: string;
+  background: string;
+  logo: string;
+  routes: IXosNavigationRoute[];
+}
+
 angular
   .module('app', [
     xosCore,
@@ -45,7 +59,7 @@
   .factory('CredentialsInterceptor', CredentialsInterceptor)
   .factory('NoHyperlinksInterceptor', NoHyperlinksInterceptor)
   .component('xos', main)
-  .run(function($rootScope: ng.IRootScopeService, $transitions: any) {
+  .run(function($rootScope: ng.IRootScopeService, $transitions: any, StyleConfig: IXosStyleConfig) {
     $rootScope['favicon'] = `./app/images/brand/${StyleConfig.favicon}`;
     $transitions.onSuccess({ to: '**' }, (transtion) => {
       if (transtion.$to().name === 'login') {
diff --git a/src/interceptors.ts b/src/interceptors.ts
index 273d19e..9e3ba65 100644
--- a/src/interceptors.ts
+++ b/src/interceptors.ts
@@ -13,9 +13,9 @@
 
   const checkLogin = (res) => {
     if (res.status === 401 || res.status === -1) {
-      $cookies.remove('xoscsrftoken');
-      $cookies.remove('xossessionid');
-      $cookies.remove('xosuser');
+      $cookies.remove('xoscsrftoken', {path: '/'});
+      $cookies.remove('xossessionid', {path: '/'});
+      $cookies.remove('xosuser', {path: '/'});
       $state.go('login');
     }
     return res;