├── .editorconfig ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── README.md ├── app.json ├── empty.js ├── nodemon.json ├── package.json ├── src ├── __workaround.browser.ts ├── __workaround.node.ts ├── angular2-meta.ts ├── app │ ├── about │ │ ├── about.component.css │ │ ├── about.component.html │ │ ├── about.component.spec.ts │ │ └── about.component.ts │ ├── app-routing.module.ts │ ├── app.component.html │ ├── app.component.ts │ ├── app.module.ts │ ├── contact │ │ ├── contact.component.css │ │ ├── contact.component.html │ │ ├── contact.component.spec.ts │ │ └── contact.component.ts │ ├── home │ │ ├── home.component.css │ │ ├── home.component.html │ │ ├── home.component.spec.ts │ │ └── home.component.ts │ └── shared │ │ ├── api.service.ts │ │ ├── cache.service.ts │ │ ├── model │ │ └── model.service.ts │ │ └── shared.module.ts ├── assets │ ├── logo.png │ └── style.css ├── backend │ ├── api.ts │ ├── cache.ts │ └── db.ts ├── browser.module.ts ├── client.aot.ts ├── client.ts ├── index.html ├── node.module.ts ├── server.aot.ts ├── server.routes.ts ├── server.ts └── typings.d.ts ├── tsconfig.aot.json ├── tsconfig.json ├── webpack.config.ts └── webpack.prod.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | insert_final_newline = false 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /__build__ 2 | /__server_build__ 3 | /node_modules 4 | /typings 5 | /tsd_typings/ 6 | npm-debug.log 7 | 8 | /dist/ 9 | 10 | .idea 11 | *.ngfactory.ts 12 | *.css.shim.ts 13 | 14 | .DS_Store 15 | 16 | webpack.records.json 17 | 18 | /npm-debug.log.* 19 | 20 | morgan.log 21 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch", 6 | "type": "node", 7 | "request": "launch", 8 | "program": "${workspaceRoot}/dist/server/index.js", 9 | "stopOnEntry": false, 10 | "args": [], 11 | "cwd": "${workspaceRoot}", 12 | "preLaunchTask": null, 13 | "runtimeExecutable": null, 14 | "runtimeArgs": [ 15 | "--nolazy" 16 | ], 17 | "env": { 18 | "NODE_ENV": "development" 19 | }, 20 | "externalConsole": false, 21 | "sourceMaps": false, 22 | "outDir": null 23 | }, 24 | { 25 | "name": "Attach", 26 | "type": "node", 27 | "request": "attach", 28 | "port": 5858, 29 | "address": "localhost", 30 | "restart": false, 31 | "sourceMaps": false, 32 | "outDir": null, 33 | "localRoot": "${workspaceRoot}", 34 | "remoteRoot": null 35 | }, 36 | { 37 | "name": "Attach to Process", 38 | "type": "node", 39 | "request": "attach", 40 | "processId": "${command.PickProcess}", 41 | "port": 5858, 42 | "sourceMaps": false, 43 | "outDir": null 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.check.workspaceVersion": false 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Angular 2 Universal Demo 2 | 3 | [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) 4 | 5 | - Clone 6 | - `npm install` to install dependencies 7 | - `npm start` to start the Demo 8 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Angular 2 Universal Starter", 3 | "description": "Angular 2 Universal starter kit by @AngularClass", 4 | "repository": "https://github.com/angular/universal-starter", 5 | "logo": "https://cloud.githubusercontent.com/assets/1016365/10639063/138338bc-7806-11e5-8057-d34c75f3cafc.png", 6 | "env": { 7 | "NPM_CONFIG_PRODUCTION": { 8 | "description": "Install `webpack` and other development modules when deploying to allow full builds.", 9 | "value": "false" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /empty.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NgProbeToken: {}, 3 | _createConditionalRootRenderer: function(rootRenderer, extraTokens, coreTokens) { 4 | return rootRenderer; 5 | }, 6 | __platform_browser_private__: {} 7 | }; 8 | -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "dist", 4 | "src/index.html" 5 | ], 6 | "ext" : "js ts json html" 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "universal-starter", 3 | "version": "2.0.0", 4 | "description": "Angular 2 Universal starter kit by @AngularClass", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/angular/universal-starter.git" 8 | }, 9 | "scripts": { 10 | "watch": "webpack --watch", 11 | "watch:dev": "npm run server & npm run watch", 12 | "clean:dist": "rimraf dist", 13 | "clean:ngc": "rimraf **/*.ngfactory.ts **/*.css.shim.ts", 14 | "prebuild": "npm run clean:dist", 15 | "build": "webpack --progress", 16 | "build:prod:ngc": "npm run clean:ngc && npm run ngc && npm run clean:dist && npm run build:prod", 17 | "build:prod:ngc:json": "npm run clean:ngc && npm run ngc && npm run clean:dist && npm run build:prod:json", 18 | "build:prod": "webpack --config webpack.prod.config.ts", 19 | "build:prod:json": "webpack --config webpack.prod.config.ts --json | webpack-bundle-size-analyzer", 20 | "ngc": "ngc -p tsconfig.aot.json", 21 | "prestart": "npm run build", 22 | "server": "nodemon dist/server/index.js", 23 | "debug:server": "node-nightly --inspect --debug-brk dist/server/index.js", 24 | "start": "npm run server", 25 | "debug:start": "npm run build && npm run debug:server", 26 | "predebug": "npm run build", 27 | "debug:build": "node-nightly --inspect --debug-brk node_modules/webpack/bin/webpack.js", 28 | "debug:build:prod": "node-nightly --inspect --debug-brk node_modules/webpack/bin/webpack.js --config webpack.prod.config.ts", 29 | "debug": "node --debug-brk dist/server/index.js" 30 | }, 31 | "license": "MIT", 32 | "contributors": [ 33 | "AngularClass ", 34 | "PatrickJS ", 35 | "Jeff Whelpley ", 36 | "Jeff Cross ", 37 | "Mark Pieszak " 38 | ], 39 | "dependencies": { 40 | "@angular/common": "~2.1.2", 41 | "@angular/compiler": "~2.1.2", 42 | "@angular/compiler-cli": "~2.1.2", 43 | "@angular/core": "~2.1.2", 44 | "@angular/forms": "~2.1.2", 45 | "@angular/http": "~2.1.2", 46 | "@angular/platform-browser": "~2.1.2", 47 | "@angular/platform-browser-dynamic": "~2.1.2", 48 | "@angular/platform-server": "~2.1.2", 49 | "@angular/router": "~3.1.2", 50 | "@angular/upgrade": "~2.1.2", 51 | "@angularclass/bootloader": "~1.0.1", 52 | "@angularclass/idle-preload": "~1.0.4", 53 | "angular2-express-engine": "~2.1.0-rc.1", 54 | "angular2-platform-node": "~2.1.0-rc.1", 55 | "angular2-universal": "~2.1.0-rc.1", 56 | "angular2-universal-polyfills": "~2.1.0-rc.1", 57 | "body-parser": "^1.15.2", 58 | "compression": "^1.6.2", 59 | "express": "^4.14.0", 60 | "js.clone": "0.0.3", 61 | "methods": "~1.1.2", 62 | "morgan": "^1.7.0", 63 | "preboot": "~4.5.2", 64 | "rxjs": "5.0.0-beta.12", 65 | "webfontloader": "^1.6.26", 66 | "zone.js": "~0.6.26" 67 | }, 68 | "devDependencies": { 69 | "@types/morgan": "^1.7.32", 70 | "@types/body-parser": "0.0.29", 71 | "@types/compression": "0.0.29", 72 | "@types/cookie-parser": "^1.3.29", 73 | "@types/express": "^4.0.32", 74 | "@types/express-serve-static-core": "^4.0.33", 75 | "@types/hammerjs": "^2.0.32", 76 | "@types/memory-cache": "0.0.29", 77 | "@types/mime": "0.0.28", 78 | "@types/node": "^6.0.38", 79 | "@types/serve-static": "^1.7.27", 80 | "@types/webfontloader": "^1.6.27", 81 | "@ngtools/webpack": "~1.1.7", 82 | "accepts": "^1.3.3", 83 | "angular2-template-loader": "^0.4.0", 84 | "awesome-typescript-loader": "^2.2.4", 85 | "cookie-parser": "^1.4.3", 86 | "express-interceptor": "^1.2.0", 87 | "iltorb": "^1.0.13", 88 | "imports-loader": "^0.6.5", 89 | "json-loader": "^0.5.4", 90 | "memory-cache": "^0.1.6", 91 | "nodemon": "^1.10.0", 92 | "raw-loader": "^0.5.1", 93 | "reflect-metadata": "0.1.8", 94 | "rimraf": "^2.5.4", 95 | "string-replace-loader": "^1.0.5", 96 | "ts-helpers": "^1.1.2", 97 | "ts-node": "^1.3.0", 98 | "typescript": "2.0.2", 99 | "v8-lazy-parse-webpack-plugin": "^0.3.0", 100 | "webpack": "2.1.0-beta.27", 101 | "webpack-bundle-analyzer": "1.4.1", 102 | "webpack-dev-middleware": "^1.8.4", 103 | "webpack-dev-server": "2.1.0-beta.11", 104 | "webpack-merge": "~0.16.0" 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/__workaround.browser.ts: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * THIS IS TEMPORARY TO PATCH 2.1.1+ Core bugs 4 | */ 5 | 6 | /* tslint:disable */ 7 | let __compiler__ = require('@angular/compiler'); 8 | import { __platform_browser_private__ } from '@angular/platform-browser'; 9 | import { __core_private__ } from '@angular/core'; 10 | if (!__core_private__['ViewUtils']) { 11 | __core_private__['ViewUtils'] = __core_private__['view_utils']; 12 | } 13 | 14 | 15 | 16 | if (__compiler__ && __compiler__.SelectorMatcher && __compiler__.CssSelector) { 17 | (__compiler__).__compiler_private__ = { 18 | SelectorMatcher: __compiler__.SelectorMatcher, 19 | CssSelector: __compiler__.CssSelector 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/__workaround.node.ts: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * THIS IS TEMPORARY TO PATCH 2.1.1+ Core bugs 4 | */ 5 | 6 | /* tslint:disable */ 7 | let __compiler__ = require('@angular/compiler'); 8 | import { __platform_browser_private__ } from '@angular/platform-browser'; 9 | import { __core_private__ } from '@angular/core'; 10 | let patch = false; 11 | if (!__core_private__['ViewUtils']) { 12 | patch = true; 13 | __core_private__['ViewUtils'] = __core_private__['view_utils']; 14 | } 15 | 16 | 17 | 18 | if (__compiler__ && __compiler__.SelectorMatcher && __compiler__.CssSelector) { 19 | patch = true; 20 | (__compiler__).__compiler_private__ = { 21 | SelectorMatcher: __compiler__.SelectorMatcher, 22 | CssSelector: __compiler__.CssSelector 23 | } 24 | } 25 | 26 | if (patch) { 27 | var __universal__ = require('angular2-platform-node/__private_imports__'); 28 | __universal__.ViewUtils = __core_private__['view_utils']; 29 | __universal__.CssSelector = __universal__.CssSelector || __compiler__.CssSelector; 30 | __universal__.SelectorMatcher = __universal__.SelectorMatcher || __compiler__.SelectorMatcher; 31 | } 32 | 33 | // Fix Material Support 34 | function universalMaterialSupports(eventName: string): boolean { return Boolean(this.isCustomEvent(eventName)); } 35 | __platform_browser_private__.HammerGesturesPlugin.prototype.supports = universalMaterialSupports; 36 | // End Fix Material Support 37 | 38 | // Fix Universal Style 39 | import { NodeDomRootRenderer, NodeDomRenderer } from 'angular2-universal/node'; 40 | function renderComponentFix(componentProto: any) { 41 | return new NodeDomRenderer(this, componentProto, this._animationDriver); 42 | } 43 | NodeDomRootRenderer.prototype.renderComponent = renderComponentFix; 44 | // End Fix Universal Style 45 | -------------------------------------------------------------------------------- /src/angular2-meta.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | 9 | import {Injectable} from '@angular/core'; 10 | // es6-modules are used here 11 | import {DomAdapter, getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; 12 | 13 | /** 14 | * Represent meta element. 15 | * 16 | * ### Example 17 | * 18 | * ```ts 19 | * { name: 'application-name', content: 'Name of my application' }, 20 | * { name: 'description', content: 'A description of the page', id: 'desc' } 21 | * // ... 22 | * // Twitter 23 | * { name: 'twitter:title', content: 'Content Title' } 24 | * // ... 25 | * // Google+ 26 | * { itemprop: 'name', content: 'Content Title' }, 27 | * { itemprop: 'description', content: 'Content Title' } 28 | * // ... 29 | * // Facebook / Open Graph 30 | * { property: 'fb:app_id', content: '123456789' }, 31 | * { property: 'og:title', content: 'Content Title' } 32 | * ``` 33 | * 34 | * @experimental 35 | */ 36 | export interface MetaDefinition { 37 | charset?: string; 38 | content?: string; 39 | httpEquiv?: string; 40 | id?: string; 41 | itemprop?: string; 42 | name?: string; 43 | property?: string; 44 | scheme?: string; 45 | url?: string; 46 | [prop: string]: string; 47 | } 48 | 49 | /** 50 | * A service that can be used to get and add meta tags. 51 | * 52 | * @experimental 53 | */ 54 | @Injectable() 55 | export class Meta { 56 | private _dom: DomAdapter = getDOM(); 57 | 58 | /** 59 | * Adds a new meta tag to the dom. 60 | * 61 | * ### Example 62 | * 63 | * ```ts 64 | * const name: MetaDefinition = {name: 'application-name', content: 'Name of my application'}; 65 | * const desc: MetaDefinition = {name: 'description', content: 'A description of the page'}; 66 | * const tags: HTMLMetaElement[] = this.meta.addTags([name, desc]); 67 | * ``` 68 | * 69 | * @param tags 70 | * @returns {HTMLMetaElement[]} 71 | */ 72 | addTags(...tags: Array): HTMLMetaElement[] { 73 | const presentTags = this._flattenArray(tags); 74 | if (presentTags.length === 0) return []; 75 | return presentTags.map((tag: MetaDefinition) => this._addInternal(tag)); 76 | } 77 | 78 | /** 79 | * Gets the meta tag by the given selector. Returns element or null 80 | * if there's no such meta element. 81 | * 82 | * ### Example 83 | * 84 | * ```ts 85 | * const meta: HTMLMetaElement = this.meta.getTag('name=description'); 86 | * const twitterMeta: HTMLMetaElement = this.meta.getTag('name="twitter:title"'); 87 | * const fbMeta: HTMLMetaElement = this.meta.getTag('property="fb:app_id"'); 88 | * ``` 89 | * 90 | * @param selector 91 | * @returns {HTMLMetaElement} 92 | */ 93 | getTag(selector: string): HTMLMetaElement { 94 | if (!selector) return null; 95 | return this._dom.query(`meta[${selector}]`); 96 | } 97 | 98 | /** 99 | * Updates the meta tag with the given selector. 100 | * 101 | * * ### Example 102 | * 103 | * ```ts 104 | * const meta: HTMLMetaElement = this.meta.updateTag('name=description', {name: 'description', 105 | * content: 'New description'}); 106 | * console.log(meta.content); // 'New description' 107 | * ``` 108 | * 109 | * @param selector 110 | * @param tag updated tag definition 111 | * @returns {HTMLMetaElement} 112 | */ 113 | updateTag(selector: string, tag: MetaDefinition): HTMLMetaElement { 114 | const meta: HTMLMetaElement = this.getTag(selector); 115 | if (!meta) { 116 | // create element if it doesn't exist 117 | return this._addInternal(tag); 118 | } 119 | return this._prepareMetaElement(tag, meta); 120 | } 121 | 122 | /** 123 | * Removes meta tag with the given selector from the dom. 124 | * 125 | * ### Example 126 | * 127 | * ```ts 128 | * this.meta.removeTagBySelector('name=description'); 129 | * ``` 130 | * 131 | * @param selector 132 | */ 133 | removeTagBySelector(selector: string): void { 134 | const meta: HTMLMetaElement = this.getTag(selector); 135 | this.removeTagElement(meta); 136 | } 137 | 138 | /** 139 | * Removes given meta element from the dom. 140 | * 141 | * ### Example 142 | * ```ts 143 | * const elem: HTMLMetaElement = this.meta.getTag('name=description'); 144 | * this.meta.removeTagElement(elem); 145 | * ``` 146 | * 147 | * @param meta meta element 148 | */ 149 | removeTagElement(meta: HTMLMetaElement): void { 150 | if (meta) { 151 | this._removeMetaElement(meta); 152 | } 153 | } 154 | 155 | private _addInternal(tag: MetaDefinition): HTMLMetaElement { 156 | const meta: HTMLMetaElement = this._createMetaElement(); 157 | this._prepareMetaElement(tag, meta); 158 | this._appendMetaElement(meta); 159 | return meta; 160 | } 161 | 162 | private _createMetaElement(): HTMLMetaElement { 163 | return this._dom.createElement('meta') as HTMLMetaElement; 164 | } 165 | 166 | private _prepareMetaElement(tag: MetaDefinition, el: HTMLMetaElement): HTMLMetaElement { 167 | Object.keys(tag).forEach((prop: string) => this._dom.setAttribute(el, prop, tag[prop])); 168 | return el; 169 | } 170 | 171 | private _appendMetaElement(meta: HTMLMetaElement): void { 172 | const head = this._dom.getElementsByTagName(this._dom.defaultDoc(), 'head')[0]; 173 | this._dom.appendChild(head, meta); 174 | } 175 | 176 | private _removeMetaElement(meta: HTMLMetaElement): void { 177 | const head = this._dom.parentElement(meta); 178 | this._dom.removeChild(head, meta); 179 | } 180 | 181 | private _flattenArray(input: any[], out: any[] = []): any[] { 182 | if (input) { 183 | for (let i = 0; i < input.length; i++) { 184 | const item: any = input[i]; 185 | if (Array.isArray(item)) { 186 | this._flattenArray(item, out); 187 | } else if (item) { 188 | out.push(item); 189 | } 190 | } 191 | } 192 | return out; 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/app/about/about.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scotch-io/angular2-universal/88f8c91f93a5064ab216ef552572e004a22574ba/src/app/about/about.component.css -------------------------------------------------------------------------------- /src/app/about/about.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Contact

