diff --git a/config/webpack.common.js b/config/webpack.common.js
index f23fe7a398..f3a6c9de1b 100644
--- a/config/webpack.common.js
+++ b/config/webpack.common.js
@@ -118,6 +118,8 @@ module.exports = {
           helpers.root('node_modules/@angular'),
           helpers.root('node_modules/@ngrx'),
           helpers.root('node_modules/@angular2-material'),
+          helpers.root('node_modules/primeng'),
+          helpers.root('node_modules/quill')
         ]
       }
 
@@ -174,6 +176,11 @@ module.exports = {
         loader: 'raw-loader',
         exclude: [helpers.root('src/index.html')]
       }
+      ,
+     {
+      test: /\.scss$/,
+      loaders: ['raw-loader', 'sass']
+    }
 
     ]
 
diff --git a/package.json b/package.json
index a9a8b0ccb3..3a6b3150d0 100644
--- a/package.json
+++ b/package.json
@@ -11,113 +11,108 @@
   "homepage": "https://github.com/angularclass/angular2-webpack-starter",
   "license": "MIT",
   "scripts": {
-     "rimraf": "rimraf",
-     "tslint": "tslint",
-     "typedoc": "typedoc",
-     "typings": "typings",
-     "webpack": "webpack",
-     "webpack-dev-server": "webpack-dev-server",
-     "webdriver-manager": "webdriver-manager",
-     "protractor": "protractor",
-
-     "typings-install": "npm run typings -- install",
-
-     "clean": "npm cache clean && npm run rimraf -- node_modules doc typings coverage dist",
-       "clean:dist": "npm run rimraf -- dist",
-         "preclean:install": "npm run clean",
-       "clean:install": "npm set progress=false && npm install",
-         "preclean:start": "npm run clean",
-       "clean:start": "npm start",
-
-     "watch": "npm run watch:dev",
-       "watch:dev": "npm run build:dev -- --watch",
-       "watch:dev:hmr": "npm run watch:dev -- --hot",
-       "watch:test": "npm run test -- --auto-watch --no-single-run",
-       "watch:prod": "npm run build:prod -- --watch",
-
-     "build": "npm run build:dev",
-         "prebuild:dev": "npm run clean:dist",
-       "build:dev": "webpack --config config/webpack.dev.js --progress --profile --colors --display-error-details --display-cached",
-         "prebuild:prod": "npm run clean:dist",
-       "build:prod": "webpack --config config/webpack.prod.js  --progress --profile --colors --display-error-details --display-cached --bail",
-
+    "rimraf": "rimraf",
+    "tslint": "tslint",
+    "typedoc": "typedoc",
+    "webpack": "webpack",
+    "webpack-dev-server": "webpack-dev-server",
+    "webdriver-manager": "webdriver-manager",
+    "protractor": "protractor",
+    "clean": "npm cache clean && npm run rimraf -- node_modules doc coverage dist",
+    "clean:dist": "npm run rimraf -- dist",
+    "preclean:install": "npm run clean",
+    "clean:install": "npm set progress=false && npm install",
+    "preclean:start": "npm run clean",
+    "clean:start": "npm start",
+    "watch": "npm run watch:dev",
+    "watch:dev": "npm run build:dev -- --watch",
+    "watch:dev:hmr": "npm run watch:dev -- --hot",
+    "watch:test": "npm run test -- --auto-watch --no-single-run",
+    "watch:prod": "npm run build:prod -- --watch",
+    "build": "npm run build:dev",
+    "prebuild:dev": "npm run clean:dist",
+    "build:dev": "webpack --config config/webpack.dev.js --progress --profile --colors --display-error-details --display-cached",
+    "prebuild:prod": "npm run clean:dist",
+    "build:prod": "webpack --config config/webpack.prod.js  --progress --profile --colors --display-error-details --display-cached --bail",
     "github-deploy": "npm run github-deploy:dev",
-      "github-deploy:dev": "webpack --config config/webpack.github-deploy.js --progress --profile --colors --display-error-details --display-cached --github-dev",
-      "github-deploy:prod": "webpack --config config/webpack.github-deploy.js --progress --profile --colors --display-error-details --display-cached --github-prod",
-
+    "github-deploy:dev": "webpack --config config/webpack.github-deploy.js --progress --profile --colors --display-error-details --display-cached --github-dev",
+    "github-deploy:prod": "webpack --config config/webpack.github-deploy.js --progress --profile --colors --display-error-details --display-cached --github-prod",
     "server": "npm run server:dev",
-       "server:dev": "webpack-dev-server --config config/webpack.dev.js --inline --progress --profile --colors --watch --display-error-details --display-cached --content-base src/",
-       "server:dev:hmr": "npm run server:dev -- --hot",
-       "server:prod": "http-server dist --cors",
-
-     "webdriver:update": "npm run webdriver-manager update",
-     "webdriver:start": "npm run webdriver-manager start",
-
-     "lint": "npm run tslint \"src/**/*.ts\"",
-
-       "pree2e": "npm run webdriver:update -- --standalone",
-     "e2e": "npm run protractor",
-       "e2e:live": "npm run e2e -- --elementExplorer",
-
-     "test": "karma start",
-
-     "ci": "npm run lint && npm test && npm run e2e",
-
-     "docs": "npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./src/",
-
-     "start": "npm run server:dev",
-       "start:hmr": "npm run server:dev:hmr",
-
-     "postinstall": "npm run typings-install",
-
-       "preversion": "npm test",
-     "version": "npm run build",
-       "postversion": "git push && git push --tags"
-
-   },
+    "server:dev": "webpack-dev-server --config config/webpack.dev.js --no-info --inline --progress --profile --colors --watch --display-error-details --display-cached --content-base src/",
+    "server:dev:hmr": "npm run server:dev -- --hot",
+    "server:prod": "http-server dist --cors",
+    "webdriver:update": "npm run webdriver-manager update",
+    "webdriver:start": "npm run webdriver-manager start",
+    "lint": "npm run tslint \"src/**/*.ts\"",
+    "pree2e": "npm run webdriver:update -- --standalone",
+    "e2e": "npm run protractor",
+    "e2e:live": "npm run e2e -- --elementExplorer",
+    "test": "karma start",
+    "ci": "npm run lint && npm test && npm run e2e",
+    "docs": "npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./src/",
+    "start": "npm run server:dev",
+    "start:hmr": "npm run server:dev:hmr",
+    "preversion": "npm test",
+    "version": "npm run build",
+    "postversion": "git push && git push --tags"
+  },
   "dependencies": {
-    "@angular/http": "2.0.0-rc.4",
-    "@angular/common": "2.0.0-rc.4",
-    "@angular/compiler": "2.0.0-rc.4",
-    "@angular/core": "2.0.0-rc.4",
-    "@angular/forms": "^0.2.0",
-    "@angular/platform-browser": "2.0.0-rc.4",
-    "@angular/platform-browser-dynamic": "2.0.0-rc.4",
-    "@angular/platform-server": "2.0.0-rc.4",
-    "@angular/router": "3.0.0-beta.2",
-    "@angular2-material/button": "2.0.0-alpha.6",
-    "@angular2-material/card": "2.0.0-alpha.6",
-    "@angular2-material/checkbox": "2.0.0-alpha.6",
-    "@angular2-material/grid-list": "2.0.0-alpha.6",
-    "@angular2-material/icon": "2.0.0-alpha.6",
-    "@angular2-material/core": "2.0.0-alpha.6",
-    "@angular2-material/input": "2.0.0-alpha.6",
-    "@angular2-material/list": "2.0.0-alpha.6",
-    "@angular2-material/progress-bar": "2.0.0-alpha.6",
-    "@angular2-material/progress-circle": "2.0.0-alpha.6",
-    "@angular2-material/radio": "2.0.0-alpha.6",
-    "@angular2-material/sidenav": "2.0.0-alpha.6",
-    "@angular2-material/slide-toggle": "2.0.0-alpha.6",
-    "@angular2-material/tabs": "2.0.0-alpha.6",
-    "@angular2-material/toolbar": "2.0.0-alpha.6",
-
-    "@angularclass/webpack-toolkit": "^1.3.3",
+    "@angular/common": "2.0.0-rc.5",
+    "@angular/compiler": "2.0.0-rc.5",
+    "@angular/core": "2.0.0-rc.5",
+    "@angular/forms": "^0.3.0",
+    "@angular/http": "2.0.0-rc.5",
+    "@angular/platform-browser": "2.0.0-rc.5",
+    "@angular/platform-browser-dynamic": "2.0.0-rc.5",
+    "@angular/platform-server": "2.0.0-rc.5",
+    "@angular/router": "3.0.0-rc.1",
+    "@angular2-material/button": "2.0.0-alpha.7-2",
+    "@angular2-material/button-toggle": "2.0.0-alpha.7-2",
+    "@angular2-material/card": "2.0.0-alpha.7-2",
+    "@angular2-material/checkbox": "2.0.0-alpha.7-2",
+    "@angular2-material/core": "2.0.0-alpha.7-2",
+    "@angular2-material/grid-list": "2.0.0-alpha.7-2",
+    "@angular2-material/icon": "2.0.0-alpha.7-2",
+    "@angular2-material/input": "2.0.0-alpha.7-2",
+    "@angular2-material/list": "2.0.0-alpha.7-2",
+    "@angular2-material/menu": "2.0.0-alpha.7-2",
+    "@angular2-material/progress-bar": "2.0.0-alpha.7-2",
+    "@angular2-material/progress-circle": "2.0.0-alpha.7-2",
+    "@angular2-material/radio": "2.0.0-alpha.7-2",
+    "@angular2-material/sidenav": "2.0.0-alpha.7-2",
+    "@angular2-material/slide-toggle": "2.0.0-alpha.7-2",
+    "@angular2-material/slider": "2.0.0-alpha.7-2",
+    "@angular2-material/tabs": "2.0.0-alpha.7-2",
+    "@angular2-material/toolbar": "2.0.0-alpha.7-2",
+    "@angular2-material/tooltip": "2.0.0-alpha.7-2",
+    "@angularclass/conventions-loader": "^1.0.8",
+    "@angularclass/form-validators": "^1.0.11",
     "@angularclass/request-idle-callback": "^1.0.7",
-
-    "ie-shim": "^0.1.0",
+    "@angularclass/resolve-angular-routes": "^1.0.8",
+    "@angularclass/webpack-toolkit": "^1.3.3",
     "core-js": "^2.4.0",
+    "http-server": "^0.9.0",
+    "ie-shim": "^0.1.0",
     "rxjs": "5.0.0-beta.6",
-    "zone.js": "~0.6.12",
-
-    "http-server": "^0.9.0"
+    "zone.js": "~0.6.12"
   },
   "devDependencies": {
+    "@types/core-js": "^0.9.28",
+    "@types/hammerjs": "^2.0.28",
+    "@types/jasmine": "^2.2.29",
+    "@types/node": "^4.0.29",
+    "@types/protractor": "^1.5.16",
+    "@types/selenium-webdriver": "^2.44.26",
+    "@types/source-map": "^0.1.26",
+    "@types/uglify-js": "^2.0.27",
+    "@types/webpack": "^1.12.29",
+    "@types/lodash": "4.14.30",
+    "@types/moment": "2.11.29",
 
     "angular2-hmr": "~0.8.0",
     "gh-pages": "^0.11.0",
     "parse5": "^1.5.1",
     "rimraf": "^2.5.2",
-
     "karma": "^0.13.22",
     "karma-chrome-launcher": "^1.0.1",
     "karma-coverage": "^1.0.0",
@@ -125,20 +120,14 @@
     "karma-mocha-reporter": "^2.0.0",
     "karma-sourcemap-loader": "^0.3.7",
     "karma-webpack": "1.7.0",
-
     "remap-istanbul": "^0.6.3",
-
     "protractor": "^3.2.2",
-
-    "codelyzer": "~0.0.21",
-
-    "tslint": "^3.7.1",
+    "codelyzer": "0.0.28",
+    "tslint": "^3.14.0",
     "ts-helpers": "1.1.1",
     "ts-node": "^0.9.1",
     "typedoc": "^0.4.4",
-    "typescript": "~1.8.10",
-    "typings": "~1.3.0",
-
+    "typescript": "^2.0.0",
     "awesome-typescript-loader": "1.1.1",
     "angular2-template-loader": "^0.4.0",
     "tslint-loader": "^2.1.3",
@@ -155,10 +144,10 @@
     "expose-loader": "^0.7.1",
     "file-loader": "^0.9.0",
     "to-string-loader": "^1.1.4",
-
+    "node-sass": "^3.7.0",
+    "sass-loader": "3.2.0",
     "html-webpack-plugin": "^2.21.0",
     "copy-webpack-plugin": "^3.0.1",
-
     "webpack": "^1.13.1",
     "webpack-dev-server": "^1.14.1",
     "webpack-md5-hash": "^0.0.5",
diff --git a/src/app/+detail/detail.component.ts b/src/app/+detail/detail.component.ts
index 38e67c842e..0e8fc554e4 100644
--- a/src/app/+detail/detail.component.ts
+++ b/src/app/+detail/detail.component.ts
@@ -1,16 +1,24 @@
-import { Component } from '@angular/core';
-import { ROUTER_DIRECTIVES } from '@angular/router';
+import { Component, NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { MaterialModule } from '../../platform/browser/angular2-material2';
+import { FormsModule } from '@angular/forms';
+import { Index } from './index.component';
 
 @Component({
   selector: 'detail',
-  directives: [
-    ...ROUTER_DIRECTIVES
-  ],
   template: `
+  Detail
     <router-outlet></router-outlet>
   `
 })
 export class Detail {
+  items = [
+   {text: 'Refresh'},
+   {text: 'Settings'},
+   {text: 'Help'},
+   {text: 'Sign Out', disabled: true}
+ ];
+
   constructor() {
 
   }
@@ -20,3 +28,11 @@ export class Detail {
   }
 
 }
+
+@NgModule({
+  imports: [BrowserModule, FormsModule, MaterialModule],
+  exports: [Detail],
+  declarations: [Detail],
+  entryComponents: [Detail]
+})
+export class DetailModule { }
diff --git a/src/app/+detail/index.ts b/src/app/+detail/index.ts
index 41ca71d5f9..6b9450e08f 100644
--- a/src/app/+detail/index.ts
+++ b/src/app/+detail/index.ts
@@ -1,6 +1,4 @@
-export { Detail } from './detail.component';
-export { Index } from './index.component';
+export * from './detail.component';
+export * from './index.component';
 
-console.log('`Detail` bundle loaded asynchronously');
-// Must be exported for WebpackAsyncRoute
 export * from './routes';
diff --git a/src/app/+detail/routes.ts b/src/app/+detail/routes.ts
index 8bbeb99ac3..60b9f16f25 100644
--- a/src/app/+detail/routes.ts
+++ b/src/app/+detail/routes.ts
@@ -1,10 +1,15 @@
+import { provideRouter, Routes } from '@angular/router';
 import { Detail } from './detail.component';
 import { Index } from './index.component';
 
-// async components must be named routes for WebpackAsyncRoute
-export const routes = {
-  path: 'detail', component: Detail,
-  children: [
-    { path: '', component: Index }
-  ]
-};
+
+
+export const detailRoutes: Routes = [
+  {
+    path: 'detail',
+    component: Detail,
+    children: [
+      { path: '', component: Index }
+    ]
+  }
+];
diff --git a/src/app/about/about.component.ts b/src/app/about/about.component.ts
index 8de4d00016..67747e88cd 100644
--- a/src/app/about/about.component.ts
+++ b/src/app/about/about.component.ts
@@ -43,27 +43,7 @@ export class About {
         // your resolved data from route
         this.localState = data.yourData;
       });
-
-    console.log('hello `About` component');
-    // static data that is bundled
-    // var mockData = require('assets/mock-data/mock-data.json');
-    // console.log('mockData', mockData);
-    // if you're working with mock data you can also use http.get('assets/mock-data/mock-data.json')
-    // this.asyncDataWithWebpack();
-  }
-  asyncDataWithWebpack() {
-    // you can also async load mock data with 'es6-promise-loader'
-    // you would do this if you don't want the mock-data bundled
-    // remember that 'es6-promise-loader' is a promise
-    // var asyncMockDataPromiseFactory = require('es6-promise!assets/mock-data/mock-data.json');
-    // setTimeout(() => {
-    //
-    //   let asyncDataPromise = asyncMockDataPromiseFactory();
-    //   asyncDataPromise.then(json => {
-    //     console.log('async mockData', json);
-    //   });
-    //
-    // });
   }
 
+
 }
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index f0fab62d11..bc13b43916 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -12,11 +12,11 @@ import { AppState } from './app.service';
 @Component({
   selector: 'app',
   encapsulation: ViewEncapsulation.None,
-  styleUrls: [
-    './app.style.css'
-  ],
+  styles: [ require('@angular2-material/core/style/core.css')
+          , require('@angular2-material/core/overlay/overlay.css')
+         , require('./app.scss')],
   template: `
-    <md-content>
+
       <md-toolbar color="primary">
           <span>{{ name }}</span>
           <span class="fill"></span>
@@ -26,6 +26,9 @@ import { AppState } from './app.service';
           <a md-button [routerLink]=" ['./home'] ">
             Home
           </a>
+          <a md-button [routerLink]=" ['./demo'] ">
+            Material Demo
+          </a>
           <a md-button [routerLink]=" ['./detail'] ">
             Detail
           </a>
@@ -33,20 +36,12 @@ import { AppState } from './app.service';
             About
           </a>
       </md-toolbar>
+      <router-outlet></router-outlet>
+
+
 
-      <md-progress-bar mode="indeterminate" color="primary" *ngIf="loading"></md-progress-bar>
-    
-      <main>
-        <router-outlet></router-outlet>
-      </main>
 
-      <pre class="app-state">this.appState.state = {{ appState.state | json }}</pre>
 
-      <footer>
-        <span id="footerText">WebPack Angular 2 Starter by <a [href]="url">@AngularClass</a></span>
-        <img [src]="angularclassLogo" width="6%">
-      </footer>
-    </md-content>
   `
 })
 export class App {
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
index 507970a66d..7532a81751 100644
--- a/src/app/app.routes.ts
+++ b/src/app/app.routes.ts
@@ -1,46 +1,21 @@
-import { WebpackAsyncRoute } from '@angularclass/webpack-toolkit';
-import { RouterConfig } from '@angular/router';
+import { provideRouter, Routes } from '@angular/router';
 import { Home } from './home';
+import { About } from './about';
+import { detailRoutes  } from './+detail';
+import { Demo } from './demo';
+
 import { NoContent } from './no-content';
 
 import { DataResolver } from './app.resolver';
 
-export const routes: RouterConfig = [
+export const routes: Routes  = [
   { path: '',      component: Home },
   { path: 'home',  component: Home },
-  // make sure you match the component type string to the require in asyncRoutes
-  { path: 'about', component: 'About',
-    resolve: {
-      'yourData': DataResolver
-    }},
-  // async components with children routes must use WebpackAsyncRoute
-  { path: 'detail', component: 'Detail',
-    canActivate: [ WebpackAsyncRoute ],
-    children: [
-      { path: '', component: 'Index' }  // must be included
-    ]},
+  { path: 'demo',  component: Demo },
+  { path: 'about', component: About},
+  ...detailRoutes,
   { path: '**',    component: NoContent },
 ];
 
-// Async load a component using Webpack's require with es6-promise-loader and webpack `require`
-// asyncRoutes is needed for our @angularclass/webpack-toolkit that will allow us to resolve
-// the component correctly
-
-export const asyncRoutes: AsyncRoutes = {
-  // we have to use the alternative syntax for es6-promise-loader to grab the routes
-  'About': require('es6-promise-loader!./about'),
-  'Detail': require('es6-promise-loader!./+detail'),
-  'Index': require('es6-promise-loader!./+detail'), // must be exported with detail/index.ts
-};
-
-
-// Optimizations for initial loads
-// An array of callbacks to be invoked after bootstrap to prefetch async routes
-export const prefetchRouteCallbacks: Array<IdleCallbacks> = [
-  asyncRoutes['About'],
-  asyncRoutes['Detail'],
-   // es6-promise-loader returns a function
-];
-
 
-// Es6PromiseLoader and AsyncRoutes interfaces are defined in custom-typings
+export const APP_ROUTE_PROVIDER = provideRouter(routes);
diff --git a/src/app/app.scss b/src/app/app.scss
new file mode 100644
index 0000000000..5f49e693e1
--- /dev/null
+++ b/src/app/app.scss
@@ -0,0 +1 @@
+@import "../styles/material";
diff --git a/src/app/app.style.css b/src/app/app.style.css
deleted file mode 100644
index 17ef163752..0000000000
--- a/src/app/app.style.css
+++ /dev/null
@@ -1,35 +0,0 @@
-html, body{
-  height: 100%;
-  background: #F4FAFA;
-  font-family: Arial, Helvetica, sans-serif;
-}
-button.active{
-  background: #fff;
-  color: #009688;
-}
-button.active:hover{
-  color: #fff;
-}
-.fill{
-  flex: 1 1 auto;
-}
-.app-state{
-  margin: 15px;
-  flex: 1;
-}
-.home{
-  flex: 1;
-}
-md-content{
-  display: flex;
-  flex-direction: column;
-  height: 100%;
-}
-footer{
-  flex: 0 0 60px;
-  padding: 10px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  background: #fff;
-}
diff --git a/src/app/demo/demo.html b/src/app/demo/demo.html
new file mode 100644
index 0000000000..83e51b02a1
--- /dev/null
+++ b/src/app/demo/demo.html
@@ -0,0 +1,23 @@
+<md-tab-group>
+  <md-tab>
+    <template md-tab-label>Menu</template>
+    <template md-tab-content>
+      <demo-menu></demo-menu>
+    </template>
+  </md-tab>
+
+  <md-tab>
+    <template md-tab-label>tooltip</template>
+    <template md-tab-content>
+      <tooltip-demo></tooltip-demo>
+    </template>
+  </md-tab>
+
+  <md-tab>
+    <template md-tab-label>Layout</template>
+    <template md-tab-content>
+      <demo-layout></demo-layout>
+    </template>
+  </md-tab>
+
+</md-tab-group>
diff --git a/src/app/demo/demo.ts b/src/app/demo/demo.ts
new file mode 100644
index 0000000000..d39a643657
--- /dev/null
+++ b/src/app/demo/demo.ts
@@ -0,0 +1,29 @@
+import { Component, NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { MaterialModule } from '../../platform/browser/angular2-material2';
+import { FormsModule } from '@angular/forms';
+import { Menu } from './menu/menu';
+import { TooltipDemo } from './tooltip/tooltip';
+import { Layout } from './layout/layout';
+
+@Component({
+  selector: 'demo',
+  template: require('./demo.html'),
+})
+export class Demo {
+
+
+  constructor() {
+
+  }
+
+
+}
+
+@NgModule({
+  imports: [BrowserModule, FormsModule, MaterialModule],
+  exports: [Demo],
+  declarations: [Demo, Menu, TooltipDemo, Layout],
+  entryComponents: [Demo]
+})
+export class DemoModule { }
diff --git a/src/app/demo/index.ts b/src/app/demo/index.ts
new file mode 100644
index 0000000000..689b5cbca9
--- /dev/null
+++ b/src/app/demo/index.ts
@@ -0,0 +1 @@
+export * from './demo';
diff --git a/src/app/demo/layout/layout.html b/src/app/demo/layout/layout.html
new file mode 100644
index 0000000000..c0bbc684c6
--- /dev/null
+++ b/src/app/demo/layout/layout.html
@@ -0,0 +1,25 @@
+<div layout="column">
+  layout="row"
+  <div layout="row" style="height: 50px">
+    <div class="md-shadow-bottom-z-2" flex="50" layout="row" layout-align="start center" style="background-color:blue; color: white">flex 66</div>
+    <div class="md-shadow-bottom-z-2" flex layout="row" layout-align="center center" style="background-color:black; color: white">flex</div>
+    <div class="md-shadow-bottom-z-2" flex="30" layout="row" layout-align="end center" style="background-color:red; color: white">flex 33</div>
+  </div>
+  </div>
+
+<div layout="column" style="margin-top:20px">
+  layout="row" layout-margin
+  <div layout="row" layout-margin style="height: 50px">
+    <div class="md-shadow-bottom-z-2" flex="50" layout="row" layout-align="start center" style="background-color:pink; color: white">flex 66</div>
+    <div class="md-shadow-bottom-z-2" flex layout="row" layout-align="center center" style="background-color:black; color: white">flex</div>
+    <div class="md-shadow-bottom-z-2" flex-nogrow layout="row" layout-align="end center" style="background-color:red; color: white; min-width:200px">flex 33</div>
+  </div>
+</div>
+
+<div class="md-display-4">md-display-4</div>
+<div class="md-display-3">md-display-3</div>
+<div class="md-display-2">md-display-2</div>
+<div class="md-display-1">md-display-1</div>
+<div class="md-headline">md-headline</div>
+<div class="md-title">md-title</div>
+<div class="md-subhead">md-subhead</div>
diff --git a/src/app/demo/layout/layout.ts b/src/app/demo/layout/layout.ts
new file mode 100644
index 0000000000..6650b6d727
--- /dev/null
+++ b/src/app/demo/layout/layout.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'demo-layout',
+  template: require('./layout.html')
+})
+export class Layout {
+
+
+}
diff --git a/src/app/demo/menu/menu.html b/src/app/demo/menu/menu.html
new file mode 100644
index 0000000000..a28d9fd12f
--- /dev/null
+++ b/src/app/demo/menu/menu.html
@@ -0,0 +1,63 @@
+<div class="demo-menu">
+  <div class="menu-section">
+    <p>You clicked on: {{ selected }}</p>
+
+    <md-toolbar>
+      <button md-icon-button [md-menu-trigger-for]="menu">
+        <md-icon>more_vert</md-icon>
+      </button>
+    </md-toolbar>
+
+    <md-menu #menu="mdMenu">
+      <button md-menu-item *ngFor="let item of items" (click)="select(item.text)" [disabled]="item.disabled">
+        {{ item.text }}
+      </button>
+    </md-menu>
+  </div>
+  <div class="menu-section">
+    <p> Clicking these will navigate:</p>
+    <md-toolbar>
+      <button md-icon-button [md-menu-trigger-for]="anchorMenu">
+        <md-icon>more_vert</md-icon>
+      </button>
+    </md-toolbar>
+
+    <md-menu #anchorMenu="mdMenu">
+      <a md-menu-item *ngFor="let item of items" href="http://www.google.com" [disabled]="item.disabled">
+        {{ item.text }}
+      </a>
+    </md-menu>
+  </div>
+  <div class="menu-section">
+    <p>
+      Position x: before
+    </p>
+    <md-toolbar class="end-icon">
+      <button md-icon-button [md-menu-trigger-for]="posXMenu">
+        <md-icon>more_vert</md-icon>
+      </button>
+    </md-toolbar>
+
+    <md-menu x-position="before" #posXMenu="mdMenu" class="before">
+      <button md-menu-item *ngFor="let item of items" [disabled]="item.disabled">
+        {{ item.text }}
+      </button>
+    </md-menu>
+  </div>
+  <div class="menu-section">
+    <p>
+      Position y: above
+    </p>
+    <md-toolbar>
+      <button md-icon-button [md-menu-trigger-for]="posYMenu">
+        <md-icon>more_vert</md-icon>
+      </button>
+    </md-toolbar>
+
+    <md-menu y-position="above" #posYMenu="mdMenu">
+      <button md-menu-item *ngFor="let item of items" [disabled]="item.disabled">
+        {{ item.text }}
+      </button>
+    </md-menu>
+  </div>
+</div>
diff --git a/src/app/demo/menu/menu.scss b/src/app/demo/menu/menu.scss
new file mode 100644
index 0000000000..f6757b40da
--- /dev/null
+++ b/src/app/demo/menu/menu.scss
@@ -0,0 +1,13 @@
+.demo-menu {
+  display: flex;
+  flex-flow: row wrap;
+
+  .menu-section {
+    width: 300px;
+    margin: 20px;
+  }
+
+  .end-icon {
+    align-items: flex-end;
+  }
+}
diff --git a/src/app/demo/menu/menu.ts b/src/app/demo/menu/menu.ts
new file mode 100644
index 0000000000..b219768f2e
--- /dev/null
+++ b/src/app/demo/menu/menu.ts
@@ -0,0 +1,16 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'demo-menu',
+  template: require('./menu.html'),
+  styles: [require('./menu.scss')]
+})
+export class Menu {
+  items = [
+   {text: 'Refresh'},
+   {text: 'Settings'},
+   {text: 'Help'},
+   {text: 'Sign Out', disabled: true}
+ ];
+
+}
diff --git a/src/app/demo/tooltip/tooltip.html b/src/app/demo/tooltip/tooltip.html
new file mode 100644
index 0000000000..9fa89c9035
--- /dev/null
+++ b/src/app/demo/tooltip/tooltip.html
@@ -0,0 +1,20 @@
+<div class="demo-tooltip">
+  <h1>Tooltip Demo</h1>
+  <p class="centered">
+    <button
+        md-raised-button
+        color="primary"
+        md-tooltip="to see a tooltip"
+        [tooltip-position]="position">
+      Mouse over this link
+    </button>
+  </p>
+  <p>
+    <md-radio-group [(ngModel)]="position">
+      <md-radio-button value="below">Below</md-radio-button>
+      <md-radio-button value="above">Above</md-radio-button>
+      <md-radio-button value="before">Before</md-radio-button>
+      <md-radio-button value="after">After</md-radio-button>
+    </md-radio-group>
+  </p>
+</div>
diff --git a/src/app/demo/tooltip/tooltip.scss b/src/app/demo/tooltip/tooltip.scss
new file mode 100644
index 0000000000..39c9602a9e
--- /dev/null
+++ b/src/app/demo/tooltip/tooltip.scss
@@ -0,0 +1,8 @@
+.demo-tooltip {
+  .centered {
+    text-align: center;
+  }
+  md-radio-button {
+    display: block;
+  }
+}
diff --git a/src/app/demo/tooltip/tooltip.ts b/src/app/demo/tooltip/tooltip.ts
new file mode 100644
index 0000000000..90264ff43c
--- /dev/null
+++ b/src/app/demo/tooltip/tooltip.ts
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+import { TooltipPosition } from '@angular2-material/tooltip/tooltip';
+
+
+@Component({
+  selector: 'tooltip-demo',
+  template: require('./tooltip.html'),
+  styles: [require('./tooltip.scss')],
+})
+export class TooltipDemo {
+  position: TooltipPosition = 'below';
+}
diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts
index a2ead3d38a..db2c53176d 100644
--- a/src/app/home/home.component.ts
+++ b/src/app/home/home.component.ts
@@ -21,9 +21,9 @@ import { XLarge } from './x-large';
   // We need to tell Angular's compiler which custom pipes are in our template.
   pipes: [ ],
   // Our list of styles in our component. We may add more to compose many styles together
-  styleUrls: [ './home.style.css' ],
+  styles: [ require('./home.style.css') ],
   // Every Angular template is first compiled by the browser before Angular runs it's compiler
-  templateUrl: './home.template.html'
+  template: require('./home.template.html')
 })
 export class Home {
   // Set our default values
diff --git a/src/appModule.ts b/src/appModule.ts
new file mode 100644
index 0000000000..1405b5826a
--- /dev/null
+++ b/src/appModule.ts
@@ -0,0 +1,46 @@
+import { NgModule, ApplicationRef } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { HttpModule } from '@angular/http';
+import { FormsModule } from '@angular/forms';
+import { RouterModule } from '@angular/router';
+import { MaterialModule } from './platform/browser/angular2-material2';
+import { App, routes, AppState, APP_ROUTE_PROVIDER } from './app';
+import { Home } from './app/home';
+import { About } from './app/about';
+import { NoContent } from './app/no-content';
+import { Detail, Index } from './app/+detail';
+import { DemoModule } from './app/demo';
+
+
+@NgModule({
+  imports: [
+    BrowserModule,
+    FormsModule,
+    HttpModule,
+    MaterialModule,
+    RouterModule,
+    DemoModule
+  ],
+  providers: [
+    AppState,
+    APP_ROUTE_PROVIDER
+  ],
+  declarations: [
+    App,
+    Home,
+    About,
+    Detail,
+    Index,
+    NoContent
+  ],
+  entryComponents: [
+    App
+  ],
+})
+export class AppModule {
+  constructor(private _appRef: ApplicationRef) { }
+
+  ngDoBootstrap() {
+    this._appRef.bootstrap(App);
+  }
+}
diff --git a/src/assets/font/MaterialIcons-Regular.eot b/src/assets/font/MaterialIcons-Regular.eot
new file mode 100644
index 0000000000..70508ebabc
Binary files /dev/null and b/src/assets/font/MaterialIcons-Regular.eot differ
diff --git a/src/assets/font/MaterialIcons-Regular.ijmap b/src/assets/font/MaterialIcons-Regular.ijmap
new file mode 100644
index 0000000000..d9f1d259f3
--- /dev/null
+++ b/src/assets/font/MaterialIcons-Regular.ijmap
@@ -0,0 +1 @@
+{"icons":{"e84d":{"name":"3d Rotation"},"eb3b":{"name":"Ac Unit"},"e190":{"name":"Access Alarm"},"e191":{"name":"Access Alarms"},"e192":{"name":"Access Time"},"e84e":{"name":"Accessibility"},"e914":{"name":"Accessible"},"e84f":{"name":"Account Balance"},"e850":{"name":"Account Balance Wallet"},"e851":{"name":"Account Box"},"e853":{"name":"Account Circle"},"e60e":{"name":"Adb"},"e145":{"name":"Add"},"e439":{"name":"Add A Photo"},"e193":{"name":"Add Alarm"},"e003":{"name":"Add Alert"},"e146":{"name":"Add Box"},"e147":{"name":"Add Circle"},"e148":{"name":"Add Circle Outline"},"e567":{"name":"Add Location"},"e854":{"name":"Add Shopping Cart"},"e39d":{"name":"Add To Photos"},"e05c":{"name":"Add To Queue"},"e39e":{"name":"Adjust"},"e630":{"name":"Airline Seat Flat"},"e631":{"name":"Airline Seat Flat Angled"},"e632":{"name":"Airline Seat Individual Suite"},"e633":{"name":"Airline Seat Legroom Extra"},"e634":{"name":"Airline Seat Legroom Normal"},"e635":{"name":"Airline Seat Legroom Reduced"},"e636":{"name":"Airline Seat Recline Extra"},"e637":{"name":"Airline Seat Recline Normal"},"e195":{"name":"Airplanemode Active"},"e194":{"name":"Airplanemode Inactive"},"e055":{"name":"Airplay"},"eb3c":{"name":"Airport Shuttle"},"e855":{"name":"Alarm"},"e856":{"name":"Alarm Add"},"e857":{"name":"Alarm Off"},"e858":{"name":"Alarm On"},"e019":{"name":"Album"},"eb3d":{"name":"All Inclusive"},"e90b":{"name":"All Out"},"e859":{"name":"Android"},"e85a":{"name":"Announcement"},"e5c3":{"name":"Apps"},"e149":{"name":"Archive"},"e5c4":{"name":"Arrow Back"},"e5db":{"name":"Arrow Downward"},"e5c5":{"name":"Arrow Drop Down"},"e5c6":{"name":"Arrow Drop Down Circle"},"e5c7":{"name":"Arrow Drop Up"},"e5c8":{"name":"Arrow Forward"},"e5d8":{"name":"Arrow Upward"},"e060":{"name":"Art Track"},"e85b":{"name":"Aspect Ratio"},"e85c":{"name":"Assessment"},"e85d":{"name":"Assignment"},"e85e":{"name":"Assignment Ind"},"e85f":{"name":"Assignment Late"},"e860":{"name":"Assignment Return"},"e861":{"name":"Assignment Returned"},"e862":{"name":"Assignment Turned In"},"e39f":{"name":"Assistant"},"e3a0":{"name":"Assistant Photo"},"e226":{"name":"Attach File"},"e227":{"name":"Attach Money"},"e2bc":{"name":"Attachment"},"e3a1":{"name":"Audiotrack"},"e863":{"name":"Autorenew"},"e01b":{"name":"Av Timer"},"e14a":{"name":"Backspace"},"e864":{"name":"Backup"},"e19c":{"name":"Battery Alert"},"e1a3":{"name":"Battery Charging Full"},"e1a4":{"name":"Battery Full"},"e1a5":{"name":"Battery Std"},"e1a6":{"name":"Battery Unknown"},"eb3e":{"name":"Beach Access"},"e52d":{"name":"Beenhere"},"e14b":{"name":"Block"},"e1a7":{"name":"Bluetooth"},"e60f":{"name":"Bluetooth Audio"},"e1a8":{"name":"Bluetooth Connected"},"e1a9":{"name":"Bluetooth Disabled"},"e1aa":{"name":"Bluetooth Searching"},"e3a2":{"name":"Blur Circular"},"e3a3":{"name":"Blur Linear"},"e3a4":{"name":"Blur Off"},"e3a5":{"name":"Blur On"},"e865":{"name":"Book"},"e866":{"name":"Bookmark"},"e867":{"name":"Bookmark Border"},"e228":{"name":"Border All"},"e229":{"name":"Border Bottom"},"e22a":{"name":"Border Clear"},"e22b":{"name":"Border Color"},"e22c":{"name":"Border Horizontal"},"e22d":{"name":"Border Inner"},"e22e":{"name":"Border Left"},"e22f":{"name":"Border Outer"},"e230":{"name":"Border Right"},"e231":{"name":"Border Style"},"e232":{"name":"Border Top"},"e233":{"name":"Border Vertical"},"e06b":{"name":"Branding Watermark"},"e3a6":{"name":"Brightness 1"},"e3a7":{"name":"Brightness 2"},"e3a8":{"name":"Brightness 3"},"e3a9":{"name":"Brightness 4"},"e3aa":{"name":"Brightness 5"},"e3ab":{"name":"Brightness 6"},"e3ac":{"name":"Brightness 7"},"e1ab":{"name":"Brightness Auto"},"e1ac":{"name":"Brightness High"},"e1ad":{"name":"Brightness Low"},"e1ae":{"name":"Brightness Medium"},"e3ad":{"name":"Broken Image"},"e3ae":{"name":"Brush"},"e6dd":{"name":"Bubble Chart"},"e868":{"name":"Bug Report"},"e869":{"name":"Build"},"e43c":{"name":"Burst Mode"},"e0af":{"name":"Business"},"eb3f":{"name":"Business Center"},"e86a":{"name":"Cached"},"e7e9":{"name":"Cake"},"e0b0":{"name":"Call"},"e0b1":{"name":"Call End"},"e0b2":{"name":"Call Made"},"e0b3":{"name":"Call Merge"},"e0b4":{"name":"Call Missed"},"e0e4":{"name":"Call Missed Outgoing"},"e0b5":{"name":"Call Received"},"e0b6":{"name":"Call Split"},"e06c":{"name":"Call To Action"},"e3af":{"name":"Camera"},"e3b0":{"name":"Camera Alt"},"e8fc":{"name":"Camera Enhance"},"e3b1":{"name":"Camera Front"},"e3b2":{"name":"Camera Rear"},"e3b3":{"name":"Camera Roll"},"e5c9":{"name":"Cancel"},"e8f6":{"name":"Card Giftcard"},"e8f7":{"name":"Card Membership"},"e8f8":{"name":"Card Travel"},"eb40":{"name":"Casino"},"e307":{"name":"Cast"},"e308":{"name":"Cast Connected"},"e3b4":{"name":"Center Focus Strong"},"e3b5":{"name":"Center Focus Weak"},"e86b":{"name":"Change History"},"e0b7":{"name":"Chat"},"e0ca":{"name":"Chat Bubble"},"e0cb":{"name":"Chat Bubble Outline"},"e5ca":{"name":"Check"},"e834":{"name":"Check Box"},"e835":{"name":"Check Box Outline Blank"},"e86c":{"name":"Check Circle"},"e5cb":{"name":"Chevron Left"},"e5cc":{"name":"Chevron Right"},"eb41":{"name":"Child Care"},"eb42":{"name":"Child Friendly"},"e86d":{"name":"Chrome Reader Mode"},"e86e":{"name":"Class"},"e14c":{"name":"Clear"},"e0b8":{"name":"Clear All"},"e5cd":{"name":"Close"},"e01c":{"name":"Closed Caption"},"e2bd":{"name":"Cloud"},"e2be":{"name":"Cloud Circle"},"e2bf":{"name":"Cloud Done"},"e2c0":{"name":"Cloud Download"},"e2c1":{"name":"Cloud Off"},"e2c2":{"name":"Cloud Queue"},"e2c3":{"name":"Cloud Upload"},"e86f":{"name":"Code"},"e3b6":{"name":"Collections"},"e431":{"name":"Collections Bookmark"},"e3b7":{"name":"Color Lens"},"e3b8":{"name":"Colorize"},"e0b9":{"name":"Comment"},"e3b9":{"name":"Compare"},"e915":{"name":"Compare Arrows"},"e30a":{"name":"Computer"},"e638":{"name":"Confirmation Number"},"e0d0":{"name":"Contact Mail"},"e0cf":{"name":"Contact Phone"},"e0ba":{"name":"Contacts"},"e14d":{"name":"Content Copy"},"e14e":{"name":"Content Cut"},"e14f":{"name":"Content Paste"},"e3ba":{"name":"Control Point"},"e3bb":{"name":"Control Point Duplicate"},"e90c":{"name":"Copyright"},"e150":{"name":"Create"},"e2cc":{"name":"Create New Folder"},"e870":{"name":"Credit Card"},"e3be":{"name":"Crop"},"e3bc":{"name":"Crop 16 9"},"e3bd":{"name":"Crop 3 2"},"e3bf":{"name":"Crop 5 4"},"e3c0":{"name":"Crop 7 5"},"e3c1":{"name":"Crop Din"},"e3c2":{"name":"Crop Free"},"e3c3":{"name":"Crop Landscape"},"e3c4":{"name":"Crop Original"},"e3c5":{"name":"Crop Portrait"},"e437":{"name":"Crop Rotate"},"e3c6":{"name":"Crop Square"},"e871":{"name":"Dashboard"},"e1af":{"name":"Data Usage"},"e916":{"name":"Date Range"},"e3c7":{"name":"Dehaze"},"e872":{"name":"Delete"},"e92b":{"name":"Delete Forever"},"e16c":{"name":"Delete Sweep"},"e873":{"name":"Description"},"e30b":{"name":"Desktop Mac"},"e30c":{"name":"Desktop Windows"},"e3c8":{"name":"Details"},"e30d":{"name":"Developer Board"},"e1b0":{"name":"Developer Mode"},"e335":{"name":"Device Hub"},"e1b1":{"name":"Devices"},"e337":{"name":"Devices Other"},"e0bb":{"name":"Dialer Sip"},"e0bc":{"name":"Dialpad"},"e52e":{"name":"Directions"},"e52f":{"name":"Directions Bike"},"e532":{"name":"Directions Boat"},"e530":{"name":"Directions Bus"},"e531":{"name":"Directions Car"},"e534":{"name":"Directions Railway"},"e566":{"name":"Directions Run"},"e533":{"name":"Directions Subway"},"e535":{"name":"Directions Transit"},"e536":{"name":"Directions Walk"},"e610":{"name":"Disc Full"},"e875":{"name":"Dns"},"e612":{"name":"Do Not Disturb"},"e611":{"name":"Do Not Disturb Alt"},"e643":{"name":"Do Not Disturb Off"},"e644":{"name":"Do Not Disturb On"},"e30e":{"name":"Dock"},"e7ee":{"name":"Domain"},"e876":{"name":"Done"},"e877":{"name":"Done All"},"e917":{"name":"Donut Large"},"e918":{"name":"Donut Small"},"e151":{"name":"Drafts"},"e25d":{"name":"Drag Handle"},"e613":{"name":"Drive Eta"},"e1b2":{"name":"Dvr"},"e3c9":{"name":"Edit"},"e568":{"name":"Edit Location"},"e8fb":{"name":"Eject"},"e0be":{"name":"Email"},"e63f":{"name":"Enhanced Encryption"},"e01d":{"name":"Equalizer"},"e000":{"name":"Error"},"e001":{"name":"Error Outline"},"e926":{"name":"Euro Symbol"},"e56d":{"name":"Ev Station"},"e878":{"name":"Event"},"e614":{"name":"Event Available"},"e615":{"name":"Event Busy"},"e616":{"name":"Event Note"},"e903":{"name":"Event Seat"},"e879":{"name":"Exit To App"},"e5ce":{"name":"Expand Less"},"e5cf":{"name":"Expand More"},"e01e":{"name":"Explicit"},"e87a":{"name":"Explore"},"e3ca":{"name":"Exposure"},"e3cb":{"name":"Exposure Neg 1"},"e3cc":{"name":"Exposure Neg 2"},"e3cd":{"name":"Exposure Plus 1"},"e3ce":{"name":"Exposure Plus 2"},"e3cf":{"name":"Exposure Zero"},"e87b":{"name":"Extension"},"e87c":{"name":"Face"},"e01f":{"name":"Fast Forward"},"e020":{"name":"Fast Rewind"},"e87d":{"name":"Favorite"},"e87e":{"name":"Favorite Border"},"e06d":{"name":"Featured Play List"},"e06e":{"name":"Featured Video"},"e87f":{"name":"Feedback"},"e05d":{"name":"Fiber Dvr"},"e061":{"name":"Fiber Manual Record"},"e05e":{"name":"Fiber New"},"e06a":{"name":"Fiber Pin"},"e062":{"name":"Fiber Smart Record"},"e2c4":{"name":"File Download"},"e2c6":{"name":"File Upload"},"e3d3":{"name":"Filter"},"e3d0":{"name":"Filter 1"},"e3d1":{"name":"Filter 2"},"e3d2":{"name":"Filter 3"},"e3d4":{"name":"Filter 4"},"e3d5":{"name":"Filter 5"},"e3d6":{"name":"Filter 6"},"e3d7":{"name":"Filter 7"},"e3d8":{"name":"Filter 8"},"e3d9":{"name":"Filter 9"},"e3da":{"name":"Filter 9 Plus"},"e3db":{"name":"Filter B And W"},"e3dc":{"name":"Filter Center Focus"},"e3dd":{"name":"Filter Drama"},"e3de":{"name":"Filter Frames"},"e3df":{"name":"Filter Hdr"},"e152":{"name":"Filter List"},"e3e0":{"name":"Filter None"},"e3e2":{"name":"Filter Tilt Shift"},"e3e3":{"name":"Filter Vintage"},"e880":{"name":"Find In Page"},"e881":{"name":"Find Replace"},"e90d":{"name":"Fingerprint"},"e5dc":{"name":"First Page"},"eb43":{"name":"Fitness Center"},"e153":{"name":"Flag"},"e3e4":{"name":"Flare"},"e3e5":{"name":"Flash Auto"},"e3e6":{"name":"Flash Off"},"e3e7":{"name":"Flash On"},"e539":{"name":"Flight"},"e904":{"name":"Flight Land"},"e905":{"name":"Flight Takeoff"},"e3e8":{"name":"Flip"},"e882":{"name":"Flip To Back"},"e883":{"name":"Flip To Front"},"e2c7":{"name":"Folder"},"e2c8":{"name":"Folder Open"},"e2c9":{"name":"Folder Shared"},"e617":{"name":"Folder Special"},"e167":{"name":"Font Download"},"e234":{"name":"Format Align Center"},"e235":{"name":"Format Align Justify"},"e236":{"name":"Format Align Left"},"e237":{"name":"Format Align Right"},"e238":{"name":"Format Bold"},"e239":{"name":"Format Clear"},"e23a":{"name":"Format Color Fill"},"e23b":{"name":"Format Color Reset"},"e23c":{"name":"Format Color Text"},"e23d":{"name":"Format Indent Decrease"},"e23e":{"name":"Format Indent Increase"},"e23f":{"name":"Format Italic"},"e240":{"name":"Format Line Spacing"},"e241":{"name":"Format List Bulleted"},"e242":{"name":"Format List Numbered"},"e243":{"name":"Format Paint"},"e244":{"name":"Format Quote"},"e25e":{"name":"Format Shapes"},"e245":{"name":"Format Size"},"e246":{"name":"Format Strikethrough"},"e247":{"name":"Format Textdirection L To R"},"e248":{"name":"Format Textdirection R To L"},"e249":{"name":"Format Underlined"},"e0bf":{"name":"Forum"},"e154":{"name":"Forward"},"e056":{"name":"Forward 10"},"e057":{"name":"Forward 30"},"e058":{"name":"Forward 5"},"eb44":{"name":"Free Breakfast"},"e5d0":{"name":"Fullscreen"},"e5d1":{"name":"Fullscreen Exit"},"e24a":{"name":"Functions"},"e927":{"name":"G Translate"},"e30f":{"name":"Gamepad"},"e021":{"name":"Games"},"e90e":{"name":"Gavel"},"e155":{"name":"Gesture"},"e884":{"name":"Get App"},"e908":{"name":"Gif"},"eb45":{"name":"Golf Course"},"e1b3":{"name":"Gps Fixed"},"e1b4":{"name":"Gps Not Fixed"},"e1b5":{"name":"Gps Off"},"e885":{"name":"Grade"},"e3e9":{"name":"Gradient"},"e3ea":{"name":"Grain"},"e1b8":{"name":"Graphic Eq"},"e3eb":{"name":"Grid Off"},"e3ec":{"name":"Grid On"},"e7ef":{"name":"Group"},"e7f0":{"name":"Group Add"},"e886":{"name":"Group Work"},"e052":{"name":"Hd"},"e3ed":{"name":"Hdr Off"},"e3ee":{"name":"Hdr On"},"e3f1":{"name":"Hdr Strong"},"e3f2":{"name":"Hdr Weak"},"e310":{"name":"Headset"},"e311":{"name":"Headset Mic"},"e3f3":{"name":"Healing"},"e023":{"name":"Hearing"},"e887":{"name":"Help"},"e8fd":{"name":"Help Outline"},"e024":{"name":"High Quality"},"e25f":{"name":"Highlight"},"e888":{"name":"Highlight Off"},"e889":{"name":"History"},"e88a":{"name":"Home"},"eb46":{"name":"Hot Tub"},"e53a":{"name":"Hotel"},"e88b":{"name":"Hourglass Empty"},"e88c":{"name":"Hourglass Full"},"e902":{"name":"Http"},"e88d":{"name":"Https"},"e3f4":{"name":"Image"},"e3f5":{"name":"Image Aspect Ratio"},"e0e0":{"name":"Import Contacts"},"e0c3":{"name":"Import Export"},"e912":{"name":"Important Devices"},"e156":{"name":"Inbox"},"e909":{"name":"Indeterminate Check Box"},"e88e":{"name":"Info"},"e88f":{"name":"Info Outline"},"e890":{"name":"Input"},"e24b":{"name":"Insert Chart"},"e24c":{"name":"Insert Comment"},"e24d":{"name":"Insert Drive File"},"e24e":{"name":"Insert Emoticon"},"e24f":{"name":"Insert Invitation"},"e250":{"name":"Insert Link"},"e251":{"name":"Insert Photo"},"e891":{"name":"Invert Colors"},"e0c4":{"name":"Invert Colors Off"},"e3f6":{"name":"Iso"},"e312":{"name":"Keyboard"},"e313":{"name":"Keyboard Arrow Down"},"e314":{"name":"Keyboard Arrow Left"},"e315":{"name":"Keyboard Arrow Right"},"e316":{"name":"Keyboard Arrow Up"},"e317":{"name":"Keyboard Backspace"},"e318":{"name":"Keyboard Capslock"},"e31a":{"name":"Keyboard Hide"},"e31b":{"name":"Keyboard Return"},"e31c":{"name":"Keyboard Tab"},"e31d":{"name":"Keyboard Voice"},"eb47":{"name":"Kitchen"},"e892":{"name":"Label"},"e893":{"name":"Label Outline"},"e3f7":{"name":"Landscape"},"e894":{"name":"Language"},"e31e":{"name":"Laptop"},"e31f":{"name":"Laptop Chromebook"},"e320":{"name":"Laptop Mac"},"e321":{"name":"Laptop Windows"},"e5dd":{"name":"Last Page"},"e895":{"name":"Launch"},"e53b":{"name":"Layers"},"e53c":{"name":"Layers Clear"},"e3f8":{"name":"Leak Add"},"e3f9":{"name":"Leak Remove"},"e3fa":{"name":"Lens"},"e02e":{"name":"Library Add"},"e02f":{"name":"Library Books"},"e030":{"name":"Library Music"},"e90f":{"name":"Lightbulb Outline"},"e919":{"name":"Line Style"},"e91a":{"name":"Line Weight"},"e260":{"name":"Linear Scale"},"e157":{"name":"Link"},"e438":{"name":"Linked Camera"},"e896":{"name":"List"},"e0c6":{"name":"Live Help"},"e639":{"name":"Live Tv"},"e53f":{"name":"Local Activity"},"e53d":{"name":"Local Airport"},"e53e":{"name":"Local Atm"},"e540":{"name":"Local Bar"},"e541":{"name":"Local Cafe"},"e542":{"name":"Local Car Wash"},"e543":{"name":"Local Convenience Store"},"e556":{"name":"Local Dining"},"e544":{"name":"Local Drink"},"e545":{"name":"Local Florist"},"e546":{"name":"Local Gas Station"},"e547":{"name":"Local Grocery Store"},"e548":{"name":"Local Hospital"},"e549":{"name":"Local Hotel"},"e54a":{"name":"Local Laundry Service"},"e54b":{"name":"Local Library"},"e54c":{"name":"Local Mall"},"e54d":{"name":"Local Movies"},"e54e":{"name":"Local Offer"},"e54f":{"name":"Local Parking"},"e550":{"name":"Local Pharmacy"},"e551":{"name":"Local Phone"},"e552":{"name":"Local Pizza"},"e553":{"name":"Local Play"},"e554":{"name":"Local Post Office"},"e555":{"name":"Local Printshop"},"e557":{"name":"Local See"},"e558":{"name":"Local Shipping"},"e559":{"name":"Local Taxi"},"e7f1":{"name":"Location City"},"e1b6":{"name":"Location Disabled"},"e0c7":{"name":"Location Off"},"e0c8":{"name":"Location On"},"e1b7":{"name":"Location Searching"},"e897":{"name":"Lock"},"e898":{"name":"Lock Open"},"e899":{"name":"Lock Outline"},"e3fc":{"name":"Looks"},"e3fb":{"name":"Looks 3"},"e3fd":{"name":"Looks 4"},"e3fe":{"name":"Looks 5"},"e3ff":{"name":"Looks 6"},"e400":{"name":"Looks One"},"e401":{"name":"Looks Two"},"e028":{"name":"Loop"},"e402":{"name":"Loupe"},"e16d":{"name":"Low Priority"},"e89a":{"name":"Loyalty"},"e158":{"name":"Mail"},"e0e1":{"name":"Mail Outline"},"e55b":{"name":"Map"},"e159":{"name":"Markunread"},"e89b":{"name":"Markunread Mailbox"},"e322":{"name":"Memory"},"e5d2":{"name":"Menu"},"e252":{"name":"Merge Type"},"e0c9":{"name":"Message"},"e029":{"name":"Mic"},"e02a":{"name":"Mic None"},"e02b":{"name":"Mic Off"},"e618":{"name":"Mms"},"e253":{"name":"Mode Comment"},"e254":{"name":"Mode Edit"},"e263":{"name":"Monetization On"},"e25c":{"name":"Money Off"},"e403":{"name":"Monochrome Photos"},"e7f2":{"name":"Mood"},"e7f3":{"name":"Mood Bad"},"e619":{"name":"More"},"e5d3":{"name":"More Horiz"},"e5d4":{"name":"More Vert"},"e91b":{"name":"Motorcycle"},"e323":{"name":"Mouse"},"e168":{"name":"Move To Inbox"},"e02c":{"name":"Movie"},"e404":{"name":"Movie Creation"},"e43a":{"name":"Movie Filter"},"e6df":{"name":"Multiline Chart"},"e405":{"name":"Music Note"},"e063":{"name":"Music Video"},"e55c":{"name":"My Location"},"e406":{"name":"Nature"},"e407":{"name":"Nature People"},"e408":{"name":"Navigate Before"},"e409":{"name":"Navigate Next"},"e55d":{"name":"Navigation"},"e569":{"name":"Near Me"},"e1b9":{"name":"Network Cell"},"e640":{"name":"Network Check"},"e61a":{"name":"Network Locked"},"e1ba":{"name":"Network Wifi"},"e031":{"name":"New Releases"},"e16a":{"name":"Next Week"},"e1bb":{"name":"Nfc"},"e641":{"name":"No Encryption"},"e0cc":{"name":"No Sim"},"e033":{"name":"Not Interested"},"e06f":{"name":"Note"},"e89c":{"name":"Note Add"},"e7f4":{"name":"Notifications"},"e7f7":{"name":"Notifications Active"},"e7f5":{"name":"Notifications None"},"e7f6":{"name":"Notifications Off"},"e7f8":{"name":"Notifications Paused"},"e90a":{"name":"Offline Pin"},"e63a":{"name":"Ondemand Video"},"e91c":{"name":"Opacity"},"e89d":{"name":"Open In Browser"},"e89e":{"name":"Open In New"},"e89f":{"name":"Open With"},"e7f9":{"name":"Pages"},"e8a0":{"name":"Pageview"},"e40a":{"name":"Palette"},"e925":{"name":"Pan Tool"},"e40b":{"name":"Panorama"},"e40c":{"name":"Panorama Fish Eye"},"e40d":{"name":"Panorama Horizontal"},"e40e":{"name":"Panorama Vertical"},"e40f":{"name":"Panorama Wide Angle"},"e7fa":{"name":"Party Mode"},"e034":{"name":"Pause"},"e035":{"name":"Pause Circle Filled"},"e036":{"name":"Pause Circle Outline"},"e8a1":{"name":"Payment"},"e7fb":{"name":"People"},"e7fc":{"name":"People Outline"},"e8a2":{"name":"Perm Camera Mic"},"e8a3":{"name":"Perm Contact Calendar"},"e8a4":{"name":"Perm Data Setting"},"e8a5":{"name":"Perm Device Information"},"e8a6":{"name":"Perm Identity"},"e8a7":{"name":"Perm Media"},"e8a8":{"name":"Perm Phone Msg"},"e8a9":{"name":"Perm Scan Wifi"},"e7fd":{"name":"Person"},"e7fe":{"name":"Person Add"},"e7ff":{"name":"Person Outline"},"e55a":{"name":"Person Pin"},"e56a":{"name":"Person Pin Circle"},"e63b":{"name":"Personal Video"},"e91d":{"name":"Pets"},"e0cd":{"name":"Phone"},"e324":{"name":"Phone Android"},"e61b":{"name":"Phone Bluetooth Speaker"},"e61c":{"name":"Phone Forwarded"},"e61d":{"name":"Phone In Talk"},"e325":{"name":"Phone Iphone"},"e61e":{"name":"Phone Locked"},"e61f":{"name":"Phone Missed"},"e620":{"name":"Phone Paused"},"e326":{"name":"Phonelink"},"e0db":{"name":"Phonelink Erase"},"e0dc":{"name":"Phonelink Lock"},"e327":{"name":"Phonelink Off"},"e0dd":{"name":"Phonelink Ring"},"e0de":{"name":"Phonelink Setup"},"e410":{"name":"Photo"},"e411":{"name":"Photo Album"},"e412":{"name":"Photo Camera"},"e43b":{"name":"Photo Filter"},"e413":{"name":"Photo Library"},"e432":{"name":"Photo Size Select Actual"},"e433":{"name":"Photo Size Select Large"},"e434":{"name":"Photo Size Select Small"},"e415":{"name":"Picture As Pdf"},"e8aa":{"name":"Picture In Picture"},"e911":{"name":"Picture In Picture Alt"},"e6c4":{"name":"Pie Chart"},"e6c5":{"name":"Pie Chart Outlined"},"e55e":{"name":"Pin Drop"},"e55f":{"name":"Place"},"e037":{"name":"Play Arrow"},"e038":{"name":"Play Circle Filled"},"e039":{"name":"Play Circle Outline"},"e906":{"name":"Play For Work"},"e03b":{"name":"Playlist Add"},"e065":{"name":"Playlist Add Check"},"e05f":{"name":"Playlist Play"},"e800":{"name":"Plus One"},"e801":{"name":"Poll"},"e8ab":{"name":"Polymer"},"eb48":{"name":"Pool"},"e0ce":{"name":"Portable Wifi Off"},"e416":{"name":"Portrait"},"e63c":{"name":"Power"},"e336":{"name":"Power Input"},"e8ac":{"name":"Power Settings New"},"e91e":{"name":"Pregnant Woman"},"e0df":{"name":"Present To All"},"e8ad":{"name":"Print"},"e645":{"name":"Priority High"},"e80b":{"name":"Public"},"e255":{"name":"Publish"},"e8ae":{"name":"Query Builder"},"e8af":{"name":"Question Answer"},"e03c":{"name":"Queue"},"e03d":{"name":"Queue Music"},"e066":{"name":"Queue Play Next"},"e03e":{"name":"Radio"},"e837":{"name":"Radio Button Checked"},"e836":{"name":"Radio Button Unchecked"},"e560":{"name":"Rate Review"},"e8b0":{"name":"Receipt"},"e03f":{"name":"Recent Actors"},"e91f":{"name":"Record Voice Over"},"e8b1":{"name":"Redeem"},"e15a":{"name":"Redo"},"e5d5":{"name":"Refresh"},"e15b":{"name":"Remove"},"e15c":{"name":"Remove Circle"},"e15d":{"name":"Remove Circle Outline"},"e067":{"name":"Remove From Queue"},"e417":{"name":"Remove Red Eye"},"e928":{"name":"Remove Shopping Cart"},"e8fe":{"name":"Reorder"},"e040":{"name":"Repeat"},"e041":{"name":"Repeat One"},"e042":{"name":"Replay"},"e059":{"name":"Replay 10"},"e05a":{"name":"Replay 30"},"e05b":{"name":"Replay 5"},"e15e":{"name":"Reply"},"e15f":{"name":"Reply All"},"e160":{"name":"Report"},"e8b2":{"name":"Report Problem"},"e56c":{"name":"Restaurant"},"e561":{"name":"Restaurant Menu"},"e8b3":{"name":"Restore"},"e929":{"name":"Restore Page"},"e0d1":{"name":"Ring Volume"},"e8b4":{"name":"Room"},"eb49":{"name":"Room Service"},"e418":{"name":"Rotate 90 Degrees Ccw"},"e419":{"name":"Rotate Left"},"e41a":{"name":"Rotate Right"},"e920":{"name":"Rounded Corner"},"e328":{"name":"Router"},"e921":{"name":"Rowing"},"e0e5":{"name":"Rss Feed"},"e642":{"name":"Rv Hookup"},"e562":{"name":"Satellite"},"e161":{"name":"Save"},"e329":{"name":"Scanner"},"e8b5":{"name":"Schedule"},"e80c":{"name":"School"},"e1be":{"name":"Screen Lock Landscape"},"e1bf":{"name":"Screen Lock Portrait"},"e1c0":{"name":"Screen Lock Rotation"},"e1c1":{"name":"Screen Rotation"},"e0e2":{"name":"Screen Share"},"e623":{"name":"Sd Card"},"e1c2":{"name":"Sd Storage"},"e8b6":{"name":"Search"},"e32a":{"name":"Security"},"e162":{"name":"Select All"},"e163":{"name":"Send"},"e811":{"name":"Sentiment Dissatisfied"},"e812":{"name":"Sentiment Neutral"},"e813":{"name":"Sentiment Satisfied"},"e814":{"name":"Sentiment Very Dissatisfied"},"e815":{"name":"Sentiment Very Satisfied"},"e8b8":{"name":"Settings"},"e8b9":{"name":"Settings Applications"},"e8ba":{"name":"Settings Backup Restore"},"e8bb":{"name":"Settings Bluetooth"},"e8bd":{"name":"Settings Brightness"},"e8bc":{"name":"Settings Cell"},"e8be":{"name":"Settings Ethernet"},"e8bf":{"name":"Settings Input Antenna"},"e8c0":{"name":"Settings Input Component"},"e8c1":{"name":"Settings Input Composite"},"e8c2":{"name":"Settings Input Hdmi"},"e8c3":{"name":"Settings Input Svideo"},"e8c4":{"name":"Settings Overscan"},"e8c5":{"name":"Settings Phone"},"e8c6":{"name":"Settings Power"},"e8c7":{"name":"Settings Remote"},"e1c3":{"name":"Settings System Daydream"},"e8c8":{"name":"Settings Voice"},"e80d":{"name":"Share"},"e8c9":{"name":"Shop"},"e8ca":{"name":"Shop Two"},"e8cb":{"name":"Shopping Basket"},"e8cc":{"name":"Shopping Cart"},"e261":{"name":"Short Text"},"e6e1":{"name":"Show Chart"},"e043":{"name":"Shuffle"},"e1c8":{"name":"Signal Cellular 4 Bar"},"e1cd":{"name":"Signal Cellular Connected No Internet 4 Bar"},"e1ce":{"name":"Signal Cellular No Sim"},"e1cf":{"name":"Signal Cellular Null"},"e1d0":{"name":"Signal Cellular Off"},"e1d8":{"name":"Signal Wifi 4 Bar"},"e1d9":{"name":"Signal Wifi 4 Bar Lock"},"e1da":{"name":"Signal Wifi Off"},"e32b":{"name":"Sim Card"},"e624":{"name":"Sim Card Alert"},"e044":{"name":"Skip Next"},"e045":{"name":"Skip Previous"},"e41b":{"name":"Slideshow"},"e068":{"name":"Slow Motion Video"},"e32c":{"name":"Smartphone"},"eb4a":{"name":"Smoke Free"},"eb4b":{"name":"Smoking Rooms"},"e625":{"name":"Sms"},"e626":{"name":"Sms Failed"},"e046":{"name":"Snooze"},"e164":{"name":"Sort"},"e053":{"name":"Sort By Alpha"},"eb4c":{"name":"Spa"},"e256":{"name":"Space Bar"},"e32d":{"name":"Speaker"},"e32e":{"name":"Speaker Group"},"e8cd":{"name":"Speaker Notes"},"e92a":{"name":"Speaker Notes Off"},"e0d2":{"name":"Speaker Phone"},"e8ce":{"name":"Spellcheck"},"e838":{"name":"Star"},"e83a":{"name":"Star Border"},"e839":{"name":"Star Half"},"e8d0":{"name":"Stars"},"e0d3":{"name":"Stay Current Landscape"},"e0d4":{"name":"Stay Current Portrait"},"e0d5":{"name":"Stay Primary Landscape"},"e0d6":{"name":"Stay Primary Portrait"},"e047":{"name":"Stop"},"e0e3":{"name":"Stop Screen Share"},"e1db":{"name":"Storage"},"e8d1":{"name":"Store"},"e563":{"name":"Store Mall Directory"},"e41c":{"name":"Straighten"},"e56e":{"name":"Streetview"},"e257":{"name":"Strikethrough S"},"e41d":{"name":"Style"},"e5d9":{"name":"Subdirectory Arrow Left"},"e5da":{"name":"Subdirectory Arrow Right"},"e8d2":{"name":"Subject"},"e064":{"name":"Subscriptions"},"e048":{"name":"Subtitles"},"e56f":{"name":"Subway"},"e8d3":{"name":"Supervisor Account"},"e049":{"name":"Surround Sound"},"e0d7":{"name":"Swap Calls"},"e8d4":{"name":"Swap Horiz"},"e8d5":{"name":"Swap Vert"},"e8d6":{"name":"Swap Vertical Circle"},"e41e":{"name":"Switch Camera"},"e41f":{"name":"Switch Video"},"e627":{"name":"Sync"},"e628":{"name":"Sync Disabled"},"e629":{"name":"Sync Problem"},"e62a":{"name":"System Update"},"e8d7":{"name":"System Update Alt"},"e8d8":{"name":"Tab"},"e8d9":{"name":"Tab Unselected"},"e32f":{"name":"Tablet"},"e330":{"name":"Tablet Android"},"e331":{"name":"Tablet Mac"},"e420":{"name":"Tag Faces"},"e62b":{"name":"Tap And Play"},"e564":{"name":"Terrain"},"e262":{"name":"Text Fields"},"e165":{"name":"Text Format"},"e0d8":{"name":"Textsms"},"e421":{"name":"Texture"},"e8da":{"name":"Theaters"},"e8db":{"name":"Thumb Down"},"e8dc":{"name":"Thumb Up"},"e8dd":{"name":"Thumbs Up Down"},"e62c":{"name":"Time To Leave"},"e422":{"name":"Timelapse"},"e922":{"name":"Timeline"},"e425":{"name":"Timer"},"e423":{"name":"Timer 10"},"e424":{"name":"Timer 3"},"e426":{"name":"Timer Off"},"e264":{"name":"Title"},"e8de":{"name":"Toc"},"e8df":{"name":"Today"},"e8e0":{"name":"Toll"},"e427":{"name":"Tonality"},"e913":{"name":"Touch App"},"e332":{"name":"Toys"},"e8e1":{"name":"Track Changes"},"e565":{"name":"Traffic"},"e570":{"name":"Train"},"e571":{"name":"Tram"},"e572":{"name":"Transfer Within A Station"},"e428":{"name":"Transform"},"e8e2":{"name":"Translate"},"e8e3":{"name":"Trending Down"},"e8e4":{"name":"Trending Flat"},"e8e5":{"name":"Trending Up"},"e429":{"name":"Tune"},"e8e6":{"name":"Turned In"},"e8e7":{"name":"Turned In Not"},"e333":{"name":"Tv"},"e169":{"name":"Unarchive"},"e166":{"name":"Undo"},"e5d6":{"name":"Unfold Less"},"e5d7":{"name":"Unfold More"},"e923":{"name":"Update"},"e1e0":{"name":"Usb"},"e8e8":{"name":"Verified User"},"e258":{"name":"Vertical Align Bottom"},"e259":{"name":"Vertical Align Center"},"e25a":{"name":"Vertical Align Top"},"e62d":{"name":"Vibration"},"e070":{"name":"Video Call"},"e071":{"name":"Video Label"},"e04a":{"name":"Video Library"},"e04b":{"name":"Videocam"},"e04c":{"name":"Videocam Off"},"e338":{"name":"Videogame Asset"},"e8e9":{"name":"View Agenda"},"e8ea":{"name":"View Array"},"e8eb":{"name":"View Carousel"},"e8ec":{"name":"View Column"},"e42a":{"name":"View Comfy"},"e42b":{"name":"View Compact"},"e8ed":{"name":"View Day"},"e8ee":{"name":"View Headline"},"e8ef":{"name":"View List"},"e8f0":{"name":"View Module"},"e8f1":{"name":"View Quilt"},"e8f2":{"name":"View Stream"},"e8f3":{"name":"View Week"},"e435":{"name":"Vignette"},"e8f4":{"name":"Visibility"},"e8f5":{"name":"Visibility Off"},"e62e":{"name":"Voice Chat"},"e0d9":{"name":"Voicemail"},"e04d":{"name":"Volume Down"},"e04e":{"name":"Volume Mute"},"e04f":{"name":"Volume Off"},"e050":{"name":"Volume Up"},"e0da":{"name":"Vpn Key"},"e62f":{"name":"Vpn Lock"},"e1bc":{"name":"Wallpaper"},"e002":{"name":"Warning"},"e334":{"name":"Watch"},"e924":{"name":"Watch Later"},"e42c":{"name":"Wb Auto"},"e42d":{"name":"Wb Cloudy"},"e42e":{"name":"Wb Incandescent"},"e436":{"name":"Wb Iridescent"},"e430":{"name":"Wb Sunny"},"e63d":{"name":"Wc"},"e051":{"name":"Web"},"e069":{"name":"Web Asset"},"e16b":{"name":"Weekend"},"e80e":{"name":"Whatshot"},"e1bd":{"name":"Widgets"},"e63e":{"name":"Wifi"},"e1e1":{"name":"Wifi Lock"},"e1e2":{"name":"Wifi Tethering"},"e8f9":{"name":"Work"},"e25b":{"name":"Wrap Text"},"e8fa":{"name":"Youtube Searched For"},"e8ff":{"name":"Zoom In"},"e900":{"name":"Zoom Out"},"e56b":{"name":"Zoom Out Map"}}}
\ No newline at end of file
diff --git a/src/assets/font/MaterialIcons-Regular.ttf b/src/assets/font/MaterialIcons-Regular.ttf
new file mode 100644
index 0000000000..7015564ad1
Binary files /dev/null and b/src/assets/font/MaterialIcons-Regular.ttf differ
diff --git a/src/assets/font/MaterialIcons-Regular.woff b/src/assets/font/MaterialIcons-Regular.woff
new file mode 100644
index 0000000000..b648a3eea2
Binary files /dev/null and b/src/assets/font/MaterialIcons-Regular.woff differ
diff --git a/src/assets/font/MaterialIcons-Regular.woff2 b/src/assets/font/MaterialIcons-Regular.woff2
new file mode 100644
index 0000000000..9fa2112520
Binary files /dev/null and b/src/assets/font/MaterialIcons-Regular.woff2 differ
diff --git a/src/main.browser.ts b/src/main.browser.ts
index 3a35786d86..29da32b11c 100644
--- a/src/main.browser.ts
+++ b/src/main.browser.ts
@@ -1,59 +1,5 @@
-/*
- * Providers provided by Angular
- */
-import { bootstrap } from '@angular/platform-browser-dynamic';
-/*
-* Platform and Environment
-* our providers/directives/pipes
-*/
-import { PLATFORM_PROVIDERS } from './platform/browser';
-import { ENV_PROVIDERS, decorateComponentRef } from './platform/environment';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import { AppModule } from './appModule';
 
 
-/*
-* App Component
-* our top level component that holds all of our components
-*/
-import { App, APP_PROVIDERS } from './app';
-
-/*
- * Bootstrap our Angular app with a top level component `App` and inject
- * our Services and Providers into Angular's dependency injection
- */
-export function main(initialHmrState?: any): Promise<any> {
-
-  return bootstrap(App, [
-    // To add more vendor providers please look in the platform/ folder
-    ...PLATFORM_PROVIDERS,
-    ...ENV_PROVIDERS,
-    ...APP_PROVIDERS,
-  ])
-  .then(decorateComponentRef)
-  .catch(err => console.error(err));
-
-}
-
-
-
-
-
-/*
- * Vendors
- * For vendors for example jQuery, Lodash, angular2-jwt just import them anywhere in your app
- * You can also import them in vendors to ensure that they are bundled in one file
- * Also see custom-typings.d.ts as you also need to do `typings install x` where `x` is your module
- */
-
-
-/*
- * Hot Module Reload
- * experimental version by @gdi2290
- */
-if ('development' === ENV && HMR === true) {
-  // activate hot module reload
-  let ngHmr = require('angular2-hmr');
-  ngHmr.hotModuleReplacement(main, module);
-} else {
-  // bootstrap when document is ready
-  document.addEventListener('DOMContentLoaded', () => main());
-}
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/src/platform/browser-directives.ts b/src/platform/browser-directives.ts
deleted file mode 100644
index 5c4ca5cd51..0000000000
--- a/src/platform/browser-directives.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * These are globally available directives in any template
- */
-// Angular 2
-import { PLATFORM_DIRECTIVES } from '@angular/core';
-// Angular 2 Router
-import { ROUTER_DIRECTIVES } from '@angular/router';
-// Angular 2 forms
-import { REACTIVE_FORM_DIRECTIVES } from '@angular/forms';
-
-// Angular 2 Material 2
-// TODO(gdi2290): replace with @angular2-material/all
-import { MATERIAL_DIRECTIVES } from './browser/angular2-material2';
-
-// application_directives: directives that are global through out the application
-export const APPLICATION_DIRECTIVES = [
-  ...ROUTER_DIRECTIVES,
-  ...REACTIVE_FORM_DIRECTIVES,
-  ...MATERIAL_DIRECTIVES
-];
-
-export const DIRECTIVES = [
-  { provide: PLATFORM_DIRECTIVES, multi: true, useValue: APPLICATION_DIRECTIVES }
-];
diff --git a/src/platform/browser-pipes.ts b/src/platform/browser-pipes.ts
deleted file mode 100644
index a08bfe0273..0000000000
--- a/src/platform/browser-pipes.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * These are globally available pipes in any template
- */
-
-import { PLATFORM_PIPES } from '@angular/core';
-
-// application_pipes: pipes that are global through out the application
-export const APPLICATION_PIPES = [
-
-];
-
-export const PIPES = [
-  { provide: PLATFORM_PIPES, multi: true, useValue: APPLICATION_PIPES }
-];
diff --git a/src/platform/browser-providers.ts b/src/platform/browser-providers.ts
deleted file mode 100644
index cc37c17b7d..0000000000
--- a/src/platform/browser-providers.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * These are globally available services in any component or any other service
- */
-
-// Angular 2
-import { HashLocationStrategy, LocationStrategy } from '@angular/common';
-// Angular 2 Http
-import { HTTP_PROVIDERS } from '@angular/http';
-// Angular 2 Router
-import { provideRouter } from '@angular/router';
-// Angular 2 forms
-import { disableDeprecatedForms, provideForms } from '@angular/forms';
-
-// Angular 2 Material
-// TODO(gdi2290): replace with @angular2-material/all
-import { MATERIAL_PROVIDERS } from './browser/angular2-material2';
-
-// AngularClass
-import { provideWebpack } from '@angularclass/webpack-toolkit';
-import { providePrefetchIdleCallbacks } from '@angularclass/request-idle-callback';
-
-
-import { routes, asyncRoutes, prefetchRouteCallbacks } from '../app/app.routes';
-import { APP_RESOLVER_PROVIDERS } from '../app/app.resolver';
-/*
-* Application Providers/Directives/Pipes
-* providers/directives/pipes that only live in our browser environment
-*/
-export const APPLICATION_PROVIDERS = [
-  // new Angular 2 forms
-  disableDeprecatedForms(),
-  provideForms(),
-
-  ...APP_RESOLVER_PROVIDERS,
-
-  provideRouter(routes),
-  provideWebpack(asyncRoutes),
-  providePrefetchIdleCallbacks(prefetchRouteCallbacks),
-
-  ...HTTP_PROVIDERS,
-  ...MATERIAL_PROVIDERS,
-
-  { provide: LocationStrategy, useClass: HashLocationStrategy }
-];
-
-export const PROVIDERS = [
-  ...APPLICATION_PROVIDERS
-];
diff --git a/src/platform/browser.ts b/src/platform/browser.ts
deleted file mode 100644
index 8376c65c99..0000000000
--- a/src/platform/browser.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-export * from './browser-directives';
-export * from './browser-pipes';
-export * from './browser-providers';
-
-import { DIRECTIVES } from './browser-directives';
-import { PIPES } from './browser-pipes';
-import { PROVIDERS } from './browser-providers';
-
-
-export const PLATFORM_PROVIDERS = [
-  ...PROVIDERS,
-  ...DIRECTIVES,
-  ...PIPES
-];
diff --git a/src/platform/browser/angular2-material2/index.ts b/src/platform/browser/angular2-material2/index.ts
index b6a3b6f1f6..db967d11bd 100644
--- a/src/platform/browser/angular2-material2/index.ts
+++ b/src/platform/browser/angular2-material2/index.ts
@@ -1,48 +1,55 @@
-import { MdAnchor, MdButton } from '@angular2-material/button';
-import { MD_CARD_DIRECTIVES } from '@angular2-material/card';
-import { MdCheckbox } from '@angular2-material/checkbox';
-import { MD_GRID_LIST_DIRECTIVES } from '@angular2-material/grid-list';
-import { MdIcon, MdIconRegistry } from '@angular2-material/icon';
-import { MD_INPUT_DIRECTIVES } from '@angular2-material/input';
-import { MD_LIST_DIRECTIVES } from '@angular2-material/list';
-import { MdProgressBar } from '@angular2-material/progress-bar';
-import { MdProgressCircle, MdSpinner } from '@angular2-material/progress-circle';
-import { MdRadioButton, MdUniqueSelectionDispatcher, MdRadioGroup } from '@angular2-material/radio';
-import { MD_SIDENAV_DIRECTIVES } from '@angular2-material/sidenav';
-import { MD_SLIDE_TOGGLE_DIRECTIVES } from '@angular2-material/slide-toggle';
-import { MD_TABS_DIRECTIVES } from '@angular2-material/tabs';
-import { MdToolbar } from '@angular2-material/toolbar';
-/*
- * we are grouping the module so we only need to manage the imports in one location
- */
 
-export const MATERIAL_PIPES = [
+import { NgModule } from '@angular/core';
+import { MdButtonToggleModule } from '@angular2-material/button-toggle/button-toggle';
+import { MdButtonModule } from '@angular2-material/button/button';
+import { MdCheckboxModule } from '@angular2-material/checkbox/checkbox';
+import { MdRadioModule } from '@angular2-material/radio/radio';
+import { MdSlideToggleModule } from '@angular2-material/slide-toggle/slide-toggle';
+import { MdSliderModule } from '@angular2-material/slider/slider';
+import { MdSidenavModule } from '@angular2-material/sidenav/sidenav';
+import { MdListModule } from '@angular2-material/list/list';
+import { MdGridListModule } from '@angular2-material/grid-list/grid-list';
+import { MdCardModule } from '@angular2-material/card/card';
+import { MdIconModule } from '@angular2-material/icon/icon';
+import { MdProgressCircleModule } from '@angular2-material/progress-circle/progress-circle';
+import { MdProgressBarModule } from '@angular2-material/progress-bar/progress-bar';
+import { MdInputModule } from '@angular2-material/input/input';
+import { MdTabsModule } from '@angular2-material/tabs/tabs';
+import { MdToolbarModule } from '@angular2-material/toolbar/toolbar';
+import { MdTooltipModule } from '@angular2-material/tooltip/tooltip';
+import { MdRippleModule } from '@angular2-material/core/ripple/ripple';
+import { PortalModule } from '@angular2-material/core/portal/portal-directives';
+import { OverlayModule } from '@angular2-material/core/overlay/overlay-directives';
+import { MdMenuModule } from '@angular2-material/menu/menu';
+import { MdLiveAnnouncer } from '@angular2-material/core/a11y/live-announcer';
 
+const MATERIAL_MODULES = [
+  MdButtonModule,
+  MdButtonToggleModule,
+  MdCardModule,
+  MdCheckboxModule,
+  MdGridListModule,
+  MdIconModule,
+  MdInputModule,
+  MdListModule,
+  MdMenuModule,
+  MdProgressBarModule,
+  MdProgressCircleModule,
+  MdRadioModule,
+  MdRippleModule,
+  MdSidenavModule,
+  MdSliderModule,
+  MdSlideToggleModule,
+  MdTabsModule,
+  MdToolbarModule,
+  MdTooltipModule,
+  OverlayModule,
+  PortalModule
 ];
 
-export const MATERIAL_DIRECTIVES = [
-  ...[
-    MdAnchor,
-    MdButton,
-    MdCheckbox,
-    MdIcon,
-    MdProgressBar,
-    MdProgressCircle,
-    MdRadioButton,
-    MdRadioGroup,
-    MdSpinner,
-    MdToolbar
-  ],
-  ...MD_CARD_DIRECTIVES,
-  ...MD_GRID_LIST_DIRECTIVES,
-  ...MD_INPUT_DIRECTIVES,
-  ...MD_LIST_DIRECTIVES,
-  ...MD_SIDENAV_DIRECTIVES,
-  ...MD_SLIDE_TOGGLE_DIRECTIVES,
-  ...MD_TABS_DIRECTIVES
-];
-
-export const MATERIAL_PROVIDERS = [
-  MdIconRegistry,
-  MdUniqueSelectionDispatcher
-];
+@NgModule({
+  imports: MATERIAL_MODULES,
+  exports: MATERIAL_MODULES,
+  providers: [MdLiveAnnouncer]
+})
+export class MaterialModule { }
diff --git a/src/styles/core/default-theme.scss b/src/styles/core/default-theme.scss
new file mode 100644
index 0000000000..3bda5e0a0c
--- /dev/null
+++ b/src/styles/core/default-theme.scss
@@ -0,0 +1,11 @@
+@import 'theme-functions';
+@import 'palette';
+
+// Person creating a theme writes variables like this:
+$md-is-dark-theme: false !default;
+
+$md-primary: md-palette($md-purple, 500, 100, 700, $md-contrast-palettes) !default;
+$md-accent: md-palette($md-pink, 500, 300, 700, $md-contrast-palettes) !default;
+$md-background: md-palette($md-grey, 500, 0, 600, $md-contrast-palettes) !default;
+$md-warn: md-palette($md-red, 500, 100, 700, $md-contrast-palettes) !default;
+$md-foreground: if($md-is-dark-theme, $md-dark-theme-foreground, $md-light-theme-foreground) !default;
diff --git a/src/styles/core/layout.scss b/src/styles/core/layout.scss
new file mode 100644
index 0000000000..dc5418505b
--- /dev/null
+++ b/src/styles/core/layout.scss
@@ -0,0 +1,569 @@
+/*
+*
+*  Responsive attributes
+*
+*  References:
+*  1) https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties#flex
+*  2) https://css-tricks.com/almanac/properties/f/flex/
+*  3) https://css-tricks.com/snippets/css/a-guide-to-flexbox/
+*  4) https://github.com/philipwalton/flexbugs#3-min-height-on-a-flex-container-wont-apply-to-its-flex-items
+*  5) http://godban.com.ua/projects/flexgrid
+*
+*/
+
+// Layout
+// ------------------------------
+
+$baseline-grid: 8px !default;
+$layout-gutter-width: ($baseline-grid * 2) !default;
+
+$layout-breakpoint-xs: 600px !default;
+$layout-breakpoint-sm: 960px !default;
+$layout-breakpoint-md: 1280px !default;
+$layout-breakpoint-lg: 1920px !default;
+
+@-moz-document url-prefix() {
+  [layout-fill] {
+    margin: 0;
+    width: 100%;
+    min-height: 100%;
+    height: 100%;
+  }
+}
+
+@mixin flex-order-for-name($sizes:null) {
+  @if $sizes == null {
+    $sizes: '';
+
+    [flex-order] {
+      order: 0;
+    }
+  }
+
+  @for $i from -20 through 20 {
+    $order: '';
+    $suffix: '';
+
+    @each $s in $sizes {
+      @if $s != '' {
+        $suffix: '-#{$s}="#{$i}"';
+      } @else {
+        $suffix: '="#{$i}"';
+      }
+
+      $order: '[flex-order#{$suffix}]';
+    }
+
+    #{$order} {
+      order: #{$i};
+    }
+  }
+}
+
+@mixin offset-for-name($sizes:null) {
+  @if $sizes == null {
+    $sizes: '';
+  }
+
+  @for $i from 0 through 19 {
+    $offsets: '';
+    $suffix: '';
+
+    @each $s in $sizes {
+      @if $s != '' {
+        $suffix: '-#{$s}="#{$i * 5}"';
+      } @else {
+        $suffix: '="#{$i * 5}"';
+      }
+
+      $offsets: $offsets + '[flex-offset#{$suffix}], ';
+    }
+
+    #{$offsets} {
+      margin-left: #{$i * 5 + '%'};
+    }
+  }
+
+  @each $i in 33 {
+    $offsets: '';
+    $suffix: '';
+
+    @each $s in $sizes {
+      @if $s != '' {
+        $suffix: '-#{$s}="#{$i}"';
+      } @else {
+        $suffix: '="#{$i}"';
+      }
+
+      $offsets: '[flex-offset#{$suffix}], ';
+    }
+
+    #{$offsets} {
+      margin-left: calc(100% / 3);
+    }
+  }
+
+  @each $i in 66 {
+    $offsets: '';
+    $suffix: '';
+
+    @each $s in $sizes {
+      @if $s != '' {
+        $suffix: '-#{$s}="#{$i}"';
+      } @else {
+        $suffix: '="#{$i}"';
+      }
+
+      $offsets: '[flex-offset#{$suffix}]';
+    }
+
+    #{$offsets} {
+      margin-left: calc(200% / 3);
+    }
+  }
+}
+
+@mixin layout-for-name($name: null) {
+  @if $name == null {
+    $name: '';
+  }
+  @if $name != '' {
+    $name: '-#{$name}';
+  }
+
+  [layout#{$name}], [layout#{$name}="column"], [layout#{$name}="row"] {
+    box-sizing: border-box;
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -moz-box;
+    display: -ms-flexbox;
+    display: flex;
+  }
+  [layout#{$name}="column"] {
+    flex-direction: column;
+  }
+  [layout#{$name}="row"] {
+    flex-direction: row;
+  }
+}
+
+@mixin flex-properties-for-name($name: null) {
+  $flexName: 'flex';
+  @if $name != null {
+    $flexName: 'flex-#{$name}';
+    $name: '-#{$name}';
+  } @else {
+    $name: '';
+  }
+
+  [#{$flexName}] {
+    flex: 1;
+    box-sizing: border-box;
+  }
+  // === flex: 1 1 0%;
+
+  // IE mediaQuery hack for 8,9,10 to set the flex-basis properly for 'flex' values
+  // Details:
+  // Do not use unitless flex-basis values in the flex shorthand because IE 10-11 will error.
+  // Also use 0% instead of 0px since minifiers will often convert 0px to 0 (which is unitless and will have the same problem).
+  // Safari, however, fails with flex-basis : 0% and requires flex-basis : 0px
+  @media screen\0
+  {
+    [#{$flexName}] {
+      flex: 1 1 0%;
+    }
+  }
+
+  [#{$flexName}-grow] {
+    flex: 1 1 100%;
+    box-sizing: border-box;
+  }
+  [#{$flexName}-initial] {
+    flex: 0 1 auto;
+    box-sizing: border-box;
+  }
+  [#{$flexName}-auto] {
+    flex: 1 1 auto;
+    box-sizing: border-box;
+  }
+  [#{$flexName}-none] {
+    flex: 0 0 auto;
+    box-sizing: border-box;
+  }
+  [#{$flexName}-noshrink] {
+    flex: 1 0 auto;
+    box-sizing: border-box;
+  }
+  [#{$flexName}-nogrow] {
+    flex: 0 1 auto;
+    box-sizing: border-box;
+  }
+
+  // (1-20) * 5 = 0-100%
+  @for $i from 0 through 20 {
+    $value: #{$i * 5 + '%'};
+
+    [#{$flexName}="#{$i * 5}"] {
+      flex: 1 1 #{$value};
+      max-width: #{$value};
+      max-height: 100%;
+      box-sizing: border-box;
+    }
+
+    [layout="row"] > [#{$flexName}="#{$i * 5}"],
+    [layout#{$name}="row"] > [#{$flexName}="#{$i * 5}"] {
+      flex: 1 1 #{$value};
+      max-width: #{$value};
+      max-height: 100%;
+      box-sizing: border-box;
+    }
+
+    [layout="column"] > [#{$flexName}="#{$i * 5}"],
+    [layout#{$name}="column"] > [#{$flexName}="#{$i * 5}"] {
+      flex: 1 1 #{$value};
+      max-width: 100%;
+      max-height: #{$value};
+      box-sizing: border-box;
+    }
+  }
+
+  [layout="row"], [layout#{$name}="row"] {
+    > [#{$flexName}="33"], > [#{$flexName}="33"] {
+      flex: 1 1 33%;
+      max-width: calc(100% / 3);
+      max-height: 100%;
+      box-sizing: border-box;
+    }
+    > [#{$flexName}="34"], > [#{$flexName}="34"] {
+      flex: 1 1 34%;
+      max-width: 34%;
+      max-height: 100%;
+      box-sizing: border-box;
+    }
+    > [#{$flexName}="66"], > [#{$flexName}="66"] {
+      flex: 1 1 66%;
+      max-width: calc(200% / 3);
+      max-height: 100%;
+      box-sizing: border-box;
+    }
+    > [#{$flexName}="67"], > [#{$flexName}="67"] {
+      flex: 1 1 67%;
+      max-width: 67%;
+      max-height: 100%;
+      box-sizing: border-box;
+    }
+  }
+  [layout="column"], [layout#{$name}="column"] {
+    > [#{$flexName}="33"], > [#{$flexName}="33"] {
+      flex: 1 1 33%;
+      max-width: 100%;
+      max-height: calc(100% / 3);
+      box-sizing: border-box;
+    }
+    > [#{$flexName}="34"], > [#{$flexName}="34"] {
+      flex: 1 1 34%;
+      max-width: 100%;
+      max-height: 34%;
+      box-sizing: border-box;
+    }
+    > [#{$flexName}="66"], > [#{$flexName}="66"] {
+      flex: 1 1 66%;
+      max-width: 100%;
+      max-height: calc(200% / 3);
+      box-sizing: border-box;
+    }
+    > [#{$flexName}="67"], > [#{$flexName}="67"] {
+      flex: 1 1 67%;
+      max-width: 100%;
+      max-height: 67%;
+      box-sizing: border-box;
+    }
+  }
+
+}
+
+@mixin layout-align-for-name($suffix: null) {
+
+  // Alignment attributes for layout containers' children
+  // Arrange on the Main Axis
+  // center, start, end, space-between, space-around
+  // flex-start is the default for justify-content
+  // ------------------------------
+
+  $name: 'layout-align';
+  @if $suffix != null {
+    $name: 'layout-align-#{$suffix}';
+  }
+
+  [#{$name}],
+  [#{$name}="start stretch"] // defaults
+  {
+    justify-content: flex-start;
+    align-content: stretch;
+    align-items: stretch;
+  }
+  // Main Axis Center
+  [#{$name}="start"],
+  [#{$name}="start start"],
+  [#{$name}="start center"],
+  [#{$name}="start end"],
+  [#{$name}="start stretch"] {
+    justify-content: start;
+  }
+
+  // Main Axis Center
+  [#{$name}="center"],
+  [#{$name}="center start"],
+  [#{$name}="center center"],
+  [#{$name}="center end"],
+  [#{$name}="center stretch"] {
+    justify-content: center;
+  }
+
+  // Main Axis End
+  [#{$name}="end"], //stretch
+  [#{$name}="end center"],
+  [#{$name}="end start"],
+  [#{$name}="end end"],
+  [#{$name}="end stretch"] {
+    justify-content: flex-end;
+  }
+
+  // Main Axis Space Around
+  [#{$name}="space-around"], //stretch
+  [#{$name}="space-around center"],
+  [#{$name}="space-around start"],
+  [#{$name}="space-around end"],
+  [#{$name}="space-around stretch"] {
+    justify-content: space-around;
+  }
+
+  // Main Axis Space Between
+  [#{$name}="space-between"], //stretch
+  [#{$name}="space-between center"],
+  [#{$name}="space-between start"],
+  [#{$name}="space-between end"],
+  [#{$name}="space-between stretch"] {
+    justify-content: space-between;
+  }
+
+  // Arrange on the Cross Axis
+  // center, start, end
+  // stretch is the default for align-items
+  // ------------------------------
+
+  // Cross Axis Start
+  [#{$name}="start start"],
+  [#{$name}="center start"],
+  [#{$name}="end start"],
+  [#{$name}="space-between start"],
+  [#{$name}="space-around start"] {
+    align-items: flex-start;
+    align-content: flex-start;
+  }
+
+  // Cross Axis Center
+  [#{$name}="start center"],
+  [#{$name}="center center"],
+  [#{$name}="end center"],
+  [#{$name}="space-between center"],
+  [#{$name}="space-around center"] {
+    align-items: center;
+    align-content: center;
+    max-width: 100%;
+  }
+
+  // Cross Axis Center IE overflow fix
+  [#{$name}="start center"] > *,
+  [#{$name}="center center"] > *,
+  [#{$name}="end center"] > *,
+  [#{$name}="space-between center"] > *,
+  [#{$name}="space-around center"] > * {
+    max-width: 100%;
+    box-sizing: border-box;
+  }
+
+  // Cross Axis End
+  [#{$name}="start end"],
+  [#{$name}="center end"],
+  [#{$name}="end end"],
+  [#{$name}="space-between end"],
+  [#{$name}="space-around end"] {
+    align-items: flex-end;
+    align-content: flex-end;
+  }
+
+  // Cross Axis  stretch
+  [#{$name}="start stretch"],
+  [#{$name}="center stretch"],
+  [#{$name}="end stretch"],
+  [#{$name}="space-between stretch"],
+  [#{$name}="space-around stretch"] {
+    align-items: stretch;
+    align-content: stretch;
+  }
+}
+
+@mixin layout-padding-margin() {
+
+  [layout-padding] > [flex-sm], [layout-padding] > [flex-lt-md] {
+    padding: $layout-gutter-width / 4;
+  }
+  [layout-padding],
+  [layout-padding] > [flex],
+  [layout-padding] > [flex-gt-sm],
+  [layout-padding] > [flex-md],
+  [layout-padding] > [flex-lt-lg] {
+    padding: $layout-gutter-width / 2;
+  }
+  [layout-padding] > [flex-gt-md],
+  [layout-padding] > [flex-lg] {
+    padding: $layout-gutter-width / 1;
+  }
+
+  [layout-margin] > [flex-sm],
+  [layout-margin] > [flex-lt-md] {
+    margin: $layout-gutter-width / 4;
+  }
+
+  [layout-margin],
+  [layout-margin] > [flex],
+  [layout-margin] > [flex-gt-sm],
+  [layout-margin] > [flex-md],
+  [layout-margin] > [flex-lt-lg] {
+    margin: $layout-gutter-width / 2;
+  }
+
+  [layout-margin] > [flex-gt-md],
+  [layout-margin] > [flex-lg] {
+    margin: $layout-gutter-width / 1;
+  }
+
+  [layout-wrap] {
+    flex-wrap: wrap;
+  }
+
+  [layout-nowrap] {
+    flex-wrap: nowrap;
+  }
+
+  [layout-fill] {
+    margin: 0;
+    width: 100%;
+    min-height: 100%;
+    height: 100%;
+  }
+}
+
+@mixin layouts_for_breakpoint($name:null) {
+  @include flex-order-for-name($name);
+  @include offset-for-name($name);
+  @include layout-align-for-name($name);
+
+  @include flex-properties-for-name($name);
+  @include layout-for-name($name);
+}
+
+/*
+ *  Apply Mixins to create Layout/Flexbox styles
+ *
+ */
+
+@include layouts_for_breakpoint();
+@include layout-padding-margin();
+
+/**
+ * `hide-gt-sm show-gt-lg` should hide from 600px to 1200px
+ * `show-md hide-gt-sm` should show from 0px to 960px and hide at >960px
+ * `hide-gt-md show-gt-sm` should show everywhere (show overrides hide)`
+ *
+ *  hide means hide everywhere
+ *  Sizes:
+ *         $layout-breakpoint-xs:     600px !default;
+ *         $layout-breakpoint-sm:     960px !default;
+ *         $layout-breakpoint-md:     1280px !default;
+ *         $layout-breakpoint-lg:     1920px !default;
+ */
+
+@media (max-width: $layout-breakpoint-xs - 1) {
+  // Xtra-SMALL  SCREEN
+  [hide-xs], [hide] {
+    &:not([show-xs]):not([show]) {
+      display: none;
+    }
+  }
+  @include layouts_for_breakpoint(xs);
+}
+
+@media (min-width: $layout-breakpoint-xs) {
+  // BIGGER THAN Xtra-SMALL SCREEN
+  @include layouts_for_breakpoint(gt-xs);
+
+}
+
+@media (min-width: $layout-breakpoint-xs) and (max-width: $layout-breakpoint-sm - 1) {
+  // SMALL SCREEN
+  [hide-sm], [hide-gt-xs] {
+    &:not([show-gt-xs]):not([show-sm]):not([show]) {
+      display: none;
+    }
+  }
+  [hide-sm]:not([show-sm]):not([show]) {
+    display: none;
+  }
+  @include layouts_for_breakpoint(sm);
+}
+
+@media (min-width: $layout-breakpoint-sm) {
+  // BIGGER THAN SMALL SCREEN
+  @include layouts_for_breakpoint(gt-sm);
+
+}
+
+@media (min-width: $layout-breakpoint-sm) and (max-width: $layout-breakpoint-md - 1) {
+  // MEDIUM SCREEN
+  [hide], [hide-gt-xs], [hide-gt-sm] {
+    &:not([show-gt-xs]):not([show-gt-sm]):not([show-md]):not([show]) {
+      display: none;
+    }
+  }
+  [hide-md]:not([show-md]):not([show]) {
+    display: none;
+  }
+  @include layouts_for_breakpoint(md);
+}
+
+@media (min-width: $layout-breakpoint-md) {
+  // BIGGER THAN MEDIUM SCREEN
+  @include layouts_for_breakpoint(gt-md);
+}
+
+@media (min-width: $layout-breakpoint-md) and (max-width: $layout-breakpoint-lg - 1) {
+  // LARGE SCREEN
+  [hide], [hide-gt-xs], [hide-gt-sm], [hide-gt-md] {
+    &:not([show-gt-xs]):not([show-gt-sm]):not([show-gt-md]):not([show-lg]):not([show]) {
+      display: none;
+    }
+  }
+  [hide-lg]:not([show-lg]):not([show]) {
+    display: none;
+  }
+
+  @include layouts_for_breakpoint(lg);
+}
+
+@media (min-width: $layout-breakpoint-lg) {
+  // BIGGER THAN LARGE SCREEN
+  @include layouts_for_breakpoint(gt-lg);
+  @include layouts_for_breakpoint(xl);
+
+  // BIGGER THAN LARGE SCREEN
+  [hide], [hide-gt-xs], [hide-gt-sm], [hide-gt-md], [hide-gt-lg] {
+    &:not([show-gt-xs]):not([show-gt-sm]):not([show-gt-md]):not([show-gt-lg]):not([show-xl]):not([show]) {
+      display: none;
+    }
+  }
+  [hide-xl]:not([show-xl]):not([show-gt-lg]):not([show]) {
+    display: none;
+  }
+}
diff --git a/src/styles/core/mixins.scss b/src/styles/core/mixins.scss
new file mode 100644
index 0000000000..c22f900bbe
--- /dev/null
+++ b/src/styles/core/mixins.scss
@@ -0,0 +1,138 @@
+/**
+ * Mixin that creates a new stacking context.
+ * see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
+ */
+@mixin md-stacking-context() {
+  position: relative;
+
+  // Use a transform to create a new stacking context.
+  transform: translate3D(0, 0, 0);
+}
+
+@mixin margin-selectors($before:1em, $after:1em, $start:0px, $end:0px) {
+  -webkit-margin-before: $before;
+  -webkit-margin-after: $after;
+  -webkit-margin-start: $start;
+  -webkit-margin-end: $end;
+}
+
+@mixin not-selectable($value:none) {
+  -webkit-touch-callout: $value;
+  -webkit-user-select: $value;
+  -khtml-user-select: $value;
+  -moz-user-select: $value;
+  -ms-user-select: $value;
+  user-select: $value;
+}
+
+@mixin input-placeholder-color($color) {
+  &::-webkit-input-placeholder,
+  &::-moz-placeholder,
+  &:-moz-placeholder,
+  &:-ms-input-placeholder {
+    color: $color;
+  }
+}
+
+@mixin pie-clearfix {
+  &:after {
+    content: '';
+    display: table;
+    clear: both;
+  }
+}
+
+@mixin md-shadow-bottom-z-1() {
+  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
+}
+
+@mixin md-shadow-bottom-z-2() {
+  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4);
+}
+
+// Mixin for a "flat" input that can be used for components that contain an input
+// (datepicker, autocomplete).
+@mixin md-flat-input() {
+  font-size: 14px;
+
+  box-sizing: border-box;
+  border: none;
+  box-shadow: none;
+  outline: none;
+  background: transparent;
+
+  // The the "clear X" that IE adds to input[type="search"]
+  &::-ms-clear {
+    display: none;
+  }
+}
+
+// Typography mixins
+
+@mixin md-title() {
+  font-size: $title-font-size-base;
+  font-weight: 500;
+  letter-spacing: 0.005em;
+}
+
+@mixin md-body-1() {
+  font-size: $body-font-size-base;
+  font-weight: 400;
+  letter-spacing: 0.010em;
+  line-height: rem(2);
+}
+
+@mixin md-body-2() {
+  font-size: $body-font-size-base;
+  font-weight: 500;
+  letter-spacing: 0.010em;
+  line-height: rem(2.4);
+}
+
+@mixin md-subhead() {
+  font-size: $subhead-font-size-base;
+  font-weight: 400;
+  letter-spacing: 0.010em;
+  line-height: rem(2.4);
+}
+
+@function map-to-string($map) {
+  $map-str: '{';
+  $keys: map-keys($map);
+  $len: length($keys);
+  @for $i from 1 through $len {
+    $key: nth($keys, $i);
+    $value: map-get($map, $key);
+    $map-str: $map-str + '_' + $key + '_: _' + map-get($map, $key) + '_';
+    @if $i != $len {
+      $map-str: $map-str + ',';
+    }
+  }
+  @return $map-str + '}';
+}
+
+// mixin definition ; sets LTR and RTL within the same style call
+// @see https://css-tricks.com/almanac/properties/d/direction/
+
+@mixin rtl($prop, $value, $rtl-value) {
+  #{$prop}: $value;
+
+  html[dir=rtl] & {
+    #{$prop}: $rtl-value;
+    unicode-bidi: embed;
+  }
+  body[dir=rtl] & {
+    #{$prop}: $rtl-value;
+    unicode-bidi: embed;
+  }
+
+  bdo[dir=rtl] {
+    direction: rtl;
+    unicode-bidi: bidi-override;
+  }
+  bdo[dir=ltr] {
+    direction: ltr;
+    unicode-bidi: bidi-override;
+  }
+
+}
diff --git a/src/styles/core/palette.scss b/src/styles/core/palette.scss
new file mode 100644
index 0000000000..82b6279b1f
--- /dev/null
+++ b/src/styles/core/palette.scss
@@ -0,0 +1,664 @@
+// Core color palettes.
+$md-red: (
+  50: #ffebee,
+  100: #ffcdd2,
+  200: #ef9a9a,
+  300: #e57373,
+  400: #ef5350,
+  500: #f44336,
+  600: #e53935,
+  700: #d32f2f,
+  800: #c62828,
+  900: #b71c1c,
+  A100: #ff8a80,
+  A200: #ff5252,
+  A400: #ff1744,
+  A700: #d50000,
+);
+
+$md-pink: (
+  50: #fce4ec,
+  100: #f8bbd0,
+  200: #f48fb1,
+  300: #f06292,
+  400: #ec407a,
+  500: #e91e63,
+  600: #d81b60,
+  700: #c2185b,
+  800: #ad1457,
+  900: #880e4f,
+  A100: #ff80ab,
+  A200: #ff4081,
+  A400: #f50057,
+  A700: #c51162,
+);
+
+$md-purple: (
+  50: #f3e5f5,
+  100: #e1bee7,
+  200: #ce93d8,
+  300: #ba68c8,
+  400: #ab47bc,
+  500: #9c27b0,
+  600: #8e24aa,
+  700: #7b1fa2,
+  800: #6a1b9a,
+  900: #4a148c,
+  A100: #ea80fc,
+  A200: #e040fb,
+  A400: #d500f9,
+  A700: #aa00ff,
+);
+
+$md-deep-purple: (
+  50: #ede7f6,
+  100: #d1c4e9,
+  200: #b39ddb,
+  300: #9575cd,
+  400: #7e57c2,
+  500: #673ab7,
+  600: #5e35b1,
+  700: #512da8,
+  800: #4527a0,
+  900: #311b92,
+  A100: #b388ff,
+  A200: #7c4dff,
+  A400: #651fff,
+  A700: #6200ea,
+);
+
+$md-indigo: (
+  50: #e8eaf6,
+  100: #c5cae9,
+  200: #9fa8da,
+  300: #7986cb,
+  400: #5c6bc0,
+  500: #3f51b5,
+  600: #3949ab,
+  700: #303f9f,
+  800: #283593,
+  900: #1a237e,
+  A100: #8c9eff,
+  A200: #536dfe,
+  A400: #3d5afe,
+  A700: #304ffe,
+);
+
+$md-blue: (
+  50: #e3f2fd,
+  100: #bbdefb,
+  200: #90caf9,
+  300: #64b5f6,
+  400: #42a5f5,
+  500: #2196f3,
+  600: #1e88e5,
+  700: #1976d2,
+  800: #1565c0,
+  900: #0d47a1,
+  A100: #82b1ff,
+  A200: #448aff,
+  A400: #2979ff,
+  A700: #2962ff,
+);
+
+$md-light-blue: (
+  50: #e1f5fe,
+  100: #b3e5fc,
+  200: #81d4fa,
+  300: #4fc3f7,
+  400: #29b6f6,
+  500: #03a9f4,
+  600: #039be5,
+  700: #0288d1,
+  800: #0277bd,
+  900: #01579b,
+  A100: #80d8ff,
+  A200: #40c4ff,
+  A400: #00b0ff,
+  A700: #0091ea,
+);
+
+$md-cyan: (
+  50: #e0f7fa,
+  100: #b2ebf2,
+  200: #80deea,
+  300: #4dd0e1,
+  400: #26c6da,
+  500: #00bcd4,
+  600: #00acc1,
+  700: #0097a7,
+  800: #00838f,
+  900: #006064,
+  A100: #84ffff,
+  A200: #18ffff,
+  A400: #00e5ff,
+  A700: #00b8d4,
+);
+
+$md-teal: (
+  50: #e0f2f1,
+  100: #b2dfdb,
+  200: #80cbc4,
+  300: #4db6ac,
+  400: #26a69a,
+  500: #009688,
+  600: #00897b,
+  700: #00796b,
+  800: #00695c,
+  900: #004d40,
+  A100: #a7ffeb,
+  A200: #64ffda,
+  A400: #1de9b6,
+  A700: #00bfa5,
+);
+
+$md-green: (
+  50: #e8f5e9,
+  100: #c8e6c9,
+  200: #a5d6a7,
+  300: #81c784,
+  400: #66bb6a,
+  500: #4caf50,
+  600: #43a047,
+  700: #388e3c,
+  800: #2e7d32,
+  900: #1b5e20,
+  A100: #b9f6ca,
+  A200: #69f0ae,
+  A400: #00e676,
+  A700: #00c853,
+);
+
+$md-light-green: (
+  50: #f1f8e9,
+  100: #dcedc8,
+  200: #c5e1a5,
+  300: #aed581,
+  400: #9ccc65,
+  500: #8bc34a,
+  600: #7cb342,
+  700: #689f38,
+  800: #558b2f,
+  900: #33691e,
+  A100: #ccff90,
+  A200: #b2ff59,
+  A400: #76ff03,
+  A700: #64dd17,
+);
+
+$md-lime: (
+  50: #f9fbe7,
+  100: #f0f4c3,
+  200: #e6ee9c,
+  300: #dce775,
+  400: #d4e157,
+  500: #cddc39,
+  600: #c0ca33,
+  700: #afb42b,
+  800: #9e9d24,
+  900: #827717,
+  A100: #f4ff81,
+  A200: #eeff41,
+  A400: #c6ff00,
+  A700: #aeea00,
+);
+
+$md-yellow: (
+  50: #fffde7,
+  100: #fff9c4,
+  200: #fff59d,
+  300: #fff176,
+  400: #ffee58,
+  500: #ffeb3b,
+  600: #fdd835,
+  700: #fbc02d,
+  800: #f9a825,
+  900: #f57f17,
+  A100: #ffff8d,
+  A200: #ffff00,
+  A400: #ffea00,
+  A700: #ffd600,
+);
+
+$md-amber: (
+  50: #fff8e1,
+  100: #ffecb3,
+  200: #ffe082,
+  300: #ffd54f,
+  400: #ffca28,
+  500: #ffc107,
+  600: #ffb300,
+  700: #ffa000,
+  800: #ff8f00,
+  900: #ff6f00,
+  A100: #ffe57f,
+  A200: #ffd740,
+  A400: #ffc400,
+  A700: #ffab00,
+);
+
+$md-orange: (
+  50: #fff3e0,
+  100: #ffe0b2,
+  200: #ffcc80,
+  300: #ffb74d,
+  400: #ffa726,
+  500: #ff9800,
+  600: #fb8c00,
+  700: #f57c00,
+  800: #ef6c00,
+  900: #e65100,
+  A100: #ffd180,
+  A200: #ffab40,
+  A400: #ff9100,
+  A700: #ff6d00,
+);
+
+$md-deep-orange: (
+  50: #fbe9e7,
+  100: #ffccbc,
+  200: #ffab91,
+  300: #ff8a65,
+  400: #ff7043,
+  500: #ff5722,
+  600: #f4511e,
+  700: #e64a19,
+  800: #d84315,
+  900: #bf360c,
+  A100: #ff9e80,
+  A200: #ff6e40,
+  A400: #ff3d00,
+  A700: #dd2c00,
+);
+
+$md-brown: (
+  50: #efebe9,
+  100: #d7ccc8,
+  200: #bcaaa4,
+  300: #a1887f,
+  400: #8d6e63,
+  500: #795548,
+  600: #6d4c41,
+  700: #5d4037,
+  800: #4e342e,
+  900: #3e2723,
+  A100: #d7ccc8,
+  A200: #bcaaa4,
+  A400: #8d6e63,
+  A700: #5d4037,
+);
+
+$md-grey: (
+  0: #ffffff,
+  50: #fafafa,
+  100: #f5f5f5,
+  200: #eeeeee,
+  300: #e0e0e0,
+  400: #bdbdbd,
+  500: #9e9e9e,
+  600: #757575,
+  700: #616161,
+  800: #424242,
+  900: #212121,
+  1000: #000000,
+  A100: #ffffff,
+  A200: #eeeeee,
+  A400: #bdbdbd,
+  A700: #616161,
+);
+
+$md-blue-grey: (
+  50: #eceff1,
+  100: #cfd8dc,
+  200: #b0bec5,
+  300: #90a4ae,
+  400: #78909c,
+  500: #607d8b,
+  600: #546e7a,
+  700: #455a64,
+  800: #37474f,
+  900: #263238,
+  A100: #cfd8dc,
+  A200: #b0bec5,
+  A400: #78909c,
+  A700: #455a64,
+);
+
+$md-light-theme-foreground: (
+  divider: rgba(black, 0.12),
+  dividers: rgba(black, 0.12),
+  disabled: rgba(black, 0.26),
+  disabled-text: rgba(black, 0.26),
+  hint-text: rgba(black, 0.26),
+  secondary-text: rgba(black, 0.54),
+  icon: rgba(black, 0.54),
+  icons: rgba(black, 0.54),
+  text: rgba(black, 0.87)
+);
+
+$md-dark-theme-foreground: (
+  divider: rgba(white, 0.12),
+  dividers: rgba(white, 0.12),
+  disabled: rgba(white, 0.30),
+  disabled-text: rgba(white, 0.30),
+  hint-text: rgba(white, 0.30),
+  secondary-text: rgba(white, 0.70),
+  icon: white,
+  icons: white,
+  text: white
+);
+
+// Contrast colors. These are hard-coded because it is too difficult to calculate them.
+// These contrast colors are pulled from the public Material Design spec swatches. While the
+// contrast colors in the spec are not perscriptive, we will use them for convenience.
+$black-87-opacity: rgba(black, 0.870588);
+$white-87-opacity: rgba(white, 0.870588);
+
+$md-contrast-palettes: (
+  $md-red: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: white,
+    600: white,
+    700: white,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: white,
+    A400: white,
+    A700: white,
+  ),
+  $md-pink: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: white,
+    600: white,
+    700: $white-87-opacity,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: white,
+    A400: white,
+    A700: white,
+  ),
+  $md-purple: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: white,
+    400: white,
+    500: $white-87-opacity,
+    600: $white-87-opacity,
+    700: $white-87-opacity,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: white,
+    A400: white,
+    A700: white,
+  ),
+  $md-deep-purple: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: white,
+    400: white,
+    500: $white-87-opacity,
+    600: $white-87-opacity,
+    700: $white-87-opacity,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: white,
+    A400: $white-87-opacity,
+    A700: $white-87-opacity,
+  ),
+  $md-indigo: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: white,
+    400: white,
+    500: $white-87-opacity,
+    600: $white-87-opacity,
+    700: $white-87-opacity,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: white,
+    A400: white,
+    A700: $white-87-opacity,
+  ),
+  $md-blue: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: white,
+    600: white,
+    700: white,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: white,
+    A400: white,
+    A700: white,
+  ),
+  $md-light-blue: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: white,
+    600: white,
+    700: white,
+    800: white,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: $black-87-opacity,
+    A700: white,
+  ),
+  $md-cyan: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: white,
+    600: white,
+    700: white,
+    800: white,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: $black-87-opacity,
+    A700: $black-87-opacity,
+  ),
+  $md-teal: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: white,
+    600: white,
+    700: white,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: $black-87-opacity,
+    A700: $black-87-opacity,
+  ),
+  $md-green: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: white,
+    600: white,
+    700: white,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: $black-87-opacity,
+    A700: $black-87-opacity,
+  ),
+  $md-light-green: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: $black-87-opacity,
+    600: $black-87-opacity,
+    700: $black-87-opacity,
+    800: white,
+    900: white,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: $black-87-opacity,
+    A700: $black-87-opacity,
+  ),
+  $md-lime: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: $black-87-opacity,
+    600: $black-87-opacity,
+    700: $black-87-opacity,
+    800: $black-87-opacity,
+    900: white,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: $black-87-opacity,
+    A700: $black-87-opacity,
+  ),
+  $md-yellow: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: $black-87-opacity,
+    600: $black-87-opacity,
+    700: $black-87-opacity,
+    800: $black-87-opacity,
+    900: $black-87-opacity,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: $black-87-opacity,
+    A700: $black-87-opacity,
+  ),
+  $md-amber: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: $black-87-opacity,
+    600: $black-87-opacity,
+    700: $black-87-opacity,
+    800: $black-87-opacity,
+    900: $black-87-opacity,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: $black-87-opacity,
+    A700: $black-87-opacity,
+  ),
+  $md-orange: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: $black-87-opacity,
+    600: $black-87-opacity,
+    700: $black-87-opacity,
+    800: white,
+    900: white,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: $black-87-opacity,
+    A700: black,
+  ),
+  $md-deep-orange: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: white,
+    600: white,
+    700: white,
+    800: white,
+    900: white,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: white,
+    A700: white,
+  ),
+  $md-brown: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: white,
+    400: white,
+    500: $white-87-opacity,
+    600: $white-87-opacity,
+    700: $white-87-opacity,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: white,
+    A700: $white-87-opacity,
+  ),
+  $md-grey: (
+    0: $black-87-opacity,
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: $black-87-opacity,
+    500: $black-87-opacity,
+    600: $white-87-opacity,
+    700: $white-87-opacity,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    1000: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: $black-87-opacity,
+    A700: $white-87-opacity,
+  ),
+  $md-blue-grey: (
+    50: $black-87-opacity,
+    100: $black-87-opacity,
+    200: $black-87-opacity,
+    300: $black-87-opacity,
+    400: white,
+    500: white,
+    600: $white-87-opacity,
+    700: $white-87-opacity,
+    800: $white-87-opacity,
+    900: $white-87-opacity,
+    A100: $black-87-opacity,
+    A200: $black-87-opacity,
+    A400: white,
+    A700: $white-87-opacity,
+  ),
+);
diff --git a/src/styles/core/shadows.scss b/src/styles/core/shadows.scss
new file mode 100644
index 0000000000..585c74e9f5
--- /dev/null
+++ b/src/styles/core/shadows.scss
@@ -0,0 +1,38 @@
+// Elements can have an "elevation" from 1 to 5, signified by shadows.
+// See http://google.com/design/spec/what-is-material/objects-in-3d-space.html
+
+$md-shadow-bottom-z-1: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
+$md-shadow-bottom-z-2: 0 4px 8px 0 rgba(0, 0, 0, 0.4);
+
+// Whiteframes
+
+$shadow-key-umbra-opacity: 0.2;
+$shadow-key-penumbra-opacity: 0.14;
+$shadow-ambient-shadow-opacity: 0.12;
+
+// NOTE(shyndman): gulp-sass seems to be failing if I split the shadow defs across
+//    multiple lines. Ugly. Sorry.
+$whiteframe-shadow-1dp: 0px 1px 3px 0px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 1px 1px 0px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 2px 1px -1px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-2dp: 0px 1px 5px 0px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 2px 2px 0px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 3px 1px -2px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-3dp: 0px 1px 8px 0px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 3px 4px 0px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 3px 3px -2px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-4dp: 0px 2px 4px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 4px 5px 0px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 1px 10px 0px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-5dp: 0px 3px 5px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 5px 8px 0px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 1px 14px 0px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-6dp: 0px 3px 5px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 6px 10px 0px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 1px 18px 0px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-7dp: 0px 4px 5px -2px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 7px 10px 1px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 2px 16px 1px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-8dp: 0px 5px 5px -3px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 8px 10px 1px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 3px 14px 2px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-9dp: 0px 5px 6px -3px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 9px 12px 1px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 3px 16px 2px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-10dp: 0px 6px 6px -3px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 10px 14px 1px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 4px 18px 3px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-11dp: 0px 6px 7px -4px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 11px 15px 1px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 4px 20px 3px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-12dp: 0px 7px 8px -4px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 12px 17px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 5px 22px 4px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-13dp: 0px 7px 8px -4px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 13px 19px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 5px 24px 4px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-14dp: 0px 7px 9px -4px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 14px 21px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 5px 26px 4px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-15dp: 0px 8px 9px -5px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 15px 22px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 6px 28px 5px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-16dp: 0px 8px 10px -5px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 16px 24px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 6px 30px 5px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-17dp: 0px 8px 11px -5px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 17px 26px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 6px 32px 5px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-18dp: 0px 9px 11px -5px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 18px 28px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 7px 34px 6px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-19dp: 0px 9px 12px -6px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 19px 29px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 7px 36px 6px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-20dp: 0px 10px 13px -6px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 20px 31px 3px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 8px 38px 7px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-21dp: 0px 10px 13px -6px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 21px 33px 3px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 8px 40px 7px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-22dp: 0px 10px 14px -6px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 22px 35px 3px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 8px 42px 7px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-23dp: 0px 11px 14px -7px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 23px 36px 3px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 9px 44px 8px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
+$whiteframe-shadow-24dp: 0px 11px 15px -7px rgba(0, 0, 0, $shadow-key-umbra-opacity), 0px 24px 38px 3px rgba(0, 0, 0, $shadow-key-penumbra-opacity), 0px 9px 46px 8px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
diff --git a/src/styles/core/structure.scss b/src/styles/core/structure.scss
new file mode 100644
index 0000000000..355d0c8611
--- /dev/null
+++ b/src/styles/core/structure.scss
@@ -0,0 +1,196 @@
+@import 'variables';
+
+html, body {
+  height: 100%;
+  color: rgba(0, 0, 0, 0.87);
+  background: white;
+  position: relative;
+}
+
+body {
+  margin: 0;
+  padding: 0;
+}
+
+[tabindex='-1']:focus {
+  outline: none;
+}
+
+.inset {
+  padding: 10px;
+}
+
+button.md-no-style {
+  font-weight: normal;
+  background-color: inherit;
+  text-align: left;
+  border: none;
+  padding: 0;
+  margin: 0;
+}
+
+select,
+button,
+textarea,
+input {
+  vertical-align: baseline;
+}
+
+// Fix Android 4.0 button bugs
+input[type="reset"],
+input[type="submit"],
+html input[type="button"],
+button {
+  cursor: pointer;
+  -webkit-appearance: button;
+
+  &[disabled] {
+    cursor: default;
+  }
+}
+
+textarea {
+  vertical-align: top;
+  overflow: auto;
+}
+
+input {
+  &[type="search"] {
+    -webkit-appearance: textfield;
+    box-sizing: content-box;
+    -webkit-box-sizing: content-box;
+
+    &::-webkit-search-decoration,
+    &::-webkit-search-cancel-button {
+      -webkit-appearance: none;
+    }
+  }
+}
+
+.md-visually-hidden {
+  border: 0;
+  clip: rect(0 0 0 0);
+  height: 1px;
+  margin: -1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  text-transform: none;
+  width: 1px;
+}
+
+.md-shadow {
+  position: absolute;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+  border-radius: inherit;
+  pointer-events: none;
+}
+
+.md-shadow-bottom-z-1 {
+  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
+}
+
+.md-shadow-bottom-z-2 {
+  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4);
+}
+
+.md-shadow-animated.md-shadow {
+  transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+/*
+ * A container inside of a rippling element (eg a button),
+ * which contains all of the individual ripples
+ */
+.md-ripple-container {
+  pointer-events: none;
+  position: absolute;
+  overflow: hidden;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+}
+
+/*
+ * A container inside of a rippling element (eg a button),
+ * which contains all of the individual ripples
+ */
+.md-ripple-container {
+  pointer-events: none;
+  position: absolute;
+  overflow: hidden;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  transition: all 0.55s $swift-ease-out-timing-function;
+}
+
+.md-ripple {
+  position: absolute;
+  transform: translate(-50%, -50%) scale(0);
+  transform-origin: 50% 50%;
+  opacity: 0;
+  border-radius: 50%;
+  &.md-ripple-placed {
+    $sizeDuration: 0.45s * 2;
+    transition: margin $sizeDuration $swift-ease-out-timing-function,
+    border $sizeDuration $swift-ease-out-timing-function,
+    width $sizeDuration $swift-ease-out-timing-function,
+    height $sizeDuration $swift-ease-out-timing-function,
+    opacity $sizeDuration $swift-ease-out-timing-function,
+    transform $sizeDuration $swift-ease-out-timing-function;
+  }
+  &.md-ripple-scaled {
+    transform: translate(-50%, -50%) scale(1);
+  }
+  &.md-ripple-active, &.md-ripple-full, &.md-ripple-visible {
+    opacity: 0.20;
+  }
+}
+
+.md-padding {
+  padding: 8px;
+}
+
+.md-margin {
+  margin: 8px;
+}
+
+.md-scroll-mask {
+  position: absolute;
+  background-color: transparent;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  > .md-scroll-mask-bar {
+    display: block;
+    position: absolute;
+    background-color: #fafafa;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    z-index: $z-index-scroll-mask;
+    box-shadow: inset 0px 0px 1px rgba(0, 0, 0, 0.3)
+  }
+}
+
+.md-no-select {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+@media (min-width: $layout-breakpoint-sm) {
+  .md-padding {
+    padding: 16px;
+  }
+}
diff --git a/src/styles/core/theme-functions.scss b/src/styles/core/theme-functions.scss
new file mode 100644
index 0000000000..02002901d5
--- /dev/null
+++ b/src/styles/core/theme-functions.scss
@@ -0,0 +1,60 @@
+// ** Two main functions for users **
+// md-palette: used for defining your theme in terms of Material hues.
+// md-color: apply colors to components from the palette. Consumes the output of md-palette
+
+// Implement the rem unit with SCSS so we don't have to actually set a font-size on
+// the user's body element.
+@function rem($multiplier) {
+  $font-size: 10px;
+  @return $multiplier * $font-size;
+}
+
+// For a given hue in a palette, return the contrast color from the map of contrast palettes.
+@function md-contrast($color-map, $hue, $contrast-color-map) {
+  @return map-get(map-get($contrast-color-map, $color-map), $hue);
+}
+
+// Creates a map of hues to colors for a theme.
+// $color-map
+// $primary
+// $lighter
+// $darker
+@function md-palette($color-map, $primary, $lighter, $darker, $contrast-color-map) {
+  $result: map_merge($color-map, (
+    default: map-get($color-map, $primary),
+    lighter: map-get($color-map, $lighter),
+    darker: map-get($color-map, $darker),
+    default-contrast: md-contrast($color-map, $primary, $contrast-color-map),
+    lighter-contrast: md-contrast($color-map, $lighter, $contrast-color-map),
+    darker-contrast: md-contrast($color-map, $darker, $contrast-color-map)
+  ));
+
+  // For each hue in the palette, add a "-contrast" color to the map.
+  @each $hue, $color in $color-map {
+    $result: map_merge($result, (
+      "#{$hue}-contrast": md-contrast($color-map, $hue, $contrast-color-map)
+    ))
+  }
+
+  @return $result;
+}
+
+// Gets a color for a material design component.
+// $color-map: a map of {key: color}.
+// $hue-key: key used to lookup the color in $colorMap. Defaults to 'default'
+//     If $hue-key is a number between 0 and 1, it will be treated as $opacity.
+// $opacity: the opacity to apply to the color.
+@function md-color($color-map, $hue-key: default, $opacity: 1) {
+  // If hueKey is a number between zero and one, then it actually contains an
+  // opacity value, so recall this function with the default hue and that given opacity.
+  @if type-of($hue-key) == number and $hue-key >= 0 and $hue-key <= 1 {
+    @return md-color($color-map, default, $hue-key)
+  }
+
+  $color: map-get($color-map, $hue-key);
+  $opacity: if(opacity($color) < 1, opacity($color), $opacity);
+
+  @return rgba($color, $opacity);
+}
+
+
diff --git a/src/styles/core/typography.scss b/src/styles/core/typography.scss
new file mode 100644
index 0000000000..4367f17d0a
--- /dev/null
+++ b/src/styles/core/typography.scss
@@ -0,0 +1,106 @@
+// Global page styles
+//
+// [2] Ensure the page always fills at least the entire height of the viewport.
+// [3] Prevent iOS text size adjust after orientation change, without disabling user zoom
+// [4] Fonts on OSX will look more consistent with other systems that do not
+// render text using sub-pixel anti-aliasing.
+
+html, body {
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+  -webkit-touch-callout: none;
+
+  min-height: 100%; // [2]
+
+  -webkit-text-size-adjust: 100%; // [3]
+  -ms-text-size-adjust: 100%; // [3]
+
+  -webkit-font-smoothing: antialiased; // [4]
+  -moz-osx-font-smoothing: grayscale; // [4]
+}
+
+md-select, md-card, md-list, md-toolbar,
+ul, ol, p, h1, h2, h3, h4, h5, h6 {
+  //text-rendering: optimizeLegibility;
+}
+
+/************
+ * Headings
+ ************/
+.md-display-4 {
+  font-size: $display-4-font-size-base;
+  font-weight: 300;
+  letter-spacing: -0.010em;
+  line-height: $display-4-font-size-base;
+}
+
+.md-display-3 {
+  font-size: $display-3-font-size-base;
+  font-weight: 400;
+  letter-spacing: -0.005em;
+  line-height: $display-3-font-size-base;
+}
+
+.md-display-2 {
+  font-size: $display-2-font-size-base;
+  font-weight: 400;
+  line-height: rem(6.4);
+}
+
+.md-display-1 {
+  font-size: $display-1-font-size-base;
+  font-weight: 400;
+  line-height: rem(4);
+}
+
+.md-headline {
+  font-size: $headline-font-size-base;
+  font-weight: 400;
+  line-height: rem(3.2);
+}
+
+.md-title {
+  @include md-title();
+}
+
+.md-subhead {
+  @include md-subhead();
+}
+
+/************
+ * Body Copy
+ ************/
+.md-body-1 {
+  @include md-body-1();
+}
+
+.md-body-2 {
+  @include md-body-2();
+}
+
+.md-caption {
+  font-size: $caption-font-size-base;
+  letter-spacing: 0.020em;
+}
+
+.md-button {
+  letter-spacing: 0.010em;
+}
+
+/************
+ * Defaults
+ ************/
+
+button,
+select,
+html,
+textarea,
+input {
+  font-family: $font-family;
+}
+
+select,
+button,
+textarea,
+input {
+  font-size: 100%;
+}
diff --git a/src/styles/core/variables.scss b/src/styles/core/variables.scss
new file mode 100644
index 0000000000..e365fe1def
--- /dev/null
+++ b/src/styles/core/variables.scss
@@ -0,0 +1,79 @@
+@import 'theme-functions';
+
+// Typography
+// ------------------------------
+$font-family: RobotoDraft, Roboto, 'Helvetica Neue', sans-serif !default;
+$font-size: 10px;
+
+$display-4-font-size-base: rem(11.20) !default;
+$display-3-font-size-base: rem(5.600) !default;
+$display-2-font-size-base: rem(4.500) !default;
+$display-1-font-size-base: rem(3.400) !default;
+$headline-font-size-base: rem(2.400) !default;
+$title-font-size-base: rem(2.000) !default;
+$subhead-font-size-base: rem(1.600) !default;
+
+$body-font-size-base: rem(1.400) !default;
+$caption-font-size-base: rem(1.200) !default;
+
+// Layout
+$baseline-grid: 8px !default;
+$layout-breakpoint-xs: 600px !default;
+$layout-breakpoint-sm: 600px !default;
+$layout-breakpoint-md: 960px !default;
+$layout-breakpoint-lg: 1280px !default;
+$layout-gutter-width: ($baseline-grid * 2) !default;
+
+// Typography
+$md-body-font-size-base: rem(1.400) !default;
+
+// App bar variables
+$app-bar-height: 64px;
+
+// Icons
+$icon-size: rem(2.4);
+
+// Toast
+$toast-height: $baseline-grid * 3 !default;
+$toast-margin: $baseline-grid * 1 !default;
+
+// Whiteframes
+$whiteframe-shadow-z1: 0px 2px 5px 0 rgba(0, 0, 0, 0.26) !default;
+$whiteframe-zindex-z1: 1 !default;
+$whiteframe-shadow-z2: 0px 8px 17px rgba(0, 0, 0, 0.2) !default;
+$whiteframe-zindex-z2: 2 !default;
+$whiteframe-shadow-z3: 0px 17px 50px rgba(0, 0, 0, 0.19) !default;
+$whiteframe-zindex-z3: 3 !default;
+$whiteframe-shadow-z4: 0px 16px 28px 0 rgba(0, 0, 0, 0.22) !default;
+$whiteframe-zindex-z4: 4 !default;
+$whiteframe-shadow-z5: 0px 27px 24px 0 rgba(0, 0, 0, 0.2) !default;
+$whiteframe-zindex-z5: 5 !default;
+
+// Z-indexes
+$z-index-tooltip: 100 !default;
+$z-index-dialog: 80 !default;
+$z-index-toast: 90 !default;
+$z-index-bottom-sheet: 70 !default;
+$z-index-scroll-mask: 65 !default;
+$z-index-sidenav: 60 !default;
+$z-index-backdrop: 50 !default;
+$z-index-toolbar: 30 !default;
+$z-index-fab: 20 !default;
+$z-index-progress-circular: 2 !default; // Used to fix animation bug in Chrome
+
+// Easing Curves
+$swift-ease-out-duration: 0.4s !default;
+$swift-ease-out-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default;
+$swift-ease-out: all $swift-ease-out-duration $swift-ease-out-timing-function !default;
+
+$swift-ease-in-duration: 0.3s !default;
+$swift-ease-in-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2) !default;
+$swift-ease-in: all $swift-ease-in-duration $swift-ease-in-timing-function !default;
+
+$swift-ease-in-out-duration: 0.5s !default;
+$swift-ease-in-out-timing-function: cubic-bezier(0.35, 0, 0.25, 1) !default;
+$swift-ease-in-out: all $swift-ease-in-out-duration $swift-ease-in-out-timing-function !default;
+
+$swift-linear-duration: 0.08s !default;
+$swift-linear-timing-function: linear !default;
+$swift-linear: all $swift-linear-duration $swift-linear-timing-function !default;
diff --git a/src/styles/font.scss b/src/styles/font.scss
new file mode 100644
index 0000000000..421b960b07
--- /dev/null
+++ b/src/styles/font.scss
@@ -0,0 +1,53 @@
+$md-font-url: '../asset/font' !default;
+
+@font-face {
+  font-family: 'Material Icons';
+  font-style: normal;
+  font-weight: 400;
+  src: url($md-font-url + 'MaterialIcons-Regular.eot'); /* For IE6-8 */
+  src: local($md-font-url + 'Material Icons'),
+       local($md-font-url + 'MaterialIcons-Regular'),
+       url($md-font-url + 'MaterialIcons-Regular.woff2') format('woff2'),
+       url($md-font-url + 'MaterialIcons-Regular.woff') format('woff'),
+       url($md-font-url + 'MaterialIcons-Regular.ttf') format('truetype');
+}
+.material-icons {
+  font-family: 'Material Icons';
+  font-weight: normal;
+  font-style: normal;
+  font-size: 24px;  /* Preferred icon size */
+  display: inline-block;
+  width: 1em;
+  height: 1em;
+  line-height: 1;
+  text-transform: none;
+  letter-spacing: normal;
+  word-wrap: normal;
+  white-space: nowrap;
+  direction: ltr;
+
+  /* Support for all WebKit browsers. */
+  -webkit-font-smoothing: antialiased;
+  /* Support for Safari and Chrome. */
+  text-rendering: optimizeLegibility;
+
+  /* Support for Firefox. */
+  -moz-osx-font-smoothing: grayscale;
+
+  /* Support for IE. */
+  font-feature-settings: 'liga';
+}
+
+// Rules for sizing the icon.
+.material-icons.md-18 { font-size: 18px; }
+.material-icons.md-24 { font-size: 24px; }
+.material-icons.md-36 { font-size: 36px; }
+.material-icons.md-48 { font-size: 48px; }
+
+// Rules for using icons as black on a light background.
+.material-icons.md-dark { color: rgba(0, 0, 0, 0.54); }
+.material-icons.md-dark.md-inactive { color: rgba(0, 0, 0, 0.26); }
+
+// Rules for using icons as white on a dark background.
+.material-icons.md-light { color: rgba(255, 255, 255, 1); }
+.material-icons.md-light.md-inactive { color: rgba(255, 255, 255, 0.3); }
diff --git a/src/styles/markdown.css b/src/styles/markdown.css
new file mode 100644
index 0000000000..dd9dac3777
--- /dev/null
+++ b/src/styles/markdown.css
@@ -0,0 +1,695 @@
+@font-face {
+  font-family: octicons-link;
+  src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff');
+}
+
+.markdown-body {
+  -ms-text-size-adjust: 100%;
+  -webkit-text-size-adjust: 100%;
+  color: #333;
+  font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+  font-size: 16px;
+  line-height: 1.6;
+  word-wrap: break-word;
+}
+
+.markdown-body a {
+  background-color: transparent;
+  -webkit-text-decoration-skip: objects;
+}
+
+.markdown-body a:active,
+.markdown-body a:hover {
+  outline-width: 0;
+}
+
+.markdown-body strong {
+  font-weight: inherit;
+}
+
+.markdown-body strong {
+  font-weight: bolder;
+}
+
+.markdown-body h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+
+.markdown-body img {
+  border-style: none;
+}
+
+.markdown-body svg:not(:root) {
+  overflow: hidden;
+}
+
+.markdown-body code,
+.markdown-body kbd,
+.markdown-body pre {
+  font-family: monospace, monospace;
+  font-size: 1em;
+}
+
+.markdown-body hr {
+  box-sizing: content-box;
+  height: 0;
+  overflow: visible;
+}
+
+.markdown-body input {
+  font: inherit;
+  margin: 0;
+}
+
+.markdown-body input {
+  overflow: visible;
+}
+
+.markdown-body button:-moz-focusring,
+.markdown-body [type="button"]:-moz-focusring,
+.markdown-body [type="reset"]:-moz-focusring,
+.markdown-body [type="submit"]:-moz-focusring {
+  outline: 1px dotted ButtonText;
+}
+
+.markdown-body [type="checkbox"] {
+  box-sizing: border-box;
+  padding: 0;
+}
+
+.markdown-body table {
+  border-spacing: 0;
+  border-collapse: collapse;
+}
+
+.markdown-body td,
+.markdown-body th {
+  padding: 0;
+}
+
+.markdown-body * {
+  box-sizing: border-box;
+}
+
+.markdown-body input {
+  font: 13px/1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+}
+
+.markdown-body a {
+  color: #4078c0;
+  text-decoration: none;
+}
+
+.markdown-body a:hover,
+.markdown-body a:active {
+  text-decoration: underline;
+}
+
+.markdown-body hr {
+  height: 0;
+  margin: 15px 0;
+  overflow: hidden;
+  background: transparent;
+  border: 0;
+  border-bottom: 1px solid #ddd;
+}
+
+.markdown-body hr::before {
+  display: table;
+  content: "";
+}
+
+.markdown-body hr::after {
+  display: table;
+  clear: both;
+  content: "";
+}
+
+.markdown-body h1,
+.markdown-body h2,
+.markdown-body h3,
+.markdown-body h4,
+.markdown-body h5,
+.markdown-body h6 {
+  margin-top: 0;
+  margin-bottom: 0;
+  line-height: 1.5;
+}
+
+.markdown-body h1 {
+  font-size: 30px;
+}
+
+.markdown-body h2 {
+  font-size: 21px;
+}
+
+.markdown-body h3 {
+  font-size: 16px;
+}
+
+.markdown-body h4 {
+  font-size: 14px;
+}
+
+.markdown-body h5 {
+  font-size: 12px;
+}
+
+.markdown-body h6 {
+  font-size: 11px;
+}
+
+.markdown-body p {
+  margin-top: 0;
+  margin-bottom: 10px;
+}
+
+.markdown-body blockquote {
+  margin: 0;
+}
+
+.markdown-body ul,
+.markdown-body ol {
+  padding-left: 0;
+  margin-top: 0;
+  margin-bottom: 0;
+}
+
+.markdown-body ol ol,
+.markdown-body ul ol {
+  list-style-type: lower-roman;
+}
+
+.markdown-body ul ul ol,
+.markdown-body ul ol ol,
+.markdown-body ol ul ol,
+.markdown-body ol ol ol {
+  list-style-type: lower-alpha;
+}
+
+.markdown-body dd {
+  margin-left: 0;
+}
+
+.markdown-body code {
+  font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
+  font-size: 12px;
+}
+
+.markdown-body pre {
+  margin-top: 0;
+  margin-bottom: 0;
+  font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
+}
+
+.markdown-body .pl-0 {
+  padding-left: 0 !important;
+}
+
+.markdown-body .pl-1 {
+  padding-left: 3px !important;
+}
+
+.markdown-body .pl-2 {
+  padding-left: 6px !important;
+}
+
+.markdown-body .pl-3 {
+  padding-left: 12px !important;
+}
+
+.markdown-body .pl-4 {
+  padding-left: 24px !important;
+}
+
+.markdown-body .pl-5 {
+  padding-left: 36px !important;
+}
+
+.markdown-body .pl-6 {
+  padding-left: 48px !important;
+}
+
+.markdown-body .form-select::-ms-expand {
+  opacity: 0;
+}
+
+.markdown-body:before {
+  display: table;
+  content: "";
+}
+
+.markdown-body:after {
+  display: table;
+  clear: both;
+  content: "";
+}
+
+.markdown-body>*:first-child {
+  margin-top: 0 !important;
+}
+
+.markdown-body>*:last-child {
+  margin-bottom: 0 !important;
+}
+
+.markdown-body a:not([href]) {
+  color: inherit;
+  text-decoration: none;
+}
+
+.markdown-body .anchor {
+  display: inline-block;
+  padding-right: 2px;
+  margin-left: -18px;
+}
+
+.markdown-body .anchor:focus {
+  outline: none;
+}
+
+.markdown-body h1,
+.markdown-body h2,
+.markdown-body h3,
+.markdown-body h4,
+.markdown-body h5,
+.markdown-body h6 {
+  margin-top: 1em;
+  margin-bottom: 16px;
+  font-weight: bold;
+  line-height: 1.4;
+}
+
+.markdown-body h1 .octicon-link,
+.markdown-body h2 .octicon-link,
+.markdown-body h3 .octicon-link,
+.markdown-body h4 .octicon-link,
+.markdown-body h5 .octicon-link,
+.markdown-body h6 .octicon-link {
+  color: #000;
+  vertical-align: middle;
+  visibility: hidden;
+}
+
+.markdown-body h1:hover .anchor,
+.markdown-body h2:hover .anchor,
+.markdown-body h3:hover .anchor,
+.markdown-body h4:hover .anchor,
+.markdown-body h5:hover .anchor,
+.markdown-body h6:hover .anchor {
+  text-decoration: none;
+}
+
+.markdown-body h1:hover .anchor .octicon-link,
+.markdown-body h2:hover .anchor .octicon-link,
+.markdown-body h3:hover .anchor .octicon-link,
+.markdown-body h4:hover .anchor .octicon-link,
+.markdown-body h5:hover .anchor .octicon-link,
+.markdown-body h6:hover .anchor .octicon-link {
+  visibility: visible;
+}
+
+.markdown-body h1 {
+  padding-bottom: 0.3em;
+  font-size: 2.25em;
+  line-height: 1.2;
+  border-bottom: 1px solid #eee;
+}
+
+.markdown-body h1 .anchor {
+  line-height: 1;
+}
+
+.markdown-body h2 {
+  padding-bottom: 0.3em;
+  font-size: 1.75em;
+  line-height: 1.225;
+  border-bottom: 1px solid #eee;
+}
+
+.markdown-body h2 .anchor {
+  line-height: 1;
+}
+
+.markdown-body h3 {
+  font-size: 1.5em;
+  line-height: 1.43;
+}
+
+.markdown-body h3 .anchor {
+  line-height: 1.2;
+}
+
+.markdown-body h4 {
+  font-size: 1.25em;
+}
+
+.markdown-body h4 .anchor {
+  line-height: 1.2;
+}
+
+.markdown-body h5 {
+  font-size: 1em;
+}
+
+.markdown-body h5 .anchor {
+  line-height: 1.1;
+}
+
+.markdown-body h6 {
+  font-size: 1em;
+  color: #777;
+}
+
+.markdown-body h6 .anchor {
+  line-height: 1.1;
+}
+
+.markdown-body p,
+.markdown-body blockquote,
+.markdown-body ul,
+.markdown-body ol,
+.markdown-body dl,
+.markdown-body table,
+.markdown-body pre {
+  margin-top: 0;
+  margin-bottom: 16px;
+}
+
+.markdown-body hr {
+  height: 4px;
+  padding: 0;
+  margin: 16px 0;
+  background-color: #e7e7e7;
+  border: 0 none;
+}
+
+.markdown-body ul,
+.markdown-body ol {
+  padding-left: 2em;
+}
+
+.markdown-body ul ul,
+.markdown-body ul ol,
+.markdown-body ol ol,
+.markdown-body ol ul {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+
+.markdown-body li>p {
+  margin-top: 16px;
+}
+
+.markdown-body dl {
+  padding: 0;
+}
+
+.markdown-body dl dt {
+  padding: 0;
+  margin-top: 16px;
+  font-size: 1em;
+  font-style: italic;
+  font-weight: bold;
+}
+
+.markdown-body dl dd {
+  padding: 0 16px;
+  margin-bottom: 16px;
+}
+
+.markdown-body blockquote {
+  padding: 0 15px;
+  color: #777;
+  border-left: 4px solid #ddd;
+}
+
+.markdown-body blockquote>:first-child {
+  margin-top: 0;
+}
+
+.markdown-body blockquote>:last-child {
+  margin-bottom: 0;
+}
+
+.markdown-body table {
+  display: block;
+  width: 100%;
+  overflow: auto;
+  word-break: normal;
+  word-break: keep-all;
+}
+
+.markdown-body table th {
+  font-weight: bold;
+}
+
+.markdown-body table th,
+.markdown-body table td {
+  padding: 6px 13px;
+  border: 1px solid #ddd;
+}
+
+.markdown-body table tr {
+  background-color: #fff;
+  border-top: 1px solid #ccc;
+}
+
+.markdown-body table tr:nth-child(2n) {
+  background-color: #f8f8f8;
+}
+
+.markdown-body img {
+  max-width: 100%;
+  box-sizing: content-box;
+  background-color: #fff;
+}
+
+.markdown-body code {
+  padding: 0;
+  padding-top: 0.2em;
+  padding-bottom: 0.2em;
+  margin: 0;
+  font-size: 85%;
+  background-color: rgba(0,0,0,0.04);
+  border-radius: 3px;
+}
+
+.markdown-body code:before,
+.markdown-body code:after {
+  letter-spacing: -0.2em;
+  content: "\00a0";
+}
+
+.markdown-body pre>code {
+  padding: 0;
+  margin: 0;
+  font-size: 100%;
+  word-break: normal;
+  white-space: pre;
+  background: transparent;
+  border: 0;
+}
+
+.markdown-body .highlight {
+  margin-bottom: 16px;
+}
+
+.markdown-body .highlight pre,
+.markdown-body pre {
+  padding: 16px;
+  overflow: auto;
+  font-size: 85%;
+  line-height: 1.45;
+  background-color: #f7f7f7;
+  border-radius: 3px;
+}
+
+.markdown-body .highlight pre {
+  margin-bottom: 0;
+  word-break: normal;
+}
+
+.markdown-body pre {
+  word-wrap: normal;
+}
+
+.markdown-body pre code {
+  display: inline;
+  max-width: initial;
+  padding: 0;
+  margin: 0;
+  overflow: initial;
+  line-height: inherit;
+  word-wrap: normal;
+  background-color: transparent;
+  border: 0;
+}
+
+.markdown-body pre code:before,
+.markdown-body pre code:after {
+  content: normal;
+}
+
+.markdown-body kbd {
+  display: inline-block;
+  padding: 3px 5px;
+  font-size: 11px;
+  line-height: 10px;
+  color: #555;
+  vertical-align: middle;
+  background-color: #fcfcfc;
+  border: solid 1px #ccc;
+  border-bottom-color: #bbb;
+  border-radius: 3px;
+  box-shadow: inset 0 -1px 0 #bbb;
+}
+
+.markdown-body .pl-c {
+  color: #969896;
+}
+
+.markdown-body .pl-c1,
+.markdown-body .pl-s .pl-v {
+  color: #0086b3;
+}
+
+.markdown-body .pl-e,
+.markdown-body .pl-en {
+  color: #795da3;
+}
+
+.markdown-body .pl-s .pl-s1,
+.markdown-body .pl-smi {
+  color: #333;
+}
+
+.markdown-body .pl-ent {
+  color: #63a35c;
+}
+
+.markdown-body .pl-k {
+  color: #a71d5d;
+}
+
+.markdown-body .pl-pds,
+.markdown-body .pl-s,
+.markdown-body .pl-s .pl-pse .pl-s1,
+.markdown-body .pl-sr,
+.markdown-body .pl-sr .pl-cce,
+.markdown-body .pl-sr .pl-sra,
+.markdown-body .pl-sr .pl-sre {
+  color: #183691;
+}
+
+.markdown-body .pl-v {
+  color: #ed6a43;
+}
+
+.markdown-body .pl-id {
+  color: #b52a1d;
+}
+
+.markdown-body .pl-ii {
+  background-color: #b52a1d;
+  color: #f8f8f8;
+}
+
+.markdown-body .pl-sr .pl-cce {
+  color: #63a35c;
+  font-weight: bold;
+}
+
+.markdown-body .pl-ml {
+  color: #693a17;
+}
+
+.markdown-body .pl-mh,
+.markdown-body .pl-mh .pl-en,
+.markdown-body .pl-ms {
+  color: #1d3e81;
+  font-weight: bold;
+}
+
+.markdown-body .pl-mq {
+  color: #008080;
+}
+
+.markdown-body .pl-mi {
+  color: #333;
+  font-style: italic;
+}
+
+.markdown-body .pl-mb {
+  color: #333;
+  font-weight: bold;
+}
+
+.markdown-body .pl-md {
+  background-color: #ffecec;
+  color: #bd2c00;
+}
+
+.markdown-body .pl-mi1 {
+  background-color: #eaffea;
+  color: #55a532;
+}
+
+.markdown-body .pl-mdr {
+  color: #795da3;
+  font-weight: bold;
+}
+
+.markdown-body .pl-mo {
+  color: #1d3e81;
+}
+
+.markdown-body kbd {
+  display: inline-block;
+  padding: 3px 5px;
+  font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
+  line-height: 10px;
+  color: #555;
+  vertical-align: middle;
+  background-color: #fcfcfc;
+  border: solid 1px #ccc;
+  border-bottom-color: #bbb;
+  border-radius: 3px;
+  box-shadow: inset 0 -1px 0 #bbb;
+}
+
+.markdown-body .full-commit .btn-outline:not(:disabled):hover {
+  color: #4078c0;
+  border: 1px solid #4078c0;
+}
+
+.markdown-body :checked+.radio-label {
+  position: relative;
+  z-index: 1;
+  border-color: #4078c0;
+}
+
+.markdown-body .octicon {
+  display: inline-block;
+  vertical-align: text-top;
+  fill: currentColor;
+}
+
+.markdown-body .task-list-item {
+  list-style-type: none;
+}
+
+.markdown-body .task-list-item+.task-list-item {
+  margin-top: 3px;
+}
+
+.markdown-body .task-list-item input {
+  margin: 0 0.2em 0.25em -1.6em;
+  vertical-align: middle;
+}
+
+.markdown-body hr {
+  border-bottom-color: #eee;
+}
diff --git a/src/styles/material.scss b/src/styles/material.scss
new file mode 100644
index 0000000000..abfa41ed5a
--- /dev/null
+++ b/src/styles/material.scss
@@ -0,0 +1,8 @@
+$md-font-url: "../assets/font/";
+@import "./font";
+@import "core/variables";
+@import "core/mixins";
+@import "core/structure";
+@import "core/typography";
+@import "core/layout";
+@import "core/default-theme";
diff --git a/src/tdcmp/accordion/accordion.header.ts b/src/tdcmp/accordion/accordion.header.ts
new file mode 100644
index 0000000000..c951e1eaf8
--- /dev/null
+++ b/src/tdcmp/accordion/accordion.header.ts
@@ -0,0 +1,9 @@
+import {Component} from '@angular/core';
+
+@Component({
+    selector: 'header',
+    template: '<ng-content></ng-content>'
+})
+export class TDHeader {}
+
+export const MD_HEADER_DIRECTIVES = [TDHeader];
diff --git a/src/tdcmp/accordion/accordion.ts b/src/tdcmp/accordion/accordion.ts
new file mode 100644
index 0000000000..1321a707c9
--- /dev/null
+++ b/src/tdcmp/accordion/accordion.ts
@@ -0,0 +1,34 @@
+import {Component, ElementRef, AfterContentInit, Input,
+  Output, EventEmitter} from '@angular/core';
+import {TDaccordionTab} from './accordiontab';
+
+@Component({
+    selector: 'td-accordion',
+    template: `
+        <div [ngClass]="'ui-accordion ui-widget ui-helper-reset'" [ngStyle]="style" [class]="styleClass">
+            <ng-content></ng-content>
+        </div>
+    `
+})
+export class TDaccordion {
+
+    @Input() multiple: boolean;
+
+    @Output() onClose: EventEmitter<any> = new EventEmitter();
+
+    @Output() onOpen: EventEmitter<any> = new EventEmitter();
+
+    @Input() style: any;
+
+    @Input() styleClass: string;
+
+    public tabs: TDaccordionTab[] = [];
+
+    constructor(protected el: ElementRef) {}
+
+    addTab(tab: TDaccordionTab) {
+        this.tabs.push(tab);
+    }
+}
+
+export const MD_ACCORDION_DIRECTIVES = [TDaccordion];
diff --git a/src/tdcmp/accordion/accordiontab.ts b/src/tdcmp/accordion/accordiontab.ts
new file mode 100644
index 0000000000..b14c51f9da
--- /dev/null
+++ b/src/tdcmp/accordion/accordiontab.ts
@@ -0,0 +1,73 @@
+import { Component, Input, ContentChild} from '@angular/core';
+import { TDaccordion } from './accordion';
+import { TDHeader } from './accordion.header';
+
+@Component({
+    selector: 'td-accordionTab',
+    template: `
+        <div class="ui-accordion-header ui-helper-reset ui-state-default" [ngClass]="{'ui-state-active': selected,'ui-state-hover':hover&&!disabled,'ui-state-disabled':disabled}"
+            (click)="toggle($event)" (mouseenter)="hover = true" (mouseleave)="hover=false">
+            <span class="fa fa-fw" [ngClass]="{'fa-caret-down': selected, 'fa-caret-right': !selected}"></span>
+            <a href="#" *ngIf="!headerFacet">{{header}}</a>
+            <a href="#" *ngIf="headerFacet">
+                <ng-content select="header"></ng-content>
+            </a>
+        </div>
+        <div class="ui-accordion-content ui-helper-reset ui-widget-content" [style.display]="selected ? 'block' : 'none'">
+            <ng-content></ng-content>
+        </div>
+    `
+})
+export class TDaccordionTab {
+
+    @Input() header: string;
+
+    @Input() selected: boolean;
+
+    @Input() disabled: boolean;
+
+    @ContentChild(TDHeader) headerFacet;
+
+    constructor(protected accordion: TDaccordion) {
+        this.accordion.addTab(this);
+    }
+
+    toggle(event) {
+        if (this.disabled) {
+            event.preventDefault();
+            return;
+        }
+
+        let index = this.findTabIndex();
+
+        if (this.selected) {
+            this.selected = !this.selected;
+            this.accordion.onClose.emit({originalEvent: event, index: index});
+        } else {
+            if (!this.accordion.multiple) {
+                for (let i = 0; i < this.accordion.tabs.length; i++) {
+                    this.accordion.tabs[i].selected = false;
+                }
+            }
+
+            this.selected = true;
+
+            this.accordion.onOpen.emit({originalEvent: event, index: index});
+        }
+
+        event.preventDefault();
+    }
+
+    findTabIndex() {
+        let index = -1;
+        for (let i = 0; i < this.accordion.tabs.length; i++) {
+            if (this.accordion.tabs[i] === this) {
+                index = i;
+                break;
+            }
+        }
+        return index;
+    }
+}
+
+export const MD_ACCORDIONTAB_DIRECTIVES = [TDaccordionTab];
diff --git a/src/tdcmp/autoComplete/autocomplete.html b/src/tdcmp/autoComplete/autocomplete.html
new file mode 100644
index 0000000000..12930737ee
--- /dev/null
+++ b/src/tdcmp/autoComplete/autocomplete.html
@@ -0,0 +1,9 @@
+<div class="autocomplete">
+  <form autocomplete="off" >
+    <md-input overlay-origin [(ngModel)]=text [ngModelOptions]="{standalone: true}"></md-input>
+  </form>
+</div>
+
+<template portal>
+  <p> Fusilli </p>
+</template>
diff --git a/src/tdcmp/autoComplete/autocomplete.scss b/src/tdcmp/autoComplete/autocomplete.scss
new file mode 100644
index 0000000000..e26616633a
--- /dev/null
+++ b/src/tdcmp/autoComplete/autocomplete.scss
@@ -0,0 +1,3 @@
+.autocomplete {
+  
+}
diff --git a/src/tdcmp/autoComplete/autocomplete.ts b/src/tdcmp/autoComplete/autocomplete.ts
new file mode 100644
index 0000000000..bc4ab95da4
--- /dev/null
+++ b/src/tdcmp/autoComplete/autocomplete.ts
@@ -0,0 +1,148 @@
+import { Component, ViewEncapsulation, Input, Output, HostListener, ViewChild
+  , EventEmitter, AfterViewInit, forwardRef, ElementRef, ViewContainerRef } from '@angular/core';
+  import {
+    NG_VALUE_ACCESSOR,
+    ControlValueAccessor,
+    NgModel
+  } from '@angular/forms';
+  import {
+    Overlay,
+    OverlayOrigin,
+    OverlayState,
+    OverlayRef,
+    OVERLAY_PROVIDERS,
+    TemplatePortal,
+    TemplatePortalDirective,
+    PORTAL_DIRECTIVES,
+    Portal,
+    OVERLAY_DIRECTIVES
+} from '@angular2-material/core/core';
+import {
+    ConnectedPositionStrategy
+} from '@angular2-material/core/overlay/position/connected-position-strategy';
+
+  export const MD_AUTOCOMPLETE_CONTROL_VALUE_ACCESSOR: any = {
+     provide: NG_VALUE_ACCESSOR,
+     useExisting: forwardRef(() => MdAutoComplete),
+     multi: true
+   };
+   const noop = () => {};
+
+@Component({
+  selector: 'md-autocomplete',
+  template: require('./autocomplete.html'),
+  styles: [require('./autocomplete.scss')],
+  directives: [PORTAL_DIRECTIVES, OVERLAY_DIRECTIVES],
+  providers: [MD_AUTOCOMPLETE_CONTROL_VALUE_ACCESSOR, OVERLAY_PROVIDERS],
+  encapsulation: ViewEncapsulation.None
+})
+export class MdAutoComplete {
+  @Input() items: Array<string>;
+  @Input() get text(): string {
+    return this._text;
+  }
+  set text(value: string) {
+    if (this.text === value) return;
+    this._text = value;
+    this._onChangeCallback(value);
+  }
+
+  @Output() onPopupOpen = new EventEmitter();
+  @Output() onPopupClose = new EventEmitter();
+  @ViewChild(TemplatePortalDirective) templatePortal: Portal<any>;
+  @ViewChild(OverlayOrigin) _overlayOrigin: OverlayOrigin;
+
+  popupOpen: boolean = false;
+  private _text: string;
+  private _onTouchedCallback: () => void = noop;
+  private _onChangeCallback: (_: any) => void = noop;
+  private _active: boolean = false;
+  private _overlayRef: OverlayRef;
+
+  constructor(private _overlay: Overlay, private _element: ElementRef,
+              private _viewContainerRef: ViewContainerRef) {}
+
+
+  ngAfterViewInit() {
+    console.log(this.templatePortal);
+    setTimeout(() => this._active = true, 200);
+  }
+
+    ngOnDestroy() { this.destroyPopup(); }
+
+  @HostListener('click')
+  togglepopup(): Promise<void> {
+    return this.popupOpen ? this.closePopup() : this.openPopup();
+  }
+
+
+  openPopup(): Promise<void> {
+    return this._createOverlay()
+      .then(() => this._overlayRef.attach(this.templatePortal))
+      .then(() => this._setIsPopupOpen(true));
+  }
+
+  closePopup(): Promise<void> {
+    if (!this._overlayRef) { return Promise.resolve(); }
+
+   return this._overlayRef.detach()
+       .then(() => this._setIsPopupOpen(false));
+  }
+
+  destroyPopup(): void {
+  this._overlayRef.dispose();
+}
+
+  writeValue(value: any) {
+      this.text = value;
+  }
+
+  registerOnChange(fn: any) {
+    this._onChangeCallback = fn;
+  }
+
+  registerOnTouched(fn: any) {
+    this._onTouchedCallback = fn;
+  }
+
+  private _setIsPopupOpen(isOpen: boolean): void {
+     this.popupOpen = isOpen;
+     // this.menu._setClickCatcher(isOpen);
+     this.popupOpen ? this.onPopupOpen.emit(undefined) : this.onPopupClose.emit(undefined);
+   }
+
+  private _createOverlay(): Promise<any> {
+     if (this._overlayRef) { return Promise.resolve(); }
+     return this._overlay.create(this._getOverlayConfig())
+         .then(overlay => this._overlayRef = overlay);
+   }
+
+
+   private _getOverlayConfig(): OverlayState {
+     const overlayState = new OverlayState();
+     overlayState.positionStrategy = this._getPosition();
+     return overlayState;
+   }
+
+   private _getPosition(): any  {
+
+  let rect = this._overlayOrigin.elementRef.nativeElement.getBoundingClientRect();
+console.log(rect);
+
+  // return this._overlay.position().global()
+  //   .left(rect.left + 'px')
+  //   .top(rect.bottom + 'px');
+
+   return this._overlay.position().connectedTo(
+     this._overlayOrigin.elementRef,
+     {originX: 'start', originY: 'top'},
+     {overlayX: 'start', overlayY: 'top'}
+   );
+ }
+
+
+
+
+}
+
+export const MD_AUTOCOMLETE_DIRECTIVES: any[] = [MdAutoComplete];
diff --git a/src/tdcmp/calendar/calendar.html b/src/tdcmp/calendar/calendar.html
new file mode 100644
index 0000000000..0677aeb289
--- /dev/null
+++ b/src/tdcmp/calendar/calendar.html
@@ -0,0 +1,44 @@
+<!-- <md-content> -->
+<div class="calendar" style="overflow:auto;margin-top:10px;">
+  <div flex layout="row" style="position:relative">
+    <div class="header-year">
+      {{yearSelected}}
+    </div>
+
+    <div layout="column" class="header-weekdays">
+      <div flex *ngFor="let d of days">{{d}}</div>
+    </div>
+
+    <div layout="column">
+      <div layout="row" class="header-month">
+        <div *ngFor="let m of monthsNumber" [class.sixDayWeek]="getNbWeekOfMonth(yearSelected,m) === 6" [class.fiveDayWeek]="getNbWeekOfMonth(yearSelected,m) === 5" [class.fourDayWeek]="getNbWeekOfMonth(yearSelected,m) === 4">
+          {{monthsValue[m-1]}}
+        </div>
+      </div>
+      <div *ngFor="let day of dayOfWeeks" class="body">
+        <div layout="row">
+          <div *ngFor="let week of weeks" (click)="displayDialogAdd($event)" [class.lastWeek]="isLastWeek(yearSelected,week,day) === true" [class.firstWeek]="isFirstWeek(yearSelected,week,day) === true" [class.dayNotInYear]="dayNotInYear(yearSelected,week,day) === true || dayIsWeekEnd(yearSelected,week,day) === true"
+              [class.dayInYear]="dayNotInYear(yearSelected,week,day) === false" [class.firstDay]="isFirstDay(yearSelected,week,day) === true" [class.isHoliday]="isHoliday(yearSelected,week,day) === true">
+            <div [class.tooltipCal]="isHoliday(yearSelected,week,day)==true">
+              <span id={{getDate(yearSelected,week,day)}}>{{getDate(yearSelected,week,day).getDate()}}</span>
+              <span *ngIf="isHoliday(yearSelected,week,day)==true" class="tooltiptextCal">{{isHolidayName(yearSelected,week,day)}}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+
+<md-dialog *ngIf="displayAddDayOff" (close)="displayAddDayOff = false">
+  <md-dialog-title flex>New day off {{dateSelected | date:'dd-MM-yyyy'}}</md-dialog-title>
+  <div layout="row" layout-margin layout-align="center center">
+    <!-- <tdcombobox flex="80" placeholder="Holiday Name" [items]=holidayNameResults [selectedItem]=dateNewdayOffName (selectedItemChanged)="dateNewdayOffName = $event" (inputChanged)="searchHolidayName($event)"></tdcombobox> -->
+    <md-input flex placeholder="Holiday Name" [(ngModel)]="dateNewdayOffName" required></md-input>
+  </div>
+
+  <md-dialog-footer>
+    <button md-raised-button class="md-raised md-primary" (click)="confirmAddDayOff()" style="margin:5px">Ok</button>
+    <button *ngIf="dayOffExist" md-raised-button class="md-raised md-warn" (click)="deleteDayOff()" style="margin:5px">delete</button>
+  </md-dialog-footer>
+</md-dialog>
diff --git a/src/tdcmp/calendar/calendar.scss b/src/tdcmp/calendar/calendar.scss
new file mode 100644
index 0000000000..54cb12a097
--- /dev/null
+++ b/src/tdcmp/calendar/calendar.scss
@@ -0,0 +1,137 @@
+@import "../../styles/promethee";
+$day-div-width:20px;
+.calendar {
+  padding-top: 18px;
+  padding-bottom: 25px;
+  padding-left: 5px;
+  padding-right: 5px;
+  .sixDayWeek{
+    width: 6 * $day-div-width;
+    text-align: center;
+  }
+  .fiveDayWeek{
+    width: 5 * $day-div-width;
+    text-align: center;
+  }
+  .fourDayWeek{
+    width: 4 * $day-div-width;
+    text-align: center;
+  }
+  .header-month{
+    position: absolute;
+    top: -20px;
+    left: 86px;
+  }
+  .header-year {
+      position: absolute;
+      top: 55px;
+      left: -40px;
+      font-size: 3rem;
+      color: gray;
+      height: 40px;
+      -webkit-transform: rotate(271deg);
+      -moz-transform: rotate(271deg);
+      -o-transform: rotate(271deg);
+      writing-mode: lr-tb;
+  }
+  .header-weekdays {
+    margin-left: 50px;
+    div {
+      font-size: 0.8rem;
+      width: percentage(1/7);
+      margin: 2px;
+      text-transform: uppercase;
+    }
+  }
+  .body {
+
+  }
+  .dayInYear {
+      background-image: -webkit-linear-gradient(top, #eaeaea, #e5e5e5 60%, #d9d9d9);
+      background-image: -moz-linear-gradient(top, #eaeaea, #e5e5e5 60%, #d9d9d9);
+      background-image: -o-linear-gradient(top, #eaeaea, #e5e5e5 60%, #d9d9d9);
+      background-image: linear-gradient(to bottom, #eaeaea, #e5e5e5 60%, #d9d9d9);
+      font-weight: bold;
+      font-size: 11px;
+      height: $day-div-width;
+      line-height:$day-div-width;
+      width: $day-div-width;
+      text-align: center;
+      span{
+        display: inline-block;
+        vertical-align: middle;
+        padding-bottom: 5px;
+        color: #808080;
+      }
+      &:hover {
+        cursor: pointer;
+        background: #f3f3f3;
+        span{
+          color: #808080;
+        }
+      }
+      &:active {
+        margin: -1px;
+        color: #f3f3f3;
+        text-shadow: 0 1px rgba(0, 0, 0, 0.3);
+        background: #6dafbf;
+        border: 1px solid #598b94;
+        -webkit-box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05);
+        box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05);
+      }
+    }
+  .dayNotInYear {
+    background: #f3f3f3;
+    height: $day-div-width;
+    line-height:$day-div-width;
+    width: $day-div-width;
+    text-align: center;
+    span{
+      color: transparent;
+    }
+  }
+  .firstDay {
+    border-top: 1px solid black;
+    box-sizing: border-box;
+    span{
+      display: inline-block;
+      vertical-align: middle;
+      margin: -1px;
+    }
+  }
+  .firstWeek {
+    border-left: 1px solid black;
+    box-sizing: border-box;
+  }
+  .lastWeek {
+    border-right: 1px solid black;
+    box-sizing: border-box;
+  }
+  .isHoliday {
+    background: $prom-toolbar-background;
+    span {
+      color:white;
+    }
+  }
+
+  .tooltipCal {
+    position: relative;
+    display: inline-block;
+}
+.tooltipCal .tooltiptextCal {
+    visibility: hidden;
+    width: 120px;
+    left:-120px;
+    top:-25px;
+    background-color: black;
+    // color: #fff;
+    text-align: center;
+     padding: 5px 0;
+    border-radius: 6px;
+    position: absolute;
+    z-index: 1;
+}
+.tooltipCal:hover .tooltiptextCal {
+    visibility: visible;
+}
+}
diff --git a/src/tdcmp/calendar/calendar.ts b/src/tdcmp/calendar/calendar.ts
new file mode 100644
index 0000000000..e4cbca2349
--- /dev/null
+++ b/src/tdcmp/calendar/calendar.ts
@@ -0,0 +1,299 @@
+import { Component, ViewEncapsulation, Input, Output, HostListener, ViewChild
+  , EventEmitter, AfterViewInit, forwardRef, ElementRef, ViewContainerRef } from '@angular/core';
+import { NG_VALUE_ACCESSOR, ControlValueAccessor, NgModel } from '@angular/forms';
+import { ICalendarDetail } from '../../app/Interfaces';
+import { MD_DIALOG_DIRECTIVES, TdComboBox }
+  from '../../tdcmp';
+
+
+export const TD_TDCALENDAR_CONTROL_VALUE_ACCESSOR: any = {
+   provide: NG_VALUE_ACCESSOR,
+   useExisting: forwardRef(() => TdCalendar),
+   multi: true
+ };
+ const noop = () => {};
+
+@Component({
+  selector: 'td-calendar',
+  template: require('./calendar.html'),
+  styles: [require('./calendar.scss')],
+  directives: [ MD_DIALOG_DIRECTIVES, TdComboBox],
+  providers: [TD_TDCALENDAR_CONTROL_VALUE_ACCESSOR],
+  encapsulation: ViewEncapsulation.None
+})
+export class TdCalendar {
+  @Output() onChange: EventEmitter<boolean> = new EventEmitter<boolean>();
+  @Input() weekEnds: boolean[];
+  @Input() calendarId: number[];
+  @Input() get items(): any[]{
+    return this._items;
+  }
+  set items(value: any[]) {
+    this._items = value;
+    this._onChangeCallback(value);
+  }
+  @Input() get yearSelected(): number{
+    return this._yearSelected;
+  }
+  set yearSelected(value: number) {
+    if (this._yearSelected === value) return;
+    this._yearSelected = value;
+    this.moveYear();
+  }
+
+  days: string[] = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
+  monthsValue: string[] = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
+  'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+  monthsNumber: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
+  dayOfWeeks: number[] = [1, 2, 3, 4, 5, 6, 7];
+  weeks: number[] = [];
+
+  dateSelected: Date = undefined;
+  displayAddDayOff: boolean = false;
+  dayOffExist: boolean = false;
+  dateNewdayOffName: string = undefined;
+
+  private _onTouchedCallback: () => void = noop;
+  private _onChangeCallback: (_: any) => void = noop;
+  private _yearSelected: number;
+  private _items: any[];
+  private _displayAddDayOff: boolean;
+
+
+  constructor() {
+    this.weekEnds = [false, false, false, false, false, true, true];
+    let currentDate = new Date();
+    this.yearSelected = currentDate.getFullYear();
+    this.moveYear();
+   }
+
+   writeValue(value: any) {
+        this.items = value;
+   }
+
+   registerOnChange(fn: any) {
+     this._onChangeCallback = fn;
+   }
+
+   registerOnTouched(fn: any) {
+     this._onTouchedCallback = fn;
+   }
+
+   private isFirstDay (y, w, d): boolean {
+     let dte = this.getDate(y, w, d);
+     if (dte.getDate() === 1) {
+       return true;
+     }
+      return false;
+   }
+
+   private isFirstWeek (y, w, d): boolean {
+     let dte = this.getDate(y, w, d);
+     let dteFirstday = new Date(dte.getFullYear(), dte.getMonth(), 1);
+     if (this.getWeek(dte) === this.getWeek(dteFirstday)) {
+       return true;
+     }
+      return false;
+   }
+
+   private isLastWeek (y, w, d): boolean {
+     let dte = this.getDate(y, w, d);
+     let dteLastDay = new Date(dte.getFullYear(), dte.getMonth() + 1 , 0);
+     if (w !== this.weeks[this.weeks.length - 1] &&  this.isFirstWeek(y, w + 1, d)) {
+       return false;
+     }
+     if (w === 1 && !this.isFirstWeek(y, w + 1, d) ) {
+       if (this.getWeek(dte) === (this.getWeek(dteLastDay))) {
+         return true;
+       }
+     }
+     if (this.getWeek(dte) === (this.getWeek(dteLastDay))) {
+       return true;
+     }
+      return false;
+   }
+
+   private getNbWeekOfMonth(y, m): number {
+     let day = 1;
+     m -= 1;
+     let counter = 0;
+     let date = new Date(y, m, day);
+     while (date.getMonth() === m) {
+       if (date.getDay() === 1) {
+           counter += 1;
+       }
+     day += 1;
+     date = new Date(y, m, day);
+     }
+     if (m === 0 && new Date( this.yearSelected, 0 , 1).getDay() !== 1) {
+       counter += 1;
+     }
+   return counter;
+   }
+
+   private dayNotInYear (y, w, d): boolean {
+     let dte = this.getDate(y, w, d);
+     if (dte.getFullYear() === this._yearSelected) {
+         return false;
+     }
+     return true;
+   }
+
+   private dayIsWeekEnd (y, w, d): boolean {
+     let dte = this.getDate(y, w, d);
+     let day = dte.getDay();
+     if (day === 0 ) {
+        day = 6;
+     }else  {
+       day = day - 1;
+     }
+
+     return this.weekEnds[day];
+   }
+
+   private getDate (y, w, d): Date {
+     let dteStart = new Date(y, 0, 1);
+     let dayStart = dteStart.getDay();
+     if (dayStart === 0 ) {
+        dayStart = 6;
+     }else  {
+       dayStart = dayStart - 1;
+     }
+
+     let nbDay = (7 * (w - 1)) + d - dayStart;
+     dteStart.setDate(nbDay);
+     return dteStart;
+   }
+
+   private getWeek(dte): number {
+     let date = new Date(dte.getTime());
+     date.setHours(0, 0, 0, 0);
+    // Thursday in current week decides the year.
+    date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
+    // January 4 is always in week 1.
+    let week1 = new Date(date.getFullYear(), 0, 4);
+    // Adjust to Thursday in week 1 and count number of weeks from date to week1.
+    return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000
+                          - 3 + (week1.getDay() + 6) % 7) / 7);
+   }
+
+   private moveYear() {
+     this.weeks = [];
+     for (let _w = 1; _w <= 52; _w++) {
+       this.weeks.push(_w);
+     }
+
+     let decalage = new Date( this._yearSelected, 0 , 1).getDay();
+     let decalageEnd = new Date(  this._yearSelected + 1, 0 , 0).getDay();
+     if (decalage === 0 ) {
+       decalage = 6;
+     }else {
+       decalage = decalage - 1;
+     }
+     if (decalageEnd === 0 ) {
+       decalageEnd = 6;
+     }
+     let nbDayInYear = this.isLeapYear(this._yearSelected) ? 364 : 365;
+     let nbEntireWeek = (7 - decalageEnd + decalage + nbDayInYear)  / 7;
+     let moreWeek = (7 - decalageEnd + decalage + nbDayInYear)  % 7 > 0;
+     if (nbEntireWeek > 52 ) {
+       this.weeks.push(53);
+       if (nbEntireWeek > 53 && moreWeek) {
+         this.weeks.push(54);
+       }
+     };
+   }
+
+   private isLeapYear(y: number): boolean {
+      return !(y % 4) && ((y % 100) > 0) || !((y % 400) === 0);
+   }
+
+   private displayDialogAdd(elm) {
+     this.dateNewdayOffName = undefined;
+     let dte = new Date(elm.srcElement.id);
+     let day = dte.getDay();
+     if (day === 0 ) {
+       day = 6;
+     }else {
+       day = day - 1;
+     }
+     if (dte.getFullYear() === this.yearSelected && this.weekEnds[day] === false) {
+       this.dayOffExist = false;
+
+         let dto = this.findDatetoDTO(dte);
+         if (dto !== undefined) {
+             this.dayOffExist = true;
+             this.dateNewdayOffName = dto.holidayName;
+          }
+       this.dateSelected = dte;
+       this.displayAddDayOff = true;
+     }
+   }
+
+   private confirmAddDayOff() {
+    this.items.push( {
+        id: 0,
+        calendarId : this.calendarId,
+        date: this.dateSelected,
+        type: 0,
+        holidayName: this.dateNewdayOffName
+      });
+     this.displayAddDayOff = false;
+     this.onChange.emit(true);
+   }
+
+   private deleteDayOff() {
+      let dto = this.findDatetoDTO(this.dateSelected);
+      let index = this.items.indexOf(dto);
+      this.items.splice(index, 1);
+      this.displayAddDayOff = false;
+      this.onChange.emit(true);
+   }
+
+   private findDatetoDTO(date): any {
+       let obj = undefined;
+       this.items.forEach(element => {
+         let dteH = new Date(element.date);
+         let dteCmp = new Date(dteH.getFullYear(), dteH.getMonth(), dteH.getDate());
+         if (dteCmp.getTime() === date.getTime())
+           obj = element;
+       });
+       return obj;
+     }
+
+   private isHoliday(y, w, d): boolean {
+     if (this.items === undefined ||  this.items === [] || this.items.length === 0) {
+      return false;
+     }
+     if (this.dayIsWeekEnd(y, w, d)) {
+         return false;
+     }
+     if (this.dayNotInYear(y, w, d)) {
+         return false;
+     }
+    let dte = this.getDate(y, w, d);
+    for (let _e = 0; _e < this.items.length; _e++) {
+      let dteH = new Date(this.items[_e].date);
+      let dteCmp = new Date(dteH.getFullYear(), dteH.getMonth(), dteH.getDate());
+      if (dteCmp.getTime() === dte.getTime()) {
+        return true;
+      }
+    }
+    return false;
+   }
+
+   private isHolidayName(y, w, d): string {
+     if (this.items === undefined ||  this.items === [] || this.items.length === 0)
+      return undefined;
+     let dte = this.getDate(y, w, d);
+     for (let _e = 0; _e < this.items.length; _e++) {
+       let dteH = new Date(this.items[_e].date);
+       let dteCmp = new Date(dteH.getFullYear(), dteH.getMonth(), dteH.getDate());
+       if (dteCmp.getTime() === dte.getTime()) {
+         return this.items[_e].holidayName;
+       }
+     }
+    return undefined;
+   }
+}
+export const MD_CALENDAR_DIRECTIVES: any[] = [ TdCalendar ];
diff --git a/src/tdcmp/chart/orgaChart.ts b/src/tdcmp/chart/orgaChart.ts
new file mode 100644
index 0000000000..238864e571
--- /dev/null
+++ b/src/tdcmp/chart/orgaChart.ts
@@ -0,0 +1,102 @@
+
+import { Component, ViewEncapsulation, ElementRef, AfterViewInit, OnInit, DoCheck
+  , IterableDiffers, Input, Output, EventEmitter, OnDestroy
+  , ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
+@Component({
+  selector: 'orga-chart',
+  template: require('./orgchart.html'),
+  styles: [require('./orgchart.scss')],
+  encapsulation: ViewEncapsulation.None,
+  changeDetection: ChangeDetectionStrategy.Default
+})
+export class OrgaChart implements AfterViewInit, DoCheck, OnDestroy  {
+  chart: any;
+  data: any;
+  initialized: number = 0;
+  differ: any;
+  drawn: number = 0;
+  _selectedNode: any = undefined;
+
+  @Input() get selectedNode(): any {return this._selectedNode; }
+  set selectedNode(value: any) {
+    this._selectedNode = value;
+    if (value) this.selectedNodeChange.emit(value);
+  }
+  @Output() selectedNodeChange: EventEmitter<any> = new EventEmitter<any>();
+
+  @Input() orga: Array<any>;
+
+  private _drawnEvent: EventEmitter<any> = new EventEmitter();
+
+  constructor(private elementRef: ElementRef,  differs: IterableDiffers
+    , private changeDetectorRef: ChangeDetectorRef) {
+    this.differ = differs.find([]).create(undefined);
+
+   }
+
+  ngAfterViewInit() {
+    // if (!google.visualization || !google.visualization.OrgChart) {
+    //   google.charts.load('current', {packages: ['orgchart']});
+    //   google.charts.setOnLoadCallback(() => this.initChart());
+    // } else
+    setTimeout(() => {
+      this.initChart();
+    }, 500);
+    this._drawnEvent.subscribe(() => {
+      this.drawn = 1;
+      this.changeDetectorRef.detectChanges();
+    });
+  }
+
+  initChart() {
+    this.data = new google.visualization.DataTable();
+    this.data.addColumn('string', 'Name');
+    this.data.addColumn('string', 'Parent');
+    this.data.addColumn('string', 'ToolTip');
+
+    this.data.addRows(this.orga);
+
+    this.chart = new google.visualization.OrgChart(this.elementRef.nativeElement.children[0]);
+    google.visualization.events.addListener(this.chart, 'select', () => {
+      this.nodeSelect();
+    });
+    google.visualization.events.addListener(this.chart, 'ready', () => {
+      this._drawnEvent.emit(true);
+      if (this.selectedNode) {
+        this.chart.setSelection([{'row' : []  }]);
+        this.chart.setSelection([{'row' : [this.orga.indexOf(this.selectedNode)]  }]);
+      }
+    });
+    this.initialized = 1;
+    this.draw();
+  }
+
+  ngDoCheck() {
+        let changes = this.differ.diff(this.orga);
+        if (changes && this.initialized === 1) {
+          this.drawn = 0;
+          setTimeout(() => {
+            this.data.removeRows(0, this.data.getNumberOfRows());
+            this.data.addRows(this.orga);
+            this.draw();
+          }, 200);
+
+        }
+    }
+
+    draw() {
+        this.chart.draw(this.data, {allowHtml: true, allowCollapse: true, size: 'medium'});
+    }
+
+    nodeSelect() {
+      if (this.chart.getSelection().length === 0) return;
+      let selectedRow = this.chart.getSelection()[0].row;
+      this.selectedNodeChange.emit(this.orga[selectedRow]);
+
+    }
+
+    ngOnDestroy() {
+        google.visualization.events.removeAllListeners(this.chart);
+    }
+
+}
diff --git a/src/tdcmp/chart/orgchart.html b/src/tdcmp/chart/orgchart.html
new file mode 100644
index 0000000000..c65acdbb1a
--- /dev/null
+++ b/src/tdcmp/chart/orgchart.html
@@ -0,0 +1,2 @@
+<!-- <div class="orgchart"></div> -->
+<div class="orgchart" [class.active]="drawn==1"></div>
diff --git a/src/tdcmp/chart/orgchart.scss b/src/tdcmp/chart/orgchart.scss
new file mode 100644
index 0000000000..b52b895bcd
--- /dev/null
+++ b/src/tdcmp/chart/orgchart.scss
@@ -0,0 +1,20 @@
+.orgchart {
+  $swift-ease-out-duration: 0.4s !default;
+  $swift-ease-out-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default;
+  $swift-ease-out: all $swift-ease-out-duration $swift-ease-out-timing-function !default;
+  $swift-ease-out-quick: all 0.2s $swift-ease-out-timing-function !default;
+  transition: $swift-ease-out;
+
+  opacity: 0;
+  transform: scaleY(0);
+  transform-origin: right top;
+  &.active {
+    opacity: 1;
+    transform: scaleY(1.0);
+  }
+  &:not(.active) {
+    transition: $swift-ease-out-quick;
+    transform: scaleY(0);
+    opacity: 0;
+  }
+}
diff --git a/src/tdcmp/checkbox/checkbox.html b/src/tdcmp/checkbox/checkbox.html
new file mode 100644
index 0000000000..c1fff754de
--- /dev/null
+++ b/src/tdcmp/checkbox/checkbox.html
@@ -0,0 +1,35 @@
+<label class="md-checkbox-layout">
+  <div class="md-checkbox-inner-container">
+    <input class="md-checkbox-input" type="checkbox"
+           [id]="inputId"
+           [checked]="checked"
+           [disabled]="disabled"
+           [name]="name"
+           [tabIndex]="tabindex"
+           [indeterminate]="indeterminate"
+           [attr.aria-label]="ariaLabel"
+           [attr.aria-labelledby]="ariaLabelledby"
+           (focus)="onInputFocus()"
+           (blur)="onInputBlur()"
+           (change)="onInteractionEvent($event)">
+    <div class="md-ink-ripple"></div>
+    <div class="md-checkbox-frame"></div>
+    <div class="md-checkbox-background">
+      <svg version="1.1"
+           class="md-checkbox-checkmark"
+           xmlns="http://www.w3.org/2000/svg"
+           viewBox="0 0 24 24"
+           xml:space="preserve">
+        <path class="md-checkbox-checkmark-path"
+              fill="none"
+              stroke="white"
+              d="M4.1,12.7 9,17.6 20.3,6.3"/>
+      </svg>
+      <!-- Element for rendering the indeterminate state checkbox. -->
+      <div class="md-checkbox-mixedmark"></div>
+    </div>
+  </div>
+  <span class="md-checkbox-label">
+    <ng-content></ng-content>
+  </span>
+</label>
diff --git a/src/tdcmp/checkbox/checkbox.scss b/src/tdcmp/checkbox/checkbox.scss
new file mode 100644
index 0000000000..b18c16d468
--- /dev/null
+++ b/src/tdcmp/checkbox/checkbox.scss
@@ -0,0 +1,476 @@
+@import './node_modules/@angular2-material/core/style/default-theme.scss';
+@import './node_modules/@angular2-material/core/style/theme-functions.scss';
+@import './node_modules/@angular2-material/core/style/variables.scss';
+@import './node_modules/@angular2-material/core/style/mixins.scss';
+
+/** The width/height of the checkbox element. */
+$md-checkbox-size: $md-toggle-size !default;
+/** The width of the line used to draw the checkmark / mixedmark. */
+$md-checkbox-mark-stroke-size: 2/15 * $md-checkbox-size !default;
+/** The width of the checkbox border shown when the checkbox is unchecked. */
+$md-checkbox-border-width: 2px;
+/** The color of the checkbox border. */
+$md-checkbox-border-color: if($md-is-dark-theme, rgba(white, 0.7), rgba(black, 0.54)) !default;
+/** The color of the checkbox's checkmark / mixedmark. */
+$md-checkbox-mark-color: md-color($md-background, background);
+
+/** The color that is used as the checkbox background when it is checked. */
+//$md-checkbox-background-color: md-color($md-accent, 500);
+$md-checkbox-background-color: #00648c;
+/** The base duration used for the majority of transitions for the checkbox. */
+$md-checkbox-transition-duration: 90ms;
+/** The amount of spacing between the checkbox and its label. */
+$md-checkbox-item-spacing: $md-toggle-padding;
+
+// Manual calculation done on SVG
+$_md-checkbox-mark-path-length: 22.910259;
+$_md-checkbox-indeterminate-checked-easing-function: cubic-bezier(0.14, 0, 0, 1);
+
+/**
+ * Fades in the background of the checkbox when it goes from unchecked -> {checked,indeterminate}.
+ */
+@keyframes md-checkbox-fade-in-background {
+  0% {
+    opacity: 0;
+  }
+
+  50% {
+    opacity: 1;
+  }
+}
+
+/**
+ * Fades out the background of the checkbox when it goes from {checked,indeterminate} -> unchecked.
+ */
+@keyframes md-checkbox-fade-out-background {
+  0%, 50% {
+    opacity: 1;
+  }
+
+  100% {
+    opacity: 0;
+  }
+}
+
+/**
+ * "Draws" in the checkmark when the checkbox goes from unchecked -> checked.
+ */
+@keyframes md-checkbox-unchecked-checked-checkmark-path {
+  0%, 50% {
+    stroke-dashoffset: $_md-checkbox-mark-path-length;
+  }
+
+  50% {
+    animation-timing-function: $md-linear-out-slow-in-timing-function;
+  }
+
+  100% {
+    stroke-dashoffset: 0;
+  }
+}
+
+/**
+ * Horizontally expands the mixedmark when the checkbox goes from unchecked -> indeterminate.
+ */
+@keyframes md-checkbox-unchecked-indeterminate-mixedmark {
+  0%, 68.2% {
+    transform: scaleX(0);
+  }
+
+  68.2% {
+    animation-timing-function: cubic-bezier(0, 0, 0, 1);
+  }
+
+  100% {
+    transform: scaleX(1);
+  }
+}
+
+/**
+ * "Erases" the checkmark when the checkbox goes from checked -> unchecked.
+ */
+@keyframes md-checkbox-checked-unchecked-checkmark-path {
+  from {
+    animation-timing-function: $md-fast-out-linear-in-timing-function;
+    stroke-dashoffset: 0;
+  }
+
+  to {
+    stroke-dashoffset: $_md-checkbox-mark-path-length * -1;
+  }
+}
+
+/**
+ * Rotates and fades out the checkmark when the checkbox goes from checked -> indeterminate. This
+ * animation helps provide the illusion of the checkmark "morphing" into the mixedmark.
+ */
+@keyframes md-checkbox-checked-indeterminate-checkmark {
+  from {
+    animation-timing-function: $md-linear-out-slow-in-timing-function;
+    opacity: 1;
+    transform: rotate(0deg);
+  }
+
+  to {
+    opacity: 0;
+    transform: rotate(45deg);
+  }
+}
+
+/**
+ * Rotates and fades the checkmark back into position when the checkbox goes from indeterminate ->
+ * checked. This animation helps provide the illusion that the mixedmark is "morphing" into the
+ * checkmark.
+ */
+@keyframes md-checkbox-indeterminate-checked-checkmark {
+  from {
+    animation-timing-function: $_md-checkbox-indeterminate-checked-easing-function;
+    opacity: 0;
+    transform: rotate(45deg);
+  }
+
+  to {
+    opacity: 1;
+    transform: rotate(360deg);
+  }
+}
+
+/**
+ * Rotates and fades in the mixedmark when the checkbox goes from checked -> indeterminate. This
+ * animation, similar to md-checkbox-checked-indeterminate-checkmark, helps provide an illusion
+ * of "morphing" from checkmark -> mixedmark.
+ */
+@keyframes md-checkbox-checked-indeterminate-mixedmark {
+  from {
+    animation-timing-function: $md-linear-out-slow-in-timing-function;
+    opacity: 0;
+    transform: rotate(-45deg);
+  }
+
+  to {
+    opacity: 1;
+    transform: rotate(0deg);
+  }
+}
+
+/**
+ * Rotates and fades out the mixedmark when the checkbox goes from indeterminate -> checked. This
+ * animation, similar to md-checkbox-indeterminate-checked-checkmark, helps provide an illusion
+ * of "morphing" from mixedmark -> checkmark.
+ */
+@keyframes md-checkbox-indeterminate-checked-mixedmark {
+  from {
+    animation-timing-function: $_md-checkbox-indeterminate-checked-easing-function;
+    opacity: 1;
+    transform: rotate(0deg);
+  }
+
+  to {
+    opacity: 0;
+    transform: rotate(315deg);
+  }
+}
+
+/**
+ * Horizontally collapses and fades out the mixedmark when the checkbox goes from indeterminate ->
+ * unchecked.
+ */
+@keyframes md-checkbox-indeterminate-unchecked-mixedmark {
+  0% {
+    animation-timing-function: linear;
+    opacity: 1;
+    transform: scaleX(1);
+  }
+
+  32.8%, 100% {
+    opacity: 0;
+    transform: scaleX(0);
+  }
+}
+
+/**
+ * Applied to elements that cover the checkbox's entire inner container.
+ */
+%md-checkbox-cover-element {
+  bottom: 0;
+  left: 0;
+  position: absolute;
+  right: 0;
+  top: 0;
+}
+
+/**
+ * Applied to elements that are considered "marks" within the checkbox, e.g. the checkmark and
+ * the mixedmark.
+ */
+%md-checkbox-mark {
+  $width-padding-inset: 2 * $md-checkbox-border-width;
+  width: calc(100% - #{$width-padding-inset});
+}
+
+/**
+ * Applied to elements that appear to make up the outer box of the checkmark, such as the frame
+ * that contains the border and the actual background element that contains the marks.
+ */
+%md-checkbox-outer-box {
+  @extend %md-checkbox-cover-element;
+  border-radius: 2px;
+  box-sizing: border-box;
+  pointer-events: none;
+}
+
+md-checkbox {
+  &, label {
+    cursor: pointer;
+  }
+}
+
+.md-checkbox-layout {
+  align-items: baseline;
+  display: inline-flex;
+}
+
+.md-checkbox-inner-container {
+  display: inline-block;
+  height: $md-checkbox-size;
+  line-height: 0;
+  margin: auto;
+  margin-right: $md-checkbox-item-spacing;
+  order: 0;
+  position: relative;
+  vertical-align: middle;
+  white-space: nowrap;
+  width: $md-checkbox-size;
+
+  [dir='rtl'] & {
+    margin: {
+      left: $md-checkbox-item-spacing;
+      right: auto;
+    }
+  }
+}
+
+// TODO(kara): Remove this style when fixing vertical baseline
+.md-checkbox-layout .md-checkbox-label {
+  line-height: 24px;
+}
+
+.md-checkbox-frame {
+  @extend %md-checkbox-outer-box;
+
+  background-color: transparent;
+  border: $md-checkbox-border-width solid $md-checkbox-border-color;
+  transition: border-color $md-checkbox-transition-duration $md-linear-out-slow-in-timing-function;
+  will-change: border-color;
+}
+
+.md-checkbox-background {
+  @extend %md-checkbox-outer-box;
+
+  align-items: center;
+  display: inline-flex;
+  justify-content: center;
+  transition: background-color $md-checkbox-transition-duration
+                  $md-linear-out-slow-in-timing-function,
+              opacity $md-checkbox-transition-duration $md-linear-out-slow-in-timing-function;
+  will-change: background-color, opacity;
+}
+
+.md-checkbox-checkmark {
+  @extend %md-checkbox-cover-element;
+  @extend %md-checkbox-mark;
+
+  fill: $md-checkbox-mark-color;
+  width: 100%;
+}
+
+.md-checkbox-checkmark-path {
+  // !important is needed here because a stroke must be set as an attribute on the SVG in order
+  // for line animation to work properly.
+  stroke: $md-checkbox-mark-color !important;
+  stroke: {
+    dashoffset: $_md-checkbox-mark-path-length;
+    dasharray: $_md-checkbox-mark-path-length;
+    width: $md-checkbox-mark-stroke-size;
+  }
+}
+
+.md-checkbox-mixedmark {
+  @extend %md-checkbox-mark;
+
+  background-color: $md-checkbox-mark-color;
+  height: floor($md-checkbox-mark-stroke-size);
+  opacity: 0;
+  transform: scaleX(0) rotate(0deg);
+}
+
+.md-checkbox-align-end {
+  .md-checkbox-inner-container {
+    order: 1;
+    margin: {
+      left: $md-checkbox-item-spacing;
+      right: auto;
+    }
+
+    [dir='rtl'] & {
+      margin: {
+        left: auto;
+        right: $md-checkbox-item-spacing;
+      }
+    }
+  }
+}
+
+.md-checkbox-checked {
+  .md-checkbox-checkmark {
+    opacity: 1;
+  }
+
+  .md-checkbox-checkmark-path {
+    stroke-dashoffset: 0;
+  }
+
+  .md-checkbox-mixedmark {
+    transform: scaleX(1) rotate(-45deg);
+  }
+
+  .md-checkbox-background {
+    background-color: $md-checkbox-background-color;
+  }
+}
+
+.md-checkbox-indeterminate {
+  .md-checkbox-background {
+    background-color: $md-checkbox-background-color;
+  }
+
+  .md-checkbox-checkmark {
+    opacity: 0;
+    transform: rotate(45deg);
+  }
+
+  .md-checkbox-checkmark-path {
+    stroke-dashoffset: 0;
+  }
+
+  .md-checkbox-mixedmark {
+    opacity: 1;
+    transform: scaleX(1) rotate(0deg);
+  }
+}
+
+
+.md-checkbox-unchecked {
+  .md-checkbox-background {
+    background-color: transparent;
+  }
+}
+
+.md-checkbox-disabled {
+  // NOTE(traviskaufman): While the spec calls for translucent blacks/whites for disabled colors,
+  // this does not work well with elements layered on top of one another. To get around this we
+  // blend the colors together based on the base color and the theme background.
+  $white-30pct-opacity-on-dark-theme: #686868;
+  $black-26pct-opacity-on-light-theme: #b0b0b0;
+  $disabled-color: if(
+      $md-is-dark-theme, $white-30pct-opacity-on-dark-theme, $black-26pct-opacity-on-light-theme);
+
+  cursor: default;
+
+  &.md-checkbox-checked,
+  &.md-checkbox-indeterminate {
+    .md-checkbox-background {
+      background-color: $disabled-color;
+    }
+  }
+
+  &:not(.md-checkbox-checked) {
+    .md-checkbox-frame {
+      border-color: $disabled-color;
+    }
+  }
+}
+
+.md-checkbox-anim {
+  $indeterminate-change-duration: 500ms;
+
+  &-unchecked-checked {
+    .md-checkbox-background {
+      animation: $md-checkbox-transition-duration * 2 linear 0ms md-checkbox-fade-in-background;
+    }
+
+    .md-checkbox-checkmark-path {
+      // Instead of delaying the animation, we simply multiply its length by 2 and begin the
+      // animation at 50% in order to prevent a flash of styles applied to a checked checkmark
+      // as the background is fading in before the animation begins.
+      animation:
+        $md-checkbox-transition-duration * 2 linear 0ms md-checkbox-unchecked-checked-checkmark-path;
+    }
+  }
+
+  &-unchecked-indeterminate {
+    .md-checkbox-background {
+      animation: $md-checkbox-transition-duration * 2 linear 0ms md-checkbox-fade-in-background;
+    }
+
+    .md-checkbox-mixedmark {
+      animation:
+        $md-checkbox-transition-duration linear 0ms md-checkbox-unchecked-indeterminate-mixedmark;
+    }
+  }
+
+  &-checked-unchecked {
+    .md-checkbox-background {
+      animation: $md-checkbox-transition-duration * 2 linear 0ms md-checkbox-fade-out-background;
+    }
+
+    .md-checkbox-checkmark-path {
+      animation:
+        $md-checkbox-transition-duration linear 0ms md-checkbox-checked-unchecked-checkmark-path;
+    }
+  }
+
+  &-checked-indeterminate {
+    .md-checkbox-checkmark {
+      animation:
+        $md-checkbox-transition-duration linear 0ms md-checkbox-checked-indeterminate-checkmark;
+    }
+
+    .md-checkbox-mixedmark {
+      animation:
+        $md-checkbox-transition-duration linear 0ms md-checkbox-checked-indeterminate-mixedmark;
+    }
+  }
+
+  &-indeterminate-checked {
+    .md-checkbox-checkmark {
+      animation:
+        $indeterminate-change-duration linear 0ms md-checkbox-indeterminate-checked-checkmark;
+    }
+
+    .md-checkbox-mixedmark {
+      animation:
+        $indeterminate-change-duration linear 0ms md-checkbox-indeterminate-checked-mixedmark;
+    }
+  }
+
+  &-indeterminate-unchecked {
+    .md-checkbox-background {
+      animation: $md-checkbox-transition-duration * 2 linear 0ms md-checkbox-fade-out-background;
+    }
+
+    .md-checkbox-mixedmark {
+      animation:
+        $indeterminate-change-duration * 0.6 linear 0ms
+        md-checkbox-indeterminate-unchecked-mixedmark;
+    }
+  }
+}
+
+// Underlying native input element.
+// Visually hidden but still able to respond to focus.
+.md-checkbox-input {
+  @include md-visually-hidden;
+}
+
+@include md-temporary-ink-ripple(checkbox);
diff --git a/src/tdcmp/checkbox/checkbox.ts b/src/tdcmp/checkbox/checkbox.ts
new file mode 100644
index 0000000000..ba62d144f0
--- /dev/null
+++ b/src/tdcmp/checkbox/checkbox.ts
@@ -0,0 +1,324 @@
+import {
+    ChangeDetectionStrategy,
+    Component,
+    ElementRef,
+    EventEmitter,
+    Input,
+    Output,
+    Provider,
+    Renderer,
+    ViewEncapsulation,
+    forwardRef,
+    AfterContentInit
+} from '@angular/core';
+import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/common';
+
+/**
+ * Monotonically increasing integer used to auto-generate unique ids for checkbox components.
+ */
+let nextId = 0;
+
+/**
+ * Provider Expression that allows md-checkbox to register as a ControlValueAccessor. This allows it
+ * to support [(ngModel)] and ngControl.
+ */
+const MD_CHECKBOX_CONTROL_VALUE_ACCESSOR = new Provider(
+    NG_VALUE_ACCESSOR, {
+      useExisting: forwardRef(() => MdCheckbox),
+      multi: true
+    });
+
+/**
+ * Represents the different states that require custom transitions between them.
+ */
+enum TransitionCheckState {
+  /** The initial state of the component before any user interaction. */
+  Init,
+  /** The state representing the component when it's becoming checked. */
+  Checked,
+  /** The state representing the component when it's becoming unchecked. */
+  Unchecked,
+  /** The state representing the component when it's becoming indeterminate. */
+  Indeterminate
+}
+
+// A simple change event emitted by the MdCheckbox component.
+export class MdCheckboxChange {
+  source: MdCheckbox;
+  checked: boolean;
+}
+
+/**
+ * A material design checkbox component. Supports all of the functionality of an HTML5 checkbox,
+ * and exposes a similar API. An MdCheckbox can be either checked, unchecked, indeterminate, or
+ * disabled. Note that all additional accessibility attributes are taken care of by the component,
+ * so there is no need to provide them yourself. However, if you want to omit a label and still
+ * have the checkbox be accessible, you may supply an [aria-label] input.
+ * See: https://www.google.com/design/spec/components/selection-controls.html
+ */
+@Component({
+  moduleId: module.id,
+  selector: 'md-checkbox',
+  template: require('./checkbox.html'),
+  styles: [require('./checkbox.scss')],
+  host: {
+    '[class.md-checkbox-indeterminate]': 'indeterminate',
+    '[class.md-checkbox-checked]': 'checked',
+    '[class.md-checkbox-disabled]': 'disabled',
+    '[class.md-checkbox-align-end]': 'align == "end"',
+    '[class.md-checkbox-focused]': 'hasFocus',
+  },
+  providers: [MD_CHECKBOX_CONTROL_VALUE_ACCESSOR],
+  encapsulation: ViewEncapsulation.None,
+  changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class MdCheckbox implements AfterContentInit, ControlValueAccessor {
+  /**
+   * Attached to the aria-label attribute of the host element. In most cases, arial-labelledby will
+   * take precedence so this may be omitted.
+   */
+  @Input('aria-label') ariaLabel: string = '';
+
+  /**
+   * Users can specify the `aria-labelledby` attribute which will be forwarded to the input element
+   */
+  @Input('aria-labelledby') ariaLabelledby: string = null;
+
+  /** A unique id for the checkbox. If one is not supplied, it is auto-generated. */
+  @Input() id: string = `md-checkbox-${++nextId}`;
+
+  /** ID to be applied to the `input` element */
+  get inputId(): string {
+    return `input-${this.id}`;
+  }
+
+  /** Whether or not the checkbox should come before or after the label. */
+  @Input() align: 'start' | 'end' = 'start';
+
+  /**
+   * Whether the checkbox is disabled. When the checkbox is disabled it cannot be interacted with.
+   * The correct ARIA attributes are applied to denote this to assistive technology.
+   */
+  @Input() disabled: boolean = false;
+
+  /**
+   * The tabindex attribute for the checkbox. Note that when the checkbox is disabled, the attribute
+   * on the host element will be removed. It will be placed back when the checkbox is re-enabled.
+   */
+  @Input() tabindex: number = 0;
+
+  /** Name value will be applied to the input element if present */
+  @Input() name: string = null;
+
+  /** Event emitted when the checkbox's `checked` value changes. */
+  @Output() change: EventEmitter<MdCheckboxChange> = new EventEmitter<MdCheckboxChange>();
+
+  /** Called when the checkbox is blurred. Needed to properly implement ControlValueAccessor. */
+  onTouched: () => any = () => {};
+
+  /** Whether the `checked` state has been set to its initial value. */
+  private _isInitialized: boolean = false;
+
+  private _currentAnimationClass: string = '';
+
+  private _currentCheckState: TransitionCheckState = TransitionCheckState.Init;
+
+  private _checked: boolean = false;
+
+  private _indeterminate: boolean = false;
+
+  private _controlValueAccessorChangeFn: (value: any) => void = (value) => {};
+
+  private hasFocus: boolean = false;
+
+  constructor(private _renderer: Renderer, private _elementRef: ElementRef) {}
+
+  /**
+   * Whether the checkbox is checked. Note that setting `checked` will immediately set
+   * `indeterminate` to false.
+   */
+  @Input() get checked() {
+    return this._checked;
+  }
+
+  set checked(checked: boolean) {
+    if (checked != this.checked) {
+      this._indeterminate = false;
+      this._checked = checked;
+      this._transitionCheckState(
+          this._checked ? TransitionCheckState.Checked : TransitionCheckState.Unchecked);
+
+      // Only fire a change event if this isn't the first time the checked property is ever set.
+      if (this._isInitialized) {
+        this._emitChangeEvent();
+      }
+    }
+  }
+
+  /** TODO: internal */
+  ngAfterContentInit() {
+    this._isInitialized = true;
+  }
+
+  /**
+   * Whether the checkbox is indeterminate. This is also known as "mixed" mode and can be used to
+   * represent a checkbox with three states, e.g. a checkbox that represents a nested list of
+   * checkable items. Note that whenever `checked` is set, indeterminate is immediately set to
+   * false. This differs from the web platform in that indeterminate state on native
+   * checkboxes is only remove when the user manually checks the checkbox (rather than setting the
+   * `checked` property programmatically). However, we feel that this behavior is more accommodating
+   * to the way consumers would envision using this component.
+   */
+  @Input() get indeterminate() {
+    return this._indeterminate;
+  }
+
+  set indeterminate(indeterminate: boolean) {
+    this._indeterminate = indeterminate;
+    if (this._indeterminate) {
+      this._transitionCheckState(TransitionCheckState.Indeterminate);
+    } else {
+      this._transitionCheckState(
+          this.checked ? TransitionCheckState.Checked : TransitionCheckState.Unchecked);
+    }
+  }
+
+  /**
+   * Implemented as part of ControlValueAccessor.
+   * TODO: internal
+   */
+  writeValue(value: any) {
+    this.checked = !!value;
+  }
+
+  /**
+   * Implemented as part of ControlValueAccessor.
+   * TODO: internal
+   */
+  registerOnChange(fn: (value: any) => void) {
+    this._controlValueAccessorChangeFn = fn;
+  }
+
+  /**
+   * Implemented as part of ControlValueAccessor.
+   * TODO: internal
+   */
+  registerOnTouched(fn: any) {
+    this.onTouched = fn;
+  }
+
+  private _transitionCheckState(newState: TransitionCheckState) {
+    let oldState = this._currentCheckState;
+    let renderer = this._renderer;
+    let elementRef = this._elementRef;
+
+    if (oldState === newState) {
+      return;
+    }
+    if (this._currentAnimationClass.length > 0) {
+      renderer.setElementClass(elementRef.nativeElement, this._currentAnimationClass, false);
+    }
+
+    this._currentAnimationClass = this._getAnimationClassForCheckStateTransition(
+        oldState, newState);
+    this._currentCheckState = newState;
+
+    if (this._currentAnimationClass.length > 0) {
+      renderer.setElementClass(elementRef.nativeElement, this._currentAnimationClass, true);
+    }
+  }
+
+  private _emitChangeEvent() {
+    let event = new MdCheckboxChange();
+    event.source = this;
+    event.checked = this.checked;
+
+    this._controlValueAccessorChangeFn(this.checked);
+    this.change.emit(event);
+  }
+
+  /**
+   * Informs the component when the input has focus so that we can style accordingly
+   * @internal
+   */
+  onInputFocus() {
+    this.hasFocus = true;
+  }
+
+  /**
+   * Informs the component when we lose focus in order to style accordingly
+   * @internal
+   */
+  onInputBlur() {
+    this.hasFocus = false;
+    this.onTouched();
+  }
+
+  /**
+   * Toggles the `checked` value between true and false
+   */
+  toggle() {
+    this.checked = !this.checked;
+  }
+
+  /**
+   * Event handler for checkbox input element.
+   * Toggles checked state if element is not disabled.
+   * @param event
+   * @internal
+   */
+  onInteractionEvent(event: Event) {
+    // We always have to stop propagation on the change event.
+    // Otherwise the change event, from the input element, will bubble up and
+    // emit its event object to the `change` output.
+    event.stopPropagation();
+
+    if (!this.disabled) {
+      this.toggle();
+    }
+  }
+
+  /** @internal */
+  onInputClick(event: Event) {
+    // We have to stop propagation for click events on the visual hidden input element.
+    // By default, when a user clicks on a label element, a generated click event will be
+    // dispatched on the associated input element. Since we are using a label element as our
+    // root container, the click event on the `checkbox` will be executed twice.
+    // The real click event will bubble up, and the generated click event also tries to bubble up.
+    // This will lead to multiple click events.
+    // Preventing bubbling for the second event will solve that issue.
+    event.stopPropagation();
+  }
+
+  private _getAnimationClassForCheckStateTransition(
+      oldState: TransitionCheckState, newState: TransitionCheckState): string {
+    var animSuffix: string;
+
+    switch (oldState) {
+    case TransitionCheckState.Init:
+      // Handle edge case where user interacts with checkbox that does not have [(ngModel)] or
+      // [checked] bound to it.
+      if (newState === TransitionCheckState.Checked) {
+        animSuffix = 'unchecked-checked';
+      } else {
+        return '';
+      }
+      break;
+    case TransitionCheckState.Unchecked:
+      animSuffix = newState === TransitionCheckState.Checked ?
+          'unchecked-checked' : 'unchecked-indeterminate';
+      break;
+    case TransitionCheckState.Checked:
+      animSuffix = newState === TransitionCheckState.Unchecked ?
+          'checked-unchecked' : 'checked-indeterminate';
+      break;
+    case TransitionCheckState.Indeterminate:
+      animSuffix = newState === TransitionCheckState.Checked ?
+          'indeterminate-checked' : 'indeterminate-unchecked';
+    }
+
+    return `md-checkbox-anim-${animSuffix}`;
+  }
+}
+
+export const MD_CHECKBOX_DIRECTIVES = [MdCheckbox];
diff --git a/src/tdcmp/chip/chip.html b/src/tdcmp/chip/chip.html
new file mode 100644
index 0000000000..a3fd1a9b9c
--- /dev/null
+++ b/src/tdcmp/chip/chip.html
@@ -0,0 +1,13 @@
+<div class="chip" [class.active]=_active>
+    <!-- <div color="#444" size="32" class="avatar">
+        <svg viewBox="0 0 24 24">
+            <path d="M9 11.75c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zm6 0c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37C11.07 8.33 14.05 10 17.42 10c.78 0 1.53-.09 2.25-.26.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8z"></path>
+        </svg>
+    </div> -->
+    <span>
+      <ng-content></ng-content>
+    </span>
+    <svg viewBox="0 0 24 24" (click)="onClose.next(trtue)" >
+        <path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"></path>
+    </svg>
+</div>
diff --git a/src/tdcmp/chip/chip.scss b/src/tdcmp/chip/chip.scss
new file mode 100644
index 0000000000..f5bb4006c1
--- /dev/null
+++ b/src/tdcmp/chip/chip.scss
@@ -0,0 +1,72 @@
+.chip {
+  border: 10px;
+  box-sizing: border-box;
+  display: flex;
+  font-family: Roboto, sans-serif;
+  text-decoration: none;
+  margin: 4px;
+  padding: 0;
+  outline: none;
+  font-size: inherit;
+  font-weight: inherit;
+  border-radius: 16px;
+  white-space: nowrap;
+  width: fit-content;
+  background-color: rgb(224, 224, 224);
+  opacity: 0.5;
+  transform: scaleX(0.5);
+  transition: all 400ms cubic-bezier(0.25, 0.8, 0.25, 1);
+  &.active {
+    opacity: 1;
+    transform: scaleX(1);    
+  }
+  .avatar {
+    color: rgb(68, 68, 68);
+    display: inline-flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 16px;
+    border-radius: 50%;
+    height: 32px;
+    width: 32px;
+    margin-right: -4px;
+    background-color: rgb(188, 188, 188);
+    svg {
+      display: inline-block;
+      color: rgb(68, 68, 68);
+      fill: rgb(68, 68, 68);
+      height: 19.2px;
+      width: 19.2px;
+      transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0;
+      font-size: 19.2px;
+      margin: 6.4px;
+      -webkit-user-select: none;
+    }
+  }
+  span {
+    color: rgba(0, 0, 0, 0.870588);
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 32px;
+    padding-left: 12px;
+    padding-right: 12px;
+    white-space: nowrap;
+    -webkit-user-select: none;
+  }
+  svg {
+    display: inline-block;
+    color: rgba(0, 0, 0, 0.258824);
+    fill: rgba(0, 0, 0, 0.258824);
+    height: 24px;
+    width: 24px;
+    transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0;
+    cursor: pointer;
+    margin: 4px 4px 0 -8px;
+    -webkit-user-select: none;
+    opacity: 1;
+    &:hover {
+      opacity: 0.8;
+      color: white;
+    }
+  }
+}
diff --git a/src/tdcmp/chip/chip.ts b/src/tdcmp/chip/chip.ts
new file mode 100644
index 0000000000..741daac608
--- /dev/null
+++ b/src/tdcmp/chip/chip.ts
@@ -0,0 +1,18 @@
+import { Component, ViewEncapsulation, Output, EventEmitter, AfterViewInit } from '@angular/core';
+
+@Component({
+  selector: 'md-chip',
+  template: require('./chip.html'),
+  styles: [require('./chip.scss')],
+  encapsulation: ViewEncapsulation.None
+})
+export class MdChip {
+  @Output() onClose: EventEmitter<boolean> = new EventEmitter<boolean>();
+
+  private _active: boolean = false;
+
+  ngAfterViewInit() {
+    setTimeout(() => this._active = true, 200);
+  }
+
+}
diff --git a/src/tdcmp/data-table/data_table.scss b/src/tdcmp/data-table/data_table.scss
new file mode 100644
index 0000000000..21f83ef8f3
--- /dev/null
+++ b/src/tdcmp/data-table/data_table.scss
@@ -0,0 +1,134 @@
+@import "../../styles/core/variables";
+@import "../../styles/core/default-theme";
+
+$data-table-font-size: rem(1.3) !default;
+$data-table-header-font-size: rem(1.2) !default;
+$data-table-header-sort-icon-size: rem(1.6) !default;
+
+//TODO (ollwenjones) somewhere support dark themeing for these colors?
+$data-table-header-sorted-icon-hover-color: rgba(#000, 0.38) !default;
+$data-table-divider-color: rgba(#000, 0.12) !default;
+$first-last-cell-padding: rem(0) !default;
+$check-cell-width: rem(1.8) !default;
+
+$data-table-hover-color: md-color($md-grey, 200) !default;
+$data-table-selection-color: md-color($md-grey, 100) !default;
+
+$data-table-dividers: 1px solid $data-table-divider-color !default;
+
+$data-table-row-height: rem(2.800) !default;
+$data-table-last-row-height: rem(2.800) !default;
+$data-table-column-padding: rem(0) !default;
+$data-table-column-spacing: rem(0) !default;
+//column spacing + column padding = the prescribed 56dp
+
+md-data-table, .md-data-table {
+  display: table;
+  border-spacing: 0;
+  border-collapse: collapse;
+  font-size: $data-table-font-size;
+
+  box-sizing: border-box;
+  width: 100%;
+
+  md-checkbox {
+    margin: 0;
+    width: $check-cell-width;
+    vertical-align: middle;
+  }
+  tr {
+    vertical-align: middle;
+    &:last-child {
+      height: $data-table-last-row-height;
+    }
+  }
+  th, td {
+    padding: 0 $data-table-column-spacing 0 $data-table-column-padding;
+    text-align: right;
+
+    &:first-of-type {
+      padding-left: $first-last-cell-padding;
+    }
+
+    &:last-of-type {
+      padding-right: $first-last-cell-padding;
+    }
+
+    &.md-text-cell { text-align: left; }
+
+    &.md-data-check-cell {
+      padding: 0 0 0 $data-table-column-padding;
+      width: $check-cell-width;
+    }
+  }
+  th {
+    font-size: $data-table-header-font-size;
+    font-weight: 600;
+    color: md-color($md-foreground, secondary-text);
+    text-overflow: ellipsis;
+    box-sizing: border-box;
+
+    &.sortable {
+      cursor: pointer;
+    }
+
+    /*
+     TODO (ollwenjones) sorting functionality pending, but these class names
+     were tested, and can be used outside of the library component structures.
+     */
+    &.sorted-ascending,
+    &.sorted-descending {
+      color: md-color($md-foreground, text);
+      &:before {
+        font-family: 'Material Icons';
+        font-size: $data-table-header-sort-icon-size;
+        content: "\e5d8";
+        margin-right: 5px;
+        vertical-align: sub;
+      }
+      &:hover {
+        cursor: pointer;
+        &:before {
+          color: $data-table-header-sorted-icon-hover-color;
+        }
+      }
+    }
+    &.sorted-descending:before {
+      content: "\e5db";
+    }
+  }
+  td {
+    position: relative;
+    vertical-align: middle;
+    height: $data-table-row-height;
+    border-top: $data-table-dividers;
+    border-bottom: $data-table-dividers;
+    box-sizing: border-box;
+    color: md-color($md-foreground, text);
+  }
+  th:first-child, td:first-child {
+    padding-left: 24px;
+  }
+  th:last-child, td:last-child {
+    padding-right: 24px;
+  }
+
+  tr {
+    position: relative;
+    height: $data-table-row-height;
+  }
+
+  tbody, .md-data-tbody {
+    tr {
+      &.selected, &.active {
+        background-color: $data-table-selection-color;
+      }
+
+      &:hover {
+        background-color: $data-table-hover-color;
+        cursor: pointer;
+      }
+    }
+  }
+
+}
diff --git a/src/tdcmp/data-table/data_table.ts b/src/tdcmp/data-table/data_table.ts
new file mode 100644
index 0000000000..52192bbadf
--- /dev/null
+++ b/src/tdcmp/data-table/data_table.ts
@@ -0,0 +1,122 @@
+import {Component, Input, Output, EventEmitter, ContentChild, ContentChildren
+  , QueryList, AfterContentInit, OnDestroy, ViewEncapsulation} from '@angular/core';
+import 'rxjs/add/operator/share';
+import {MdDataTableHeaderSelectableRow, MdDataTableSelectableRow
+  , ITableSelectableRowSelectionChange} from './data_table_selectable_tr';
+
+export * from './data_table_selectable_tr';
+
+/**
+ * Selectable change event data
+ */
+export interface ITableSelectionChange {
+  name: string;
+  allSelected: boolean;
+  values: any[];
+}
+
+@Component({
+  selector: 'md-data-table',
+  template: `<ng-content></ng-content>`,
+  directives: [MdDataTableHeaderSelectableRow, MdDataTableSelectableRow],
+  styles: [require('./data_table.scss')],
+  encapsulation: ViewEncapsulation.None,
+  host: {
+    '[class.md-data-table]': 'true',
+    '[class.md-data-table-selectable]': 'selectable'
+  }
+})
+export class MdDataTable implements AfterContentInit, OnDestroy {
+  @Input()
+  selectable: boolean;
+  @Output()
+  onSelectableAll: EventEmitter<any> = new EventEmitter(false);
+  @Output()
+  onSelectableChange: EventEmitter<any> = new EventEmitter(false);
+
+  @ContentChild(MdDataTableHeaderSelectableRow)
+  _masterRow: MdDataTableHeaderSelectableRow;
+
+  @ContentChildren(MdDataTableSelectableRow, true)
+  _rows: QueryList<MdDataTableSelectableRow>;
+
+  _listeners: EventEmitter<any>[] = [];
+
+  selected: Array<string> = [];
+
+  constructor() {
+    this.onSelectableChange.share();
+  }
+
+  change(event: ITableSelectableRowSelectionChange) {
+    let outputEvent: ITableSelectionChange = {
+      name: 'selectable_change',
+      allSelected: false,
+      values: []
+    };
+    if (event.target instanceof MdDataTableHeaderSelectableRow === true) {
+      if (event.isActive === true) {
+        outputEvent.allSelected = true;
+        outputEvent.values = this._getRowsValues();
+      }
+    } else {
+      outputEvent.values = this.selected.slice(0);
+
+      if (event.isActive === true) {
+        outputEvent.values.push(event.selectableValue);
+      } else {
+        let index = outputEvent.values.indexOf(event.selectableValue);
+        if (index !== -1) {
+          outputEvent.values.splice(index, 1);
+        }
+      }
+    }
+
+    // dispatch change
+    this.selected = outputEvent.values;
+    this.onSelectableChange.emit(outputEvent);
+  }
+
+  /**
+   * @returns {Array<string>}
+   */
+  _getRowsValues(): any[] {
+    return this._rows.toArray()
+      .map((tr: MdDataTableSelectableRow) => tr.selectableValue);
+  }
+
+  _unsubscribeChildren() {
+    this.selected = [];
+    if (this._listeners.length) {
+      this._listeners.forEach(listener => {
+        listener.unsubscribe();
+      });
+      this._listeners = [];
+    }
+  }
+
+  _updateChildrenListener(list: QueryList<MdDataTableSelectableRow>) {
+    this._unsubscribeChildren();
+
+    list.toArray()
+      .map((tr: MdDataTableSelectableRow) => {
+        tr.onChange.subscribe(this.change.bind(this));
+      });
+  }
+
+  ngAfterContentInit() {
+    if (this.selectable === true) {
+      if (!!this._masterRow) {
+        this._masterRow.onChange.subscribe(this.change.bind(this));
+      }
+
+      this._rows.changes.subscribe(this._updateChildrenListener.bind(this));
+      this._updateChildrenListener(this._rows);
+    }
+  }
+
+  ngOnDestroy() {
+    this._unsubscribeChildren();
+  }
+
+}
diff --git a/src/tdcmp/data-table/data_table_selectable_tr.ts b/src/tdcmp/data-table/data_table_selectable_tr.ts
new file mode 100644
index 0000000000..2f0c21bc80
--- /dev/null
+++ b/src/tdcmp/data-table/data_table_selectable_tr.ts
@@ -0,0 +1,149 @@
+import {Component, Output, Input, EventEmitter, Inject, Optional, forwardRef
+  , ElementRef, AfterContentInit, ViewEncapsulation} from '@angular/core';
+import 'rxjs/add/operator/share';
+import 'rxjs/add/operator/map';
+import {MdDataTable} from './data_table';
+
+/**
+ * MdDataTable row
+ */
+export interface ITableSelectableRow {
+  selectableValue: string;
+  onChange: EventEmitter<ITableSelectableRowSelectionChange>;
+  isActive: boolean;
+  change: (event: any) => void;
+  ngAfterContentInit: () => void;
+}
+
+/**
+ * Selectable change event data
+ */
+export interface ITableSelectableRowSelectionChange {
+  name: string;
+  target: ITableSelectableRow;
+  isActive: boolean;
+  selectableValue: string;
+}
+
+export abstract class AbstractMdDataTableSelectableRow
+    implements AfterContentInit, ITableSelectableRow {
+  @Input('selectable-value') selectableValue: string;
+  @Output() onChange: EventEmitter<ITableSelectableRowSelectionChange>
+    = new EventEmitter<ITableSelectableRowSelectionChange>(false);
+  isActive: boolean = false;
+
+  constructor(@Optional()
+              @Inject(forwardRef(() => MdDataTable))
+              public table: MdDataTable, protected _element: ElementRef) {
+    this.onChange.share();
+  }
+
+  /**
+   * Change active status
+   */
+  change(event) {
+    if (event.target.classList.contains('md-checkbox-inner-container')) {
+      event.preventDefault();
+    }
+
+    this.isActive = !this.isActive;
+
+    let changeEvent: ITableSelectableRowSelectionChange = {
+      name: 'selectable_row_change',
+      target: this,
+      isActive: this.isActive,
+      selectableValue: this.selectableValue
+    };
+    this.onChange.emit(changeEvent);
+  }
+
+  ngAfterContentInit() {}
+}
+
+@Component({
+  selector: 'tr[md-data-table-header-selectable-row]',
+  template: `
+        <th class="md-data-check-cell">
+            <md-checkbox [checked]="isActive"></md-checkbox>
+        </th>
+        <ng-content></ng-content>
+    `,
+    styles: [require('./data_table.scss')],
+    encapsulation: ViewEncapsulation.None,
+  host: {
+    '[class.active]': 'isActive',
+    '(click)': 'change($event)'
+  }
+})
+export class MdDataTableHeaderSelectableRow extends AbstractMdDataTableSelectableRow {
+  constructor(@Optional()
+              @Inject(forwardRef(() => MdDataTable))
+              public table: MdDataTable, protected _element: ElementRef) {
+    super(table, _element);
+  }
+
+  _bindListener(): void {
+    this.table.onSelectableChange
+      .map(event => event.allSelected)
+      .subscribe(newActiveStatus => this.isActive = newActiveStatus);
+  }
+
+  ngAfterContentInit() {
+    if (!!this.table) {
+      this._bindListener();
+    }
+  }
+}
+
+@Component({
+  selector: 'tr[md-data-table-selectable-row]',
+  template: `
+        <td class="md-data-check-cell">
+          <md-checkbox [checked]="isActive"></md-checkbox>
+        </td>
+        <ng-content></ng-content>
+    `,
+    styles: [require('./data_table.scss')],
+    encapsulation: ViewEncapsulation.None,
+  host: {
+    '[class.active]': 'isActive',
+    '(click)': 'change($event)'
+  }
+})
+export class MdDataTableSelectableRow extends AbstractMdDataTableSelectableRow {
+  constructor(@Optional()
+              @Inject(forwardRef(() => MdDataTable))
+              public table: MdDataTable, protected _element: ElementRef) {
+    super(table, _element);
+  }
+
+  /**
+   * @param {any} element
+   *
+   * @returns {string}
+   */
+  _getIndex(element): string {
+    return Array.prototype.indexOf.call(element.parentNode.children, element).toString();
+  }
+
+  _bindListener(): void {
+    this.table.onSelectableChange
+      .map(event => {
+        return event.values !== undefined &&
+          event.values.length &&
+          (event.values.findIndex((value: string) => value === this.selectableValue)) !== -1;
+      })
+      .subscribe(newActiveStatus => this.isActive = newActiveStatus);
+  }
+
+  ngAfterContentInit() {
+    let element = this._element.nativeElement;
+    if (this.selectableValue === undefined) {
+      this.selectableValue = this._getIndex(element);
+    }
+
+    if (!!this.table) {
+      this._bindListener();
+    }
+  }
+}
diff --git a/src/tdcmp/data-table/index.ts b/src/tdcmp/data-table/index.ts
new file mode 100644
index 0000000000..608db9baf8
--- /dev/null
+++ b/src/tdcmp/data-table/index.ts
@@ -0,0 +1,2 @@
+export * from './data_table';
+export * from './data_table_selectable_tr';
diff --git a/src/tdcmp/data-table/readme.md b/src/tdcmp/data-table/readme.md
new file mode 100644
index 0000000000..be636a41c4
--- /dev/null
+++ b/src/tdcmp/data-table/readme.md
@@ -0,0 +1,66 @@
+# MdDataTable
+MdDataTable is an enhancment of classic data tables.
+
+## Basic data table
+### Classes
+| Name | Target | Description |
+| --- | --- | --- |
+| md-data-table | table | Style table, without using md-data-table component |
+| sortable | th | mark column as sortable |
+| sorted-ascending | th | mark column as sorted ascending |
+| sorted-descending | th | mark column as sorted descending |
+| md-text-cell | thead th, tbody td | Declare a cell as non-numeric and left align its text. |
+
+## Selectable data table
+### Properties
+| Name | Target | Type | Description |
+| --- | --- | --- | --- |
+| selectable | md-data-table | boolean | Enable listeners to children's checkbox.   
+
+### Events
+| Name | Description |
+| --- | --- |
+| onSelectableChange | Emitted when the user select or unselect a row |
+
+## Selectable header row
+### Properties
+| Name | Target | Type | Description |
+| --- | --- | --- | --- |
+| md-data-table-header-selectable-row | thead tr | boolean | Enable the master checkbox on header. |
+
+### Events
+| Name | Description |
+| --- | --- |
+| onChange | Emitted when the user check or uncheck the master checkbox |
+
+## Selectable header row
+### Properties
+| Name | Target | Type | Description |
+| --- | --- | --- | --- |
+| md-data-table-selectable-row | tbody tr | boolean | Enable a checkbox for this row. |
+| selectable-value | tbody tr | string | value of the checkbox. If it's not set the checkbox's value will be the index of the row. |
+
+### Events
+| Name | Description |
+| --- | --- |
+| onChange | Emitted when the user check or uncheck the checkbox |
+
+## Examples
+```
+<md-data-table [selectable]="true">
+  <thead>
+  <tr md-data-table-header-selectable-row>
+    <th class="md-text-cell">Material</th>
+    <th>Quantity</th>
+    <th>Unit price</th>
+  </tr>
+  </thead>
+  <tbody>
+  <tr *ngFor="let material of materials"  md-data-table-selectable-row [selectable-value]="material.id">
+    <td class="md-text-cell">{{ material.name }}</td>
+    <td>{{ material.quantity }}</td>
+    <td>{{ material.price }}</td>
+  </tr>
+  </tbody>
+</md-data-table>
+```
diff --git a/src/tdcmp/dateTimePicker/calendar/calendar-content.html b/src/tdcmp/dateTimePicker/calendar/calendar-content.html
new file mode 100644
index 0000000000..7f93f78157
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/calendar/calendar-content.html
@@ -0,0 +1,41 @@
+<div style="display: flex; align-content: space-between; justify-content: space-between; flex-direction: column; font-size: 12px; font-weight: 400; padding: 0px 8px; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; width: auto;">
+<div style="display: flex; justify-content: space-between; height: 48px; background-color: inherit;">
+  <button (click)="changeMonth(-1)" style="border: 10px; box-sizing: border-box; display: inline-block; font-family: Roboto, sans-serif; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer; text-decoration: none; outline: none; font-size: 0px; font-weight: inherit; transform: translate3d(0px, 0px, 0px); position: relative; overflow: visible; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; padding: 12px; width: 48px; height: 48px; background: none;">
+    <div>
+      <svg viewBox="0 0 24 24" style="display: inline-block; fill: rgba(0, 0, 0, 0.870588); height: 24px; width: 24px; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; -webkit-user-select: none;">
+        <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path>
+      </svg>
+    </div>
+  </button>
+  <div style="position: relative; overflow: hidden; height: 100%; font-size: 14px; font-weight: 500; text-align: center; width: 100%;">
+    <div direction="up" style="position: absolute; height: 100%; width: 100%; top: 0px; left: 0px; transition: transform 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms, opacity 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;">
+      <div style="height: inherit; padding-top: 12px;">{{_displayDate | date:"MMMM"}} {{_displayDate.getFullYear()}}</div>
+    </div>
+  </div>
+  <button (click)="changeMonth(1)" style="border: 10px; box-sizing: border-box; display: inline-block; font-family: Roboto, sans-serif; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer; text-decoration: none; outline: none; font-size: 0px; font-weight: inherit; transform: translate3d(0px, 0px, 0px); position: relative; overflow: visible; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; padding: 12px; width: 48px; height: 48px; background: none;">
+    <div>
+      <svg viewBox="0 0 24 24" style="display: inline-block; fill: rgba(0, 0, 0, 0.870588); height: 24px; width: 24px; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; -webkit-user-select: none;">
+        <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path>
+      </svg>
+    </div>
+  </button>
+</div>
+
+<div calendar-days>
+  <span>M</span><span>T</span><span>W</span><span>T</span><span>F</span><span>S</span><span>S</span></div>
+<div style="position: relative; overflow: hidden; height: 214px;">
+  <div style="position: absolute; height: 100%; width: 100%; top: 0px; left: 0px; transition: transform 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms, opacity 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;">
+    <div style="display: flex; flex-direction: column; justify-content: flex-start; font-weight: 400; height: 228px; line-height: 2; position: relative; text-align: center;">
+      <div *ngFor="let w of monthCalendar" style="display: flex; flex-direction: row; justify-content: space-around; height: 34px; margin-bottom: 2px;">
+        <div *ngFor="let d of w" style="box-sizing: border-box; font-weight: 400; padding: 4px 0px; position: relative; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); width: 42px;">
+          <span *ngIf="d == undefined"></span>
+          <button day-button *ngIf="d != undefined" (click)="changeDate($event, d)" [class.selected] = "_selectedDate.toLocaleDateString() === d.toLocaleDateString()">
+            <div></div>
+            <span>{{d | date:"dd"}}</span>
+          </button>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+</div>
diff --git a/src/tdcmp/dateTimePicker/calendar/calendar-content.scss b/src/tdcmp/dateTimePicker/calendar/calendar-content.scss
new file mode 100644
index 0000000000..4bde918705
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/calendar/calendar-content.scss
@@ -0,0 +1,54 @@
+$swift-ease-out-duration: 0.4s !default;
+$swift-ease-out-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default;
+$swift-ease-out: all $swift-ease-out-duration $swift-ease-out-timing-function !default;
+
+    button[day-button] {
+        border: 10px;
+        box-sizing: border-box;
+        display: inline-block;
+        font-family: Roboto, sans-serif;
+        cursor: pointer;
+        text-decoration: none;
+        outline: none;
+        font-size: inherit;
+        font-weight: 400;
+        padding: 4px 0;
+        position: relative;
+        width: 42px;
+        background: none;
+        div {
+            border-radius: 50%;
+            height: 34px;
+            left: 4px;
+            opacity: 0;
+            position: absolute;
+            top: 0;
+            transform: scale(0);
+            transition:  $swift-ease-out;
+            width: 34px;
+            background-color: #00648c;
+        }
+        span {
+            color: rgba(0, 0, 0, 0.870588);
+            font-weight: 400;
+            position: relative;
+        }
+        &.selected {
+            div {
+                opacity: 1;
+                transform: scale(1);
+            }
+            span {
+                color: rgb(255, 255, 255);
+            }
+        }
+        &:hover {
+          div {
+              opacity: 0.6;
+              transform: scale(1);
+          }
+          span {
+              color: rgb(255, 255, 255);
+          }
+        }
+    }
diff --git a/src/tdcmp/dateTimePicker/calendar/calendar-content.ts b/src/tdcmp/dateTimePicker/calendar/calendar-content.ts
new file mode 100644
index 0000000000..bbfa50513b
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/calendar/calendar-content.ts
@@ -0,0 +1,52 @@
+import {Component, ViewEncapsulation, ChangeDetectionStrategy, Input, Output,
+  EventEmitter} from '@angular/core';
+import { DateUtils } from '../../tools/dateUtils';
+
+@Component({
+  selector: 'md-calendar-content',
+  template: require('./calendar-content.html'),
+  styles: [require('./calendar-content.scss')],
+  encapsulation: ViewEncapsulation.None,
+  changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class MdCalendarContent {
+
+@Input()
+get date(): Date {
+  return this._date;
+}
+set date(value) {
+  this._date = value;
+  this._selectedDate = value;
+
+}
+@Output()
+dateChanged: EventEmitter<Date> = new  EventEmitter<Date>();
+
+@Input()
+set displayDate(value: Date) {
+  this._displayDate = value;
+  let firstDayOfWeek = DateUtils.getFirstDayOfWeek();
+  this.monthCalendar = DateUtils.getWeekArray(this._displayDate, firstDayOfWeek.getDay() + 1);
+}
+
+
+monthCalendar: Array<Array<Date>>;
+
+private _date: Date;
+private _displayDate: Date;
+private _selectedDate: Date;
+
+  constructor () {}
+
+
+  changeDate(e: any, d: Date) {
+    this._selectedDate = d;
+    this.dateChanged.emit(d);
+  }
+
+  changeMonth(m) {
+    this.displayDate = DateUtils.addMonths(this._displayDate, m);
+  }
+
+}
diff --git a/src/tdcmp/dateTimePicker/calendar/calendar-year.html b/src/tdcmp/dateTimePicker/calendar/calendar-year.html
new file mode 100644
index 0000000000..69e8cb11c7
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/calendar/calendar-year.html
@@ -0,0 +1,7 @@
+<div class="yearcontainer">
+  <div class="yearborder">
+    <div>
+      <button *ngFor="let y of years" class="year" [class.selected]="y==year" (click)="year=y"><span>{{y}}</span></button>
+    </div>
+  </div>
+</div>
diff --git a/src/tdcmp/dateTimePicker/calendar/calendar-year.scss b/src/tdcmp/dateTimePicker/calendar/calendar-year.scss
new file mode 100644
index 0000000000..d0c347e1a7
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/calendar/calendar-year.scss
@@ -0,0 +1,55 @@
+.yearcontainer {
+  display: flex;
+  justify-content: space-between;
+  flex-direction: column;
+  height: 272px;
+  margin-top: 10px;
+  overflow: hidden;
+  width: 310px;
+}
+.yearborder {
+  height: inherit;
+  line-height: 35px;
+  overflow-x: hidden;
+  overflow-y: scroll;
+  position: relative;
+  display: flex;
+  //flex-direction: column;
+  justify-content: center;
+  background-color: rgb(255, 255, 255);
+}
+.year {
+  border: 10px;
+  box-sizing: border-box;
+  display: block;
+  font-family: Roboto, sans-serif;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+  cursor: pointer;
+  text-decoration: none;
+  outline: none;
+  font-size: 14px;
+  font-weight: inherit;
+  margin: 0 auto;
+  position: relative;
+  text-align: center;
+  line-height: inherit;
+  background: none;
+  span {
+    align-self: center;
+    color: rgba(0, 0, 0, 0.870588);
+    font-size: 17px;
+    font-weight: 400;
+    position: relative;
+    top: -1px;
+  }
+  &.selected {
+    span {
+      align-self: center;
+      color: rgb(0, 188, 212);
+      font-size: 26px;
+      font-weight: 500;
+      position: relative;
+      top: -1px;
+    }
+  }
+}
diff --git a/src/tdcmp/dateTimePicker/calendar/calendar-year.ts b/src/tdcmp/dateTimePicker/calendar/calendar-year.ts
new file mode 100644
index 0000000000..aa7f7cd5d2
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/calendar/calendar-year.ts
@@ -0,0 +1,71 @@
+import {Component, ViewEncapsulation, ChangeDetectionStrategy
+  , ViewChild, Input, Output, EventEmitter,  AfterViewInit
+, ElementRef, Renderer  } from '@angular/core';
+import { DateUtils } from '../../tools/dateUtils';
+
+@Component({
+  selector: 'md-calendar-year',
+  template: require('./calendar-year.html'),
+  styles: [require('./calendar-year.scss')],
+  encapsulation: ViewEncapsulation.None,
+  changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class MdCalendarYear implements AfterViewInit {
+  @Input()
+  get date(): Date {
+    return this._date;
+  }
+  set date(value: Date) {
+    this._date = value;
+    if (this._year === 0) {
+      this.year = value.getFullYear();
+      for (let y = this.year - 30; y <= this.year + 30; y++) {
+        this.years.push(y);
+      }
+    } else {
+      this.dateChanged.emit(this.date);
+    }
+
+  }
+
+  @Output()
+  dateChanged: EventEmitter<Date> = new  EventEmitter<Date>();
+
+
+    get year(): number {
+      return this._year;
+    }
+    set year(value: number) {
+        this._year = value;
+        this.years = [];
+        for (let y = this._year - 30; y <= this._year + 30; y++) {
+          this.years.push(y);
+        }
+        this.scrollToYear();
+        this.date = new Date(value, this.date.getMonth(), this.date.getDate());
+    }
+
+
+    years: Array<number> = [];
+
+    private _date: Date;
+    private _year: number = 0;
+    private _root: Element;
+
+
+    constructor(private _element: ElementRef, private _renderer: Renderer) {
+      this._root = _element.nativeElement;
+    }
+
+    ngAfterViewInit() {
+        this.scrollToYear();
+}
+
+
+    scrollToYear() {
+
+      let yb = this._root.getElementsByClassName('yearborder')[0];
+      let index = this.years.indexOf(this._year);
+      yb.scrollTop = 33 * index + 39;
+    }
+}
diff --git a/src/tdcmp/dateTimePicker/calendar/calendar.html b/src/tdcmp/dateTimePicker/calendar/calendar.html
new file mode 100644
index 0000000000..1d101ba7a4
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/calendar/calendar.html
@@ -0,0 +1,42 @@
+<div class="calendar" [class.active]=active [class.upper]=upper>
+  <div calendar-border>
+    <div calendar-inner-border>
+      <div calendar-text-color>
+
+        <div calendar-upper-block>
+          <div calendar-year-block>
+            <div class="fullabsolute">
+              <div [class.defaultcursor]=showYears [class.pointer]=!showYears (click)="showYears=true">{{date.getFullYear()}}</div>
+            </div>
+          </div>
+          <div calendar-date-block>
+            <div class="fullabsolute">
+              <div [class.defaultcursor]=!showYears [class.pointer]=showYears (click)="showYears=false">{{date | date:"EEE"}}, {{date | date:"MMM"}} {{date.getDate()}}</div>
+            </div>
+          </div>
+        </div>
+
+
+        <div style="display: flex; flex-direction: column;">
+
+          <md-calendar-year *ngIf=showYears [(date)]="date" (dateChanged)="date = $event"></md-calendar-year>
+          <md-calendar-content *ngIf=!showYears [(date)]="date" (dateChanged)="date = $event" [displayDate]="displayDate"></md-calendar-content>
+
+
+          <div style="display: flex; flex-direction: row; justify-content: flex-end; margin: 0px; max-height: 48px; padding: 0px;">
+            <button (click)="abort()" class="okcancelbutton">
+              <div><span style="position: relative; padding-left: 16px; padding-right: 16px; vertical-align: middle; letter-spacing: 0px; text-transform: uppercase; font-weight: 500; font-size: 14px;">Cancel</span></div>
+            </button>
+            <button (click)="selectDate()" class="okcancelbutton">
+              <div><span style="position: relative; padding-left: 16px; padding-right: 16px; vertical-align: middle; letter-spacing: 0px; text-transform: uppercase; font-weight: 500; font-size: 14px;">OK</span></div>
+            </button>
+          </div>
+
+        </div>
+
+      </div>
+    </div>
+  </div>
+</div>
+  <div *ngIf=fullpage style="position: fixed; height: 100%; width: 100%; top: 0px; left: 0px; opacity: 1; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); will-change: opacity; transform: translateZ(0px); transition: left 0ms cubic-bezier(0.23, 1, 0.32, 1) 0ms, opacity 400ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; z-index: 1400; background-color: rgba(0, 0, 0, 0.541176);">
+  </div>
diff --git a/src/tdcmp/dateTimePicker/calendar/calendar.scss b/src/tdcmp/dateTimePicker/calendar/calendar.scss
new file mode 100644
index 0000000000..4cbe789e6c
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/calendar/calendar.scss
@@ -0,0 +1,151 @@
+md-calendar {
+
+z-index: 3000;
+
+$swift-ease-out-duration: 0.4s !default;
+$swift-ease-out-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default;
+$swift-ease-out: all $swift-ease-out-duration $swift-ease-out-timing-function !default;
+$swift-ease-out-quick: all 0.2 $swift-ease-out-timing-function !default;
+
+.calendar {
+  box-sizing: border-box;
+  transition: $swift-ease-out;
+  transform: scaleY(0);
+  transform-origin: right top;
+  position: relative;
+  width: 310px;
+  max-width: 768px;
+  margin: 0 auto;
+  z-index: 3000;
+  opacity: 0;
+  top: -5px;
+&.upper {
+  transform-origin: right bottom;
+}
+  &.active {
+      transform: scaleY(1.0);
+      opacity: 1;
+  }
+  &:not(.active) {
+    transition: $swift-ease-out-quick;
+      transform: scaleY(0);
+      opacity: 0;
+  }
+
+  div[calendar-border] {
+    color: rgba(0, 0, 0, 0.870588);
+    transition: $swift-ease-out;
+    box-sizing: border-box;
+    font-family: Roboto, sans-serif;
+    box-shadow: rgba(0, 0, 0, 0.247059) 0 14px 45px, rgba(0, 0, 0, 0.219608) 0 10px 18px;
+    border-radius: 2px;
+    background-color: rgb(255, 255, 255);
+    div[calendar-inner-border] {
+      font-size: 16px;
+      color: rgba(0, 0, 0, 0.6);
+      padding: 0;
+      box-sizing: border-box;
+      overflow-y: hidden;
+      min-height: 434px;
+      min-width: 310px;
+      max-height: 859px;
+      div[calendar-text-color] {
+        color: rgba(0, 0, 0, 0.870588);
+        width: 310px;
+      }
+    }
+  }
+  div[calendar-days] {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    font-weight: 500;
+    height: 20px;
+    line-height: 15px;
+    opacity: 0.5;
+    text-align: center;
+    span {
+      width: 42px;
+    }
+  }
+  div[calendar-upper-block] {
+    width: 270px;
+    height: auto;
+    float: none;
+    font-weight: 700;
+    display: inline-block;
+    border-top-left-radius: 2px;
+    border-top-right-radius: 2px;
+    border-bottom-left-radius: 0;
+    color: rgb(255, 255, 255);
+    padding: 20px;
+    background-color: #00648c;
+    div[calendar-year-block] {
+      position: relative;
+      overflow: hidden;
+      height: 16px;
+      margin: 0 0 10px;
+      font-size: 16px;
+      font-weight: 500;
+      line-height: 16px;
+      opacity: 0.7;
+      transition: $swift-ease-out;
+    }
+  }
+  div[calendar-date-block] {
+    position: relative;
+    overflow: hidden;
+    height: 38px;
+    display: block;
+    font-size: 36px;
+    line-height: 36px;
+    opacity: 1;
+    width: 100%;
+    font-weight: 500;
+  }
+  .pointer {
+    cursor: pointer;
+  }
+  .defaultcursor {
+    cursor: default;
+    width: 100%;
+    display: block;
+  }
+  .fullabsolute {
+    position: absolute;
+    height: 100%;
+    width: 100%;
+    top: 0;
+    left: 0;
+  }
+  .okcancelbutton {
+    border: 10px;
+    box-sizing: border-box;
+    display: inline-block;
+    font-family: Roboto, sans-serif;
+    cursor: pointer;
+    text-decoration: none;
+    outline: none;
+    font-size: inherit;
+    font-weight: inherit;
+    transform: translate3d(0px, 0px, 0px);
+    height: 36px;
+    line-height: 36px;
+    min-width: 64px;
+    color: #00648c;
+    transition: $swift-ease-out;
+    border-radius: 2px;
+    position: relative;
+    overflow: hidden;
+    padding: 0;
+    margin: 4px 8px 8px 0;
+    text-align: center;
+    max-height: 36px;
+    -webkit-user-select: none;
+    background-color: rgba(0, 0, 0, 0);
+    &:hover {
+      background-color: rgba(153, 153, 153, 0.2);
+    }
+  }
+}
+}
diff --git a/src/tdcmp/dateTimePicker/calendar/calendar.ts b/src/tdcmp/dateTimePicker/calendar/calendar.ts
new file mode 100644
index 0000000000..1a5a81e109
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/calendar/calendar.ts
@@ -0,0 +1,60 @@
+import {Component, ViewEncapsulation, ChangeDetectionStrategy
+  , ViewChild, Input, Output, EventEmitter, AfterViewInit  } from '@angular/core';
+import { MdCalendarContent } from './calendar-content';
+import { MdCalendarYear } from './calendar-year';
+import { DateUtils } from '../../tools/dateUtils';
+
+@Component({
+  selector: 'md-calendar',
+  template: require('./calendar.html'),
+  styles: [require('./calendar.scss')],
+  directives: [MdCalendarContent, MdCalendarYear],
+  encapsulation: ViewEncapsulation.None,
+  changeDetection: ChangeDetectionStrategy.Default
+
+})
+export class MdCalendar implements AfterViewInit {
+  @Input() active: boolean;
+  @Input()
+  get date(): Date {
+    return this._date;
+  }
+  set date(value: Date) {
+    if (!value) this._date = new Date(); else this._date = value;
+    this.displayDate = this._date;
+  }
+
+  @Output()
+  dateChange: EventEmitter<Date> = new EventEmitter<Date>();
+
+  displayDate: Date = undefined;
+  showYears: boolean = false;
+  fullpage: boolean = false;
+  @Input() upper: boolean = false;
+
+  private _date: Date = undefined;
+  private _initDate: Date;
+  constructor() { }
+
+  ngAfterViewInit() {
+    this._initDate = this._date;
+  }
+
+
+  selectDate() {
+    this._initDate = this._date;
+    this.dateChange.emit(this.date);
+  }
+
+  abort() {
+    this.date = this._initDate;
+    this.dateChange.emit(undefined);
+  }
+
+  resetDate() {
+    this.date = this._initDate;
+  }
+}
+
+
+export const MD_CALENDAR_DIRECTIVES: any[] = [MdCalendar];
diff --git a/src/tdcmp/dateTimePicker/dateTimePicker.html b/src/tdcmp/dateTimePicker/dateTimePicker.html
new file mode 100644
index 0000000000..b3440e79f6
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/dateTimePicker.html
@@ -0,0 +1,13 @@
+<div>
+  <md-input
+    placeholder={{placeHolder}}
+    [(ngModel)]=internalDate
+    (click)=clicked($event)
+    [required]="required"
+    style="width:100%"
+    >
+    <md-hint align="start"><span><ng-content select="error"></ng-content></span></md-hint>
+  </md-input>
+  <md-calendar style="position:fixed; top:0; left:0" [(date)]="CalendarDate" (dateChanged)="date = $event"
+  [hidden]="!displayCalendar" [active]="active" [upper]=upper> </md-calendar>
+</div>
diff --git a/src/tdcmp/dateTimePicker/dateTimePicker.scss b/src/tdcmp/dateTimePicker/dateTimePicker.scss
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/tdcmp/dateTimePicker/dateTimePicker.ts b/src/tdcmp/dateTimePicker/dateTimePicker.ts
new file mode 100644
index 0000000000..f2e8ae0998
--- /dev/null
+++ b/src/tdcmp/dateTimePicker/dateTimePicker.ts
@@ -0,0 +1,224 @@
+import {Component, Input, Output, EventEmitter, HostListener
+  , ElementRef, Renderer, AfterContentInit, OnDestroy, ViewChild
+  , forwardRef, Provider, ViewEncapsulation } from '@angular/core';
+import { DateFormatter } from '@angular/common/src/facade/intl';
+import { MdCalendar } from './calendar/calendar';
+import {BooleanFieldValue} from '@angular2-material/core/annotations/field-value';
+import {
+  NG_VALUE_ACCESSOR,
+  ControlValueAccessor,
+  NgModel
+} from '@angular/forms';
+
+export const MD_DATEPICKER_CONTROL_VALUE_ACCESSOR = new Provider(NG_VALUE_ACCESSOR, {
+  useExisting: forwardRef(() => MDDateTimePicker),
+  multi: true
+});
+
+const noop = () => {};
+
+export class MdDateChange {
+  source: MDDateTimePicker;
+  oldDate: Date;
+  newDate: Date;
+}
+
+
+@Component({
+  selector: 'md-datetimepicker',
+  template: require('./dateTimePicker.html'),
+  styles: [require('./dateTimePicker.scss')],
+  providers: [MD_DATEPICKER_CONTROL_VALUE_ACCESSOR],
+  directives: [MdCalendar],
+  encapsulation: ViewEncapsulation.None
+})
+export class MDDateTimePicker implements AfterContentInit, OnDestroy, ControlValueAccessor {
+  @ViewChild(MdCalendar) calendar: MdCalendar;
+
+  upper: boolean = false;
+
+  @Input()
+  get date(): Date {
+    return this._date;
+  }
+  set date(value: Date) {
+    this._date = value;
+    if (value) {
+      this._internalDate = DateFormatter.format(this._date, 'fr-FR', 'dd/MM/yyyy');
+    } else this._internalDate = '';
+
+  }
+
+get CalendarDate(): Date
+{
+  return this._calendarDate;
+}
+set CalendarDate(value: Date) {
+  let ev = new MdDateChange();
+  ev.source = this;
+  ev.oldDate = this._calendarDate;
+  ev.newDate = value;
+  this._calendarDate = value;
+  this.change.emit(ev);
+  this.date = value;
+  this.dateChange.emit(value);
+  this._onChangeCallback(value);
+  if (this._internalDateChanged) {
+    this._internalDateChanged = false;
+    return;
+  }
+  this.displayCalendar = false;
+  this.active = false;
+}
+
+
+  @Input() placeHolder: string;
+
+  @Output() dateChange: EventEmitter<Date> = new EventEmitter<Date>();
+  @Output() change: EventEmitter<MdDateChange> = new EventEmitter<MdDateChange>();
+  @Input() @BooleanFieldValue() required: boolean = false;
+
+  displayCalendar: boolean = false;
+
+  get internalDate(): string {
+    return this._internalDate;
+  }
+  set internalDate (value: string) {
+    this._internalDate = value;
+    this._internalDateChanged = true;
+    if (!value) {
+      this.CalendarDate = undefined;
+      return;
+    }
+    let d: Date = this.checkDate(value);
+    if (d) this.CalendarDate = d;
+  }
+
+  checkDate(v: string): Date {
+    let a = v.split('/');
+    if (a.length !== 3) return undefined;
+    if (a[0].length !== 2 || a[1].length !== 2 || a[2].length !== 4) return undefined;
+
+    let d = Date.parse(a[1] + '/' + a[0] + '/' + a[2]);
+    if (isNaN(d) || d < 0) return undefined;
+    return new Date(d);
+  }
+
+  @HostListener('body:click', ['$event'])
+  closeMenu($event: MouseEvent) {
+    if (!this.displayCalendar) return;
+    if (this._justClicked) {
+      this._justClicked = false;
+      return;
+    }
+    if (!this.isInElement(this._calElement, $event.clientX, $event.clientY)) {
+      this.calendar.resetDate();
+      this.displayCalendar = false;
+      this.active = false;
+    }
+
+  }
+
+  @HostListener('window:resize', ['$event.target'])
+  setCalendarPosition() {
+    let rec = this._inputElement.getBoundingClientRect();
+    let wh = window.innerHeight;
+
+
+    if (rec.bottom + 3 + 410 < wh) {
+      this._renderer.setElementStyle(this._calElement, 'top', rec.bottom + 3 + 'px');
+      this._renderer.setElementStyle(this._calElement, 'left', rec.left + 'px');
+      this.upper = false;
+      return;
+    }
+
+     if (rec.bottom > 434 ) {
+       this._renderer.setElementStyle(this._calElement, 'top', rec.bottom  - 490 + 'px');
+       this._renderer.setElementStyle(this._calElement, 'left', rec.left + 'px');
+       this.upper = true;
+      return;
+    }
+
+    this.upper = false;
+    this._renderer.setElementStyle(this._calElement, 'top', '30px');
+    this._renderer.setElementStyle(this._calElement, 'left', '50%');
+  }
+
+
+  private _calendarDate: Date
+  private _date: Date = undefined;
+  private _calElement: Element;
+  private _inputElement: Element;
+  private _isclicked: boolean = false;
+  private _overlay: Element;
+  private _internalDate: string;
+  private _justClicked: boolean = false;
+  private _internalDateChanged: boolean = false;
+  private active: boolean = false;
+  private _isInitialized: boolean = false;
+
+  private _onTouchedCallback: () => void = noop;
+  private _onChangeCallback: (_: any) => void = noop;
+
+constructor(private _element: ElementRef, private _renderer: Renderer) {
+
+}
+
+ngAfterContentInit() {
+  this._overlay = document.getElementsByClassName('md-overlay-container')[0];
+  let root: Element = this._element.nativeElement;
+  this._calElement = root.getElementsByTagName('md-calendar')[0];
+  this._inputElement = root.getElementsByTagName('md-input')[0];
+
+  this._overlay.appendChild(this._calElement);
+  this._isInitialized = true;
+  this._calendarDate = this._date;
+}
+
+
+
+  clicked($event) {
+    if (this.displayCalendar) return;
+    this.setCalendarPosition();
+    this._justClicked = true;
+    this.displayCalendar = true;
+    setTimeout(() => this.active = true, 10);
+  }
+
+  isInElement(element, x, y): boolean {
+     let rect = element.getBoundingClientRect();
+
+     return rect.top <= y &&
+       y <= rect.top + rect.height &&
+       rect.left <= x &&
+       x <= rect.left + rect.width;
+   }
+
+
+
+     writeValue(value: any) {
+       if (!value) {
+        this.internalDate = value;
+        return;
+       }
+       if (value instanceof Date) this.date = value; else {
+         this.internalDate = value;
+       }
+     }
+
+     registerOnChange(fn: any) {
+       this._onChangeCallback = fn;
+     }
+
+     registerOnTouched(fn: any) {
+       this._onTouchedCallback = fn;
+     }
+
+
+
+   ngOnDestroy() {
+     this._overlay.removeChild(this._calElement);
+   }
+}
+
+export const MD_DATETIMEPICKER_DIRECTIVES: any[] = [MDDateTimePicker];
diff --git a/src/tdcmp/dialog/dialog.html b/src/tdcmp/dialog/dialog.html
new file mode 100644
index 0000000000..93e01dcfeb
--- /dev/null
+++ b/src/tdcmp/dialog/dialog.html
@@ -0,0 +1,30 @@
+<div class="tddialog" [class.active]=active>
+  <div style="position: relative;">
+    <div class="border">
+      <div style=" color: rgba(0, 0, 0, 0.870588); transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; box-sizing: border-box; font-family: Roboto, sans-serif; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); box-shadow: rgba(0, 0, 0, 0.247059) 0px 14px 45px, rgba(0, 0, 0, 0.219608) 0px 10px 18px; border-radius: 2px; background-color: rgb(255, 255, 255);">
+        <h3 style="margin: 0px; padding: 24px 24px 20px; color: rgba(0, 0, 0, 0.870588); font-size: 22px; line-height: 32px; font-weight: 400; border-bottom-style: none;">
+          <div layout="row">
+            <div flex style="white-space: nowrap;">
+              <ng-content select="md-dialog-title"></ng-content>
+            </div>
+            <div flex></div>
+            <div flex style="text-align:right">
+                <md-icon class="md-24 close"  (click)="closeDialog()">close</md-icon>
+            </div>
+        </div>
+        </h3>
+        <div class="inkbartitle"></div>
+        <div style="font-size: 16px; color: rgba(0, 0, 0, 0.6); padding: 0px 24px 24px; box-sizing: border-box; overflow-y: hidden; max-height: 731px;">
+          <ng-content></ng-content>
+        </div>
+        <div class="inkbarfooter"></div>
+        <div class="footer">
+            <ng-content select="md-dialog-footer"></ng-content>
+        </div>
+      </div>
+    </div>
+  </div>
+
+</div>
+<div class="overlay" [class.active]=active>
+</div>
diff --git a/src/tdcmp/dialog/dialog.scss b/src/tdcmp/dialog/dialog.scss
new file mode 100644
index 0000000000..29a286ad3f
--- /dev/null
+++ b/src/tdcmp/dialog/dialog.scss
@@ -0,0 +1,116 @@
+$swift-ease-out-duration: 0.4s !default;
+$swift-ease-out-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default;
+$swift-ease-out: all $swift-ease-out-duration $swift-ease-out-timing-function !default;
+.tddialog {
+  opacity: 0;
+  transition: $swift-ease-out;
+  transform: scale(0.2);
+  position: fixed;
+  box-sizing: border-box;
+  z-index: 1500;
+  top: 20%;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  //display: none;
+  .border {
+    box-sizing: border-box;
+    position: relative;
+    max-width: 768px;
+    margin: 0 auto;
+    z-index: 1500;
+    opacity: 1;
+  }
+  .inkbartitle {
+    position: absolute;
+    top: 60px;
+    left: 15px;
+    height: 1px;
+    background-color: #169dd4;
+    width: calc(100% - 30px);
+  }
+  .footer {
+    box-sizing: border-box;
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+    padding: 8px;
+    width: 100%;
+    text-align: right;
+    margin-top: 0;
+    border-top-style: none;
+    button {
+      border: 10px;
+      box-sizing: border-box;
+      display: inline-block;
+      font-family: Roboto, sans-serif;
+      cursor: pointer;
+      text-decoration: none;
+      margin: 0;
+      padding: 0;
+      outline: none;
+      font-size: inherit;
+      font-weight: inherit;
+      transform: translate3d(0px, 0px, 0px);
+      height: 36px;
+      line-height: 36px;
+      min-width: 88px;
+      color: rgb(0, 188, 212);
+      transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1);
+      border-radius: 2px;
+      position: relative;
+      overflow: hidden;
+      text-align: center;
+      -webkit-user-select: none;
+      background-color: rgba(0, 0, 0, 0);
+      &:hover {
+        background-color: rgba(153, 153, 153, 0.2);
+      }
+      span {
+        position: relative;
+        padding-left: 16px;
+        padding-right: 16px;
+        vertical-align: middle;
+        letter-spacing: 0;
+        text-transform: uppercase;
+        font-weight: 500;
+        font-size: 14px;
+      }
+    }
+
+
+  }
+  .inkbarfooter {
+    /* position: absolute; */
+    /* bottom: 52px; */
+    /* left: 15px; */
+    height: 1px;
+    background-color: #169dd4;
+    /* width: 100%; */
+    margin-left: 15px;
+    margin-right: 15px;
+  }
+  &.active {
+    opacity: 1;
+    transform: perspective(1px) scale(1.0);
+  }
+
+  .close {
+    cursor:pointer;
+    &:hover {
+      opacity: 0.4;
+    }
+  }
+}
+.overlay {
+  opacity: 0;
+  position: fixed;
+  height: 100%;
+  width: 100%;
+  top: 0;
+  left: 0;
+  z-index: 1400;
+  transition: all 0.5s;
+  background-color: rgb(0, 0, 0);
+  &.active {
+    opacity: 0.5;
+  }
+}
diff --git a/src/tdcmp/dialog/dialog.ts b/src/tdcmp/dialog/dialog.ts
new file mode 100644
index 0000000000..a148e2effc
--- /dev/null
+++ b/src/tdcmp/dialog/dialog.ts
@@ -0,0 +1,33 @@
+import { Component, Input, ViewEncapsulation, OnInit, ViewChild, ContentChild
+, ElementRef, EventEmitter, Output  } from '@angular/core';
+
+@Component({
+  selector: 'md-dialog',
+  template: require('./dialog.html'),
+  styles: [require('./dialog.scss')],
+  encapsulation: ViewEncapsulation.None
+})
+export class MdDialog implements OnInit {
+
+  @Output() close: EventEmitter<boolean> = new  EventEmitter<boolean>();
+
+  active: boolean = false;
+
+  constructor(private _element: ElementRef) {
+  }
+
+  ngOnInit() {
+    let overlay = document.getElementsByClassName('md-overlay-container')[0];
+    overlay.appendChild(this._element.nativeElement);
+    setTimeout(() => { this.active = true; }, 10);
+  }
+
+
+
+  closeDialog() {
+    this.close.emit(false);
+  }
+
+}
+
+export const MD_DIALOG_DIRECTIVES: any[] = [MdDialog];
diff --git a/src/tdcmp/hutton/hutton.scss b/src/tdcmp/hutton/hutton.scss
new file mode 100644
index 0000000000..efee6c063b
--- /dev/null
+++ b/src/tdcmp/hutton/hutton.scss
@@ -0,0 +1,47 @@
+.hutton {
+
+  span {
+    position: relative;
+    cursor: pointer;
+    // color: #00648c;
+    &:hover {
+      color: #00648c;
+    }
+  }
+
+  .hlabel {
+    &:hover {
+      color: #00648c;
+    }
+  }
+
+
+  .hmd-icon {
+    position: absolute;
+    top: -2px;
+    right: -30px;
+    color: #00648c;
+    transform: scale(0.2);
+    opacity: 0;
+    cursor:default;
+    transition: all 0.4s ease;
+    &.visible {
+      opacity: 1;
+      transform: scale(0.8);
+      cursor: pointer;
+    }
+  }
+
+  .hmd-menu {
+    position: absolute;
+    top: -10px;
+    right: -40px;
+    opacity: 0;
+    cursor:default;
+    transition: all 0.4s ease;
+    &.visible {
+      opacity: 1;
+      cursor: pointer;
+    }
+  }
+}
diff --git a/src/tdcmp/hutton/hutton.ts b/src/tdcmp/hutton/hutton.ts
new file mode 100644
index 0000000000..c11aea39dc
--- /dev/null
+++ b/src/tdcmp/hutton/hutton.ts
@@ -0,0 +1,61 @@
+import {Component, Input, Output, EventEmitter, HostListener, HostBinding
+  , ElementRef, OnDestroy, Renderer, ViewEncapsulation, ContentChild } from '@angular/core';
+import {MdIcon} from '@angular2-material/icon';
+import {TDMenu} from '../menu/menu';
+
+
+@Component({
+    selector: 'hutton',
+    template: `
+    <span class="hutton">
+    <span
+      (mouseover)="setVisible(true)"
+      (mouseleave)=setVisible(false)>
+      <span (click)=labelClicked()><ng-content></ng-content></span>
+
+      <span [class.hmd-icon]=!menu [class.hmd-menu]=menu [class.visible]=visible *ngIf="icon"
+        (mouseover)="iconover=true;setVisible(true)"
+        (mouseleave)="blurIcon()"
+        (click)=clicked()>
+        <ng-content select="trigger"></ng-content>
+      </span>
+
+    </span>
+
+    </span>
+    `,
+    styles: [require('./hutton.scss')],
+    encapsulation: ViewEncapsulation.None
+  })
+  export class Hutton {
+    @ContentChild(MdIcon) icon: MdIcon;
+    @ContentChild(TDMenu) menu: TDMenu;
+    @Output() huttonClick: EventEmitter<any> = new EventEmitter<any>();
+    @Output() labelClick: EventEmitter<any> = new EventEmitter<any>();
+    private visible: boolean;
+    private iconover: boolean;
+    private timer: any;
+
+    setVisible(v: boolean) {
+      clearTimeout(this.timer);
+      if (!v) {
+        this.timer = setTimeout(() => {
+          if (!this.iconover) this.visible = false;
+        }, 200);
+      } else setTimeout(() => this.visible = v, 100);
+    }
+
+    blurIcon() {
+      this.iconover = false;
+      this.setVisible(false);
+    }
+
+    clicked() {
+      this.huttonClick.emit(undefined);
+    }
+
+    labelClicked() {
+      this.labelClick.emit(undefined);
+    }
+
+  }
diff --git a/src/tdcmp/index.ts b/src/tdcmp/index.ts
new file mode 100644
index 0000000000..7df43d2bcb
--- /dev/null
+++ b/src/tdcmp/index.ts
@@ -0,0 +1,47 @@
+export * from './dateTimePicker/dateTimePicker';
+export * from './dateTimePicker/calendar/calendar';
+export * from './tdcombobox/tdcombobox.component';
+export * from './dialog/dialog';
+export * from './checkbox/checkbox';
+export * from './select/select';
+export * from './tools/dateUtils';
+export * from './tools/tools';
+export * from './tools/dictionary';
+export * from './searchbox/searchbox';
+export * from './pipes/filter';
+export * from './chart/orgaChart';
+export * from './snackbar/snackbar';
+export * from './smartSearch/smartSearch';
+export * from './chip/chip';
+export * from './autoComplete/autocomplete';
+export * from './messageBox/messageBox';
+export * from './treeView/treeView';
+export * from './hutton/hutton';
+export * from './menu/menu';
+export * from './data-table';
+export * from './accordion/accordion';
+export * from './accordion/accordiontab';
+
+
+import { MdSnackBar } from './snackbar/snackbar';
+import { MDDateTimePicker } from './dateTimePicker/dateTimePicker';
+import { MdSelect } from './select/select';
+import { MdDialog } from './dialog/dialog';
+import { TDSearchBox } from './searchbox/searchbox';
+import { SmartSearch } from './smartSearch/smartSearch';
+import { MdChip } from './chip/chip';
+import { MdAutoComplete } from './autoComplete/autocomplete';
+import { MessageBox } from './messageBox/messageBox';
+import { TdCalendar } from './calendar/calendar';
+import { TreeView } from './treeView/treeView';
+import { Hutton } from './hutton/hutton';
+import { TDMenu, TDMenuItem } from './menu/menu';
+import {MdDataTable, MdDataTableSelectableRow, MdDataTableHeaderSelectableRow
+  , AbstractMdDataTableSelectableRow} from './data-table';
+import { TDaccordion } from './accordion/accordion';
+import { TDaccordionTab } from './accordion/accordiontab';
+
+export const MD_TD_DIRECTIVES: any[] = [MdSnackBar, MDDateTimePicker, MdSelect, MdDialog, TDMenu
+  , TDMenuItem, TDSearchBox, SmartSearch, MdChip, MdAutoComplete, MessageBox, TreeView, TdCalendar
+  , Hutton, MdDataTable, MdDataTableSelectableRow, MdDataTableHeaderSelectableRow
+  , TDaccordion, TDaccordionTab];
diff --git a/src/tdcmp/menu/menu.html b/src/tdcmp/menu/menu.html
new file mode 100644
index 0000000000..1b5efb21bd
--- /dev/null
+++ b/src/tdcmp/menu/menu.html
@@ -0,0 +1,6 @@
+<div (click)="togglePopup()"><ng-content select="button" ></ng-content></div>
+
+
+<div class="tdpopup" [class.active]=active [class.upper]=upper [style.top]=top [style.left]=left >
+  <div (click)="active=false"><ng-content select="td-menu-items"></ng-content></div>
+</div>
diff --git a/src/tdcmp/menu/menu.scss b/src/tdcmp/menu/menu.scss
new file mode 100644
index 0000000000..c0799c9a9a
--- /dev/null
+++ b/src/tdcmp/menu/menu.scss
@@ -0,0 +1,72 @@
+.tdpopup {
+  $swift-ease-out-duration: 0.4s !default;
+  $swift-ease-out-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default;
+  $swift-ease-out: all $swift-ease-out-duration $swift-ease-out-timing-function !default;
+  $swift-ease-out-quick: all 0.2 $swift-ease-out-timing-function !default;
+  color: rgba(0, 0, 0, 0.870588);
+  transition: $swift-ease-out;
+  transform: scaleY(0);
+  transform-origin: right top;
+  box-sizing: border-box;
+  font-family: Roboto, sans-serif;
+  box-shadow: rgba(0, 0, 0, 0.247059) 0 14px 45px, rgba(0, 0, 0, 0.219608) 0 10px 18px;
+  // box-shadow: rgba(0, 0, 0, 0.117647) 0 1px 6px, rgba(0, 0, 0, 0.117647) 0 1px 4px;
+  background-color: rgb(255, 255, 255);
+  border-radius: 2px;
+  opacity: 0;
+  position: fixed;
+  z-index: 2100;
+  padding-top: 5px;
+  padding-bottom: 5px;
+  &.upper {
+    transform-origin: right bottom;
+  }
+  &.active {
+    transform: scaleY(1.0);
+    opacity: 1;
+  }
+  &:not(.active) {
+    transition: $swift-ease-out-quick;
+    transform: scaleY(0);
+    opacity: 0;
+  }
+  div {
+    z-index: 1000;
+    top: 0;
+    right: 0;
+    max-height: 500px;
+    overflow-y: auto;
+    overflow-x: hidden;
+    max-width: 500px;
+    min-width: 192px;
+    // padding: 16px 0;
+  }
+  .item {
+    border: 10px;
+    box-sizing: border-box;
+    display: block;
+    font-family: Roboto, sans-serif;
+    cursor: pointer;
+    text-decoration: none;
+    outline: none;
+    font-size: 15px;
+    font-weight: inherit;
+    color: rgba(0, 0, 0, 0.870588);
+    line-height: 32px;
+    position: relative;
+    white-space: nowrap;
+    background: none;
+    &:hover {
+      background-color: rgba(0,0,0,0.0980392);
+    }
+    &.selected {
+      color: rgb(64,64,155);
+      font-weight: bold;
+    }
+    span {
+      margin-left: 0;
+      padding: 0 24px;
+      position: relative;
+    }
+  }
+}
diff --git a/src/tdcmp/menu/menu.ts b/src/tdcmp/menu/menu.ts
new file mode 100644
index 0000000000..23fe155258
--- /dev/null
+++ b/src/tdcmp/menu/menu.ts
@@ -0,0 +1,101 @@
+import {Component, ViewEncapsulation, ElementRef, Input, Output, EventEmitter
+  , HostListener, ContentChildren, AfterViewInit, OnDestroy, QueryList
+  , ContentChild, Renderer} from '@angular/core';
+
+
+  @Component({
+    selector: 'td-menu-item',
+    template: '<span class="item" (click)=test()><span><ng-content></ng-content></span></span>',
+    styles: [require('./menu.scss')],
+    encapsulation: ViewEncapsulation.None
+  })
+export class TDMenuItem {
+  public menu: TDMenu;
+  constructor (private elementRef: ElementRef) {}
+
+  test() {
+    let s = (<HTMLElement>this.elementRef.nativeElement).firstChild.firstChild.firstChild.nodeValue;
+    this.menu.menuSelected.emit(s);
+  }
+}
+
+@Component({
+  selector: 'td-menu',
+  template: require('./menu.html'),
+  styles: [require('./menu.scss')],
+  directives: [TDMenuItem],
+  encapsulation: ViewEncapsulation.None
+})
+export class TDMenu implements AfterViewInit, OnDestroy {
+@Output() menuSelected: EventEmitter<string> = new EventEmitter<string>();
+@ContentChildren(TDMenuItem) items: QueryList<TDMenuItem>;
+
+private active: boolean = false;
+private _justClicked: boolean = false;
+private _overlay: Element;
+private _popupElement: Element;
+private _triggerElement: Element;
+private upper: boolean;
+private top: string;
+private left: string;
+
+@HostListener('body:click', ['$event'])
+closePopup() {
+  if (!this.active) return;
+  if (this._justClicked) {
+    this._justClicked = false;
+    return;
+  }
+  this.active = false;
+}
+
+constructor(private _element: ElementRef, private _renderer: Renderer) {}
+
+ngAfterViewInit() {
+  this.items.forEach(p => p.menu = this);
+  this._overlay = document.getElementsByClassName('md-overlay-container')[0];
+  this._popupElement = this._element.nativeElement.getElementsByClassName('tdpopup')[0];
+  this._triggerElement = (<HTMLElement>this._element.nativeElement).firstElementChild;
+  this._overlay.appendChild(this._popupElement);
+}
+
+togglePopup() {
+  this._justClicked = true;
+  this.active = !this.active;
+  if (this.active) this.setPosition();
+}
+
+setPosition() {
+  let rec = this._triggerElement.getBoundingClientRect();
+
+  let height: number = 10.0;
+  if (this.items) height = (this.items.length * 16.0);
+  if (height > 500) height = 500;
+  let wh = window.innerHeight;
+  this.left = rec.left - 10 + 'px';
+
+  if (rec.bottom - 40 + height < wh) {
+    this.top = rec.bottom - 40 + 'px';
+    this.upper = false;
+    return;
+  }
+
+   if (rec.top - height + 40  > 0 ) {
+     this.top = rec.top  - height + 40 + 'px';
+     this.upper = true;
+    return;
+  }
+
+  this.upper = false;
+  this.top = '30px';
+  this.left = '50%';
+
+}
+
+ngOnDestroy() {
+    this._overlay.removeChild(this._popupElement);
+}
+
+}
+
+export const MD_TDMENU_DIRECTIVES: any[] = [TDMenu, TDMenuItem];
diff --git a/src/tdcmp/messageBox/messageBox.html b/src/tdcmp/messageBox/messageBox.html
new file mode 100644
index 0000000000..d881c8ac2e
--- /dev/null
+++ b/src/tdcmp/messageBox/messageBox.html
@@ -0,0 +1,30 @@
+<div class="messageBox" [class.active]="active" *ngIf="opened">
+  <div class="border">
+    <div class="container">
+      <h3>
+        <div layout="row">
+          <div>
+            <ng-content select="md-title"></ng-content>
+          </div>
+
+          <div flex style="text-align:right">
+              <md-icon class="md-24 close"  (click)="closeDialog(false)">close</md-icon>
+          </div>
+      </div>
+      </h3>
+      <div class="inkbartitle"></div>
+      <div style="font-size: 16px; padding: 16px 0px 16px; box-sizing: border-box; overflow-y: hidden; max-height: 731px;text-align:center">
+        <ng-content></ng-content>
+      </div>
+
+    <div class="footer">
+        <button (click)=closeDialog(false)><div><span>Cancel</span></div></button>
+        <button (click)=closeDialog(true)><div><span>Ok</span></div></button>
+    </div>
+    </div>
+  </div>
+
+</div>
+<div *ngIf="opened" class="backdrop">
+
+</div>
diff --git a/src/tdcmp/messageBox/messageBox.scss b/src/tdcmp/messageBox/messageBox.scss
new file mode 100644
index 0000000000..c842c121fe
--- /dev/null
+++ b/src/tdcmp/messageBox/messageBox.scss
@@ -0,0 +1,115 @@
+.messageBox {
+  position: fixed;
+  z-index: 1500;
+  top: 20%;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  box-sizing: border-box;
+  opacity: 0;
+  transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
+  transform: scale(0.2);
+  &.active {
+    opacity: 1;
+    transform: perspective(1px) scale(1.0);
+  }
+  .border {
+    box-sizing: border-box;
+    position: relative;
+    max-width: 512px;
+    margin: 0 auto;
+    z-index: 1500;
+    opacity: 1;
+    .container {
+      color: rgba(0, 0, 0, 0.870588);
+      box-sizing: border-box;
+      font-family: Roboto, sans-serif;
+      box-shadow: rgba(0, 0, 0, 0.247059) 0 14px 45px, rgba(0, 0, 0, 0.219608) 0 10px 18px;
+      border-radius: 2px;
+      background-color: rgb(255, 255, 255);
+      h3 {
+        margin: 0;
+        padding: 24px 24px 20px;
+        color: rgba(0, 0, 0, 0.870588);
+        font-size: 22px;
+        line-height: 32px;
+        font-weight: 400;
+        border-bottom-style: none;
+        md-icon {
+          &:hover {
+            opacity: 0.7;
+            cursor: pointer;
+          }
+        }
+      }
+      .inkbartitle {
+        position: absolute;
+        top: 60px;
+        left: 15px;
+        height: 1px;
+        background-color: #00648c;
+        width: calc(100% - 30px);
+        opacity: 0.8;
+      }
+      .footer {
+        box-sizing: border-box;
+        -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+        padding: 8px;
+        width: 100%;
+        text-align: right;
+        margin-top: 0;
+        border-top-style: none;
+        button {
+          border: 10px;
+          box-sizing: border-box;
+          display: inline-block;
+          font-family: Roboto, sans-serif;
+          -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+          cursor: pointer;
+          text-decoration: none;
+          margin: 0;
+          padding: 0;
+          outline: none;
+          font-size: inherit;
+          font-weight: inherit;
+          transform: translate3d(0px, 0px, 0px);
+          height: 36px;
+          line-height: 36px;
+          min-width: 88px;
+          color: rgb(0, 188, 212);
+          transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0;
+          border-radius: 2px;
+          position: relative;
+          overflow: hidden;
+          text-align: center;
+          -webkit-user-select: none;
+          background-color: rgba(0, 0, 0, 0);
+          &:hover {
+            background-color: rgba(153, 153, 153, 0.2);
+          }
+          span {
+            position: relative;
+            padding-left: 16px;
+            padding-right: 16px;
+            vertical-align: middle;
+            letter-spacing: 0;
+            text-transform: uppercase;
+            font-weight: 500;
+            font-size: 14px;
+          }
+        }
+      }
+    }
+  }
+
+}
+
+.backdrop {
+  position: fixed;
+  top:0;
+  left:0;
+  width: 100%;
+  height: 100%;
+  opacity: 0.2;
+  background-color: black;
+}
diff --git a/src/tdcmp/messageBox/messageBox.ts b/src/tdcmp/messageBox/messageBox.ts
new file mode 100644
index 0000000000..c921c0cf6d
--- /dev/null
+++ b/src/tdcmp/messageBox/messageBox.ts
@@ -0,0 +1,45 @@
+import {Component, ViewEncapsulation, ElementRef, Input, Output, EventEmitter
+  , OnInit, ViewChild, OnDestroy} from '@angular/core';
+
+
+@Component({
+  selector: 'message-box',
+  template: require('./messageBox.html'),
+  styles: [require('./messageBox.scss')],
+  encapsulation: ViewEncapsulation.None
+})
+export class MessageBox implements OnInit, OnDestroy {
+  @Output() onClose: EventEmitter<boolean> = new  EventEmitter<boolean>();
+
+  private active: boolean = false;
+  private opened: boolean = false;
+
+
+  private _overlay: Element;
+
+  constructor(private _element: ElementRef) {}
+
+  public Open() {
+    this.opened = true;
+    setTimeout(() => { this.active = true; }, 10);
+  }
+
+  ngOnInit() {
+    this._overlay = document.getElementsByClassName('md-overlay-container')[0];
+    this._overlay.appendChild(this._element.nativeElement);
+  }
+
+  closeDialog(value: boolean) {
+    this.onClose.emit(value);
+    this.active = false;
+    setTimeout(() => this.opened = false, 200);
+  }
+
+  ngOnDestroy() {
+    if (this._overlay) {
+      this._overlay.removeChild(this._element.nativeElement);
+    }
+  }
+}
+
+export const MD_MESSAGEBOX_DIRECTIVES: any[] = [MessageBox];
diff --git a/src/tdcmp/pipes/filter.ts b/src/tdcmp/pipes/filter.ts
new file mode 100644
index 0000000000..115162b9ee
--- /dev/null
+++ b/src/tdcmp/pipes/filter.ts
@@ -0,0 +1,34 @@
+import {Pipe, PipeTransform} from '@angular/core';
+
+@Pipe({
+    name: 'filter',
+    pure: true
+})
+export class FilterPipe implements PipeTransform {
+
+  keys: any;
+
+    transform(items: any[], args: any): any {
+      // console.log(args);
+        if (!items) return items;
+        this.keys = Object.keys(args);
+        if (this.keys.length === 0) return items;
+        return items.filter(item => this.checkItem(item, args));
+    }
+
+    checkItem(item: any, arg: any): boolean {
+        let res = false;
+        for (let key of this.keys) {
+            let value = <string>item[key];
+            let a = <string>arg[key];
+            if ((!value || value === '') && !a) { res = false; continue; }
+            if (value) value = value.toUpperCase();
+            if (!a) res = true; else {
+                if (value && value.indexOf(a.toUpperCase()) !== -1) return true;
+                res = false;
+            }
+        }
+        return res;
+
+    }
+}
diff --git a/src/tdcmp/searchbox/searchbox.html b/src/tdcmp/searchbox/searchbox.html
new file mode 100644
index 0000000000..62d7f32f38
--- /dev/null
+++ b/src/tdcmp/searchbox/searchbox.html
@@ -0,0 +1,10 @@
+<div class="searchBox" style="max-width:{{width}}">
+  <span>
+
+    <span><i class="fa fa-search"></i></span>
+    <input placeholder={{placeholder}} [(ngModel)]="text" />
+                <a *ngIf="text!==''"  (click)="clearText()">
+                    <span><i class="fa fa-times-circle"></i></span>
+                </a>
+  </span>
+</div>
diff --git a/src/tdcmp/searchbox/searchbox.scss b/src/tdcmp/searchbox/searchbox.scss
new file mode 100644
index 0000000000..e17df10d76
--- /dev/null
+++ b/src/tdcmp/searchbox/searchbox.scss
@@ -0,0 +1,36 @@
+.searchBox{
+	padding: 0 10px 0px 0px;
+	span{
+	 border-radius: 20px;
+	 border: 1px solid #CACACA;
+	 position:relative;
+	 margin: 0 10px;
+	 display: block;
+	 span{
+	 	border: none;
+	 	box-shadow: none;
+	 	display: inline-block;
+	 	text-align: center;
+	 }
+ }
+ span i{
+ 	color:#cacaca;
+ }
+ input{
+ 	height: 25px;
+ 	width : calc(100% - 70px);
+ 	background: transparent;
+ 	outline-style: none;
+ 	border:none;
+ 	display: inline-block;
+     color: #5e5e5e;
+ }
+ a{
+     cursor:pointer;
+		 span {
+		     right:3px;
+		     top:5px;
+		     position:absolute;
+		 }
+ }
+}
diff --git a/src/tdcmp/searchbox/searchbox.ts b/src/tdcmp/searchbox/searchbox.ts
new file mode 100644
index 0000000000..81c44f4935
--- /dev/null
+++ b/src/tdcmp/searchbox/searchbox.ts
@@ -0,0 +1,41 @@
+import {Component, ViewEncapsulation, Input, Output, EventEmitter
+  , AfterContentInit} from '@angular/core';
+
+@Component({
+  selector: 'td-searchbox',
+  inputs: ['text', 'width'],
+  template: require('./searchbox.html'),
+  styles: [require('./searchbox.scss')],
+  directives: []
+
+
+
+})
+export class TDSearchBox implements  AfterContentInit {
+
+  @Output()
+  textChange: EventEmitter<string> = new EventEmitter<string>();
+
+  @Input() placeholder: string = 'Search';
+
+  get text(): string { return this._text; }
+  @Input() set text(value: string) {
+    if (value !== this._text) {
+      this._text = value;
+      if (this._initialized)
+        this.textChange.emit(value);
+   }
+
+  }
+
+private _alreadyChanged: boolean = false;
+private _text: string = '';
+private _initialized: boolean = false;
+
+ngAfterContentInit() {
+  this._initialized = true;
+}
+  clearText() {
+    this.text = '';
+  }
+}
diff --git a/src/tdcmp/select/select.html b/src/tdcmp/select/select.html
new file mode 100644
index 0000000000..1f6479fd07
--- /dev/null
+++ b/src/tdcmp/select/select.html
@@ -0,0 +1,51 @@
+<div class="select" style="margin-right:2px">
+
+  <div (click)=clicked($event) class="inputpopup" >
+    <!-- <div style="position: absolute; opacity: 0; color: rgba(0, 0, 0, 0.298039); transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1); bottom: 12px;"> </div> -->
+    <label class="labela" [class.upper]="selectedItem || selectedItems.length>0">
+      {{placeHolder}}
+      <span [hidden]="!required" style="color:#9c27b0">*</span>
+    </label>
+
+    <div style="display: inline-block; font-size: inherit; height: 100%; font-family: inherit; outline: none; position: relative; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1); -webkit-tap-highlight-color: rgba(0, 0, 0, 0); padding: 0px; width: 100%; border: none; color: rgba(0, 0, 0, 0.870588); font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; background-color: rgba(0, 0, 0, 0)">
+      <div class="inputcursor" [class.disabled]="disabled">
+
+        <div class="textItem">
+          {{getDisplayItemLabel()}}
+        </div>
+
+      </div>
+      <div style="position:relative; height:20px">
+        <span style="position:absolute;top:-15px;font-size: 0.70em;color:red"><ng-content select="error"></ng-content></span>
+      </div>
+    </div>
+
+
+
+    <div [hidden]="hidedivider" style="position:relative">
+      <hr style="border-bottom-width: 1px; border-style: none none solid; border-color: rgb(158, 158, 158);  bottom: 15px; box-sizing: content-box; position: absolute; width: 100%;">
+      <div [hidden]="hidedivider">
+        <svg viewBox="0 0 24 24" class="arrow">
+          <path d="M7 10l5 5 5-5z"></path>
+        </svg>
+      </div>
+      <md-icon *ngIf="clearable && getDisplayItemLabel()" (click)="clear()" class="md-16 clearable ">cancel</md-icon>
+    </div>
+  </div>
+
+
+  <div [hidden]=!showPopup [class.active]=active [class.upper]=upper class="popup">
+    <td-searchbox *ngIf=search (click)="_justClicked=true" style="margin-left: -17px;margin-bottom: 7px; margin-right: -12px;" flex placeholder="search" (textChange)="searchTerm=$event"></td-searchbox>
+    <div *ngIf="!multi"  class="monodiv">
+        <span *ngFor="let item of filteredItems" (click)="itemClicked(item)" class="item" [class.selected]="item==selectedItem">
+          <span>{{getDisplayItem(item)}}</span>
+        </span>
+    </div>
+    <div *ngIf="multi" class="multidiv" layout="column">
+        <span *ngFor="let item of filteredItems" class="multiitem">
+          <label class="item" (click)="_justClicked=true;" style="position:relative;padding-left: 20px;"><input type="checkbox" style="position: absolute;left: 0px;top: 9px;" [checked]="isChecked(item)" (change)="checkClicked(item, $event.target.checked)" (click)="_justClicked=true">{{getDisplayItem(item)}}</label>
+        </span>
+    </div>
+  </div>
+
+</div>
diff --git a/src/tdcmp/select/select.scss b/src/tdcmp/select/select.scss
new file mode 100644
index 0000000000..3dc633d3c1
--- /dev/null
+++ b/src/tdcmp/select/select.scss
@@ -0,0 +1,178 @@
+@import "../styles/tdcmp";
+.select {
+  max-width: 350px;
+  .inputpopup {
+    font-size: 16px;
+    line-height: 24px;
+    width: 100%;
+    height: 48px;
+    display: inline-block;
+    position: relative;
+    font-family: Roboto, sans-serif;
+    transition: height 200ms cubic-bezier(0.23, 1, 0.32, 1) 0;
+    background-color: transparent;
+    .textItem {
+      max-width: 350px;
+      color: rgba(0, 0, 0, 0.870588);
+      height: 56px;
+      line-height: 56px;
+      opacity: 1;
+      padding-left: 0;
+      padding-right: 48px;
+      top: -4px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+    .labela {
+      position: absolute;
+      line-height: 22px;
+      top: 38px;
+      transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0;
+      z-index: 1;
+      cursor: text;
+      transform: perspective(1px) scale(0.75) translate3d(0px, -28px, 0px);
+      transform-origin: left top 0;
+      pointer-events: none;
+      color: rgba(0, 0, 0, 0.498039);
+      &.upper {
+        top: 20px;
+      }
+    }
+    .inputcursor {
+      cursor: pointer;
+      height: 100%;
+      position: relative;
+      width: 100%;
+      &.disabled {
+        cursor: default;
+      }
+    }
+    .arrow {
+      display: inline-block;
+      fill: rgb(158, 158, 158);
+      height: 24px;
+      width: 24px;
+      transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1);
+      position: absolute;
+      right: 0;
+      top: -48px;
+    }
+    .clearable {
+      color: #C34B7D;
+      position: absolute;
+      right: 0;
+      top: -63px;
+      transform: scale(0.9);
+      transition: transform scale 0.2s ease;
+      &:hover {
+        transform: scale(1.0);
+        opacity: 0.8;
+      }
+    }
+  }
+}
+.popup {
+  color: rgba(0, 0, 0, 0.870588);
+  transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
+  transform: scaleY(0);
+  transform-origin: right top;
+  box-sizing: border-box;
+  font-family: Roboto, sans-serif;
+  box-shadow: rgba(0, 0, 0, 0.247059) 0 14px 45px, rgba(0, 0, 0, 0.219608) 0 10px 18px;
+  background-color: rgb(255, 255, 255);
+  border-radius: 2px;
+  opacity: 0;
+  position: fixed;
+  z-index: 2100;
+  padding-top: 5px;
+  padding-bottom: 5px;
+  &.upper {
+    transform-origin: right bottom;
+  }
+  &.active {
+    transform: scaleY(1.0);
+    opacity: 1;
+  }
+  &:not(.active) {
+    transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);
+    transform: scaleY(0);
+    opacity: 0;
+  }
+  .monodiv {
+    z-index: 1000;
+    top: 0;
+    right: 0;
+    max-height: 500px;
+    overflow-y: auto;
+    overflow-x: hidden;
+    max-width: 500px;
+    min-width: 192px;
+    padding-left: 16px;
+    padding-right: 1em;
+    padding-bottom: 12px;
+    // padding: 16px 0;
+    span {
+      white-space: nowrap;
+      &:hover {
+        // background-color: rgba(0,0,0,0.0980392);
+      }
+    }
+  }
+  .multidiv {
+    z-index: 1000;
+    top: 0;
+    right: 0;
+    min-width: 192px;
+    overflow-y: auto;
+    overflow-x: hidden;
+    max-height: 500px;
+    min-height: 36px;
+    padding-left: 16px;
+    padding-right: 1em;
+    padding-bottom: 12px;
+    span {
+      white-space: nowrap;
+      &:hover {
+        // background-color: rgba(0,0,0,0.0980392);
+      }
+    }
+    label {
+      white-space: nowrap;
+      cursor: pointer;
+    }
+  }
+  .item {
+    border: 10px;
+    box-sizing: border-box;
+    display: block;
+    font-family: Roboto, sans-serif;
+    cursor: pointer;
+    text-decoration: none;
+    outline: none;
+    font-size: 15px;
+    font-weight: inherit;
+    color: rgba(0, 0, 0, 0.870588);
+    line-height: 32px;
+    position: relative;
+    white-space: nowrap;
+    background: none;
+    &:hover {
+      background-color: rgba(0,0,0,0.0980392);
+    }
+    &.selected {
+      color: rgb(64,64,155);
+      font-weight: bold;
+    }
+    span {
+      margin-left: 0;
+      padding: 0 24px;
+      position: relative;
+    }
+  }
+  .multiitem {
+    input {
+      margin-right: 5px;
+    }
+  }
+}
diff --git a/src/tdcmp/select/select.ts b/src/tdcmp/select/select.ts
new file mode 100644
index 0000000000..e18795df7b
--- /dev/null
+++ b/src/tdcmp/select/select.ts
@@ -0,0 +1,351 @@
+import * as _ from 'lodash';
+
+import {Component, Input, Output, EventEmitter, HostListener, HostBinding
+  , ElementRef, OnInit, OnDestroy, Renderer, forwardRef, ViewEncapsulation } from '@angular/core';
+import {BooleanFieldValue} from '@angular2-material/core/annotations/field-value';
+import {
+  NG_VALUE_ACCESSOR,
+  ControlValueAccessor,
+  NgModel
+} from '@angular/forms';
+
+
+export const MD_SELECT_CONTROL_VALUE_ACCESSOR: any = {
+  provide: NG_VALUE_ACCESSOR,
+  useExisting: forwardRef(() => MdSelect),
+  multi: true
+};
+const noop = () => { };
+
+@Component({
+  selector: 'md-select',
+  template: require('./select.html'),
+  styles: [require('./select.scss')],
+  providers: [MD_SELECT_CONTROL_VALUE_ACCESSOR],
+  directives: [],
+  encapsulation: ViewEncapsulation.None
+})
+export class MdSelect implements OnInit, OnDestroy, ControlValueAccessor {
+  @Input() placeHolder: string;
+  @Input() @BooleanFieldValue() required: boolean = false;
+  @Input() items: Array<any>;
+  @Input() displayItem: string = undefined;
+  @Input() get selectedItem(): any {
+    return this._selectedItem;
+  }
+  set selectedItem(value) {
+    this._selectedItem = value;
+    if (this._initialized) {
+      this.selectedItemChange.emit(this._selectedItem);
+      if (!this.valuePropertyName) this._onChangeCallback(value);
+    } else this._initialized = true;
+  }
+
+  @Input() get selectedItems(): Array<any> {
+    return this._selectedItems;
+  }
+  set selectedItems(value) {
+    this._selectedItems = value;
+    if (this._initialized) {
+      this.selectedItemsChange.emit(this._selectedItems);
+      if (!this.valuePropertyName) this._onChangeCallback(value);
+    } else this._initialized = true;
+  }
+
+
+  @Output() selectedItemChange: EventEmitter<any> = new EventEmitter<any>();
+  @Output() selectedItemsChange: EventEmitter<any> = new EventEmitter<any>();
+
+  @Input() valuePropertyName: string = undefined;
+  @Input() get selectedValue(): any {
+    return this._selectedValue;
+  }
+  set selectedValue(value) {
+    this._selectedValue = value;
+    this.selectedItem = this.findItemByValue(value);
+    this.selectedValueChange.emit(this._selectedValue);
+    if (this.valuePropertyName) this._onChangeCallback(value);
+  }
+  @Output() selectedValueChange: EventEmitter<any> = new EventEmitter<any>();
+
+  @Input() get selectedValues(): any {
+    return this._selectedValues;
+  }
+  set selectedValues(values) {
+    this._selectedValues = values;
+    this.findItemsByValue(this.selectedItems, values);
+    this.selectedValuesChange.emit(this._selectedValues);
+    if (this.valuePropertyName) this._onChangeCallback(values);
+  }
+  @Output() selectedValuesChange: EventEmitter<any> = new EventEmitter<any>();
+
+
+  @HostBinding('attr.disabled')
+  @Input('disabled')
+  get disabled() { return this._disabled; }
+
+  set disabled(value: boolean) {
+    // The presence of *any* disabled value makes the component disabled, *except* for false.
+    this._disabled = (value !== undefined && value !== false) ? true : false;
+  }
+  _disabled: boolean = false;
+
+  @HostBinding('attr.clearable')
+  @Input('clearable')
+  get clearable() { return this._clearable; }
+  set clearable(value: boolean) {
+    this._clearable = (value !== undefined && value !== false) ? true : false;
+  }
+  _clearable: boolean = false;
+
+  @HostBinding('attr.hidedivider')
+  @Input('hidedivider')
+  get hidedivider() { return this._hidedivider; }
+  set hidedivider(value: boolean) {
+    this._hidedivider = (value !== undefined && value !== false) ? true : false;
+  }
+  _hidedivider: boolean = false;
+
+  _multi: boolean = false;
+  @HostBinding('attr.multi')
+  @Input('multi')
+  get multi() { return this._multi; }
+  set multi(value: boolean) {
+    this._multi = (value !== undefined && value !== false) ? true : false;
+  }
+
+
+
+  _search: boolean = false;
+  @HostBinding('attr.search')
+  @Input('search')
+  get search() { return this._search; }
+  set search(value: boolean) {
+    this._search = (value !== undefined && value !== false) ? true : false;
+  }
+
+  searchTerm: string;
+
+  private _selectedItem: any;
+  private _selectedItems: Array<any> = [];
+  private _selectedValue: any;
+  private _selectedValues: Array<any> = [];
+  private showPopup: boolean = false;
+  private _overlay: Element;
+  private _popupElement: Element;
+  private _inputElement: Element;
+  private active: boolean = false;
+  private _justClicked: boolean = false;
+  private _justOpened: boolean = false;
+  private upper: boolean = false;
+  private _initialized = false;
+
+  private _onTouchedCallback: () => void = noop;
+  private _onChangeCallback: (_: any) => void = noop;
+  private sortedItems: Array<any>;
+
+  sortItems(items: Array<any>): Array<any> {
+    if (!this.multi) return items;
+    let arr = [];
+    this.selectedItems.forEach(p => {
+      if (items.indexOf(p) !== -1) arr.push(p);
+    });
+    items.forEach(p => {
+      if (this.selectedItems.indexOf(p) === -1) arr.push(p);
+    });
+    return arr;
+  }
+
+  get filteredItems(): Array<any> {
+    if (!this.searchTerm || this.searchTerm === '')
+      return this.sortedItems;
+    return this.sortedItems.filter(p => {
+      return p[this.displayItem].toUpperCase().indexOf(this.searchTerm.toUpperCase()) >= 0;
+    }
+    );
+  }
+
+
+  @HostListener('body:click', ['$event'])
+  closePopup() {
+    if (!this.showPopup) return;
+    if (this._justClicked) {
+      this._justClicked = false;
+      return;
+    }
+    this.active = false;
+    setTimeout(() => {
+      this.showPopup = false;
+    }, 100);
+  }
+
+  constructor(private _element: ElementRef, private _renderer: Renderer) { }
+
+  ngOnInit() {
+    if (this.valuePropertyName && this.selectedValue && !this.selectedItem)
+      this.selectedItem = this.findItemByValue(this.selectedValue);
+
+    this._overlay = document.getElementsByClassName('md-overlay-container')[0];
+    this._popupElement = this._element.nativeElement.getElementsByClassName('popup')[0];
+    this._inputElement = this._element.nativeElement.getElementsByClassName('inputpopup')[0];
+    this._overlay.appendChild(this._popupElement);
+  }
+
+  findItemByValue(value: any): any {
+    for (let item of this.items) {
+      if (item[this.valuePropertyName] === value) {
+        return item;
+      }
+    }
+
+    return undefined;
+  }
+
+  findItemsByValue(result: Array<any>, values: Array<any>) {
+    while (result.pop());
+
+    for (let value of values) {
+      result.push(this.findItemByValue(value));
+    }
+  }
+
+  setPosition() {
+    let rec = this._inputElement.getBoundingClientRect();
+
+    let height: number = 32.0;
+    if (this.items) height = (this.items.length * 32.0) + 32.0;
+    if (height > 500) height = 500;
+    let wh = window.innerHeight;
+
+    if (rec.bottom + height - 100 < wh) {
+      this._renderer.setElementStyle(this._popupElement, 'top', rec.bottom - 55 + 'px');
+      this._renderer.setElementStyle(this._popupElement, 'left', rec.left + 'px');
+      this.upper = false;
+      return;
+    }
+
+    if (rec.bottom > height) {
+      this._renderer.setElementStyle(this._popupElement, 'top', rec.bottom - height + 'px');
+      this._renderer.setElementStyle(this._popupElement, 'left', rec.left + 'px');
+      this.upper = true;
+      return;
+    }
+    this.upper = false;
+    this._renderer.setElementStyle(this._popupElement, 'top', '30px');
+    this._renderer.setElementStyle(this._popupElement, 'left', '50%');
+  }
+
+  openPopup() {
+    this.sortedItems = this.sortItems(this.items);
+    this._justOpened = true;
+    this.setPosition();
+    this.showPopup = true;
+    setTimeout(() => {
+      this.active = true;
+      if (!this._multi) this.scrollToSelected();
+    }, 10);
+  }
+
+
+  scrollToSelected() {
+    if (!this.selectedItem) return;
+    let pos = this.items.indexOf(this.selectedItem) + 1;
+    if (this.upper)
+      this._popupElement.firstElementChild.scrollTop = pos * 32 - 470; else
+      this._popupElement.firstElementChild.scrollTop = pos * 32 - 48;
+  }
+
+  getDisplayItem(item: any): string {
+    if (!item) return '';
+    if (this.displayItem)
+      return item[this.displayItem];
+    return item.toString();
+  }
+
+  getDisplayItemLabel(): string {
+    if (!this.multi) return this.getDisplayItem(this.selectedItem);
+    let text = '';
+    this.selectedItems.forEach(p => {
+      text += this.getDisplayItem(p) + ', ';
+    });
+    if (text !== '') text = text.replace(new RegExp(', *$'), '');
+    return text;
+    // if (this.selectedItems.length === 0) return '';
+    // if (this.selectedItems.length === 1) return this.getDisplayItem(this.selectedItems[0]);
+    // if (this.selectedItems.length === 2) return this.getDisplayItem(this.selectedItems[0])
+    //   + ', ' + this.getDisplayItem(this.selectedItems[1]);
+    // return this.getDisplayItem(this.selectedItems[0])
+    //   + ', ' + this.getDisplayItem(this.selectedItems[1]) + ', ...';
+  }
+
+  clicked($event) {
+    if (this.disabled) return;
+    if (this._justClicked) {
+      this._justClicked = false;
+      return;
+    }
+    this._justClicked = true;
+    this.openPopup();
+  }
+
+  itemClicked(item) {
+    this.selectedItem = item;
+    if (this.valuePropertyName)
+      this.selectedValue = item[this.valuePropertyName];
+    this.closePopup();
+  }
+  ngOnDestroy() {
+    this._overlay.removeChild(this._popupElement);
+  }
+
+  clear() {
+    this._justClicked = true;
+    if (this.valuePropertyName)
+      this.selectedValue = undefined; else this.selectedItem = undefined;
+  }
+
+  writeValue(value: any) {
+    // if valuePropertyName specified, we bind using id
+    if (this.valuePropertyName) {
+      if (this.multi) this.selectedValues = value; else this.selectedValue = value;
+    } else {
+      if (this.multi) this.selectedItems = value; else this.selectedItem = value;
+    }
+  }
+
+  registerOnChange(fn: any) {
+    this._onChangeCallback = fn;
+  }
+
+  registerOnTouched(fn: any) {
+    this._onTouchedCallback = fn;
+  }
+
+
+
+  checkClicked(item: any, checked: boolean) {
+    if (checked) {
+      if (this.valuePropertyName) this.selectedValues.push(item[this.valuePropertyName]);
+        this.selectedItems.push(item);
+    } else {
+      if (this.valuePropertyName) {
+        let index = this.selectedValues.indexOf(item[this.valuePropertyName]);
+        if (index !== -1) this.selectedValues.splice(index, 1);
+      }
+      let index = this.selectedItems.indexOf(item);
+      if (index !== -1) this.selectedItems.splice(index, 1);
+
+    }
+    if (this.valuePropertyName) this._onChangeCallback(this.selectedValues); else
+      this._onChangeCallback(this.selectedItems);
+    this.selectedItemsChange.emit(this._selectedItems);
+  }
+
+  isChecked(item: any): boolean {
+    if (this.valuePropertyName) {
+      return this.selectedValues.indexOf(item[this.valuePropertyName]) !== -1;
+    } else return this.selectedItems.indexOf(item) !== -1;
+  }
+}
+
+export const MD_SELECT_DIRECTIVES: any[] = [MdSelect];
diff --git a/src/tdcmp/smartSearch/smartSearch.html b/src/tdcmp/smartSearch/smartSearch.html
new file mode 100644
index 0000000000..77d14b1b48
--- /dev/null
+++ b/src/tdcmp/smartSearch/smartSearch.html
@@ -0,0 +1,39 @@
+<div class="smart-search">
+  <div layout="row">
+
+    <!-- search icon -->
+    <div [hidden]="focused || text">
+      <md-icon class="md-16 search-icon" style="cursor: pointer" (click)="inp.focus(); openPopup()">search</md-icon>
+    </div>
+
+    <!-- chips -->
+    <div layout="row" style="margin-top:-10px;">
+      <md-chip *ngFor="let key of dico.keys" (onClose)="deleteKey(key)"><i>{{key}}:</i> {{dico[key]}}</md-chip>
+    </div>
+
+    <div flex>
+      <input #inp class="md-input-element"
+        [(ngModel)]="text" (focus)="focused=true"
+        (blur)="blur()"
+        (ngModelChange)=textChange($event)
+        (keydown)="keyPress($event.code, $event.ctrlKey)"
+      >
+      <div class="md-input-holder">{{text}}{{_suggestion}}</div>
+    </div>
+
+  </div>
+
+  <div class="md-input-underline">
+    <span class="md-input-ripple" [class.md-focused]="focused"></span>
+  </div>
+
+</div>
+
+<!-- popup -->
+<div class="smart-search-popup" [class.active]=_active [hidden]="!_popupVisible || _items.length==0">
+  <div class="overflow">
+    <span class="item" [class.selected]="item==_selectedItem" *ngFor="let item of _items" (click)="itemClick(item)">
+        <span>{{item}}</span>
+    </span>
+  </div>
+</div>
diff --git a/src/tdcmp/smartSearch/smartSearch.scss b/src/tdcmp/smartSearch/smartSearch.scss
new file mode 100644
index 0000000000..1ce0faa4be
--- /dev/null
+++ b/src/tdcmp/smartSearch/smartSearch.scss
@@ -0,0 +1,152 @@
+.smart-search {
+  position: relative;
+  height: 64px;
+  margin: 0px 0;
+
+.search-icon {
+  transform: scale(0.9);
+  color: #CACACA;
+}
+
+  .md-input-holder {
+    position: absolute;
+    top: 1px;
+    color: #00648c;
+    opacity: 0.7;
+  }
+
+  .md-input-element {
+    // position: absolute;
+    // top:0px;
+    width: 100%;
+    font: inherit;
+    background: transparent;
+    border: none;
+    outline: none;
+    color: blue;
+
+
+
+
+  }
+  .md-input-underline {
+    position: absolute;
+    top:25px;
+    height: 1px;
+    width: 100%;
+    margin-top: 4px;
+    border-top: 1px solid #00648C;
+    .md-input-ripple {
+      position: absolute;
+      height: 2px;
+      z-index: 1;
+      background-color: #00648C;
+      top: -1px;
+      width: 100%;
+      transform-origin:left top;
+      opacity: 0;
+      transform: scale3d(0,0,1);
+      transition: transform 800ms cubic-bezier(0.25, 0.8, 0.25, 1), opacity 800ms cubic-bezier(0.25, 0.8, 0.25, 1);
+      &.md-focused {
+        opacity: 1;
+        transform: scale3d(1,1,1);
+      }
+    }
+  }
+  .keys-container {
+    position: absolute;
+    top: 28px;
+    width: 100%;
+    .key {
+      position: relative;
+      background-color: #38758E;
+      color: white;
+      margin: 1px;
+      border-radius: 50px;
+      border: 1px solid #CACACA;
+
+      padding-right: 35px;
+      padding-left: 10px;
+      padding-bottom: 4px;
+      padding-top: 2px;
+
+      md-icon {
+        position: absolute;
+        cursor: pointer;
+        top:1px;
+        right: 3px;
+        transform: scale(0.6);
+        border-radius: 10px;
+        background: #C34B7D;
+      }
+    }
+  }
+}
+
+.smart-search-popup {
+  color: rgba(0, 0, 0, 0.870588);
+  transition: all 0.4s ease;
+  transform: scaleY(0);
+  transform-origin: right top;
+  box-sizing: border-box;
+  font-family: Roboto, sans-serif;
+  box-shadow: rgba(0, 0, 0, 0.247059) 0 14px 45px, rgba(0, 0, 0, 0.219608) 0 10px 18px;
+  // box-shadow: rgba(0, 0, 0, 0.117647) 0 1px 6px, rgba(0, 0, 0, 0.117647) 0 1px 4px;
+  background-color: rgb(255, 255, 255);
+  border-radius: 2px;
+  opacity: 0;
+  position: fixed;
+  z-index: 2100;
+  padding-top: 5px;
+  padding-bottom: 5px;
+  &.upper {
+    transform-origin: right bottom;
+  }
+  &.active {
+    transform: scaleY(1.0);
+    opacity: 1;
+  }
+  &:not(.active) {
+    transition: all 0.2 ease;
+    transform: scaleY(0);
+    opacity: 0;
+  }
+  div {
+    z-index: 1000;
+    top: 0;
+    right: 0;
+    max-height: 512px;
+    overflow-y: auto;
+    overflow-x: hidden;
+    max-width: 512px;
+    min-width: 192px;
+  }
+  .item {
+    border: 10px;
+    box-sizing: border-box;
+    display: block;
+    font-family: Roboto, sans-serif;
+    cursor: pointer;
+    text-decoration: none;
+    outline: none;
+    font-size: 15px;
+    font-weight: inherit;
+    color: rgba(0, 0, 0, 0.870588);
+    line-height: 32px;
+    position: relative;
+    white-space: nowrap;
+    background: none;
+    &:hover {
+      background-color: rgba(0,0,0,0.0980392);
+    }
+    &.selected {
+      color: rgb(64,64,155);
+      font-weight: bold;
+    }
+    span {
+      margin-left: 0;
+      padding: 0 24px;
+      position: relative;
+    }
+  }
+}
diff --git a/src/tdcmp/smartSearch/smartSearch.ts b/src/tdcmp/smartSearch/smartSearch.ts
new file mode 100644
index 0000000000..11732e881c
--- /dev/null
+++ b/src/tdcmp/smartSearch/smartSearch.ts
@@ -0,0 +1,357 @@
+import {Component, ViewEncapsulation, Input, Output, EventEmitter
+  , AfterViewInit, ElementRef, Renderer, HostListener, OnDestroy} from '@angular/core';
+import {Dictionary} from '../tools/dictionary';
+
+@Component({
+  selector: 'smart-search',
+  template: require('./smartSearch.html'),
+  styles: [require('./smartSearch.scss')],
+  encapsulation: ViewEncapsulation.None
+})
+export class SmartSearch implements AfterViewInit, OnDestroy {
+  @Input() public keys: {
+    [key: string]: (text: string
+      , filters: { [key: string]: string }) => Array<string>
+  };
+  @Input() public text: string;
+  @Input() public dico: Dictionary = new Dictionary([]);
+  @Output() filterChange: EventEmitter<{ [key: string]: string }> =
+  new EventEmitter<{ [key: string]: string }>();
+
+  public filters: { [key: string]: string } = {};
+
+  private _items: Array<string> = [];
+
+  private get _suggestion(): string {
+    if (!this._lockedKey) {
+      if (!this._key) return undefined;
+      if (!this.text) return this._key;
+      return this._key.substring(this.text.length);
+    } else {
+      if (!this._candidate) return undefined;
+      if (!this._value) return this._candidate;
+      return this._candidate.substring(this._value.length);
+    }
+  }
+
+  private _key: string;
+  private _lockedKey: string;
+
+  private get _value(): string {
+    if (!this.text || !this._lockedKey) return undefined;
+    return this.text.substring((this._lockedKey + ': ').length);
+  }
+
+  private get _keys(): Array<string> {
+    let arr = [];
+    for (let key in this.keys) {
+      if (true === true)
+        arr.push(key);
+    }
+    return arr;
+  }
+
+  private get _selectedItem(): string {
+    if (this._lockedKey) return this._candidate;
+    return this._key;
+  }
+  private set _selectedItem(value: string) {
+    if (this._lockedKey) {
+      this._candidate = value;
+    } else this._key = value;
+  }
+
+  private _candidate: string;
+
+  private _overlay: Element;
+  private _popup: Element;
+  private _input: HTMLElement;
+  private _overflow: HTMLElement;
+  private _popupVisible: boolean = false;
+  private _active: boolean = false;
+  private focused: boolean;
+
+  constructor(private _elementRef: ElementRef, private _renderer: Renderer) { }
+
+  ngAfterViewInit() {
+    this._overlay = document.getElementsByClassName('md-overlay-container')[0];
+    this._popup = this._elementRef.nativeElement.getElementsByClassName('smart-search-popup')[0];
+    this._input = this._elementRef.nativeElement.getElementsByClassName('md-input-element')[0];
+    this._overflow = this._elementRef.nativeElement.getElementsByClassName('overflow')[0];
+    this._overlay.appendChild(this._popup);
+    // this._input.focus();
+  }
+  blur() {
+    this.focused = false;
+    if (!this._popupVisible) return;
+    setTimeout(() => {
+      if (this.focused) return;
+      this._active = false;
+      setTimeout(() => {
+        this._popupVisible = false;
+      }, 200);
+    }, 200);
+  }
+  textChange(text: string) {
+    // Check if we've lost locked key
+    if (this._lockedKey && text.toUpperCase().startsWith(this._lockedKey.toUpperCase() + ':')) {
+      // Todo manage input items
+      this._items = this.getCandidates(this._lockedKey, this._value);
+      this._candidate = undefined;
+      for (let candidate of this._items) {
+        if (candidate.toUpperCase().indexOf(this._value.toUpperCase()) !== -1) {
+          if (!this._candidate) this._candidate = candidate;
+          // this._items.push(candidate);
+        }
+      }
+      return;
+    }
+    this._candidate = undefined;
+    this._lockedKey = undefined;
+    if (!this._popupVisible) this.openPopup(); else
+      this.setPosition();
+
+
+
+    this._key = undefined;
+    if (!text || text === '') {
+      this._items = this._keys;
+      return;
+    }
+
+    this._items = [];
+
+    for (let key in this.keys) {
+      if (key.toUpperCase().startsWith(text.toUpperCase())) {
+        if (!this._key) {
+          this._key = key;
+        }
+        this._items.push(key);
+      }
+    }
+  }
+
+
+  keyPress(code: string, ctrlKey: boolean) {
+    switch (code) {
+      case 'Space':
+        if (ctrlKey) {
+          this.togglePopup();
+        }
+        break;
+      case 'PageUp':
+        this.pageUp();
+        break;
+      case 'PageDown':
+        this.pageDown();
+        break;
+      case 'ArrowDown':
+      case 'ArrowUp':
+        this.manageArrowKeys(code);
+        break;
+      case 'Escape':
+        this.manageEscapeKey();
+        break;
+      case 'Enter':
+      case 'NumpadEnter':
+        this.manageEnterKey();
+        break;
+      case 'Backspace':
+        if ((!this.text || this.text === '') && this.dico.keys.length > 0) {
+          this.deleteKey(this.dico.keys[this.dico.keys.length - 1]);
+          setTimeout(() => this.setPosition());
+        }
+        break;
+      default:
+        return;
+    }
+  }
+
+  manageEnterKey() {
+    if (this._lockedKey) {
+      if (this._candidate) {
+        this.addKey(this._lockedKey, this._candidate);
+        // this.text = this._lockedKey + ': ' + this._candidate;
+        setTimeout(() => this.setPosition());
+        this.closePopup();
+        return;
+      }
+      if (!this._value) return;
+      this.addKey(this._lockedKey, this._value);
+      // if (!this._popupVisible) this.openPopup(); else this.setPosition();
+      if (this._popupVisible) this.setPosition();
+      return;
+    }
+
+    if (this._key) {
+      this.lockKey(this._key);
+    }
+  }
+
+  manageArrowKeys(code: string) {
+    let length = this._items.length;
+    if (length === 0) return;
+
+    if (!this._selectedItem) {
+      // No element selected, select first or last
+      if (code === 'ArrowDown') {
+        this._selectedItem = this._items[0];
+        return;
+      }
+      this._selectedItem = this._items[length - 1];
+      this._overflow.scrollTop = length * 32;
+      return;
+    }
+    let index = this._items.indexOf(this._selectedItem);
+    let st = this._overflow.scrollTop;
+    if (code === 'ArrowDown') {
+      if (index === length - 1) return;
+      this._selectedItem = this._items[index + 1];
+      if (index + 1 - st / 32 > 15)
+        this._overflow.scrollTop = st + 32;
+    } else {
+      if (index === 0) return;
+      this._selectedItem = this._items[index - 1];
+      if (index - 1 - st / 32 < 0)
+        this._overflow.scrollTop = st - 32;
+    }
+  }
+
+
+  pageUp() {
+    let length = this._items.length;
+    if (length === 0) return;
+    if (!this._selectedItem) {
+      this._selectedItem = this._items[length - 1];
+      this._overflow.scrollTop = length * 32;
+      return;
+    }
+    let index = this._items.indexOf(this._selectedItem);
+    if (index === 0) return;
+    let newIndex = index - 16;
+    if (newIndex < 0) newIndex = 0;
+    this._selectedItem = this._items[newIndex];
+    let st = this._overflow.scrollTop;
+    if (newIndex - st / 32 < 0) this._overflow.scrollTop = st  + (newIndex - index) * 32;
+  }
+
+  pageDown() {
+    let length = this._items.length;
+    if (length === 0) return;
+    if (!this._selectedItem) {
+      // No element selected, select first or last
+      this._selectedItem = this._items[0];
+      return;
+    }
+    let index = this._items.indexOf(this._selectedItem);
+    if (index === length - 1) return;
+    let st = this._overflow.scrollTop;
+    let newIndex = index + 16;
+    if (newIndex >= length) newIndex = length - 1;
+    this._selectedItem = this._items[newIndex];
+    if (newIndex - st / 32 > 15) this._overflow.scrollTop = st + (newIndex - index) * 32;
+  }
+
+
+  manageEscapeKey() {
+    if (!this._lockedKey) {
+      this.text = undefined;
+      this._key = undefined;
+      this._items = this._keys;
+    } else {
+      if (this.text === this._lockedKey + ': ') {
+        this._lockedKey = undefined;
+        this.text = undefined;
+        this._key = undefined;
+        this._items = this._keys;
+      } else this.text = this._lockedKey + ': ';
+    }
+    this.closePopup();
+  }
+
+  itemClick(item: string) {
+    if (!this._lockedKey) this.lockKey(item); else {
+      this.addKey(this._lockedKey, item);
+    }
+
+    this._input.focus();
+  }
+
+  lockKey(key: string) {
+    if (!this._lockedKey) {
+      this._lockedKey = key;
+      this.text = key + ': ';
+      this._key = undefined;
+      this._candidate = undefined;
+      this._items = this.getCandidates(key, undefined);
+      // if (this.keys[key]) this._candidates = this.keys[key](''); else this._candidates = [];
+      // this._items = this._candidates;
+      this.setPosition();
+    }
+  }
+
+  getCandidates(key: string, text: string): Array<string> {
+    if (!this.keys[key]) return [];
+    return this.keys[key](text, this.filters);
+  }
+
+  addKey(key: string, value: string) {
+    this.dico.add(this._lockedKey, value);
+    this.filters[this._lockedKey] = value;
+    this._lockedKey = undefined;
+    this.text = '';
+    this._items = this._keys;
+    this.filterChange.emit(this.filters);
+    setTimeout(() => this.setPosition());
+  }
+
+  deleteKey(key: string) {
+    this.dico.remove(key);
+    delete this.filters[key];
+    this.filterChange.emit(this.filters);
+  }
+
+  togglePopup() {
+    if (this._popupVisible) this.closePopup(); else this.openPopup();
+  }
+
+  openPopup() {
+    if (!this._lockedKey) {
+      // this._items = [];
+      this._items = this._keys;
+    } else {
+      // ToDo input items
+      this._items = this.getCandidates(this._lockedKey, this._value);
+    }
+    this.setPosition();
+    this._popupVisible = true;
+    setTimeout(() => {
+      this._active = true;
+    }, 10);
+  }
+
+  closePopup() {
+    this._popupVisible = false;
+  }
+
+  setPosition() {
+    let rec = this._input.getBoundingClientRect();
+    this._renderer.setElementStyle(this._popup, 'top', rec.bottom + 10 + 'px');
+    if (!this._lockedKey)
+      this._renderer.setElementStyle(this._popup, 'left', rec.left + 'px'); else
+      this._renderer.setElementStyle(
+        this._popup, 'left', rec.left + ((this._lockedKey.length + 2) * 6) + 'px');
+  }
+
+  isInElement(element, x, y): boolean {
+    let rect = element.getBoundingClientRect();
+    return rect.top <= y &&
+      y <= rect.top + rect.height &&
+      rect.left <= x &&
+      x <= rect.left + rect.width;
+  }
+
+  ngOnDestroy() {
+    this._overlay.removeChild(this._popup);
+  }
+}
diff --git a/src/tdcmp/snackbar/snackbar.html b/src/tdcmp/snackbar/snackbar.html
new file mode 100644
index 0000000000..f52dd7b752
--- /dev/null
+++ b/src/tdcmp/snackbar/snackbar.html
@@ -0,0 +1,10 @@
+<div class="snackbar" [class.open]="opened" >
+    <div width="2" class="snackbarbody" [class.small]="small" [class.error]=error>
+        <div class="content" [class.open]="opened">
+          <span>{{message}}</span>
+          <button *ngIf="action" tabindex="0" class="actionbutton" [class.error]=error (click)="opened = false">
+              <div><span>{{action}}</span></div>
+          </button>
+        </div>
+    </div>
+</div>
diff --git a/src/tdcmp/snackbar/snackbar.scss b/src/tdcmp/snackbar/snackbar.scss
new file mode 100644
index 0000000000..bcc026ed49
--- /dev/null
+++ b/src/tdcmp/snackbar/snackbar.scss
@@ -0,0 +1,88 @@
+.snackbar {
+  position: fixed;
+  left: 0;
+  display: flex;
+  right: 0;
+  bottom: 0;
+  z-index: 2900;
+  visibility: hidden;
+  transform: translate3d(0px, 48px, 0px);
+  transition: transform 400ms cubic-bezier(0.23, 1, 0.32, 1), visibility 400ms cubic-bezier(0.23, 1, 0.32, 1);
+  &.open {
+    visibility: visible;
+    transform: translate3d(0px, 0px, 0px);
+  }
+  .snackbarbody {
+    padding: 0 24px;
+    height: 48px;
+    line-height: 48px;
+    border-radius: 2px;
+    max-width: 568px;
+    min-width: 288px;
+    flex-grow: 0;
+    margin: auto;
+    background-color: rgba(0, 100, 140, 0.870588);
+    &.error {
+      background-color: rgba(255, 0, 0, 0.870588);
+    }
+    &.small {
+        border-radius: 0px;
+        max-width: inherit;
+        min-width: inherit;
+        flex-grow: 1;
+    }
+
+    .content {
+      font-size: 14px;
+      color: rgb(255, 255, 255);
+      opacity: 0;
+      transition: opacity 400ms cubic-bezier(0.23, 1, 0.32, 1);
+      &.open {
+          transition: opacity 500ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
+          opacity: 1;
+      }
+      .actionbutton {
+        border: 10px;
+        box-sizing: border-box;
+        display: inline-block;
+        font-family: Roboto, sans-serif;
+        -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+        cursor: pointer;
+        text-decoration: none;
+        margin: 6px -16px 0 24px;
+        padding: 0;
+        outline: none;
+        font-size: inherit;
+        font-weight: inherit;
+        transform: translate3d(0px, 0px, 0px);
+        height: 36px;
+        line-height: 36px;
+        min-width: 88px;
+        color: rgb(255, 255, 255);
+        transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1);
+        border-radius: 2px;
+        position: relative;
+        overflow: hidden;
+        text-align: center;
+        float: right;
+        -webkit-user-select: none;
+        background-color: transparent;
+        &.error {
+          color: rgb(255, 255, 255);
+        }
+        div {
+          span {
+            position: relative;
+            padding-left: 16px;
+            padding-right: 16px;
+            vertical-align: middle;
+            letter-spacing: 0;
+            text-transform: uppercase;
+            font-weight: 500;
+            font-size: 14px;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/src/tdcmp/snackbar/snackbar.ts b/src/tdcmp/snackbar/snackbar.ts
new file mode 100644
index 0000000000..4254edb89d
--- /dev/null
+++ b/src/tdcmp/snackbar/snackbar.ts
@@ -0,0 +1,47 @@
+import {Component, Input, EventEmitter, HostListener, HostBinding
+  , ElementRef, OnInit, OnDestroy, Renderer } from '@angular/core';
+
+@Component({
+  selector: 'md-snackbar',
+  template: require('./snackbar.html'),
+  styles: [require('./snackbar.scss')],
+  directives: []
+})
+export class MdSnackBar {
+  opened: boolean = false;
+  small: boolean = false;
+  action: string = 'Ok';
+  timeout: number = 5000;
+  public error: boolean = false;
+  timer: any;
+
+@Input()
+public get message(): string {return this._message; }
+public set message(value: string) {
+  this._message = value;
+  if (value && value !== '') {
+
+    if (this.opened) {
+      clearTimeout(this.timer);
+      this.opened = false;
+      setTimeout(() => this.open(), 400);
+    } else this.open();
+  }
+}
+
+private _message: string = undefined;
+
+open() {
+  this.opened = true;
+  this.timer = setTimeout(() => {
+    this.opened = false;
+    this.message = undefined;
+  }, this.timeout);
+}
+
+
+
+  constructor() {}
+}
+
+export const MD_SNACKBAR_DIRECTIVES: any[] = [MdSnackBar];
diff --git a/src/tdcmp/styles/tdcmp.scss b/src/tdcmp/styles/tdcmp.scss
new file mode 100644
index 0000000000..150c511285
--- /dev/null
+++ b/src/tdcmp/styles/tdcmp.scss
@@ -0,0 +1,38 @@
+.footerButton {
+  border: 10px;
+  box-sizing: border-box;
+  display: inline-block;
+  font-family: Roboto, sans-serif;
+  cursor: pointer;
+  text-decoration: none;
+  margin: 0;
+  padding: 0;
+  outline: none;
+  font-size: inherit;
+  font-weight: inherit;
+  transform: translate3d(0px, 0px, 0px);
+  height: 36px;
+  line-height: 36px;
+  min-width: 88px;
+  color: rgb(0, 188, 212);
+  transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1);
+  border-radius: 2px;
+  position: relative;
+  overflow: hidden;
+  text-align: center;
+  -webkit-user-select: none;
+  background-color: rgba(0, 0, 0, 0);
+  &:hover {
+    background-color: rgba(153, 153, 153, 0.2);
+  }
+  span {
+    position: relative;
+    padding-left: 16px;
+    padding-right: 16px;
+    vertical-align: middle;
+    letter-spacing: 0;
+    text-transform: uppercase;
+    font-weight: 500;
+    font-size: 14px;
+  }
+}
diff --git a/src/tdcmp/tdcombobox/tdcombobox.component.ts b/src/tdcmp/tdcombobox/tdcombobox.component.ts
new file mode 100644
index 0000000000..f685c06817
--- /dev/null
+++ b/src/tdcmp/tdcombobox/tdcombobox.component.ts
@@ -0,0 +1,91 @@
+import { Component, Input, Output, EventEmitter, HostListener } from '@angular/core';
+
+@Component({
+  selector: 'tdcombobox',
+  template: require('./tdcombobox.html'),
+  styles: [require('./tdcombobox.scss')]
+})
+
+export class TdComboBox {
+  @Input() displayMember: string;
+  @Input() placeholder: string;
+  @Output() selectedItemChanged = new EventEmitter();
+  @Output() inputChanged = new EventEmitter();
+  _selectedItem: any;
+  visible: boolean = false;
+  _selectedItemName: string = undefined;
+  inputChangedTimer: any;
+  _items: any = undefined;
+  _searchlist: Element;
+  @Input()
+  get items() {
+    return this._items;
+  }
+  set items(value: any) {
+    if (value && value.length > 0) {
+      this._items = value;
+      this.visible = true;
+    } else {
+      this.visible = false;
+    }
+  }
+
+  @Input()
+  get selectedItem() {
+    return this._selectedItem;
+  }
+  set selectedItem(value: any) {
+    if (value === undefined) {
+      this._selectedItemName = '';
+    } else {
+      this._selectedItem = value;
+      this._selectedItemName = this.displayMember ? value[this.displayMember] : value;
+      this.selectedItemChanged.emit(this.selectedItem);
+    }
+  }
+
+  get selectedItemName () {
+    return this._selectedItemName;
+  }
+  set selectedItemName(value: string) {
+    clearTimeout(this.inputChangedTimer);
+    this._selectedItemName = value;
+    this.inputChangedTimer = setTimeout(() => {
+       this.inputChanged.emit(value); }, 100 );
+  }
+
+  @HostListener('body:click', ['$event'])
+  closeSearch($event: MouseEvent) {
+    if (!this._searchlist) {
+      this._searchlist = document.getElementsByClassName('tdcombobox')[0];
+    }
+    if (this.visible &&
+      !this.isInElement(this._searchlist, $event.clientX, $event.clientY)) {
+      this.items = [];
+    }
+    if (!this.visible &&
+      this.isInElement(this._searchlist, $event.clientX, $event.clientY)) {
+        this.inputChangedTimer = setTimeout(() => {
+        this.inputChanged.emit(''); }, 100 );
+      }
+  }
+  isInElement(element, x, y): boolean {
+     let rect = element.getBoundingClientRect();
+     return rect.top <= y &&
+       y <= rect.top + rect.height &&
+       rect.left <= x &&
+       x <= rect.left + rect.width;
+   }
+
+  onBlur() {
+    setTimeout(() => {
+      this.visible = false;
+    }, 100 );
+  }
+
+  selectItem(item) {
+    this.visible = false;
+    this.selectedItem = item;
+    this.selectedItemChanged.emit(this.selectedItem);
+  }
+}
diff --git a/src/tdcmp/tdcombobox/tdcombobox.html b/src/tdcmp/tdcombobox/tdcombobox.html
new file mode 100644
index 0000000000..f9f5c5189b
--- /dev/null
+++ b/src/tdcmp/tdcombobox/tdcombobox.html
@@ -0,0 +1,14 @@
+<div class="tdcombobox">
+  <md-input [placeholder]=placeholder [(ngModel)]="selectedItemName"></md-input>
+  <svg viewBox="0 0 24 24" style="cursor:pointer; display: inline-block; fill: rgb(158, 158, 158); height: 24px; width: 24px; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; position: absolute; right: 0px; top: 14px; -webkit-user-select: none;">
+    <path d="M7 10l5 5 5-5z"></path>
+  </svg>
+  <div class="list-container" [style.display]="visible?'inherit':'none'">
+    <md-nav-list dense>
+      <md-list-item *ngFor="let item of items" (click)=selectItem(item)>
+        <span *ngIf=displayMember md-line >{{ item.name }}</span>
+        <span *ngIf=!displayMember md-line>{{ item }}</span>
+      </md-list-item>
+    </md-nav-list>
+  </div>
+</div>
diff --git a/src/tdcmp/tdcombobox/tdcombobox.scss b/src/tdcmp/tdcombobox/tdcombobox.scss
new file mode 100644
index 0000000000..b20282a2b1
--- /dev/null
+++ b/src/tdcmp/tdcombobox/tdcombobox.scss
@@ -0,0 +1,35 @@
+@import "../../styles/promethee";
+
+.tdcombobox {
+  $item-height : 32px;
+
+   position: relative;
+   display: block;
+   width: 100%;
+   padding:0;
+
+  md-input{
+    width: 100%;
+  }
+
+  .list-container{
+    background-color: rgb(255,255,255);
+    box-shadow: 0 0 3px #505050;
+    // display: block;
+    z-index: 1000;
+    position: absolute;
+    left:1px;
+    top: 45px;
+    min-height: $item-height;
+    max-height: 5*$item-height;
+    overflow-y: auto;
+    width: calc(100% - 2px);
+     md-nav-list {
+       md-list-item{
+         .md-list-item{
+           height: $item-height !important;
+         }
+       }
+     }
+  }
+}
diff --git a/src/tdcmp/tools/dateUtils.ts b/src/tdcmp/tools/dateUtils.ts
new file mode 100644
index 0000000000..0c3bb0d9d8
--- /dev/null
+++ b/src/tdcmp/tools/dateUtils.ts
@@ -0,0 +1,94 @@
+import { Response } from '@angular/http';
+import {Json, isString} from '@angular/core/src/facade/lang';
+import {isJsObject} from '@angular/http/src/http_utils';
+
+
+export class DateUtils {
+
+  public static addDays(d: Date, days: number): Date {
+    const newDate = this.cloneDate(d);
+    newDate.setDate(d.getDate() + days);
+    return newDate;
+  }
+
+  public static cloneDate(d: Date): Date {
+    return new Date(d.getTime());
+  }
+
+  public static getDaysInMonth(d: Date): number {
+    const resultDate = this.getFirstDayOfMonth(d);
+
+    resultDate.setMonth(resultDate.getMonth() + 1);
+    resultDate.setDate(resultDate.getDate() - 1);
+
+    return resultDate.getDate();
+  }
+
+
+  public static getFirstDayOfMonth(d: Date): Date {
+    return new Date(d.getFullYear(), d.getMonth(), 1);
+  }
+
+  public static getFirstDayOfWeek(): Date {
+    const now = new Date();
+    return new Date(now.setDate(now.getDate() - now.getDay()));
+  }
+
+  public static getWeekArray(d: Date, firstDayOfWeek: number) {
+    const dayArray: Array<Date> = [];
+    const daysInMonth = this.getDaysInMonth(d);
+    const weekArray = [];
+    let week = [];
+
+    for (let i = 1; i <= daysInMonth; i++) {
+      dayArray.push(new Date(d.getFullYear(), d.getMonth(), i));
+    }
+
+    const addWeek = (week) => {
+      const emptyDays = 7 - week.length;
+      for (let i = 0; i < emptyDays; ++i) {
+        week[weekArray.length ? 'push' : 'unshift'](undefined);
+      }
+      weekArray.push(week);
+    };
+
+    dayArray.forEach((day) => {
+      if (week.length > 0 && day.getDay() === firstDayOfWeek) {
+        addWeek(week);
+        week = [];
+      }
+      week.push(day);
+      if (dayArray.indexOf(day) === dayArray.length - 1) {
+        addWeek(week);
+      }
+    });
+
+    return weekArray;
+  }
+
+  public static addMonths(d: Date, months: number): Date {
+  const newDate = this.cloneDate(d);
+  newDate.setMonth(d.getMonth() + months);
+  return newDate;
+}
+
+public static JsonDate(r: Response): any {
+
+  if (isJsObject(r.text())) return r.text();
+
+  if (isString(r.text())) {
+        return JSON.parse(<string>r.text()
+        , function (key, value) {
+            if (typeof value === 'string') {
+              if (/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})((?:\.\d*)?)(?:Z|(\+|-)([\d|:]*))?$/.exec(value))
+              return new Date(value);
+            }
+            return value;
+          }
+        );
+      }
+}
+
+
+
+}
diff --git a/src/tdcmp/tools/dictionary.ts b/src/tdcmp/tools/dictionary.ts
new file mode 100644
index 0000000000..805e3f1404
--- /dev/null
+++ b/src/tdcmp/tools/dictionary.ts
@@ -0,0 +1,62 @@
+export interface IDictionary {
+    keys: string[];
+    add(key: string, value: any): void;
+    remove(key: string): void;
+    containsKey(key: string): boolean;
+    values(): any[];
+}
+
+export class Dictionary implements IDictionary {
+
+    _keys: string[] = [];
+    _values: any[] = [];
+
+    constructor(init: { key: string; value: any; }[]) {
+
+        for (let x = 0; x < init.length; x++) {
+            this[init[x].key] = init[x].value;
+            this._keys.push(init[x].key);
+            this._values.push(init[x].value);
+        }
+    }
+
+    add(key: string, value: any) {
+       let index = this._keys.indexOf(key);
+       if (index !== -1) {
+         this._values[index] = value;
+         this[key] = value;
+         return;
+       }
+        this[key] = value;
+        this._keys.push(key);
+        this._values.push(value);
+    }
+
+    remove(key: string) {
+        let index = this._keys.indexOf(key, 0);
+        this._keys.splice(index, 1);
+        this._values.splice(index, 1);
+
+        delete this[key];
+    }
+
+    public get keys(): string[] {
+        return this._keys;
+    }
+
+    values(): any[] {
+        return this._values;
+    }
+
+    containsKey(key: string) {
+        if (typeof this[key] === 'undefined') {
+            return false;
+        }
+
+        return true;
+    }
+
+    toLookup(): IDictionary {
+        return this;
+    }
+}
diff --git a/src/tdcmp/tools/tools.ts b/src/tdcmp/tools/tools.ts
new file mode 100644
index 0000000000..e51de7e3b7
--- /dev/null
+++ b/src/tdcmp/tools/tools.ts
@@ -0,0 +1,23 @@
+export class Objector {
+  public static clone(obj: any): any {
+    let res: any = {};
+    for (let attribut in obj) {
+      if (typeof obj[attribut] === 'object') {
+           res[attribut] = Objector.clone(obj[attribut]);
+       } else  {
+         res[attribut] = obj[attribut];
+      }
+    }
+    return res;
+  }
+
+  public static copy(source: any, target: any) {
+    for (let attribut in source) {
+      if (typeof source[attribut] === 'object') {
+           Objector.copy(source[attribut], target[attribut]);
+       } else  {
+         target[attribut] = source[attribut];
+      }
+    }
+  }
+}
diff --git a/src/tdcmp/treeView/treeView.scss b/src/tdcmp/treeView/treeView.scss
new file mode 100644
index 0000000000..49eff218f2
--- /dev/null
+++ b/src/tdcmp/treeView/treeView.scss
@@ -0,0 +1,95 @@
+.treeview {
+  height: 100%;
+  width: 100%;
+  border: solid 1px #00648c;
+  padding-right: 5px;
+  ul {
+    list-style: none;
+
+  }
+  .content {
+    position: relative;
+  }
+  .arrow {
+    position: absolute;
+    top: -5px;
+    left: -27px;
+    transform: rotate(90deg) scale(0.8);
+    cursor: pointer;
+    color: #00648c;
+    opacity: 0.8;
+    // transition: all 0.2s ease 0.1s;
+    &.collapsed {
+      transform: scale(0.8);
+      top: -3px;
+    }
+    &:hover {
+      opacity: 0.6;
+    }
+  }
+  .horizontalLine {
+    width: 40px;
+    height: 1px;
+    position: absolute;
+    left: -51px;
+    top:10px;
+     border-bottom-style: dotted;
+     border-bottom-width: 1px;
+     border-bottom-color: black;
+    &.hasArrow {
+      width: 30px;
+    }
+  }
+  .children {
+    display: block;
+    position: relative;
+    &.collapsed {
+      display: none;
+    }
+
+  }
+  .verticalLine {
+    width: 100px;
+    // height: 100%;
+    position: absolute;
+    left: -14px;
+    top: -7px;
+    border-left-style: dotted;
+    border-left-width: 1px;
+    border-left-color: black;
+  }
+
+  .iconContainer {
+    position: relative;
+    display: inline-block;
+    .icon {
+      position: absolute;
+      top: -17px;
+      left: -5px;
+      transform: scale(0.6);
+      color: #00648c;
+      cursor: pointer;
+      &:hover {
+        opacity: 0.7;
+      }
+    }
+  }
+
+  .separator {
+    width:10px;
+    display:inline-block
+  }
+
+  .label {
+    cursor: pointer;
+    &:hover {
+      color: #00648c;
+      // opacity: 0.6;
+    }
+    &.selected {
+        color: #00648c;
+    }
+  }
+
+
+}
diff --git a/src/tdcmp/treeView/treeView.ts b/src/tdcmp/treeView/treeView.ts
new file mode 100644
index 0000000000..3b95ffbf99
--- /dev/null
+++ b/src/tdcmp/treeView/treeView.ts
@@ -0,0 +1,124 @@
+export interface INode {
+  label: string;
+  data?: any;
+  icon?: string;
+  type?: string;
+  selected?: boolean;
+  huttonIcon?: string;
+  menuItems?: Array<string>;
+  children?: Array<INode>;
+};
+
+import {Component, Input, Output, EventEmitter, HostListener, HostBinding
+  , ElementRef, OnDestroy, Renderer, ViewEncapsulation, ViewChildren
+  , QueryList, ChangeDetectorRef } from '@angular/core';
+
+
+  @Component({
+    selector: 'treeviewnode',
+    template: require('./treeViewNode.html'),
+    styles: [require('./treeView.scss')],
+    directives: [TreeViewNode],
+    encapsulation: ViewEncapsulation.None
+  })
+  export class TreeViewNode {
+    @Input() node: INode;
+    @Input() parent: INode;
+    @Input() root: TreeView;
+    @ViewChildren(TreeViewNode) viewChildren: QueryList<TreeViewNode>;
+    get huttonClicked(): EventEmitter<INode> {
+      return this.root.huttonClicked;
+    }
+
+    collapsed: boolean = false;
+    private _oldHeight;
+
+    constructor(private changeDetectorRef: ChangeDetectorRef) {
+    }
+    get selectedNode(): INode {
+      return this.root.selectedNode;
+    }
+
+    get hasChildren(): boolean {
+      return this.node.children && this.node.children.length > 0;
+    }
+
+    toggleCollapse() {
+      if (this.collapsed) this.collapsed = false; else this.collapsed = true;
+    }
+
+    select(node: INode) {
+      this.root.selectedNode = node;
+    }
+
+    get computeHeight(): number {
+      let h = 29;
+      if (this.collapsed || !this.viewChildren) return h;
+      this.viewChildren.forEach(p => h += p.computeHeight);
+      return h;
+    }
+
+    public get lineHight(): number {
+      if (this.collapsed || !this.viewChildren) return 0;
+      if (this.viewChildren.length === 0) return 0;
+
+      let h = -10; // top of horizontal line
+      this.viewChildren.forEach(p => {
+            if (this.viewChildren.last !== p) h += p.computeHeight; else h += 29;
+      });
+
+      if (h !== this._oldHeight) {
+        this._oldHeight = h;
+        this.changeDetectorRef.detectChanges();
+      }
+      return h;
+    }
+
+    huttonClick(node: INode) {
+      this.root.huttonClicked.emit(node);
+    }
+
+    menuClick(node: INode, text: string) {
+        this.root.menuClicked.emit({node: node, text: text});
+    }
+  }
+
+
+@Component({
+  selector: 'treeview',
+  template: `
+  <div class="treeview" *ngIf="node">
+    <treeviewnode [node]=node [root]=self></treeviewnode>
+    <ng-content></ng-content>
+  </div>
+  `,
+  styles: [require('./treeView.scss')],
+  directives: [TreeViewNode],
+  encapsulation: ViewEncapsulation.None
+})
+export class TreeView {
+@Input() node: INode;
+@Output() nodeSelected: EventEmitter<INode> = new EventEmitter<INode>();
+@Output() huttonClicked: EventEmitter<INode> = new EventEmitter<INode>();
+@Output() menuClicked: EventEmitter<any> = new EventEmitter<any>();
+
+public get selectedNode(): INode {
+  return this._selectedNode;
+}
+public set selectedNode(value: INode) {
+  if (this._selectedNode !== value) {
+    this._selectedNode = value;
+    this.nodeSelected.emit(value);
+  }
+}
+private _selectedNode: INode;
+
+// This is used to bind parent in child nodes
+get self(): TreeView {
+  return this;
+}
+
+
+
+
+}
diff --git a/src/tdcmp/treeView/treeViewNode.html b/src/tdcmp/treeView/treeViewNode.html
new file mode 100644
index 0000000000..7745ae8496
--- /dev/null
+++ b/src/tdcmp/treeView/treeViewNode.html
@@ -0,0 +1,43 @@
+<ul>
+  <li>
+    <div class="content">
+      <div class="horizontalLine" [class.hasArrow]="hasChildren" *ngIf=parent></div>
+      <span *ngIf=hasChildren class="arrow" [class.collapsed]=collapsed (click)=toggleCollapse()>
+        <md-icon>play_arrow</md-icon>
+      </span>
+      <div style="margin-bottom: 10px;">
+        <span *ngIf="node.icon" class="iconContainer">
+          <md-icon class="icon" (click)="select(node)">{{node.icon}}</md-icon>
+        </span>
+        <span *ngIf="node.icon" class="separator"></span>
+        <span class="label" [class.selected]="node==selectedNode">
+          <hutton (huttonClick)=huttonClick(node) (labelClick)=select(node)>
+              {{node.label}}
+              <trigger>
+                <td-menu (menuSelected)="menuClick(node, $event)">
+                  <md-icon >{{node.huttonIcon}}</md-icon>
+                    <button *ngIf="node.huttonIcon" md-mini-fab style="transform: scale(0.5); background-color: #00648c"><md-icon style="color:white">{{node.huttonIcon}}</md-icon></button>
+                  <!-- <button md-mini-fab style="transform: scale(0.5); background-color: #00648c"><md-icon style="transform: scale(2); background-color: white;">{{node.huttonIcon}}</md-icon></button> -->
+                  <td-menu-items>
+                    <span *ngFor="let item of node.menuItems">
+                      <td-menu-item *ngIf="item!='-'">{{item}}</td-menu-item>
+                      <md-divider *ngIf="item=='-'"></md-divider>
+                  </span>
+                </td-menu-items>
+                </td-menu>
+              </trigger>
+              <!-- <trigger>
+                <md-icon *ngIf="node.huttonIcon">{{node.huttonIcon}}</md-icon>
+              </trigger> -->
+        </hutton>
+
+        </span>
+      </div>
+    </div>
+    <div class="children" [class.collapsed]=collapsed [hidden]="!hasChildren">
+      <div class="verticalLine" [style.height.px]="lineHight"></div>
+      <treeviewnode *ngFor="let child of node.children" [node]=child [parent]=node [root]=root>
+      </treeviewnode>
+    </div>
+  </li>
+</ul>
diff --git a/tsconfig.json b/tsconfig.json
index eece1a052a..5df73c00f6 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -6,14 +6,44 @@
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,
     "sourceMap": true,
-    "noEmitHelpers": true
+    "noEmitHelpers": true,
+    "strictNullChecks": false,
+    "baseUrl": "./src",
+    "paths": [
+    ],
+    "lib": [
+      "es6",
+      "dom"
+    ],
+    "types": [
+     "core-js",
+     "hammerjs",
+     "jasmine",
+     "node",
+     "protractor",
+     "selenium-webdriver",
+     "source-map",
+     "uglify-js",
+     "webpack"
+   ]
   },
   "exclude": [
-    "node_modules"
+    "node_modules",
+    "dist"
   ],
   "awesomeTypescriptLoaderOptions": {
-    "forkChecker": true,
-    "useWebpackText": true
+  "forkChecker": true,
+  "useWebpackText": true
+},
+  "filesGlob": [
+    "./src/**/*.ts",
+    "!./node_modules/**",
+    "./src/custom-typings.d.ts",
+    "./typings/index.d.ts"
+  ],
+  "awesomeTypescriptLoaderOptions": {
+    "resolveGlobs": true,
+    "forkChecker": true
   },
   "compileOnSave": false,
   "buildOnSave": false,
diff --git a/typings.json b/typings.json
deleted file mode 100644
index db6aba8649..0000000000
--- a/typings.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "globalDependencies": {
-    "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459",
-    "core-js": "registry:dt/core-js#0.0.0+20160602141332",
-    "hammerjs": "registry:dt/hammerjs#2.0.4+20160417130828",
-    "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
-    "node": "registry:dt/node#6.0.0+20160621231320",
-    "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654",
-    "source-map": "registry:dt/source-map#0.0.0+20160317120654",
-    "uglify-js": "registry:dt/uglify-js#2.6.1+20160316155526",
-    "webpack": "registry:dt/webpack#1.12.9+20160523035535"
-  }
-}