3 |
4 |
5 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus assumenda, atque beatae cumque dignissimos eligendi eos hic id incidunt ipsam ipsum iste maxime, nemo nesciunt odio recusandae sed tenetur!

6 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus assumenda, atque beatae cumque dignissimos eligendi eos hic id incidunt ipsam ipsum iste maxime, nemo nesciunt odio recusandae sed tenetur!

7 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus assumenda, atque beatae cumque dignissimos eligendi eos hic id incidunt ipsam ipsum iste maxime, nemo nesciunt odio recusandae sed tenetur!

8 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus assumenda, atque beatae cumque dignissimos eligendi eos hic id incidunt ipsam ipsum iste maxime, nemo nesciunt odio recusandae sed tenetur!

9 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus assumenda, atque beatae cumque dignissimos eligendi eos hic id incidunt ipsam ipsum iste maxime, nemo nesciunt odio recusandae sed tenetur!

10 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus assumenda, atque beatae cumque dignissimos eligendi eos hic id incidunt ipsam ipsum iste maxime, nemo nesciunt odio recusandae sed tenetur!

11 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus assumenda, atque beatae cumque dignissimos eligendi eos hic id incidunt ipsam ipsum iste maxime, nemo nesciunt odio recusandae sed tenetur!

12 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus assumenda, atque beatae cumque dignissimos eligendi eos hic id incidunt ipsam ipsum iste maxime, nemo nesciunt odio recusandae sed tenetur!

13 |
14 | -------------------------------------------------------------------------------- /src/app/about/about.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 3 | import { By } from '@angular/platform-browser'; 4 | import { DebugElement } from '@angular/core'; 5 | 6 | import { AboutComponent } from './about.component'; 7 | 8 | describe('AboutComponent', () => { 9 | let component: AboutComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async(() => { 13 | TestBed.configureTestingModule({ 14 | declarations: [ AboutComponent ] 15 | }) 16 | .compileComponents(); 17 | })); 18 | 19 | beforeEach(() => { 20 | fixture = TestBed.createComponent(AboutComponent); 21 | component = fixture.componentInstance; 22 | fixture.detectChanges(); 23 | }); 24 | 25 | it('should create', () => { 26 | expect(component).toBeTruthy(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/app/about/about.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-about', 5 | templateUrl: './about.component.html', 6 | styleUrls: ['./about.component.css'] 7 | }) 8 | export class AboutComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | 4 | import { HomeComponent } from './home/home.component'; 5 | import { AboutComponent } from './about/about.component'; 6 | import { ContactComponent } from './contact/contact.component'; 7 | 8 | @NgModule({ 9 | imports: [ 10 | RouterModule.forChild([ 11 | { path: '', redirectTo: '/home', pathMatch: 'full' }, 12 | { path: 'home', component: HomeComponent, data: { title: 'Home | Scotchiversal' } }, 13 | { path: 'about', component: AboutComponent, data: { title: 'About | Scotchiversal' } }, 14 | { path: 'contact', component: ContactComponent, data: { title: 'Contact | Scotchiversal' } } 15 | ]) 16 | ], 17 | }) 18 | export class AppRoutingModule { } 19 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 24 |
25 | 26 |
27 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Directive, ElementRef, Renderer, ChangeDetectionStrategy, ViewEncapsulation, OnInit } from '@angular/core'; 2 | import { Title } from '@angular/platform-browser'; 3 | import { Router, NavigationEnd, ActivatedRoute } from '@angular/router'; 4 | import 'rxjs/add/operator/filter'; 5 | import 'rxjs/add/operator/map'; 6 | import 'rxjs/add/operator/mergeMap'; 7 | 8 | // 9 | ///////////////////////// 10 | // ** Example Directive 11 | // Notice we don't touch the Element directly 12 | 13 | @Directive({ 14 | selector: '[xLarge]' 15 | }) 16 | export class XLargeDirective { 17 | constructor(element: ElementRef, renderer: Renderer) { 18 | // ** IMPORTANT ** 19 | // we must interact with the dom through -Renderer- 20 | // for webworker/server to see the changes 21 | renderer.setElementStyle(element.nativeElement, 'fontSize', 'x-large'); 22 | // ^^ 23 | } 24 | } 25 | 26 | @Component({ 27 | changeDetection: ChangeDetectionStrategy.Default, 28 | encapsulation: ViewEncapsulation.Emulated, 29 | selector: 'app', 30 | templateUrl: './app.component.html' 31 | }) 32 | export class AppComponent implements OnInit { 33 | title = 'ftw'; 34 | constructor( 35 | private router: Router, 36 | private titleService: Title, 37 | private activatedRoute: ActivatedRoute, 38 | ) {} 39 | ngOnInit() { 40 | this.router.events 41 | .filter(event => event instanceof NavigationEnd) 42 | .map(() => this.activatedRoute) 43 | .map(route => { 44 | while (route.firstChild) route = route.firstChild; 45 | return route; 46 | }) 47 | .filter(route => route.outlet === 'primary') 48 | .mergeMap(route => route.data) 49 | .subscribe((event) => { 50 | this.titleService.setTitle(event['title']) 51 | console.log(event['title']); 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | 4 | import { HomeComponent } from './home/home.component'; 5 | import { AboutComponent } from './about/about.component'; 6 | import { ContactComponent } from './contact/contact.component'; 7 | 8 | import { SharedModule } from './shared/shared.module'; 9 | 10 | import { AppRoutingModule } from './app-routing.module'; 11 | import { AppComponent, XLargeDirective } from './app.component'; 12 | 13 | 14 | @NgModule({ 15 | declarations: [ 16 | AppComponent, 17 | XLargeDirective, 18 | 19 | HomeComponent, 20 | AboutComponent, 21 | ContactComponent 22 | ], 23 | imports: [ 24 | SharedModule, 25 | AppRoutingModule 26 | ] 27 | }) 28 | export class AppModule { 29 | } 30 | 31 | export { AppComponent } from './app.component'; 32 | -------------------------------------------------------------------------------- /src/app/contact/contact.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scotch-io/angular2-universal/88f8c91f93a5064ab216ef552572e004a22574ba/src/app/contact/contact.component.css -------------------------------------------------------------------------------- /src/app/contact/contact.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Contact

3 |
4 |
5 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium blanditiis, consectetur, culpa cumque delectus dolorem dolorum exercitationem fuga harum, ipsum magnam minima nemo odio officiis possimus qui quos sunt tempora.

6 |
7 |
8 | 9 | 10 |
11 |
12 | 13 | 14 |
15 | 16 |
17 |
18 | -------------------------------------------------------------------------------- /src/app/contact/contact.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 3 | import { By } from '@angular/platform-browser'; 4 | import { DebugElement } from '@angular/core'; 5 | 6 | import { ContactComponent } from './contact.component'; 7 | 8 | describe('ContactComponent', () => { 9 | let component: ContactComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async(() => { 13 | TestBed.configureTestingModule({ 14 | declarations: [ ContactComponent ] 15 | }) 16 | .compileComponents(); 17 | })); 18 | 19 | beforeEach(() => { 20 | fixture = TestBed.createComponent(ContactComponent); 21 | component = fixture.componentInstance; 22 | fixture.detectChanges(); 23 | }); 24 | 25 | it('should create', () => { 26 | expect(component).toBeTruthy(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/app/contact/contact.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-contact', 5 | templateUrl: './contact.component.html', 6 | styleUrls: ['./contact.component.css'] 7 | }) 8 | export class ContactComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/home/home.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scotch-io/angular2-universal/88f8c91f93a5064ab216ef552572e004a22574ba/src/app/home/home.component.css -------------------------------------------------------------------------------- /src/app/home/home.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Home

3 |
4 |
5 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus, libero sunt! At, consectetur, distinctio enim et excepturi expedita facere nam natus nisi nostrum quidem reprehenderit similique sint, ullam vel veniam?

6 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus, libero sunt! At, consectetur, distinctio enim et excepturi expedita facere nam natus nisi nostrum quidem reprehenderit similique sint, ullam vel veniam?

7 |
8 |
Panel heading without title
9 |
10 | Panel content 11 |
12 |
13 |
14 | -------------------------------------------------------------------------------- /src/app/home/home.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 3 | import { By } from '@angular/platform-browser'; 4 | import { DebugElement } from '@angular/core'; 5 | 6 | import { HomeComponent } from './home.component'; 7 | 8 | describe('HomeComponent', () => { 9 | let component: HomeComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async(() => { 13 | TestBed.configureTestingModule({ 14 | declarations: [ HomeComponent ] 15 | }) 16 | .compileComponents(); 17 | })); 18 | 19 | beforeEach(() => { 20 | fixture = TestBed.createComponent(HomeComponent); 21 | component = fixture.componentInstance; 22 | fixture.detectChanges(); 23 | }); 24 | 25 | it('should create', () => { 26 | expect(component).toBeTruthy(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-home', 5 | templateUrl: './home.component.html', 6 | styleUrls: ['./home.component.css'] 7 | }) 8 | export class HomeComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/shared/api.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http } from '@angular/http'; 3 | import { Observable } from 'rxjs/Observable'; 4 | import 'rxjs/add/observable/throw'; 5 | import 'rxjs/add/operator/map'; 6 | import 'rxjs/add/operator/catch'; 7 | 8 | import { CacheService } from './cache.service'; 9 | 10 | 11 | @Injectable() 12 | export class ApiService { 13 | constructor(public _http: Http) { 14 | 15 | } 16 | 17 | /** 18 | * whatever domain/feature method name 19 | */ 20 | get(url: string, options?: any) { 21 | return this._http.get(url, options) 22 | .map(res => res.json()) 23 | .catch(err => { 24 | console.log('Error: ', err); 25 | return Observable.throw(err); 26 | }); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/app/shared/cache.service.ts: -------------------------------------------------------------------------------- 1 | import { Inject, Injectable, isDevMode } from '@angular/core'; 2 | 3 | @Injectable() 4 | export class CacheService { 5 | static KEY = 'CacheService'; 6 | 7 | constructor(@Inject('LRU') public _cache: Map) { 8 | 9 | } 10 | 11 | /** 12 | * check if there is a value in our store 13 | */ 14 | has(key: string | number): boolean { 15 | let _key = this.normalizeKey(key); 16 | return this._cache.has(_key); 17 | } 18 | 19 | /** 20 | * store our state 21 | */ 22 | set(key: string | number, value: any): void { 23 | let _key = this.normalizeKey(key); 24 | this._cache.set(_key, value); 25 | } 26 | 27 | /** 28 | * get our cached value 29 | */ 30 | get(key: string | number): any { 31 | let _key = this.normalizeKey(key); 32 | return this._cache.get(_key); 33 | } 34 | 35 | /** 36 | * release memory refs 37 | */ 38 | clear(): void { 39 | this._cache.clear(); 40 | } 41 | 42 | /** 43 | * convert to json for the client 44 | */ 45 | dehydrate(): any { 46 | let json = {}; 47 | this._cache.forEach((value: any, key: string) => json[key] = value); 48 | return json; 49 | } 50 | 51 | /** 52 | * convert server json into out initial state 53 | */ 54 | rehydrate(json: any): void { 55 | Object.keys(json).forEach((key: string) => { 56 | let _key = this.normalizeKey(key); 57 | let value = json[_key]; 58 | this._cache.set(_key, value); 59 | }); 60 | } 61 | 62 | /** 63 | * allow JSON.stringify to work 64 | */ 65 | toJSON(): any { 66 | return this.dehydrate(); 67 | } 68 | 69 | /** 70 | * convert numbers into strings 71 | */ 72 | normalizeKey(key: string | number): string { 73 | if (isDevMode() && this._isInvalidValue(key)) { 74 | throw new Error('Please provide a valid key to save in the CacheService'); 75 | } 76 | 77 | return key + ''; 78 | } 79 | 80 | _isInvalidValue(key): boolean { 81 | return key === null || 82 | key === undefined || 83 | key === 0 || 84 | key === '' || 85 | typeof key === 'boolean' || 86 | Number.isNaN(key); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/app/shared/model/model.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable } from 'rxjs/Observable'; 3 | import 'rxjs/add/observable/of'; 4 | import 'rxjs/add/operator/do'; 5 | import 'rxjs/add/operator/share'; 6 | 7 | import { CacheService } from '../cache.service'; 8 | import { ApiService } from '../api.service'; 9 | 10 | export function hashCodeString(str: string): string { 11 | let hash = 0; 12 | if (str.length === 0) { 13 | return hash + ''; 14 | } 15 | for (let i = 0; i < str.length; i++) { 16 | let char = str.charCodeAt(i); 17 | hash = ((hash << 5) - hash) + char; 18 | hash = hash & hash; // Convert to 32bit integer 19 | } 20 | return hash + ''; 21 | } 22 | 23 | // domain/feature service 24 | @Injectable() 25 | export class ModelService { 26 | // This is only one example of one Model depending on your domain 27 | constructor(public _api: ApiService, public _cache: CacheService) { 28 | 29 | } 30 | 31 | /** 32 | * whatever domain/feature method name 33 | */ 34 | get(url) { 35 | // you want to return the cache if there is a response in it. 36 | // This would cache the first response so if your API isn't idempotent 37 | // you probably want to remove the item from the cache after you use it. LRU of 10 38 | // you can use also hashCodeString here 39 | let key = url; 40 | 41 | if (this._cache.has(key)) { 42 | return Observable.of(this._cache.get(key)); 43 | } 44 | // you probably shouldn't .share() and you should write the correct logic 45 | return this._api.get(url) 46 | .do(json => { 47 | this._cache.set(key, json); 48 | }) 49 | .share(); 50 | } 51 | // don't cache here since we're creating 52 | create() { 53 | // TODO 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, ModuleWithProviders } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { RouterModule } from '@angular/router'; 4 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 5 | import { ApiService } from './api.service'; 6 | import { ModelService } from './model/model.service'; 7 | 8 | const MODULES = [ 9 | // Do NOT include UniversalModule, HttpModule, or JsonpModule here 10 | CommonModule, 11 | RouterModule, 12 | FormsModule, 13 | ReactiveFormsModule 14 | ]; 15 | 16 | const PIPES = [ 17 | // put pipes here 18 | ]; 19 | 20 | const COMPONENTS = [ 21 | // put shared components here 22 | ]; 23 | 24 | const PROVIDERS = [ 25 | ModelService, 26 | ApiService 27 | ] 28 | 29 | @NgModule({ 30 | imports: [ 31 | ...MODULES 32 | ], 33 | declarations: [ 34 | ...PIPES, 35 | ...COMPONENTS 36 | ], 37 | exports: [ 38 | ...MODULES, 39 | ...PIPES, 40 | ...COMPONENTS 41 | ] 42 | }) 43 | export class SharedModule { 44 | static forRoot(): ModuleWithProviders { 45 | return { 46 | ngModule: SharedModule, 47 | providers: [ 48 | ...PROVIDERS 49 | ] 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scotch-io/angular2-universal/88f8c91f93a5064ab216ef552572e004a22574ba/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Roboto:400,700");/*! 2 | * bootswatch v3.3.7 3 | * Homepage: http://bootswatch.com 4 | * Copyright 2012-2016 Thomas Park 5 | * Licensed under MIT 6 | * Based on Bootstrap 7 | *//*! 8 | * Bootstrap v3.3.7 (http://getbootstrap.com) 9 | * Copyright 2011-2016 Twitter, Inc. 10 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 11 | *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#888888;background-color:#060606}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#2a9fd6;text-decoration:none}a:hover,a:focus{color:#2a9fd6;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#282828;border:1px solid #282828;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #282828}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1;color:#ffffff}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#888888}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:56px}h2,.h2{font-size:45px}h3,.h3{font-size:34px}h4,.h4{font-size:24px}h5,.h5{font-size:20px}h6,.h6{font-size:16px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{background-color:#ff8800;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#888888}.text-primary{color:#2a9fd6}a.text-primary:hover,a.text-primary:focus{color:#2180ac}.text-success{color:#ffffff}a.text-success:hover,a.text-success:focus{color:#e6e6e6}.text-info{color:#ffffff}a.text-info:hover,a.text-info:focus{color:#e6e6e6}.text-warning{color:#ffffff}a.text-warning:hover,a.text-warning:focus{color:#e6e6e6}.text-danger{color:#ffffff}a.text-danger:hover,a.text-danger:focus{color:#e6e6e6}.bg-primary{color:#fff;background-color:#2a9fd6}a.bg-primary:hover,a.bg-primary:focus{background-color:#2180ac}.bg-success{background-color:#77b300}a.bg-success:hover,a.bg-success:focus{background-color:#558000}.bg-info{background-color:#9933cc}a.bg-info:hover,a.bg-info:focus{background-color:#7a29a3}.bg-warning{background-color:#ff8800}a.bg-warning:hover,a.bg-warning:focus{background-color:#cc6d00}.bg-danger{background-color:#cc0000}a.bg-danger:hover,a.bg-danger:focus{background-color:#990000}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #282828}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #888888}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #282828}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#555555}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #282828;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#ffffff;background-color:#333333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#282828;background-color:#f5f5f5;border:1px solid #cccccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0%}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}}table{background-color:#181818}caption{padding-top:8px;padding-bottom:8px;color:#888888;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #282828}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #282828}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #282828}.table .table{background-color:#060606}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #282828}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #282828}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#080808}.table-hover>tbody>tr:hover{background-color:#282828}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#282828}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#1b1b1b}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#77b300}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#669a00}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#9933cc}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#8a2eb8}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#ff8800}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#e67a00}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#cc0000}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#b30000}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #282828}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#888888;border:0;border-bottom:1px solid #282828}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:9px;font-size:14px;line-height:1.42857143;color:#888888}.form-control{display:block;width:100%;height:38px;padding:8px 12px;font-size:14px;line-height:1.42857143;color:#888888;background-color:#ffffff;background-image:none;border:1px solid #282828;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#888888;opacity:1}.form-control:-ms-input-placeholder{color:#888888}.form-control::-webkit-input-placeholder{color:#888888}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#adafae;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:38px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:54px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:9px;padding-bottom:9px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:54px;line-height:54px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:54px;line-height:54px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:54px;min-height:38px;padding:15px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:47.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:38px;height:38px;line-height:38px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:54px;height:54px;line-height:54px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#ffffff}.has-success .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.has-success .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#77b300}.has-success .form-control-feedback{color:#ffffff}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#ffffff}.has-warning .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.has-warning .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#ff8800}.has-warning .form-control-feedback{color:#ffffff}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#ffffff}.has-error .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.has-error .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#cc0000}.has-error .form-control-feedback{color:#ffffff}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#c8c8c8}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:9px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:29px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:9px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:15px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:8px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#ffffff;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#ffffff;background-color:#424242;border-color:#424242}.btn-default:focus,.btn-default.focus{color:#ffffff;background-color:#282828;border-color:#020202}.btn-default:hover{color:#ffffff;background-color:#282828;border-color:#232323}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#ffffff;background-color:#282828;border-color:#232323}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#ffffff;background-color:#161616;border-color:#020202}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#424242;border-color:#424242}.btn-default .badge{color:#424242;background-color:#ffffff}.btn-primary{color:#ffffff;background-color:#2a9fd6;border-color:#2a9fd6}.btn-primary:focus,.btn-primary.focus{color:#ffffff;background-color:#2180ac;border-color:#15506c}.btn-primary:hover{color:#ffffff;background-color:#2180ac;border-color:#1f79a3}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#2180ac;border-color:#1f79a3}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#ffffff;background-color:#1b698e;border-color:#15506c}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#2a9fd6;border-color:#2a9fd6}.btn-primary .badge{color:#2a9fd6;background-color:#ffffff}.btn-success{color:#ffffff;background-color:#77b300;border-color:#77b300}.btn-success:focus,.btn-success.focus{color:#ffffff;background-color:#558000;border-color:#223300}.btn-success:hover{color:#ffffff;background-color:#558000;border-color:#4e7600}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#558000;border-color:#4e7600}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#ffffff;background-color:#3d5c00;border-color:#223300}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#77b300;border-color:#77b300}.btn-success .badge{color:#77b300;background-color:#ffffff}.btn-info{color:#ffffff;background-color:#9933cc;border-color:#9933cc}.btn-info:focus,.btn-info.focus{color:#ffffff;background-color:#7a29a3;border-color:#4c1966}.btn-info:hover{color:#ffffff;background-color:#7a29a3;border-color:#74279b}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#7a29a3;border-color:#74279b}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#ffffff;background-color:#652287;border-color:#4c1966}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#9933cc;border-color:#9933cc}.btn-info .badge{color:#9933cc;background-color:#ffffff}.btn-warning{color:#ffffff;background-color:#ff8800;border-color:#ff8800}.btn-warning:focus,.btn-warning.focus{color:#ffffff;background-color:#cc6d00;border-color:#804400}.btn-warning:hover{color:#ffffff;background-color:#cc6d00;border-color:#c26700}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#cc6d00;border-color:#c26700}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#ffffff;background-color:#a85a00;border-color:#804400}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#ff8800;border-color:#ff8800}.btn-warning .badge{color:#ff8800;background-color:#ffffff}.btn-danger{color:#ffffff;background-color:#cc0000;border-color:#cc0000}.btn-danger:focus,.btn-danger.focus{color:#ffffff;background-color:#990000;border-color:#4d0000}.btn-danger:hover{color:#ffffff;background-color:#990000;border-color:#8f0000}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#990000;border-color:#8f0000}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#ffffff;background-color:#750000;border-color:#4d0000}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#cc0000;border-color:#cc0000}.btn-danger .badge{color:#cc0000;background-color:#ffffff}.btn-link{color:#2a9fd6;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a9fd6;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#888888;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;text-align:left;background-color:#222222;border:1px solid #444444;border:1px solid rgba(255,255,255,0.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:rgba(255,255,255,0.1)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#ffffff;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#ffffff;background-color:#2a9fd6}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#2a9fd6}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#888888}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#888888;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:54px;line-height:54px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:8px 12px;font-size:14px;font-weight:normal;line-height:1;color:#888888;text-align:center;background-color:#424242;border:1px solid #282828;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:14px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#222222}.nav>li.disabled>a{color:#888888}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#888888;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#222222;border-color:#2a9fd6}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #282828}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:transparent transparent #282828}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#ffffff;background-color:#2a9fd6;border:1px solid #282828;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #dddddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #dddddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#060606}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#ffffff;background-color:#2a9fd6}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #dddddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #dddddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#060606}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:6px;margin-bottom:6px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:6px;margin-bottom:6px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#060606;border-color:#282828}.navbar-default .navbar-brand{color:#ffffff}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-default .navbar-text{color:#888888}.navbar-default .navbar-nav>li>a{color:#888888}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#ffffff;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#ffffff;background-color:transparent}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#888888;background-color:transparent}.navbar-default .navbar-toggle{border-color:#282828}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#282828}.navbar-default .navbar-toggle .icon-bar{background-color:#cccccc}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#282828}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:transparent;color:#ffffff}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#888888}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#888888;background-color:transparent}}.navbar-default .navbar-link{color:#888888}.navbar-default .navbar-link:hover{color:#ffffff}.navbar-default .btn-link{color:#888888}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#ffffff}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#888888}.navbar-inverse{background-color:#222222;border-color:#080808}.navbar-inverse .navbar-brand{color:#ffffff}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-text{color:#888888}.navbar-inverse .navbar-nav>li>a{color:#888888}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#aaaaaa;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#ffffff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:transparent;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#888888}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#aaaaaa;background-color:transparent}}.navbar-inverse .navbar-link{color:#888888}.navbar-inverse .navbar-link:hover{color:#ffffff}.navbar-inverse .btn-link{color:#888888}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#aaaaaa}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#222222;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ffffff}.breadcrumb>.active{color:#888888}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:8px 12px;line-height:1.42857143;text-decoration:none;color:#ffffff;background-color:#222222;border:1px solid #282828;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#ffffff;background-color:#2a9fd6;border-color:transparent}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#ffffff;background-color:#2a9fd6;border-color:transparent;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#888888;background-color:#222222;border-color:#282828;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:14px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#222222;border:1px solid #282828;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#2a9fd6}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#888888;background-color:#222222;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#424242}.label-default[href]:hover,.label-default[href]:focus{background-color:#282828}.label-primary{background-color:#2a9fd6}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#2180ac}.label-success{background-color:#77b300}.label-success[href]:hover,.label-success[href]:focus{background-color:#558000}.label-info{background-color:#9933cc}.label-info[href]:hover,.label-info[href]:focus{background-color:#7a29a3}.label-warning{background-color:#ff8800}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#cc6d00}.label-danger{background-color:#cc0000}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#990000}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#ffffff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#2a9fd6;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#2a9fd6;background-color:#ffffff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#151515}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#000000}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px;padding-left:15px;padding-right:15px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#282828;border:1px solid #282828;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#2a9fd6}.thumbnail .caption{padding:9px;color:#888888}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#77b300;border-color:#809a00;color:#ffffff}.alert-success hr{border-top-color:#6a8000}.alert-success .alert-link{color:#e6e6e6}.alert-info{background-color:#9933cc;border-color:#6e2caf;color:#ffffff}.alert-info hr{border-top-color:#61279b}.alert-info .alert-link{color:#e6e6e6}.alert-warning{background-color:#ff8800;border-color:#f05800;color:#ffffff}.alert-warning hr{border-top-color:#d64f00}.alert-warning .alert-link{color:#e6e6e6}.alert-danger{background-color:#cc0000;border-color:#bd001f;color:#ffffff}.alert-danger hr{border-top-color:#a3001b}.alert-danger .alert-link{color:#e6e6e6}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#222222;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#ffffff;text-align:center;background-color:#2a9fd6;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#77b300}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#9933cc}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#ff8800}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#cc0000}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#222222;border:1px solid #282828}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#888888}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#ffffff}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#888888;background-color:#484848}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#adafae;color:#888888;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#888888}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#2a9fd6;border-color:#2a9fd6}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#d5ecf7}.list-group-item-success{color:#ffffff;background-color:#77b300}a.list-group-item-success,button.list-group-item-success{color:#ffffff}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#ffffff;background-color:#669a00}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff}.list-group-item-info{color:#ffffff;background-color:#9933cc}a.list-group-item-info,button.list-group-item-info{color:#ffffff}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#ffffff;background-color:#8a2eb8}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff}.list-group-item-warning{color:#ffffff;background-color:#ff8800}a.list-group-item-warning,button.list-group-item-warning{color:#ffffff}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#ffffff;background-color:#e67a00}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff}.list-group-item-danger{color:#ffffff;background-color:#cc0000}a.list-group-item-danger,button.list-group-item-danger{color:#ffffff}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#ffffff;background-color:#b30000}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#222222;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#3c3c3c;border-top:1px solid #282828;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:3px;border-bottom-right-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #282828}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #282828}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #282828}.panel-default{border-color:#282828}.panel-default>.panel-heading{color:#888888;background-color:#3c3c3c;border-color:#282828}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#282828}.panel-default>.panel-heading .badge{color:#3c3c3c;background-color:#888888}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#282828}.panel-primary{border-color:#2a9fd6}.panel-primary>.panel-heading{color:#ffffff;background-color:#2a9fd6;border-color:#2a9fd6}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#2a9fd6}.panel-primary>.panel-heading .badge{color:#2a9fd6;background-color:#ffffff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#2a9fd6}.panel-success{border-color:#809a00}.panel-success>.panel-heading{color:#ffffff;background-color:#77b300;border-color:#809a00}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#809a00}.panel-success>.panel-heading .badge{color:#77b300;background-color:#ffffff}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#809a00}.panel-info{border-color:#6e2caf}.panel-info>.panel-heading{color:#ffffff;background-color:#9933cc;border-color:#6e2caf}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#6e2caf}.panel-info>.panel-heading .badge{color:#9933cc;background-color:#ffffff}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#6e2caf}.panel-warning{border-color:#f05800}.panel-warning>.panel-heading{color:#ffffff;background-color:#ff8800;border-color:#f05800}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#f05800}.panel-warning>.panel-heading .badge{color:#ff8800;background-color:#ffffff}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#f05800}.panel-danger{border-color:#bd001f}.panel-danger>.panel-heading{color:#ffffff;background-color:#cc0000;border-color:#bd001f}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bd001f}.panel-danger>.panel-heading .badge{color:#cc0000;background-color:#ffffff}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bd001f}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#151515;border:1px solid #030303;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#202020;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #282828}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:20px}.modal-footer{padding:20px;text-align:right;border-top:1px solid #282828}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;background-color:#2c2c2c;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#2c2c2c}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#2c2c2c}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#2c2c2c}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#2c2c2c}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#2c2c2c}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#2c2c2c}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#2c2c2c}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#2c2c2c}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:14px;background-color:#2c2c2c;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #2c2c2c;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;background-color:#252525;border-bottom:1px solid #181818;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#2c2c2c;border-top-color:rgba(0,0,0,0.2);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#2c2c2c}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#2c2c2c;border-right-color:rgba(0,0,0,0.2)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#2c2c2c}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#2c2c2c;border-bottom-color:rgba(0,0,0,0.2);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#2c2c2c}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#2c2c2c;border-left-color:rgba(0,0,0,0.2)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#2c2c2c;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;line-height:1;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}.text-primary,.text-primary:hover{color:#2a9fd6}.text-success,.text-success:hover{color:#77b300}.text-danger,.text-danger:hover{color:#cc0000}.text-warning,.text-warning:hover{color:#ff8800}.text-info,.text-info:hover{color:#9933cc}.bg-success,.bg-info,.bg-warning,.bg-danger{color:#fff}table,.table{color:#fff}table a:not(.btn),.table a:not(.btn){color:#fff;text-decoration:underline}table .dropdown-menu a,.table .dropdown-menu a{text-decoration:none}table .text-muted,.table .text-muted{color:#888888}.table-responsive>.table{background-color:#181818}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label,.has-warning .form-control-feedback{color:#ff8800}.has-warning .form-control,.has-warning .form-control:focus,.has-warning .input-group-addon{border-color:#ff8800}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label,.has-error .form-control-feedback{color:#cc0000}.has-error .form-control,.has-error .form-control:focus,.has-error .input-group-addon{border-color:#cc0000}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label,.has-success .form-control-feedback{color:#77b300}.has-success .form-control,.has-success .form-control:focus,.has-success .input-group-addon{border-color:#77b300}legend{color:#fff}.nav-tabs a,.nav-pills a,.breadcrumb a,.pager a{color:#fff}.alert .alert-link,.alert a{color:#ffffff;text-decoration:underline}.alert .close{text-decoration:none}.close{color:#fff;text-decoration:none;opacity:0.4}.close:hover,.close:focus{color:#fff;opacity:1}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#282828}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{border-color:#282828}a.list-group-item-success.active{background-color:#77b300}a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{background-color:#669a00}a.list-group-item-warning.active{background-color:#ff8800}a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{background-color:#e67a00}a.list-group-item-danger.active{background-color:#cc0000}a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{background-color:#b30000}.jumbotron h1,.jumbotron h2,.jumbotron h3,.jumbotron h4,.jumbotron h5,.jumbotron h6{color:#fff} -------------------------------------------------------------------------------- /src/backend/api.ts: -------------------------------------------------------------------------------- 1 | var util = require('util'); 2 | var {Router} = require('express'); 3 | 4 | // Our API for demos only 5 | import {fakeDataBase} from './db'; 6 | import {fakeDemoRedisCache} from './cache'; 7 | 8 | // you would use cookies/token etc 9 | var USER_ID = 'f9d98cf1-1b96-464e-8755-bcc2a5c09077'; // hardcoded as an example 10 | 11 | // Our API for demos only 12 | export function serverApi(req, res) { 13 | let key = USER_ID + '/data.json'; 14 | let cache = fakeDemoRedisCache.get(key); 15 | if (cache !== undefined) { 16 | console.log('/data.json Cache Hit'); 17 | return res.json(cache); 18 | } 19 | console.log('/data.json Cache Miss'); 20 | 21 | fakeDataBase.get() 22 | .then(data => { 23 | fakeDemoRedisCache.set(key, data); 24 | return data; 25 | }) 26 | .then(data => res.json(data)); 27 | } 28 | 29 | 30 | // todo API 31 | 32 | var COUNT = 4; 33 | var TODOS = [ 34 | { id: 0, value: 'finish example', created_at: new Date(), completed: false }, 35 | { id: 1, value: 'add tests', created_at: new Date(), completed: false }, 36 | { id: 2, value: 'include development environment', created_at: new Date(), completed: false }, 37 | { id: 3, value: 'include production environment', created_at: new Date(), completed: false } 38 | ]; 39 | 40 | export function createTodoApi() { 41 | 42 | var router = Router() 43 | 44 | router.route('/todos') 45 | .get(function(req, res) { 46 | console.log('GET'); 47 | // 70ms latency 48 | setTimeout(function() { 49 | res.json(TODOS); 50 | }, 0); 51 | 52 | }) 53 | .post(function(req, res) { 54 | console.log('POST', util.inspect(req.body, {colors: true})); 55 | var todo = req.body; 56 | if (todo) { 57 | TODOS.push({ 58 | value: todo.value, 59 | created_at: new Date(), 60 | completed: todo.completed, 61 | id: COUNT++ 62 | }); 63 | return res.json(todo); 64 | } 65 | 66 | return res.end(); 67 | }); 68 | 69 | router.param('todo_id', function(req, res, next, todo_id) { 70 | // ensure correct prop type 71 | var id = Number(req.params.todo_id); 72 | try { 73 | var todo = TODOS[id]; 74 | req.todo_id = id; 75 | req.todo = TODOS[id]; 76 | next(); 77 | } catch (e) { 78 | next(new Error('failed to load todo')); 79 | } 80 | }); 81 | 82 | router.route('/todos/:todo_id') 83 | .get(function(req, res) { 84 | console.log('GET', util.inspect(req.todo, {colors: true})); 85 | 86 | res.json(req.todo); 87 | }) 88 | .put(function(req, res) { 89 | console.log('PUT', util.inspect(req.body, {colors: true})); 90 | 91 | var index = TODOS.indexOf(req.todo); 92 | var todo = TODOS[index] = req.body; 93 | 94 | res.json(todo); 95 | }) 96 | .delete(function(req, res) { 97 | console.log('DELETE', req.todo_id); 98 | 99 | var index = TODOS.indexOf(req.todo); 100 | TODOS.splice(index, 1); 101 | 102 | res.json(req.todo); 103 | }); 104 | 105 | return router; 106 | }; 107 | -------------------------------------------------------------------------------- /src/backend/cache.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | var _fakeLRUcount = 0; 4 | export const fakeDemoRedisCache = { 5 | _cache: {}, 6 | get: (key) => { 7 | let cache = fakeDemoRedisCache._cache[key]; 8 | _fakeLRUcount++; 9 | if (_fakeLRUcount >= 10) { 10 | fakeDemoRedisCache.clear(); 11 | _fakeLRUcount = 0; 12 | } 13 | return cache; 14 | }, 15 | set: (key, data) => fakeDemoRedisCache._cache[key] = data, 16 | clear: () => fakeDemoRedisCache._cache = {} 17 | }; 18 | -------------------------------------------------------------------------------- /src/backend/db.ts: -------------------------------------------------------------------------------- 1 | // Our API for demos only 2 | export const fakeDataBase = { 3 | get() { 4 | let res = { data: 'This fake data came from the db on the server.' }; 5 | return Promise.resolve(res); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /src/browser.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { RouterModule } from '@angular/router'; 4 | import { UniversalModule, isBrowser, isNode, AUTO_PREBOOT } from 'angular2-universal/browser'; // for AoT we need to manually split universal packages 5 | import { IdlePreload, IdlePreloadModule } from '@angularclass/idle-preload'; 6 | 7 | import { AppModule, AppComponent } from './app/app.module'; 8 | import { SharedModule } from './app/shared/shared.module'; 9 | import { CacheService } from './app/shared/cache.service'; 10 | 11 | // Will be merged into @angular/platform-browser in a later release 12 | // see https://github.com/angular/angular/pull/12322 13 | import { Meta } from './angular2-meta'; 14 | 15 | // import * as LRU from 'modern-lru'; 16 | 17 | export function getLRU(lru?: any) { 18 | // use LRU for node 19 | // return lru || new LRU(10); 20 | return lru || new Map(); 21 | } 22 | export function getRequest() { 23 | // the request object only lives on the server 24 | return { cookie: document.cookie }; 25 | } 26 | export function getResponse() { 27 | // the response object is sent as the index.html and lives on the server 28 | return {}; 29 | } 30 | 31 | 32 | // TODO(gdi2290): refactor into Universal 33 | export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE'; 34 | 35 | @NgModule({ 36 | bootstrap: [ AppComponent ], 37 | imports: [ 38 | // MaterialModule.forRoot() should be included first 39 | UniversalModule, // BrowserModule, HttpModule, and JsonpModule are included 40 | 41 | FormsModule, 42 | RouterModule.forRoot([], { useHash: false, preloadingStrategy: IdlePreload }), 43 | 44 | IdlePreloadModule.forRoot(), 45 | SharedModule.forRoot(), 46 | AppModule, 47 | ], 48 | providers: [ 49 | { provide: 'isBrowser', useValue: isBrowser }, 50 | { provide: 'isNode', useValue: isNode }, 51 | 52 | { provide: 'req', useFactory: getRequest }, 53 | { provide: 'res', useFactory: getResponse }, 54 | 55 | { provide: 'LRU', useFactory: getLRU, deps: [] }, 56 | 57 | CacheService, 58 | 59 | Meta, 60 | 61 | // { provide: AUTO_PREBOOT, useValue: false } // turn off auto preboot complete 62 | ] 63 | }) 64 | export class MainModule { 65 | constructor(public cache: CacheService) { 66 | // TODO(gdi2290): refactor into a lifecycle hook 67 | this.doRehydrate(); 68 | } 69 | 70 | doRehydrate() { 71 | let defaultValue = {}; 72 | let serverCache = this._getCacheValue(CacheService.KEY, defaultValue); 73 | this.cache.rehydrate(serverCache); 74 | } 75 | 76 | _getCacheValue(key: string, defaultValue: any): any { 77 | // browser 78 | const win: any = window; 79 | if (win[UNIVERSAL_KEY] && win[UNIVERSAL_KEY][key]) { 80 | let serverCache = defaultValue; 81 | try { 82 | serverCache = JSON.parse(win[UNIVERSAL_KEY][key]); 83 | if (typeof serverCache !== typeof defaultValue) { 84 | console.log('Angular Universal: The type of data from the server is different from the default value type'); 85 | serverCache = defaultValue; 86 | } 87 | } catch (e) { 88 | console.log('Angular Universal: There was a problem parsing the server data during rehydrate'); 89 | serverCache = defaultValue; 90 | } 91 | return serverCache; 92 | } else { 93 | console.log('Angular Universal: UNIVERSAL_CACHE is missing'); 94 | } 95 | return defaultValue; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/client.aot.ts: -------------------------------------------------------------------------------- 1 | // the polyfills must be the first thing imported 2 | import 'angular2-universal-polyfills'; 3 | import 'ts-helpers'; 4 | import './__workaround.browser'; // temporary until 2.1.1 things are patched in Core 5 | 6 | // Angular 2 7 | import { enableProdMode } from '@angular/core'; 8 | import { platformBrowser } from '@angular/platform-browser'; 9 | import { bootloader } from '@angularclass/bootloader'; 10 | // for AoT use platformBrowser 11 | // import { platformUniversalDynamic } from 'angular2-universal/browser'; 12 | 13 | import { load as loadWebFont } from 'webfontloader'; 14 | 15 | // enable prod for faster renders 16 | enableProdMode(); 17 | 18 | import { MainModuleNgFactory } from './browser.module.ngfactory'; 19 | 20 | export const platformRef = platformBrowser(); 21 | 22 | // on document ready bootstrap Angular 2 23 | export function main() { 24 | // Load fonts async 25 | // https://github.com/typekit/webfontloader#configuration 26 | loadWebFont({ 27 | google: { 28 | families: ['Droid Sans'] 29 | } 30 | }); 31 | 32 | return platformRef.bootstrapModuleFactory(MainModuleNgFactory); 33 | } 34 | 35 | // support async tag or hmr 36 | bootloader(main); 37 | -------------------------------------------------------------------------------- /src/client.ts: -------------------------------------------------------------------------------- 1 | // the polyfills must be the first thing imported 2 | import 'angular2-universal-polyfills'; 3 | import 'ts-helpers'; 4 | import './__workaround.browser'; // temporary until 2.1.1 things are patched in Core 5 | 6 | // Angular 2 7 | import { enableProdMode } from '@angular/core'; 8 | import { platformUniversalDynamic } from 'angular2-universal/browser'; 9 | import { bootloader } from '@angularclass/bootloader'; 10 | 11 | import { load as loadWebFont } from 'webfontloader'; 12 | 13 | // enable prod for faster renders 14 | // enableProdMode(); 15 | 16 | import { MainModule } from './browser.module'; 17 | 18 | export const platformRef = platformUniversalDynamic(); 19 | 20 | // on document ready bootstrap Angular 2 21 | export function main() { 22 | // Load fonts async 23 | // https://github.com/typekit/webfontloader#configuration 24 | loadWebFont({ 25 | google: { 26 | families: ['Droid Sans'] 27 | } 28 | }); 29 | 30 | return platformRef.bootstrapModule(MainModule); 31 | } 32 | 33 | // support async tag or hmr 34 | bootloader(main); 35 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Sctochiversal 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Loading Universal ... 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/node.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { RouterModule } from '@angular/router'; 4 | import { UniversalModule, isBrowser, isNode } from 'angular2-universal/node'; // for AoT we need to manually split universal packages 5 | 6 | import { AppModule, AppComponent } from './app/app.module'; 7 | import { SharedModule } from './app/shared/shared.module'; 8 | import { CacheService } from './app/shared/cache.service'; 9 | 10 | // Will be merged into @angular/platform-browser in a later release 11 | // see https://github.com/angular/angular/pull/12322 12 | import { Meta } from './angular2-meta'; 13 | 14 | export function getLRU() { 15 | return new Map(); 16 | } 17 | export function getRequest() { 18 | return Zone.current.get('req') || {}; 19 | } 20 | export function getResponse() { 21 | return Zone.current.get('res') || {}; 22 | } 23 | 24 | // TODO(gdi2290): refactor into Universal 25 | export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE'; 26 | 27 | @NgModule({ 28 | bootstrap: [ AppComponent ], 29 | imports: [ 30 | // MaterialModule.forRoot() should be included first 31 | UniversalModule, // BrowserModule, HttpModule, and JsonpModule are included 32 | 33 | FormsModule, 34 | RouterModule.forRoot([], { useHash: false }), 35 | 36 | SharedModule.forRoot(), 37 | AppModule, 38 | ], 39 | providers: [ 40 | { provide: 'isBrowser', useValue: isBrowser }, 41 | { provide: 'isNode', useValue: isNode }, 42 | 43 | { provide: 'req', useFactory: getRequest }, 44 | { provide: 'res', useFactory: getResponse }, 45 | 46 | { provide: 'LRU', useFactory: getLRU, deps: [] }, 47 | 48 | CacheService, 49 | 50 | Meta, 51 | ] 52 | }) 53 | export class MainModule { 54 | constructor(public cache: CacheService) { 55 | 56 | } 57 | 58 | /** 59 | * We need to use the arrow function here to bind the context as this is a gotcha 60 | * in Universal for now until it's fixed 61 | */ 62 | universalDoDehydrate = (universalCache) => { 63 | universalCache[CacheService.KEY] = JSON.stringify(this.cache.dehydrate()); 64 | } 65 | 66 | /** 67 | * Clear the cache after it's rendered 68 | */ 69 | universalAfterDehydrate = () => { 70 | // comment out if LRU provided at platform level to be shared between each user 71 | this.cache.clear(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/server.aot.ts: -------------------------------------------------------------------------------- 1 | // the polyfills must be one of the first things imported in node.js. 2 | // The only modules to be imported higher - node modules with es6-promise 3.x or other Promise polyfill dependency 3 | // (rule of thumb: do it if you have zone.js exception that it has been overwritten) 4 | // if you are including modules that modify Promise, such as NewRelic,, you must include them before polyfills 5 | import 'angular2-universal-polyfills'; 6 | import 'ts-helpers'; 7 | import './__workaround.node'; // temporary until 2.1.1 things are patched in Core 8 | 9 | import * as fs from 'fs'; 10 | import * as path from 'path'; 11 | import * as express from 'express'; 12 | import * as bodyParser from 'body-parser'; 13 | import * as cookieParser from 'cookie-parser'; 14 | import * as morgan from 'morgan'; 15 | import * as compression from 'compression'; 16 | 17 | // Angular 2 18 | import { enableProdMode } from '@angular/core'; 19 | // Angular 2 Universal 20 | import { createEngine } from 'angular2-express-engine'; 21 | 22 | // App 23 | import { MainModuleNgFactory } from './node.module.ngfactory'; 24 | 25 | // Routes 26 | import { routes } from './server.routes'; 27 | 28 | // enable prod for faster renders 29 | enableProdMode(); 30 | 31 | const app = express(); 32 | const ROOT = path.join(path.resolve(__dirname, '..')); 33 | 34 | // Express View 35 | app.engine('.html', createEngine({ 36 | precompile: false, // this needs to be false when using ngFactory 37 | ngModule: MainModuleNgFactory, 38 | providers: [ 39 | // use only if you have shared state between users 40 | // { provide: 'LRU', useFactory: () => new LRU(10) } 41 | 42 | // stateless providers only since it's shared 43 | ] 44 | })); 45 | app.set('port', process.env.PORT || 3000); 46 | app.set('views', __dirname); 47 | app.set('view engine', 'html'); 48 | app.set('json spaces', 2); 49 | 50 | app.use(cookieParser('Angular 2 Universal')); 51 | app.use(bodyParser.json()); 52 | app.use(compression()); 53 | 54 | const accessLogStream = fs.createWriteStream(ROOT + '/morgan.log', {flags: 'a'}) 55 | 56 | app.use(morgan('common', { 57 | skip: (req, res) => res.statusCode < 400, 58 | stream: accessLogStream 59 | })); 60 | 61 | function cacheControl(req, res, next) { 62 | // instruct browser to revalidate in 60 seconds 63 | res.header('Cache-Control', 'max-age=60'); 64 | next(); 65 | } 66 | // Serve static files 67 | app.use('/assets', cacheControl, express.static(path.join(__dirname, 'assets'), {maxAge: 30})); 68 | app.use(cacheControl, express.static(path.join(ROOT, 'dist/client'), {index: false})); 69 | 70 | // 71 | ///////////////////////// 72 | // ** Example API 73 | // Notice API should be in aseparate process 74 | import { serverApi, createTodoApi } from './backend/api'; 75 | // Our API for demos only 76 | app.get('/data.json', serverApi); 77 | app.use('/api', createTodoApi()); 78 | 79 | function ngApp(req, res) { 80 | res.render('index', { 81 | req, 82 | res, 83 | // time: true, // use this to determine what part of your app is slow only in development 84 | preboot: false, 85 | baseUrl: '/', 86 | requestUrl: req.originalUrl, 87 | originUrl: `http://localhost:${ app.get('port') }` 88 | }); 89 | } 90 | 91 | /** 92 | * use universal for specific routes 93 | */ 94 | app.get('/', ngApp); 95 | routes.forEach(route => { 96 | app.get(`/${route}`, ngApp); 97 | app.get(`/${route}/*`, ngApp); 98 | }); 99 | 100 | 101 | app.get('*', function(req, res) { 102 | res.setHeader('Content-Type', 'application/json'); 103 | var pojo = { status: 404, message: 'No Content' }; 104 | var json = JSON.stringify(pojo, null, 2); 105 | res.status(404).send(json); 106 | }); 107 | 108 | // Server 109 | let server = app.listen(app.get('port'), () => { 110 | console.log(`Listening on: http://localhost:${server.address().port}`); 111 | }); 112 | -------------------------------------------------------------------------------- /src/server.routes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Server-side routes. Only the listed routes support html5pushstate. 3 | * Has to match client side routes. 4 | * 5 | * Index (/) route does not have to be listed here. 6 | * 7 | * @example 8 | * export const routes: string[] = [ 9 | * 'home', 'about' 10 | * ]; 11 | **/ 12 | export const routes: string[] = [ 13 | 'about', 14 | 'home', 15 | 'contact' 16 | ]; 17 | -------------------------------------------------------------------------------- /src/server.ts: -------------------------------------------------------------------------------- 1 | // the polyfills must be one of the first things imported in node.js. 2 | // The only modules to be imported higher - node modules with es6-promise 3.x or other Promise polyfill dependency 3 | // (rule of thumb: do it if you have zone.js exception that it has been overwritten) 4 | // if you are including modules that modify Promise, such as NewRelic,, you must include them before polyfills 5 | import 'angular2-universal-polyfills'; 6 | import 'ts-helpers'; 7 | import './__workaround.node'; // temporary until 2.1.1 things are patched in Core 8 | 9 | import * as path from 'path'; 10 | import * as express from 'express'; 11 | import * as bodyParser from 'body-parser'; 12 | import * as cookieParser from 'cookie-parser'; 13 | import * as morgan from 'morgan'; 14 | import * as compression from 'compression'; 15 | 16 | // Angular 2 17 | import { enableProdMode } from '@angular/core'; 18 | import { Title } from '@angular/platform-browser'; 19 | // Angular 2 Universal 20 | import { createEngine } from 'angular2-express-engine'; 21 | 22 | // App 23 | import { MainModule } from './node.module'; 24 | 25 | // Routes 26 | import { routes } from './server.routes'; 27 | 28 | // enable prod for faster renders 29 | enableProdMode(); 30 | 31 | const app = express(); 32 | const ROOT = path.join(path.resolve(__dirname, '..')); 33 | 34 | // Express View 35 | app.engine('.html', createEngine({ 36 | ngModule: MainModule, 37 | providers: [ 38 | // use only if you have shared state between users 39 | // { provide: 'LRU', useFactory: () => new LRU(10) } 40 | 41 | // stateless providers only since it's shared 42 | Title 43 | ] 44 | })); 45 | app.set('port', process.env.PORT || 3000); 46 | app.set('views', __dirname); 47 | app.set('view engine', 'html'); 48 | app.set('json spaces', 2); 49 | 50 | app.use(cookieParser('Angular 2 Universal')); 51 | app.use(bodyParser.json()); 52 | app.use(compression()); 53 | 54 | app.use(morgan('dev')); 55 | 56 | function cacheControl(req, res, next) { 57 | // instruct browser to revalidate in 60 seconds 58 | res.header('Cache-Control', 'max-age=60'); 59 | next(); 60 | } 61 | // Serve static files 62 | app.use('/assets', cacheControl, express.static(path.join(__dirname, 'assets'), {maxAge: 30})); 63 | app.use(cacheControl, express.static(path.join(ROOT, 'dist/client'), {index: false})); 64 | 65 | // 66 | ///////////////////////// 67 | // ** Example API 68 | // Notice API should be in aseparate process 69 | import { serverApi, createTodoApi } from './backend/api'; 70 | // Our API for demos only 71 | app.get('/data.json', serverApi); 72 | app.use('/api', createTodoApi()); 73 | 74 | function ngApp(req, res) { 75 | res.render('index', { 76 | req, 77 | res, 78 | // time: true, // use this to determine what part of your app is slow only in development 79 | preboot: false, 80 | baseUrl: '/', 81 | requestUrl: req.originalUrl, 82 | originUrl: `http://localhost:${ app.get('port') }` 83 | }); 84 | } 85 | 86 | /** 87 | * use universal for specific routes 88 | */ 89 | app.get('/', ngApp); 90 | routes.forEach(route => { 91 | app.get(`/${route}`, ngApp); 92 | app.get(`/${route}/*`, ngApp); 93 | }); 94 | 95 | app.get('*', function(req, res) { 96 | res.setHeader('Content-Type', 'application/json'); 97 | var pojo = { status: 404, message: 'No Content' }; 98 | var json = JSON.stringify(pojo, null, 2); 99 | res.status(404).send(json); 100 | }); 101 | 102 | // Server 103 | let server = app.listen(app.get('port'), () => { 104 | console.log(`Listening on: http://localhost:${server.address().port}`); 105 | }); 106 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Custom Type Definitions 3 | * When including 3rd party modules you also need to include the type definition for the module 4 | * if they don't provide one within the module. You can try to install it with typings 5 | typings install node --save 6 | * If you can't find the type definition in the registry we can make an ambient definition in 7 | * this file for now. For example 8 | declare module "my-module" { 9 | export function doesSomething(value: string): string; 10 | } 11 | * 12 | * If you're prototying and you will fix the types later you can also declare it as type any 13 | * 14 | declare var assert: any; 15 | * 16 | * If you're importing a module that uses Node.js modules which are CommonJS you need to import as 17 | * 18 | import * as _ from 'lodash' 19 | * You can include your type definitions in this file until you create one for the typings registry 20 | * see https://github.com/typings/registry 21 | * 22 | */ 23 | 24 | // declare module '*'; // default type definitions for any for modules that are not found. 25 | // caveat: if this is enabled and you do not have the proper module there may not be an error. 26 | // suggestion: follow the pattern below with modern-lru which provides an alternative way to create an 'any' module. 27 | 28 | // for legacy tslint etc to understand 29 | declare module 'modern-lru' { 30 | let x: any; 31 | export = x; 32 | } 33 | 34 | declare var System: SystemJS; 35 | 36 | interface SystemJS { 37 | import: (path?: string) => Promise; 38 | } 39 | // Extra variables that live on Global that will be replaced by webpack DefinePlugin 40 | declare var ENV: string; 41 | declare var HMR: boolean; 42 | declare var Zone: {current: any}; 43 | interface GlobalEnvironment { 44 | ENV; 45 | HMR; 46 | SystemJS: SystemJS; 47 | System: SystemJS; 48 | } 49 | 50 | interface WebpackModule { 51 | hot: { 52 | data?: any, 53 | idle: any, 54 | accept(dependencies?: string | string[], callback?: (updatedDependencies?: any) => void): void; 55 | decline(dependencies?: string | string[]): void; 56 | dispose(callback?: (data?: any) => void): void; 57 | addDisposeHandler(callback?: (data?: any) => void): void; 58 | removeDisposeHandler(callback?: (data?: any) => void): void; 59 | check(autoApply?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void; 60 | apply(options?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void; 61 | status(callback?: (status?: string) => void): void | string; 62 | removeStatusHandler(callback?: (status?: string) => void): void; 63 | }; 64 | } 65 | 66 | interface WebpackRequire { 67 | context(file: string, flag?: boolean, exp?: RegExp): any; 68 | } 69 | 70 | // Extend typings 71 | interface NodeRequire extends WebpackRequire {} 72 | interface NodeModule extends WebpackModule {} 73 | interface Global extends GlobalEnvironment {} 74 | -------------------------------------------------------------------------------- /tsconfig.aot.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": false, 4 | "emitDecoratorMetadata": true, 5 | "experimentalDecorators": true, 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "outDir": "dist", 9 | "sourceMap": true, 10 | "sourceRoot": "src", 11 | "noEmitHelpers": true, 12 | "target": "es5", 13 | "typeRoots": [ 14 | "node_modules/@types" 15 | ], 16 | "lib": ["es6", "dom"] 17 | }, 18 | "include": [ 19 | "./src/**/*.module.ts", 20 | "./src/*.d.ts" 21 | ], 22 | "angularCompilerOptions": { 23 | "debug": false 24 | }, 25 | "compileOnSave": false, 26 | "buildOnSave": false, 27 | "atom": { "rewriteTsconfig": false } 28 | } 29 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": false, 4 | "emitDecoratorMetadata": true, 5 | "experimentalDecorators": true, 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "outDir": "dist", 9 | "sourceMap": true, 10 | "sourceRoot": "src", 11 | "noEmitHelpers": true, 12 | "target": "es5", 13 | "typeRoots": [ 14 | "node_modules/@types" 15 | ], 16 | "lib": ["es6", "dom"] 17 | }, 18 | "exclude": [ 19 | "node_modules" 20 | ], 21 | "angularCompilerOptions": { 22 | "debug": false 23 | }, 24 | "compileOnSave": false, 25 | "buildOnSave": false, 26 | "atom": { "rewriteTsconfig": false } 27 | } 28 | -------------------------------------------------------------------------------- /webpack.config.ts: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var path = require('path'); 3 | var clone = require('js.clone'); 4 | var webpackMerge = require('webpack-merge'); 5 | 6 | export var commonPlugins = [ 7 | new webpack.ContextReplacementPlugin( 8 | // The (\\|\/) piece accounts for path separators in *nix and Windows 9 | /angular(\\|\/)core(\\|\/)src(\\|\/)linker/, 10 | root('./src'), 11 | { 12 | // your Angular Async Route paths relative to this root directory 13 | } 14 | ), 15 | 16 | // Loader options 17 | new webpack.LoaderOptionsPlugin({ 18 | 19 | }), 20 | 21 | ]; 22 | export var commonConfig = { 23 | // https://webpack.github.io/docs/configuration.html#devtool 24 | devtool: 'source-map', 25 | resolve: { 26 | extensions: ['.ts', '.js', '.json'], 27 | modules: [ root('node_modules') ] 28 | }, 29 | context: __dirname, 30 | output: { 31 | publicPath: '', 32 | filename: '[name].bundle.js' 33 | }, 34 | module: { 35 | rules: [ 36 | // TypeScript 37 | { test: /\.ts$/, use: ['awesome-typescript-loader', 'angular2-template-loader'] }, 38 | { test: /\.html$/, use: 'raw-loader' }, 39 | { test: /\.css$/, use: 'raw-loader' }, 40 | { test: /\.json$/, use: 'json-loader' } 41 | ], 42 | }, 43 | plugins: [ 44 | // Use commonPlugins. 45 | ] 46 | 47 | }; 48 | 49 | // Client. 50 | export var clientPlugins = [ 51 | 52 | ]; 53 | export var clientConfig = { 54 | target: 'web', 55 | entry: './src/client', 56 | output: { 57 | path: root('dist/client') 58 | }, 59 | node: { 60 | global: true, 61 | crypto: 'empty', 62 | __dirname: true, 63 | __filename: true, 64 | process: true, 65 | Buffer: false 66 | } 67 | }; 68 | 69 | 70 | // Server. 71 | export var serverPlugins = [ 72 | 73 | ]; 74 | export var serverConfig = { 75 | target: 'node', 76 | entry: './src/server', // use the entry file of the node server if everything is ts rather than es5 77 | output: { 78 | filename: 'index.js', 79 | path: root('dist/server'), 80 | libraryTarget: 'commonjs2' 81 | }, 82 | module: { 83 | rules: [ 84 | { test: /@angular(\\|\/)material/, use: "imports-loader?window=>global" } 85 | ], 86 | }, 87 | externals: includeClientPackages( 88 | /@angularclass|@angular|angular2-|ng2-|ng-|@ng-|angular-|@ngrx|ngrx-|@angular2|ionic|@ionic|-angular2|-ng2|-ng/ 89 | ), 90 | node: { 91 | global: true, 92 | crypto: true, 93 | __dirname: true, 94 | __filename: true, 95 | process: true, 96 | Buffer: true 97 | } 98 | }; 99 | 100 | export default [ 101 | // Client 102 | webpackMerge(clone(commonConfig), clientConfig, { plugins: clientPlugins.concat(commonPlugins) }), 103 | 104 | // Server 105 | webpackMerge(clone(commonConfig), serverConfig, { plugins: serverPlugins.concat(commonPlugins) }) 106 | ]; 107 | 108 | 109 | 110 | 111 | // Helpers 112 | export function includeClientPackages(packages, localModule?: string[]) { 113 | return function(context, request, cb) { 114 | if (localModule instanceof RegExp && localModule.test(request)) { 115 | return cb(); 116 | } 117 | if (packages instanceof RegExp && packages.test(request)) { 118 | return cb(); 119 | } 120 | if (Array.isArray(packages) && packages.indexOf(request) !== -1) { 121 | return cb(); 122 | } 123 | if (!path.isAbsolute(request) && request.charAt(0) !== '.') { 124 | return cb(null, 'commonjs ' + request); 125 | } 126 | return cb(); 127 | }; 128 | } 129 | 130 | export function root(args) { 131 | args = Array.prototype.slice.call(arguments, 0); 132 | return path.join.apply(path, [__dirname].concat(args)); 133 | } 134 | -------------------------------------------------------------------------------- /webpack.prod.config.ts: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const path = require('path'); 3 | const clone = require('js.clone'); 4 | const webpackMerge = require('webpack-merge'); 5 | const V8LazyParseWebpackPlugin = require('v8-lazy-parse-webpack-plugin'); 6 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 7 | import webpackConfig, { root, includeClientPackages } from './webpack.config'; 8 | // const CompressionPlugin = require('compression-webpack-plugin'); 9 | 10 | 11 | export const commonPlugins = [ 12 | new V8LazyParseWebpackPlugin(), 13 | 14 | new webpack.DefinePlugin({ 15 | // do not use an object for 'process.env' otherwise all other environment 16 | // variables are set to 'undefined' see issue #291 17 | 'process.env.NODE_ENV': JSON.stringify('production'), 18 | 'process.env.AOT': true 19 | }), 20 | 21 | // Loader options 22 | new webpack.LoaderOptionsPlugin({ 23 | minimize: true, 24 | debug: false 25 | }), 26 | 27 | new webpack.NormalModuleReplacementPlugin( 28 | /facade(\\|\/)async/, 29 | root('node_modules/@angular/core/src/facade/async.js') 30 | ), 31 | new webpack.NormalModuleReplacementPlugin( 32 | /facade(\\|\/)collection/, 33 | root('node_modules/@angular/core/src/facade/collection.js') 34 | ), 35 | new webpack.NormalModuleReplacementPlugin( 36 | /facade(\\|\/)errors/, 37 | root('node_modules/@angular/core/src/facade/errors.js') 38 | ), 39 | new webpack.NormalModuleReplacementPlugin( 40 | /facade(\\|\/)lang/, 41 | root('node_modules/@angular/core/src/facade/lang.js') 42 | ), 43 | new webpack.NormalModuleReplacementPlugin( 44 | /facade(\\|\/)math/, 45 | root('node_modules/@angular/core/src/facade/math.js') 46 | ), 47 | 48 | ]; 49 | export const commonConfig = { 50 | output: { 51 | filename: '[name].bundle.js', 52 | chunkFilename: '[chunkhash].js' 53 | }, 54 | }; 55 | 56 | // Client. 57 | export const clientPlugins = [ 58 | new BundleAnalyzerPlugin({ 59 | analyzerMode: 'disabled', // change it to `server` to view bundle stats 60 | reportFilename: 'report.html', 61 | generateStatsFile: true, 62 | statsFilename: 'stats.json', 63 | }), 64 | // To use gzip, you can run 'npm install compression-webpack-plugin --save-dev' 65 | // add 'var CompressionPlugin = require("compression-webpack-plugin");' on the top 66 | // and comment out below codes 67 | // 68 | // new CompressionPlugin({ 69 | // asset: "[path].gz[query]", 70 | // algorithm: "gzip", 71 | // test: /\.js$|\.css$|\.html$/, 72 | // threshold: 10240, 73 | // minRatio: 0.8 74 | // }), 75 | 76 | new webpack.optimize.UglifyJsPlugin({ 77 | // beautify: true, 78 | // mangle: false, 79 | output: { 80 | comments: false 81 | }, 82 | compress: { 83 | warnings: false, 84 | conditionals: true, 85 | unused: true, 86 | comparisons: true, 87 | sequences: true, 88 | dead_code: true, 89 | evaluate: true, 90 | if_return: true, 91 | join_vars: true, 92 | negate_iife: false // we need this for lazy v8 93 | }, 94 | sourceMap: true 95 | }), 96 | 97 | new webpack.NormalModuleReplacementPlugin( 98 | /@angular(\\|\/)upgrade/, 99 | root('empty.js') 100 | ), 101 | // problem with platformUniversalDynamic on the server/client 102 | new webpack.NormalModuleReplacementPlugin( 103 | /@angular(\\|\/)compiler/, 104 | root('empty.js') 105 | ), 106 | new webpack.NormalModuleReplacementPlugin( 107 | /@angular(\\|\/)platform-browser-dynamic/, 108 | root('empty.js') 109 | ), 110 | new webpack.NormalModuleReplacementPlugin( 111 | /dom(\\|\/)debug(\\|\/)ng_probe/, 112 | root('empty.js') 113 | ), 114 | new webpack.NormalModuleReplacementPlugin( 115 | /dom(\\|\/)debug(\\|\/)by/, 116 | root('empty.js') 117 | ), 118 | new webpack.NormalModuleReplacementPlugin( 119 | /src(\\|\/)debug(\\|\/)debug_node/, 120 | root('empty.js') 121 | ), 122 | new webpack.NormalModuleReplacementPlugin( 123 | /src(\\|\/)debug(\\|\/)debug_renderer/, 124 | root('empty.js') 125 | ), 126 | 127 | // Waiting for https://github.com/ampedandwired/html-webpack-plugin/issues/446 128 | // new webpack.optimize.AggressiveSplittingPlugin({ 129 | // minSize: 30000, 130 | // maxSize: 250000 131 | // }), 132 | 133 | ]; 134 | export const clientConfig = { 135 | entry: './src/client.aot', 136 | recordsOutputPath: root('webpack.records.json') 137 | }; 138 | 139 | // Server. 140 | 141 | export const serverPlugins = [ 142 | new webpack.optimize.UglifyJsPlugin({ 143 | // beautify: true, 144 | mangle: false, // to ensure process.env still works 145 | output: { 146 | comments: false 147 | }, 148 | compress: { 149 | warnings: false, 150 | conditionals: true, 151 | unused: true, 152 | comparisons: true, 153 | sequences: true, 154 | dead_code: true, 155 | evaluate: true, 156 | if_return: true, 157 | join_vars: true, 158 | negate_iife: false // we need this for lazy v8 159 | }, 160 | sourceMap: true 161 | }), 162 | ]; 163 | export const serverConfig = { 164 | entry: './src/server.aot', 165 | output: { 166 | filename: 'index.js', 167 | chunkFilename: '[id].bundle.js', 168 | crossOriginLoading: false 169 | }, 170 | }; 171 | 172 | export default [ 173 | // Client 174 | webpackMerge(webpackConfig[0], clone(commonConfig), clientConfig, {plugins: webpackConfig[0].plugins.concat(commonPlugins, clientPlugins) }), 175 | 176 | // Server 177 | webpackMerge(webpackConfig[1], clone(commonConfig), serverConfig, {plugins: webpackConfig[1].plugins.concat(commonPlugins, serverPlugins) }) 178 | ]; 179 | --------------------------------------------------------------------------------