diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index f87dd47ec27..8c972237bb4 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -10,6 +10,7 @@ Please ask before on our gitter channel https://gitter.im/Alfresco/alfresco-ng2- - [ ] New feature request - [ ] Bug - [ ] Support request +- [ ] Documentation ``` **Current behavior:** diff --git a/.travis.yml b/.travis.yml index 1e14c4ce252..e15bf35b9ca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,24 +32,31 @@ env: before_script: - if ([ "$MODULE" != "ng2-alfresco-core" ]); then - (cd ng2-components/ng2-alfresco-core; if [ ! -d "dist" ]; then npm install; fi; npm link); + (cd ng2-components/ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); fi - if ([ "$MODULE" == "ng2-alfresco-documentlist" ] || [ "$MODULE" == "ng2-alfresco-webscript" ] || [ "$MODULE" == "ng2-activiti-processlist" ] || [ "$MODULE" == "ng2-activiti-tasklist" ]); then - (cd ng2-components/ng2-alfresco-datatable; npm link ng2-alfresco-core; if [ ! -d "dist" ]; then npm install; fi; npm link); + (cd ng2-components/ng2-alfresco-datatable; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); fi - if ([ "$MODULE" == "ng2-activiti-tasklist" ] || [ "$MODULE" == "ng2-activiti-processlist" ]); then - (cd ng2-components/ng2-activiti-form; npm link ng2-alfresco-core; if [ ! -d "dist" ]; then npm install; fi; npm link); + (cd ng2-components/ng2-alfresco-datatable; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); + (cd ng2-components/ng2-activiti-form; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); fi - if ([ "$MODULE" == "ng2-activiti-processlist" ]); then - (cd ng2-components/ng2-activiti-tasklist; npm link ng2-alfresco-core; npm link ng2-alfresco-datatable; npm link ng2-activiti-form; if [ ! -d "dist" ]; then npm install; fi; npm link); + (cd ng2-components/ng2-alfresco-datatable; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); + (cd ng2-components/ng2-activiti-form; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); + (cd ng2-components/ng2-activiti-tasklist; npm link ng2-alfresco-core; npm link ng2-alfresco-datatable; npm link ng2-activiti-form; if [ ! -d "bundles" ]; then npm link; fi); fi - if ([ "$MODULE" == "ng2-activiti-analytics" ]); then - (cd ng2-components/ng2-activiti-diagrams; npm link ng2-alfresco-core; if [ ! -d "dist" ]; then npm install; fi; npm link); + (cd ng2-components/ng2-activiti-diagrams; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); + fi + - if ([ "$MODULE" == "ng2-alfresco-search" ]); then + (cd ng2-components/ng2-alfresco-datatable; npm link ng2-alfresco-core; if [ ! -d "bundles" ]; then npm link; fi); + (cd ng2-components/ng2-alfresco-documentlist; npm link ng2-alfresco-core; npm link ng2-alfresco-datatable; if [ ! -d "bundles" ]; then npm link; fi); fi - cd ng2-components/$MODULE; - npm run travis; - - npm install; -script: npm run test +#npm insall run install, build and tests +script: npm install # Send coverage data to Coveralls after_success: bash <(curl -s https://codecov.io/bash) -X gcov diff --git a/.vscode/settings.json b/.vscode/settings.json index ee92513479d..30d10b67e52 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,8 @@ "**/.hg": true, "**/.DS_Store": true, "**/*.js": { "when": "$(basename).ts"}, - "**/*.js.map": { "when": "$(basename)"} - } + "**/*.js.map": { "when": "$(basename)"}, + "**/*.d.ts": { "when": "$(basename).ts"} + }, + "editor.renderIndentGuides": true } diff --git a/README.md b/README.md index 78ddedf5904..e2c3265749c 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,12 @@ To view the complete list of all the components that you can use to build your c You can browse all the components at the following [page](http://devproducts.alfresco.com/). +## Demo Application + +A separate application showcasing integration of components can be found [here](https://github.com/Alfresco/alfresco-ng2-components/tree/master/demo-shell-ng2). + +You will find examples of basic interaction for both BPM and ECM sets of widgets. + ## Yeoman generators To speed up the development of your Alfresco Angular 2 application, or Alfresco Angular 2 component, use one of the Yeoman generators. diff --git a/appveyor.yml b/appveyor.yml index cefe10fbfd7..f328219a3fa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,9 @@ # Test against this version of Node.js +branches: + only: + - master + - development + - dev-build-test environment: nodejs_version: "5" @@ -25,22 +30,19 @@ install: # Get the latest stable version of Node.js or io.js - ps: Install-Product node $env:nodejs_version # install module - - IF %COMPONENT_NAME% NEQ ng2-alfresco-core (cd ng2-components/ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-alfresco-documentlist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-activiti-form && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-activiti-tasklist && npm link ng2-alfresco-core && npm link ng2-alfresco-datatable && npm link ng2-activiti-form && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (cd ng2-components/ng2-activiti-form && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-alfresco-webscript (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - - IF %COMPONENT_NAME% EQU ng2-activiti-analytics (cd ng2-components/ng2-activiti-diagrams && npm link link ng2-alfresco-core && npm install && npm link && cd ../../) + - IF %COMPONENT_NAME% NEQ ng2-alfresco-core (cd ng2-components/ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-alfresco-documentlist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-alfresco-search (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-alfresco-search (cd ng2-components/ng2-alfresco-documentlist && npm link ng2-alfresco-core && npm link ng2-alfresco-datatable && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-activiti-form && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-activiti-tasklist && npm link ng2-alfresco-core && npm link ng2-alfresco-datatable && npm link ng2-activiti-form && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (cd ng2-components/ng2-activiti-form && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-alfresco-webscript (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-analytics (cd ng2-components/ng2-activiti-diagrams && npm link link ng2-alfresco-core && npm link && cd ../../) - cd ng2-components/%COMPONENT_NAME% - - IF %COMPONENT_NAME% NEQ ng2-alfresco-core (npm link ng2-alfresco-core) - - IF %COMPONENT_NAME% EQU ng2-alfresco-documentlist (npm link ng2-alfresco-datatable) - - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (npm link ng2-alfresco-datatable && npm link ng2-activiti-form && npm link ng2-activiti-tasklist) - - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (npm link ng2-alfresco-datatable && npm link ng2-activiti-form) - - IF %COMPONENT_NAME% EQU ng2-alfresco-webscript (npm link ng2-alfresco-datatable) - - IF %COMPONENT_NAME% EQU ng2-activiti-analytics (npm link ng2-activiti-diagrams) + - npm run travis # Post-install test scripts. test_script: diff --git a/demo-shell-ng2/README.md b/demo-shell-ng2/README.md index 13db6efa47c..31136a7a7c4 100644 --- a/demo-shell-ng2/README.md +++ b/demo-shell-ng2/README.md @@ -12,9 +12,11 @@ ## Installing -To correctly use this demo check that on your machine is running Node version 6.9.2 LTS or higher. +To correctly use this demo check that on your machine is running [Node](https://nodejs.org/en/) version 6.9.2 LTS or higher. ```sh +git clone https://github.com/Alfresco/alfresco-ng2-components.git +cd alfresco-ng2-components/demo-shell-ng2/ npm install ``` @@ -28,22 +30,26 @@ This command compiles and starts the project in watch mode. Browser will automatically reload upon changes. Upon start you can navigate to `http://localhost:3000` with your preferred browser. +### Important notes + +This script is recommended for development environment and not suited for headless servers and network access. + ## Production build ```sh npm run build +npm run start:dist ``` This command builds broject in `production` mode. All output is placed to `dist` folder and can be served your preferred web server. You should need no additional files outside the `dist` folder. -In order to quickly test the output you can use the [wsrv](https://www.npmjs.com/package/wsrv) tool (lightweight web server): +### Important notes -```sh -npm install -g wsrv -wsrv -s -o dist/ -``` +By default demo application is configured to use [wsrv](https://www.npmjs.com/package/wsrv) tool (lightweight web server) +to serve production build output. It will be running at `0.0.0.0` address with port `3000` and allow you accessing your application +via network. However you can use any web server of your choice in production. ## Development branch build diff --git a/demo-shell-ng2/app/app.component.html b/demo-shell-ng2/app/app.component.html index 5ee422e46d3..aeee137ec91 100644 --- a/demo-shell-ng2/app/app.component.html +++ b/demo-shell-ng2/app/app.component.html @@ -1,6 +1,6 @@
-
+
diff --git a/demo-shell-ng2/app/app.component.ts b/demo-shell-ng2/app/app.component.ts index 766bbdd6fdf..ca207009451 100644 --- a/demo-shell-ng2/app/app.component.ts +++ b/demo-shell-ng2/app/app.component.ts @@ -17,13 +17,7 @@ import { Component } from '@angular/core'; import { Router } from '@angular/router'; - -import { - AlfrescoTranslationService, - AlfrescoAuthenticationService, - AlfrescoSettingsService, - StorageService -} from 'ng2-alfresco-core'; +import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoSettingsService, StorageService, LogService } from 'ng2-alfresco-core'; declare var document: any; @@ -38,44 +32,34 @@ export class AppComponent { ecmHost: string = 'http://' + window.location.hostname + ':8080'; bpmHost: string = 'http://' + window.location.hostname + ':9999'; - constructor(public auth: AlfrescoAuthenticationService, - public router: Router, - public alfrescoSettingsService: AlfrescoSettingsService, - private translate: AlfrescoTranslationService, - private storage: StorageService) { + constructor(private authService: AlfrescoAuthenticationService, + private router: Router, + private settingsService: AlfrescoSettingsService, + private translateService: AlfrescoTranslationService, + private storage: StorageService, + private logService: LogService) { this.setEcmHost(); this.setBpmHost(); this.setProvider(); - if (translate) { + if (translateService) { if (process.env.ENV === 'production') { - translate.addTranslationFolder('custom', 'i18n/custom-translation'); - translate.addTranslationFolder('ng2-alfresco-login', 'i18n/custom-translation/alfresco-login'); + translateService.addTranslationFolder('custom', 'i18n/custom-translation'); + translateService.addTranslationFolder('ng2-alfresco-login', 'i18n/custom-translation/alfresco-login'); } else { - translate.addTranslationFolder('custom', 'custom-translation'); - translate.addTranslationFolder('ng2-alfresco-login', 'custom-translation/alfresco-login'); + translateService.addTranslationFolder('custom', 'custom-translation'); + translateService.addTranslationFolder('ng2-alfresco-login', 'custom-translation/alfresco-login'); } } } - isLoggedIn(): boolean { - this.redirectToLoginPageIfNotLoggedIn(); - return this.auth.isLoggedIn(); - } - - redirectToLoginPageIfNotLoggedIn(): void { - if (!this.isLoginPage() && !this.auth.isLoggedIn()) { - this.router.navigate(['/login']); - } - } - - isLoginPage(): boolean { + isAPageWithHeaderBar(): boolean { return location.pathname === '/login' || location.pathname === '/settings'; } onLogout(event) { event.preventDefault(); - this.auth.logout() + this.authService.logout() .subscribe( () => { this.navigateToLogin(); @@ -84,7 +68,7 @@ export class AppComponent { if (error && error.response && error.response.status === 401) { this.navigateToLogin(); } else { - console.error('An unknown error occurred while logging out', error); + this.logService.error('An unknown error occurred while logging out', error); this.navigateToLogin(); } } @@ -107,7 +91,7 @@ export class AppComponent { } changeLanguage(lang: string) { - this.translate.use(lang); + this.translateService.use(lang); this.hideDrawer(); } @@ -118,25 +102,25 @@ export class AppComponent { private setEcmHost() { if (this.storage.hasItem(`ecmHost`)) { - this.alfrescoSettingsService.ecmHost = this.storage.getItem(`ecmHost`); + this.settingsService.ecmHost = this.storage.getItem(`ecmHost`); this.ecmHost = this.storage.getItem(`ecmHost`); } else { - this.alfrescoSettingsService.ecmHost = this.ecmHost; + this.settingsService.ecmHost = this.ecmHost; } } private setBpmHost() { if (this.storage.hasItem(`bpmHost`)) { - this.alfrescoSettingsService.bpmHost = this.storage.getItem(`bpmHost`); + this.settingsService.bpmHost = this.storage.getItem(`bpmHost`); this.bpmHost = this.storage.getItem(`bpmHost`); } else { - this.alfrescoSettingsService.bpmHost = this.bpmHost; + this.settingsService.bpmHost = this.bpmHost; } } private setProvider() { if (this.storage.hasItem(`providers`)) { - this.alfrescoSettingsService.setProviders(this.storage.getItem(`providers`)); + this.settingsService.setProviders(this.storage.getItem(`providers`)); } } } diff --git a/demo-shell-ng2/app/app.module.ts b/demo-shell-ng2/app/app.module.ts index 8be249c8829..cd3eddb146f 100644 --- a/demo-shell-ng2/app/app.module.ts +++ b/demo-shell-ng2/app/app.module.ts @@ -32,7 +32,6 @@ import { ActivitiTaskListModule } from 'ng2-activiti-tasklist'; import { ActivitiProcessListModule } from 'ng2-activiti-processlist'; import { UserInfoComponentModule } from 'ng2-alfresco-userinfo'; import { AnalyticsModule } from 'ng2-activiti-analytics'; - import { AppComponent } from './app.component'; import { routing } from './app.routes'; import { CustomEditorsModule } from './components/activiti/custom-editor/custom-editor.component'; @@ -59,13 +58,13 @@ import { BrowserModule, routing, CoreModule.forRoot(), - LoginModule, + LoginModule.forRoot(), SearchModule.forRoot(), - DataTableModule, + DataTableModule.forRoot(), DocumentListModule.forRoot(), UploadModule.forRoot(), TagModule.forRoot(), - WebScriptModule, + WebScriptModule.forRoot(), ViewerModule.forRoot(), ActivitiFormModule.forRoot(), ActivitiTaskListModule.forRoot(), diff --git a/demo-shell-ng2/app/components/about/about.component.ts b/demo-shell-ng2/app/components/about/about.component.ts index fbcd09611da..4fba975fe8e 100644 --- a/demo-shell-ng2/app/components/about/about.component.ts +++ b/demo-shell-ng2/app/components/about/about.component.ts @@ -18,6 +18,7 @@ import { Component, OnInit } from '@angular/core'; import { Http } from '@angular/http'; import { ObjectDataTableAdapter } from 'ng2-alfresco-datatable'; +import { LogService } from 'ng2-alfresco-core'; @Component({ selector: 'about-page', @@ -27,31 +28,31 @@ export class AboutComponent implements OnInit { data: ObjectDataTableAdapter; - constructor(private http: Http) { + constructor(private http: Http, + private logService: LogService) { } ngOnInit() { this.http.get('/versions.json').subscribe(response => { - var regexp = new RegExp("^(ng2-activiti|ng2-alfresco|alfresco-)", 'g'); + let regexp = new RegExp('^(ng2-activiti|ng2-alfresco|alfresco-)', 'g'); - var alfrescoPackages = Object.keys(response.json().dependencies).filter(function (val) { - console.log(val); + let alfrescoPackages = Object.keys(response.json().dependencies).filter((val) => { + this.logService.log(val); return regexp.test(val); }); - let alfrescoPackagesTableRappresentation = []; - alfrescoPackages.forEach((val)=> { - console.log(response.json().dependencies[val]); - alfrescoPackagesTableRappresentation.push({name:val,version:response.json().dependencies[val].version}); + let alfrescoPackagesTableRappresentation = []; + alfrescoPackages.forEach((val) => { + this.logService.log(response.json().dependencies[val]); + alfrescoPackagesTableRappresentation.push({name: val, version: response.json().dependencies[val].version}); }); - console.log(alfrescoPackagesTableRappresentation); + this.logService.log(alfrescoPackagesTableRappresentation); this.data = new ObjectDataTableAdapter(alfrescoPackagesTableRappresentation, [ {type: 'text', key: 'name', title: 'Name', sortable: true}, {type: 'text', key: 'version', title: 'Version', sortable: true} ]); }); - } } diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html index 5206baf609f..4f00688632a 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html @@ -5,9 +5,9 @@
@@ -15,7 +15,7 @@ -
+
@@ -36,6 +36,7 @@ [state]="taskFilter.filter.state" [sort]="taskFilter.filter.sort" [data]="dataTasks" + [landingTaskId]="currentTaskId" (rowClick)="onTaskRowClick($event)" (onSuccess)="onSuccessTaskList($event)" #activititasklist>
@@ -43,6 +44,7 @@
Task Details

@@ -52,8 +54,8 @@ -
-
+
+
@@ -66,7 +68,7 @@ (filterClick)="onProcessFilterClick($event)" (onSuccess)="onSuccessProcessFilterList($event)">
-
+
Process List

-
+
Process Details

- + +
-
- Start Process +
+
Start Process

@@ -98,8 +104,8 @@ -
-
+
+
Report List
diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts index 98125b37306..0fee1a11278 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts @@ -19,15 +19,16 @@ import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular import { ActivitiApps, ActivitiFilters, - ActivitiTaskDetails, ActivitiTaskList, - FilterRepresentationModel + FilterRepresentationModel, + TaskDetailsEvent } from 'ng2-activiti-tasklist'; import { ActivitiProcessFilters, ActivitiProcessInstanceDetails, ActivitiProcessInstanceListComponent, ActivitiStartProcessInstance, + FilterProcessRepresentationModel, ProcessInstance } from 'ng2-activiti-processlist'; import { AnalyticsReportListComponent } from 'ng2-activiti-analytics'; @@ -35,10 +36,11 @@ import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Rx'; import { ObjectDataTableAdapter, + ObjectDataRow, DataSorting } from 'ng2-alfresco-datatable'; import { AlfrescoApiService } from 'ng2-alfresco-core'; -import { FormRenderingService } from 'ng2-activiti-form'; +import { FormService, FormRenderingService, FormEvent, FormFieldEvent } from 'ng2-activiti-form'; import { /*CustomEditorComponent*/ CustomStencil01 } from './custom-editor/custom-editor.component'; declare var componentHandler; @@ -52,18 +54,12 @@ const currentProcessIdNew = '__NEW__'; }) export class ActivitiDemoComponent implements AfterViewInit { - @ViewChild(ActivitiApps) - activitiapps: ActivitiApps; - @ViewChild(ActivitiFilters) activitifilter: ActivitiFilters; @ViewChild(ActivitiTaskList) activititasklist: ActivitiTaskList; - @ViewChild(ActivitiTaskDetails) - activitidetails: ActivitiTaskDetails; - @ViewChild(ActivitiProcessFilters) activitiprocessfilter: ActivitiProcessFilters; @@ -80,7 +76,7 @@ export class ActivitiDemoComponent implements AfterViewInit { analyticsreportlist: AnalyticsReportListComponent; @Input() - appId: number; + appId: number = null; layoutType: string; currentTaskId: string; @@ -89,13 +85,11 @@ export class ActivitiDemoComponent implements AfterViewInit { taskSchemaColumns: any [] = []; processSchemaColumns: any [] = []; - processTabActivie: boolean = false; - - reportsTabActivie: boolean = false; + activeTab: string = 'tasks'; // tasks|processes|reports taskFilter: FilterRepresentationModel; report: any; - processFilter: FilterRepresentationModel; + processFilter: FilterProcessRepresentationModel; sub: Subscription; @@ -105,7 +99,8 @@ export class ActivitiDemoComponent implements AfterViewInit { constructor(private elementRef: ElementRef, private route: ActivatedRoute, private apiService: AlfrescoApiService, - private formRenderingService: FormRenderingService) { + private formRenderingService: FormRenderingService, + private formService: FormService) { this.dataTasks = new ObjectDataTableAdapter( [], [ @@ -122,12 +117,21 @@ export class ActivitiDemoComponent implements AfterViewInit { {type: 'text', key: 'started', title: 'Started', cssClass: 'hidden', sortable: true} ] ); + this.dataProcesses.setSorting(new DataSorting('started', 'desc')); // Uncomment this line to replace all 'text' field editors with custom component // formRenderingService.setComponentTypeResolver('text', () => CustomEditorComponent, true); // Uncomment this line to map 'custom_stencil_01' to local editor component formRenderingService.setComponentTypeResolver('custom_stencil_01', () => CustomStencil01, true); + + formService.formLoaded.subscribe((e: FormEvent) => { + console.log(`Form loaded: ${e.form.id}`); + }); + + formService.formFieldValueChanged.subscribe((e: FormFieldEvent) => { + console.log(`Field value changed. Form: ${e.form.id}, Field: ${e.field.id}, Value: ${e.field.value}`); + }); } ngOnInit() { @@ -150,7 +154,9 @@ export class ActivitiDemoComponent implements AfterViewInit { } onTaskFilterClick(event: FilterRepresentationModel) { - this.taskFilter = event; + if(event){ + this.taskFilter = event; + } } onReportClick(event: any) { @@ -171,11 +177,12 @@ export class ActivitiDemoComponent implements AfterViewInit { this.currentTaskId = this.activititasklist.getCurrentId(); } - onProcessFilterClick(event: FilterRepresentationModel) { + onProcessFilterClick(event: FilterProcessRepresentationModel) { + this.currentProcessInstanceId = null; this.processFilter = event; } - onSuccessProcessFilterList(event: any) { + onSuccessProcessFilterList() { this.processFilter = this.activitiprocessfilter.getCurrentFilter(); } @@ -196,13 +203,15 @@ export class ActivitiDemoComponent implements AfterViewInit { } navigateStartProcess() { + this.resetProcessFilters(); + this.reloadProcessFilters(); this.currentProcessInstanceId = currentProcessIdNew; } onStartProcessInstance(instance: ProcessInstance) { this.currentProcessInstanceId = instance.id; this.activitiStartProcess.reset(); - this.activitiprocesslist.reload(); + this.resetProcessFilters(); } isStartProcessMode() { @@ -218,15 +227,16 @@ export class ActivitiDemoComponent implements AfterViewInit { this.activitiprocesslist.reload(); } - taskFormCompleted(data: any) { - this.activitiprocesslist.reload(); - } - onFormCompleted(form) { this.activititasklist.reload(); this.currentTaskId = null; } + onTaskCreated(data: any) { + this.currentTaskId = data.parentTaskId; + this.activititasklist.reload(); + } + ngAfterViewInit() { // workaround for MDL issues with dynamic components if (componentHandler) { @@ -236,14 +246,6 @@ export class ActivitiDemoComponent implements AfterViewInit { this.loadStencilScriptsInPageFromActiviti(); } - activeProcess() { - this.processTabActivie = true; - } - - activeReports() { - this.reportsTabActivie = true; - } - loadStencilScriptsInPageFromActiviti() { this.apiService.getInstance().activiti.scriptFileApi.getControllers().then(response => { if (response) { @@ -255,4 +257,26 @@ export class ActivitiDemoComponent implements AfterViewInit { }); } + onProcessDetailsTaskClick(event: TaskDetailsEvent) { + event.preventDefault(); + this.activeTab = 'tasks'; + let processTaskDataRow = new ObjectDataRow({ + id: event.value.id, + name: event.value.name || 'No name', + created: event.value.created + }); + this.activitifilter.selectFilter(null); + this.dataTasks.setRows([processTaskDataRow]); + this.activititasklist.selectTask(event.value.id); + this.currentTaskId = event.value.id; + } + + private resetProcessFilters() { + this.processFilter = null; + } + + private reloadProcessFilters() { + this.activitiprocessfilter.selectFilter(null); + } + } diff --git a/demo-shell-ng2/app/components/files/files.component.html b/demo-shell-ng2/app/components/files/files.component.html index 5cf0ac0361a..f8b6e7e7abf 100644 --- a/demo-shell-ng2/app/components/files/files.component.html +++ b/demo-shell-ng2/app/components/files/files.component.html @@ -1,12 +1,11 @@
+ [target]="documentList" + [folderNode]="documentList.folderNode">
- + (preview)="showFile($event)"> Sorry, no content here key="name" sortable="true" class="full-width ellipsis-cell"> + + - Sorry, no content here - -
-
-
    -
  • Current path: {{currentPath}}
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
-
- -

Upload
Upload
{ - this.currentFolderId = params.hasOwnProperty('id') ? params['id'] : null; + if (params['id']) { + this.currentFolderId = params['id']; + this.changeDetector.detectChanges(); + } }); } - if (this.auth.isBpmLoggedIn()) { + if (this.authService.isBpmLoggedIn()) { this.formService.getProcessDefinitions().subscribe( defs => this.setupBpmActions(defs || []), - err => console.log(err) + err => this.logService.error(err) ); } else { - console.log('You are not logged in'); + this.logService.warn('You are not logged in to BPM'); } } diff --git a/demo-shell-ng2/app/components/home/home.component.html b/demo-shell-ng2/app/components/home/home.component.html index c8891588382..6be4519ac1d 100644 --- a/demo-shell-ng2/app/components/home/home.component.html +++ b/demo-shell-ng2/app/components/home/home.component.html @@ -7,11 +7,11 @@

- Demonstrates multiple Alfresco ECM components used together to show the files of you ECM instance : + Demonstrates multiple Alfresco ECM components used together to display the files of your ECM instance:
  • brightness_1 - Comunication with the Rest Api and core services + Communication with the Rest Api and core services ng2-alfresco-core
  • @@ -43,11 +43,11 @@

- Demonstrates multiple Alfresco BPM components used together to show your BPM prorcess and tasks: + Demonstrates multiple Alfresco BPM components used together to show your BPM process and tasks:
  • brightness_1 - Comunication with the Rest Api and core services + Communication with the Rest Api and core services ng2-alfresco-core
  • @@ -99,7 +99,7 @@

    • brightness_1 - Comunication with the Rest Api and core services + Communication with the Rest Api and core services ng2-alfresco-core
    @@ -119,7 +119,7 @@

    • brightness_1 - Comunication with the Rest Api and core services + Communication with the Rest Api and core services ng2-alfresco-core
    @@ -139,7 +139,7 @@

    • brightness_1 - Comunication with the Rest Api and core services + Communication with the Rest Api and core services ng2-alfresco-core
    @@ -155,11 +155,11 @@

- Shows and create webscripts in your ECM instance: + Displays and creates webscripts in your ECM instance:
  • brightness_1 - Comunication with the Rest Api and core services + Communication with the Rest Api and core services ng2-alfresco-core
@@ -175,11 +175,11 @@

- Shows and add tags to the node of your ECM instance: + Displays and adds tags to the node of your ECM instance: diff --git a/demo-shell-ng2/app/components/login/login-demo.component.ts b/demo-shell-ng2/app/components/login/login-demo.component.ts index d5ee054b33d..2026b9044e9 100644 --- a/demo-shell-ng2/app/components/login/login-demo.component.ts +++ b/demo-shell-ng2/app/components/login/login-demo.component.ts @@ -18,7 +18,7 @@ import { Component, ViewChild, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { Validators } from '@angular/forms'; -import { StorageService } from 'ng2-alfresco-core'; +import { StorageService, LogService } from 'ng2-alfresco-core'; @Component({ selector: 'login-demo', @@ -37,17 +37,20 @@ export class LoginDemoComponent implements OnInit { disableCsrf: boolean = false; isECM: boolean = true; isBPM: boolean = false; + customMinLenght: number = 2; - constructor(public router: Router, private storage: StorageService) { + constructor(private router: Router, + private storage: StorageService, + private logService: LogService) { this.customValidation = { - username: ['', Validators.compose([Validators.required, Validators.minLength(4)])], + username: ['', Validators.compose([Validators.required, Validators.minLength(this.customMinLenght)])], password: ['', Validators.required] }; } ngOnInit() { this.alfrescologin.addCustomValidationError('username', 'required', 'LOGIN.MESSAGES.USERNAME-REQUIRED'); - this.alfrescologin.addCustomValidationError('username', 'minlength', 'LOGIN.MESSAGES.USERNAME-MIN'); + this.alfrescologin.addCustomValidationError('username', 'minlength', 'LOGIN.MESSAGES.USERNAME-MIN', {customMinLenght: this.customMinLenght}); this.alfrescologin.addCustomValidationError('password', 'required', 'LOGIN.MESSAGES.PASSWORD-REQUIRED'); if (this.storage.hasItem('providers')) { @@ -75,7 +78,7 @@ export class LoginDemoComponent implements OnInit { } onError($event) { - console.log($event); + this.logService.error($event); } toggleECM() { @@ -92,7 +95,7 @@ export class LoginDemoComponent implements OnInit { this.disableCsrf = !this.disableCsrf; } - updateProvider(){ + updateProvider() { if (this.isBPM && this.isECM) { this.providers = 'ALL'; return this.providers; diff --git a/demo-shell-ng2/app/components/search/search-bar.component.ts b/demo-shell-ng2/app/components/search/search-bar.component.ts index 366e618434b..357303d4bdc 100644 --- a/demo-shell-ng2/app/components/search/search-bar.component.ts +++ b/demo-shell-ng2/app/components/search/search-bar.component.ts @@ -34,11 +34,11 @@ export class SearchBarComponent { expand = new EventEmitter(); constructor(public router: Router, - public auth: AlfrescoAuthenticationService) { + public authService: AlfrescoAuthenticationService) { } isLoggedIn(): boolean { - return this.auth.isLoggedIn(); + return this.authService.isLoggedIn(); } /** diff --git a/demo-shell-ng2/app/components/search/search.component.html b/demo-shell-ng2/app/components/search/search.component.html index 8e5f7d755c1..bdd4757b172 100644 --- a/demo-shell-ng2/app/components/search/search.component.html +++ b/demo-shell-ng2/app/components/search/search.component.html @@ -1,8 +1,12 @@

Search results

- +
- -
-
+
+ +
+
+
diff --git a/demo-shell-ng2/app/components/search/search.component.ts b/demo-shell-ng2/app/components/search/search.component.ts index 6351a0b5b23..98826092491 100644 --- a/demo-shell-ng2/app/components/search/search.component.ts +++ b/demo-shell-ng2/app/components/search/search.component.ts @@ -47,18 +47,18 @@ import { MinimalNodeEntity } from 'alfresco-js-api'; }) export class SearchComponent { - fileShowed: boolean = false; fileNodeId: string; + fileShowed: boolean = false; constructor(public router: Router) { } - onNavigateItem(event: MinimalNodeEntity) { - if (event.entry.isFile) { - this.fileNodeId = event.entry.id; + showFile(event) { + if (event.value.entry.isFile) { + this.fileNodeId = event.value.entry.id; this.fileShowed = true; - } else if (event.entry.isFolder) { - this.router.navigate(['/files', event.entry.id]); + } else { + this.fileShowed = false; } } } diff --git a/demo-shell-ng2/app/components/setting/setting.component.ts b/demo-shell-ng2/app/components/setting/setting.component.ts index 3fd92786438..b0d7d17a53b 100644 --- a/demo-shell-ng2/app/components/setting/setting.component.ts +++ b/demo-shell-ng2/app/components/setting/setting.component.ts @@ -16,7 +16,7 @@ */ import { Component } from '@angular/core'; -import { AlfrescoSettingsService, StorageService } from 'ng2-alfresco-core'; +import { AlfrescoSettingsService, StorageService, LogService } from 'ng2-alfresco-core'; @Component({ selector: 'alfresco-setting-demo', @@ -28,24 +28,31 @@ export class SettingComponent { ecmHost: string; bpmHost: string; - constructor(public alfrescoSettingsService: AlfrescoSettingsService, - private storage: StorageService) { - this.ecmHost = this.alfrescoSettingsService.ecmHost; - this.bpmHost = this.alfrescoSettingsService.bpmHost; + constructor(private settingsService: AlfrescoSettingsService, + private storage: StorageService, + private logService: LogService) { + this.ecmHost = this.settingsService.ecmHost; + this.bpmHost = this.settingsService.bpmHost; } public onChangeECMHost(event: KeyboardEvent): void { - console.log((event.target).value); - this.ecmHost = (event.target).value; - this.alfrescoSettingsService.ecmHost = this.ecmHost; - this.storage.setItem(`ecmHost`, this.ecmHost); + let value = (event.target).value.trim(); + if (value) { + this.logService.info(`ECM host: ${value}`); + this.ecmHost = value; + this.settingsService.ecmHost = value; + this.storage.setItem(`ecmHost`, value); + } } public onChangeBPMHost(event: KeyboardEvent): void { - console.log((event.target).value); - this.bpmHost = (event.target).value; - this.alfrescoSettingsService.bpmHost = this.bpmHost; - this.storage.setItem(`bpmHost`, this.bpmHost); + let value = (event.target).value.trim(); + if (value) { + this.logService.info(`BPM host: ${value}`); + this.bpmHost = value; + this.settingsService.bpmHost = value; + this.storage.setItem(`bpmHost`, value); + } } } diff --git a/demo-shell-ng2/app/components/webscript/webscript.component.ts b/demo-shell-ng2/app/components/webscript/webscript.component.ts index 9d003320367..4587498c80f 100644 --- a/demo-shell-ng2/app/components/webscript/webscript.component.ts +++ b/demo-shell-ng2/app/components/webscript/webscript.component.ts @@ -16,42 +16,41 @@ */ import { Component } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; @Component({ selector: 'alfresco-webscript-demo', template: ` - -
-
-
-
-
-
- +
+
+
+
+
+
+ + ` }) export class WebscriptComponent { currentPath: string = '/'; - authenticated: boolean; - host: string = 'http://127.0.0.1:8080'; - scriptPath: string = 'sample/folder/Company%20Home'; - contextRoot: string = 'alfresco'; - servicePath: string = 'service'; - scriptArgs: string = ''; + constructor(private logService: LogService) { + } + logData(data) { - console.log(data); + this.logService.log(data); } } diff --git a/demo-shell-ng2/app/vendor.ts b/demo-shell-ng2/app/vendor.ts index f5333ae066f..f8900561aef 100644 --- a/demo-shell-ng2/app/vendor.ts +++ b/demo-shell-ng2/app/vendor.ts @@ -32,9 +32,13 @@ import 'dialog-polyfill/dialog-polyfill.css'; // Flags import 'flag-icon-css/css/flag-icon.min.css'; + import '../public/css/app.css'; import '../public/css/muli-font.css'; +// Load the Angular Material 2 stylesheet +import '@angular/material/core/theming/prebuilt/deeppurple-amber.css' + import 'ng2-activiti-form/stencils/runtime.ng1'; import 'ng2-activiti-form/stencils/runtime.adf'; diff --git a/demo-shell-ng2/config/webpack.dev.js b/demo-shell-ng2/config/webpack.dev.js index 40a565e0709..c1684029e50 100644 --- a/demo-shell-ng2/config/webpack.dev.js +++ b/demo-shell-ng2/config/webpack.dev.js @@ -10,7 +10,6 @@ module.exports = webpackMerge(commonConfig, { output: { path: helpers.root('dist'), - publicPath: 'http://localhost:3000/', filename: '[name].js', chunkFilename: '[id].chunk.js' }, @@ -60,6 +59,9 @@ module.exports = webpackMerge(commonConfig, { ], devServer: { + host: '0.0.0.0', + port: 3000, + inline: true, historyApiFallback: true, stats: 'minimal' } diff --git a/demo-shell-ng2/config/webpack.test.js b/demo-shell-ng2/config/webpack.test.js index d1f6c28a874..f2fe2870e01 100644 --- a/demo-shell-ng2/config/webpack.test.js +++ b/demo-shell-ng2/config/webpack.test.js @@ -1,6 +1,5 @@ var helpers = require('./helpers'); var fs = require('fs'); -var ExtractTextPlugin = require('extract-text-webpack-plugin'); var glob = require('glob'); const rootPath = helpers.root('node_modules'); @@ -34,12 +33,21 @@ module.exports = { }, module: { + preLoaders: [ + { + test: /\.js$/, + include: [ + ...alfrescoLibs + ], + loader: 'source-map-loader' + } + ], loaders: [ - { - test: /\.ts$/, - exclude: /node_modules/, - loaders: ['awesome-typescript-loader', 'angular2-template-loader'] - }, + { + test: /\.ts$/, + loaders: ['awesome-typescript-loader', 'angular2-template-loader', 'systemjs-loader'], + exclude: ['node_modules','public'] + }, { test: /\.js$/, include: [ diff --git a/demo-shell-ng2/custom-translation/alfresco-login/i18n/en.json b/demo-shell-ng2/custom-translation/alfresco-login/i18n/en.json index 7c1ef10cd96..d7e59007bde 100644 --- a/demo-shell-ng2/custom-translation/alfresco-login/i18n/en.json +++ b/demo-shell-ng2/custom-translation/alfresco-login/i18n/en.json @@ -1,26 +1,29 @@ { - "LOGIN": { - "LOGO": "Alfresco", - "LABEL": { - "LOGIN": "Login", - "USERNAME": "Username", - "PASSWORD": "Password", - "REMEMBER": "Remember" - }, - "MESSAGES": { - "USERNAME-REQUIRED": "Required", - "USERNAME-MIN": "Your username needs to be at least 4 characters.", - "PASSWORD-REQUIRED": "Enter your password to sign in", - "LOGIN-ERROR-CREDENTIALS": "You have entered an invalid username or password", - "LOGIN-ERROR-PROVIDERS": "Providers cannot be undefined", - "LOGIN-SUCCESS": "Login successful" - }, - "BUTTON": { - "LOGIN": "SIGN IN" - }, - "ACTION": { - "HELP": "NEED HELP?", - "REGISTER": "REGISTER" + "LOGIN": { + "LOGO": "Alfresco", + "LABEL": { + "LOGIN": "Login", + "USERNAME": "Username", + "PASSWORD": "Password", + "REMEMBER": "Remember" + }, + "MESSAGES": { + "USERNAME-REQUIRED": "Required", + "USERNAME-MIN": "Your username needs to be at least {{customMinLenght}} characters.", + "PASSWORD-REQUIRED": "Enter your password to sign in", + "LOGIN-ERROR-CREDENTIALS": "You have entered an invalid username or password", + "LOGIN-ERROR-PROVIDERS": "Providers cannot be undefined", + "LOGIN-SUCCESS": "Login successful", + "LOGIN-ERROR-CORS": "CORS exception, check your server configuration", + "LOGIN-ERROR-CSRF": "CSRF exception, set [disableCsrf]=\"true\" in alfresco-login component", + "LOGIN-ECM-LICENSE": "The ECM is in read-only mode" + }, + "BUTTON": { + "LOGIN": "SIGN IN" + }, + "ACTION": { + "HELP": "NEED HELP?", + "REGISTER": "REGISTER" + } } - } } diff --git a/demo-shell-ng2/custom-translation/alfresco-login/i18n/it.json b/demo-shell-ng2/custom-translation/alfresco-login/i18n/it.json index c274b009129..b1c50a86bfb 100644 --- a/demo-shell-ng2/custom-translation/alfresco-login/i18n/it.json +++ b/demo-shell-ng2/custom-translation/alfresco-login/i18n/it.json @@ -1,25 +1,28 @@ { - "LOGIN": { - "LABEL": { - "LOGIN": "Autenticazione", - "USERNAME": "Nome utente", - "PASSWORD": "Password", - "REMEMBER": "Ricordami" - }, - "MESSAGES": { - "USERNAME-REQUIRED": "Campo obbligatorio", - "USERNAME-MIN": "Inserire un nome utente di minimo 4 caratteri.", - "PASSWORD-REQUIRED": "Campo obbligatorio", - "LOGIN-ERROR-CREDENTIALS": "Nome utente o password non validi", - "LOGIN-ERROR-PROVIDERS": "Providers non può essere nullo", - "LOGIN-SUCCESS": "Login effettuata con successo" - }, - "BUTTON": { - "LOGIN": "Accedi" - }, - "ACTION": { - "HELP": "BISOGNO DI AIUTO?", - "REGISTER": "REGISTRATI" + "LOGIN": { + "LABEL": { + "LOGIN": "Autenticazione", + "USERNAME": "Nome utente", + "PASSWORD": "Password", + "REMEMBER": "Ricordami" + }, + "MESSAGES": { + "USERNAME-REQUIRED": "Campo obbligatorio", + "USERNAME-MIN": "Inserire un nome utente di minimo 4 caratteri.", + "PASSWORD-REQUIRED": "Campo obbligatorio", + "LOGIN-ERROR-CREDENTIALS": "Nome utente o password non validi", + "LOGIN-ERROR-PROVIDERS": "Providers non può essere nullo", + "LOGIN-SUCCESS": "Login effettuata con successo", + "LOGIN-ERROR-CORS": "CORS exception, controlla le configurazioni del tuo server", + "LOGIN-ERROR-CSRF": "CSRF exception, set [disableCsrf]=\"true\" in alfresco-login component", + "LOGIN-ECM-LICENSE": "l'ECM e' in read-only mode" + }, + "BUTTON": { + "LOGIN": "Accedi" + }, + "ACTION": { + "HELP": "BISOGNO DI AIUTO?", + "REGISTER": "REGISTRATI" + } } - } -} \ No newline at end of file +} diff --git a/demo-shell-ng2/index.html b/demo-shell-ng2/index.html index e8f703cec77..0e8d01209c3 100644 --- a/demo-shell-ng2/index.html +++ b/demo-shell-ng2/index.html @@ -11,10 +11,12 @@ + + + @@ -46,9 +65,14 @@
-
+
+
+
+
+
Loading Demo Shell..
-
+
diff --git a/demo-shell-ng2/package.json b/demo-shell-ng2/package.json index 8e35ae6db45..1a87abb25ac 100644 --- a/demo-shell-ng2/package.json +++ b/demo-shell-ng2/package.json @@ -1,11 +1,11 @@ { "name": "Alfresco-Angular2-Demo", "description": "Demo shell for Alfresco Angular2 components", - "version": "1.0.0", + "version": "1.1.0", "author": "Alfresco Software, Ltd.", "scripts": { "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings dist", - "start": "npm run server-versions && webpack-dev-server --inline --progress --port 3000 --max_old_space_size=4096 --max_new_space_size=4096", + "start": "npm run server-versions && webpack-dev-server --progress --max_old_space_size=4096 --max_new_space_size=4096", "start:dist": "wsrv -s dist/ -p 3000 -a 0.0.0.0", "clean-build": "rimraf 'app/{,**/}**.js' 'app/{,**/}**.js.map' 'app/{,**/}**.d.ts'", "test": "karma start", @@ -62,6 +62,7 @@ "@angular/platform-browser-dynamic": "2.2.2", "@angular/router": "3.2.2", "@angular/upgrade": "2.2.2", + "@angular/material": "2.0.0-beta.1", "systemjs": "0.19.27", "core-js": "^2.4.1", "reflect-metadata": "^0.1.8", @@ -73,25 +74,25 @@ "pdfjs-dist": "1.5.404", "flag-icon-css": "2.3.0", "moment": "2.15.1", - "chart.js": "^2.1.4", + "chart.js": "2.3.0", "ng2-charts": "1.1.0", "raphael": "^2.2.6", "md-date-time-picker": "^2.2.0", - "alfresco-js-api": "^1.0.0", - "ng2-activiti-analytics": "1.0.0", - "ng2-alfresco-core": "1.0.0", - "ng2-alfresco-datatable": "1.0.0", - "ng2-alfresco-documentlist": "1.0.0", - "ng2-alfresco-login": "1.0.0", - "ng2-alfresco-search": "1.0.0", - "ng2-alfresco-upload": "1.0.0", - "ng2-alfresco-viewer": "1.0.0", - "ng2-activiti-form": "1.0.0", - "ng2-activiti-tasklist": "1.0.0", - "ng2-alfresco-userinfo": "1.0.0", - "ng2-activiti-processlist": "1.0.0", - "ng2-alfresco-webscript": "1.0.0", - "ng2-alfresco-tag": "1.0.0", + "alfresco-js-api": "~1.1.0", + "ng2-activiti-analytics": "1.1.0", + "ng2-alfresco-core": "1.1.0", + "ng2-alfresco-datatable": "1.1.0", + "ng2-alfresco-documentlist": "1.1.0", + "ng2-alfresco-login": "1.1.0", + "ng2-alfresco-search": "1.1.0", + "ng2-alfresco-upload": "1.1.0", + "ng2-alfresco-viewer": "1.1.0", + "ng2-activiti-form": "1.1.0", + "ng2-activiti-tasklist": "1.1.0", + "ng2-alfresco-userinfo": "1.1.0", + "ng2-activiti-processlist": "1.1.0", + "ng2-alfresco-webscript": "1.1.0", + "ng2-alfresco-tag": "1.1.0", "dialog-polyfill": "^0.4.3", "element.scrollintoviewifneeded-polyfill": "^1.0.1" }, diff --git a/demo-shell-ng2/public/css/app.css b/demo-shell-ng2/public/css/app.css index 3656efa93b2..7119266e910 100644 --- a/demo-shell-ng2/public/css/app.css +++ b/demo-shell-ng2/public/css/app.css @@ -3,7 +3,6 @@ body, html { height: 100%; } - .p-10 { padding: 10px; } @@ -13,24 +12,24 @@ body, html { } .loader-container { - display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */ - display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */ - display: -webkit-flex; /* NEW - Chrome */ - display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */ + display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */ + display: -webkit-flex; /* NEW - Chrome */ + display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */ -webkit-box-flex-direction: row; -moz-box-flex-direction: row; -webkit-flex-direction: row; flex-direction: row; - height:100%; + height: 100%; } .loader-item { margin: auto; - max-height:100px; - max-width:300px; + max-height: 100px; + max-width: 300px; } -.loader-text{ +.loader-text { white-space: nowrap; text-align: center; position: relative; @@ -39,3 +38,27 @@ body, html { ._dialog_overlay { position: static !important; } + +.main_header_adf .mdl-layout__drawer-button { + right: 0 !important; + left: initial !important; + left: auto; +} + +.mdl-layout__header { + color: rgb(255, 255, 255); + background-color: rgb(31, 188, 210); +} + +.mdl-layout__header .material-icons { + color: rgb(255, 255, 255); +} + +.mdl-layout__header-row .mdl-navigation__link { + color: rgb(255, 255, 255); +} + +.md-simple-snackbar-action { + border: 0px; + cursor: pointer; +} diff --git a/demo-shell-ng2/public/css/material.orange-blue.min.css b/demo-shell-ng2/public/css/material.orange-blue.min.css index fb184ae5327..ea17be04617 100644 --- a/demo-shell-ng2/public/css/material.orange-blue.min.css +++ b/demo-shell-ng2/public/css/material.orange-blue.min.css @@ -1,8 +1,8 @@ /** * material-design-lite - Material Design Components in CSS, JS and HTML - * @version v1.1.3 + * @version v1.3.0 * @license Apache-2.0 * @copyright 2015 Google, Inc. * @link https://github.com/google/material-design-lite */ -@charset "UTF-8";html{color:rgba(0,0,0,.87)}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}.browserupgrade{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.hidden{display:none!important}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}@media print{*,*:before,*:after,*:first-letter{background:transparent!important;color:#000!important;box-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}}a,.mdl-accordion,.mdl-button,.mdl-card,.mdl-checkbox,.mdl-dropdown-menu,.mdl-icon-toggle,.mdl-item,.mdl-radio,.mdl-slider,.mdl-switch,.mdl-tabs__tab{-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:rgba(255,255,255,0)}html{width:100%;height:100%;-ms-touch-action:manipulation;touch-action:manipulation}body{width:100%;min-height:100%}main{display:block}*[hidden]{display:none!important}html,body{font-family:"Helvetica","Arial",sans-serif;font-size:14px;font-weight:400;line-height:20px}h1,h2,h3,h4,h5,h6,p{padding:0}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400;line-height:1.35;letter-spacing:-.02em;opacity:.54;font-size:.6em}h1{font-size:56px;line-height:1.35;letter-spacing:-.02em;margin:24px 0}h1,h2{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400}h2{font-size:45px;line-height:48px}h2,h3{margin:24px 0}h3{font-size:34px;line-height:40px}h3,h4{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400}h4{font-size:24px;line-height:32px;-moz-osx-font-smoothing:grayscale;margin:24px 0 16px}h5{font-size:20px;font-weight:500;line-height:1;letter-spacing:.02em}h5,h6{font-family:"Roboto","Helvetica","Arial",sans-serif;margin:24px 0 16px}h6{font-size:16px;letter-spacing:.04em}h6,p{font-weight:400;line-height:24px}p{font-size:14px;letter-spacing:0;margin:0 0 16px}a{color:rgb(68,138,255);font-weight:500}blockquote{font-family:"Roboto","Helvetica","Arial",sans-serif;position:relative;font-size:24px;font-weight:300;font-style:italic;line-height:1.35;letter-spacing:.08em}blockquote:before{position:absolute;left:-.5em;content:'“'}blockquote:after{content:'”';margin-left:-.05em}mark{background-color:#f4ff81}dt{font-weight:700}address{font-size:12px;line-height:1;font-style:normal}address,ul,ol{font-weight:400;letter-spacing:0}ul,ol{font-size:14px;line-height:24px}.mdl-typography--display-4,.mdl-typography--display-4-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:112px;font-weight:300;line-height:1;letter-spacing:-.04em}.mdl-typography--display-4-color-contrast{opacity:.54}.mdl-typography--display-3,.mdl-typography--display-3-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:56px;font-weight:400;line-height:1.35;letter-spacing:-.02em}.mdl-typography--display-3-color-contrast{opacity:.54}.mdl-typography--display-2,.mdl-typography--display-2-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:45px;font-weight:400;line-height:48px}.mdl-typography--display-2-color-contrast{opacity:.54}.mdl-typography--display-1,.mdl-typography--display-1-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:34px;font-weight:400;line-height:40px}.mdl-typography--display-1-color-contrast{opacity:.54}.mdl-typography--headline,.mdl-typography--headline-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:24px;font-weight:400;line-height:32px;-moz-osx-font-smoothing:grayscale}.mdl-typography--headline-color-contrast{opacity:.87}.mdl-typography--title,.mdl-typography--title-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:20px;font-weight:500;line-height:1;letter-spacing:.02em}.mdl-typography--title-color-contrast{opacity:.87}.mdl-typography--subhead,.mdl-typography--subhead-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:16px;font-weight:400;line-height:24px;letter-spacing:.04em}.mdl-typography--subhead-color-contrast{opacity:.87}.mdl-typography--body-2,.mdl-typography--body-2-color-contrast{font-size:14px;font-weight:700;line-height:24px;letter-spacing:0}.mdl-typography--body-2-color-contrast{opacity:.87}.mdl-typography--body-1,.mdl-typography--body-1-color-contrast{font-size:14px;font-weight:400;line-height:24px;letter-spacing:0}.mdl-typography--body-1-color-contrast{opacity:.87}.mdl-typography--body-2-force-preferred-font,.mdl-typography--body-2-force-preferred-font-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;line-height:24px;letter-spacing:0}.mdl-typography--body-2-force-preferred-font-color-contrast{opacity:.87}.mdl-typography--body-1-force-preferred-font,.mdl-typography--body-1-force-preferred-font-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:400;line-height:24px;letter-spacing:0}.mdl-typography--body-1-force-preferred-font-color-contrast{opacity:.87}.mdl-typography--caption,.mdl-typography--caption-force-preferred-font{font-size:12px;font-weight:400;line-height:1;letter-spacing:0}.mdl-typography--caption-force-preferred-font{font-family:"Roboto","Helvetica","Arial",sans-serif}.mdl-typography--caption-color-contrast,.mdl-typography--caption-force-preferred-font-color-contrast{font-size:12px;font-weight:400;line-height:1;letter-spacing:0;opacity:.54}.mdl-typography--caption-force-preferred-font-color-contrast,.mdl-typography--menu{font-family:"Roboto","Helvetica","Arial",sans-serif}.mdl-typography--menu{font-size:14px;font-weight:500;line-height:1;letter-spacing:0}.mdl-typography--menu-color-contrast{opacity:.87}.mdl-typography--menu-color-contrast,.mdl-typography--button,.mdl-typography--button-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;line-height:1;letter-spacing:0}.mdl-typography--button,.mdl-typography--button-color-contrast{text-transform:uppercase}.mdl-typography--button-color-contrast{opacity:.87}.mdl-typography--text-left{text-align:left}.mdl-typography--text-right{text-align:right}.mdl-typography--text-center{text-align:center}.mdl-typography--text-justify{text-align:justify}.mdl-typography--text-nowrap{white-space:nowrap}.mdl-typography--text-lowercase{text-transform:lowercase}.mdl-typography--text-uppercase{text-transform:uppercase}.mdl-typography--text-capitalize{text-transform:capitalize}.mdl-typography--font-thin{font-weight:200!important}.mdl-typography--font-light{font-weight:300!important}.mdl-typography--font-regular{font-weight:400!important}.mdl-typography--font-medium{font-weight:500!important}.mdl-typography--font-bold{font-weight:700!important}.mdl-typography--font-black{font-weight:900!important}.material-icons{font-family:'Material Icons';font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;word-wrap:normal;-moz-font-feature-settings:'liga';font-feature-settings:'liga';-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased}.mdl-color-text--red{color:#f44336 !important}.mdl-color--red{background-color:#f44336 !important}.mdl-color-text--red-50{color:#ffebee !important}.mdl-color--red-50{background-color:#ffebee !important}.mdl-color-text--red-100{color:#ffcdd2 !important}.mdl-color--red-100{background-color:#ffcdd2 !important}.mdl-color-text--red-200{color:#ef9a9a !important}.mdl-color--red-200{background-color:#ef9a9a !important}.mdl-color-text--red-300{color:#e57373 !important}.mdl-color--red-300{background-color:#e57373 !important}.mdl-color-text--red-400{color:#ef5350 !important}.mdl-color--red-400{background-color:#ef5350 !important}.mdl-color-text--red-500{color:#f44336 !important}.mdl-color--red-500{background-color:#f44336 !important}.mdl-color-text--red-600{color:#e53935 !important}.mdl-color--red-600{background-color:#e53935 !important}.mdl-color-text--red-700{color:#d32f2f !important}.mdl-color--red-700{background-color:#d32f2f !important}.mdl-color-text--red-800{color:#c62828 !important}.mdl-color--red-800{background-color:#c62828 !important}.mdl-color-text--red-900{color:#b71c1c !important}.mdl-color--red-900{background-color:#b71c1c !important}.mdl-color-text--red-A100{color:#ff8a80 !important}.mdl-color--red-A100{background-color:#ff8a80 !important}.mdl-color-text--red-A200{color:#ff5252 !important}.mdl-color--red-A200{background-color:#ff5252 !important}.mdl-color-text--red-A400{color:#ff1744 !important}.mdl-color--red-A400{background-color:#ff1744 !important}.mdl-color-text--red-A700{color:#d50000 !important}.mdl-color--red-A700{background-color:#d50000 !important}.mdl-color-text--pink{color:#e91e63 !important}.mdl-color--pink{background-color:#e91e63 !important}.mdl-color-text--pink-50{color:#fce4ec !important}.mdl-color--pink-50{background-color:#fce4ec !important}.mdl-color-text--pink-100{color:#f8bbd0 !important}.mdl-color--pink-100{background-color:#f8bbd0 !important}.mdl-color-text--pink-200{color:#f48fb1 !important}.mdl-color--pink-200{background-color:#f48fb1 !important}.mdl-color-text--pink-300{color:#f06292 !important}.mdl-color--pink-300{background-color:#f06292 !important}.mdl-color-text--pink-400{color:#ec407a !important}.mdl-color--pink-400{background-color:#ec407a !important}.mdl-color-text--pink-500{color:#e91e63 !important}.mdl-color--pink-500{background-color:#e91e63 !important}.mdl-color-text--pink-600{color:#d81b60 !important}.mdl-color--pink-600{background-color:#d81b60 !important}.mdl-color-text--pink-700{color:#c2185b !important}.mdl-color--pink-700{background-color:#c2185b !important}.mdl-color-text--pink-800{color:#ad1457 !important}.mdl-color--pink-800{background-color:#ad1457 !important}.mdl-color-text--pink-900{color:#880e4f !important}.mdl-color--pink-900{background-color:#880e4f !important}.mdl-color-text--pink-A100{color:#ff80ab !important}.mdl-color--pink-A100{background-color:#ff80ab !important}.mdl-color-text--pink-A200{color:#ff4081 !important}.mdl-color--pink-A200{background-color:#ff4081 !important}.mdl-color-text--pink-A400{color:#f50057 !important}.mdl-color--pink-A400{background-color:#f50057 !important}.mdl-color-text--pink-A700{color:#c51162 !important}.mdl-color--pink-A700{background-color:#c51162 !important}.mdl-color-text--purple{color:#9c27b0 !important}.mdl-color--purple{background-color:#9c27b0 !important}.mdl-color-text--purple-50{color:#f3e5f5 !important}.mdl-color--purple-50{background-color:#f3e5f5 !important}.mdl-color-text--purple-100{color:#e1bee7 !important}.mdl-color--purple-100{background-color:#e1bee7 !important}.mdl-color-text--purple-200{color:#ce93d8 !important}.mdl-color--purple-200{background-color:#ce93d8 !important}.mdl-color-text--purple-300{color:#ba68c8 !important}.mdl-color--purple-300{background-color:#ba68c8 !important}.mdl-color-text--purple-400{color:#ab47bc !important}.mdl-color--purple-400{background-color:#ab47bc !important}.mdl-color-text--purple-500{color:#9c27b0 !important}.mdl-color--purple-500{background-color:#9c27b0 !important}.mdl-color-text--purple-600{color:#8e24aa !important}.mdl-color--purple-600{background-color:#8e24aa !important}.mdl-color-text--purple-700{color:#7b1fa2 !important}.mdl-color--purple-700{background-color:#7b1fa2 !important}.mdl-color-text--purple-800{color:#6a1b9a !important}.mdl-color--purple-800{background-color:#6a1b9a !important}.mdl-color-text--purple-900{color:#4a148c !important}.mdl-color--purple-900{background-color:#4a148c !important}.mdl-color-text--purple-A100{color:#ea80fc !important}.mdl-color--purple-A100{background-color:#ea80fc !important}.mdl-color-text--purple-A200{color:#e040fb !important}.mdl-color--purple-A200{background-color:#e040fb !important}.mdl-color-text--purple-A400{color:#d500f9 !important}.mdl-color--purple-A400{background-color:#d500f9 !important}.mdl-color-text--purple-A700{color:#a0f !important}.mdl-color--purple-A700{background-color:#a0f !important}.mdl-color-text--deep-purple{color:#673ab7 !important}.mdl-color--deep-purple{background-color:#673ab7 !important}.mdl-color-text--deep-purple-50{color:#ede7f6 !important}.mdl-color--deep-purple-50{background-color:#ede7f6 !important}.mdl-color-text--deep-purple-100{color:#d1c4e9 !important}.mdl-color--deep-purple-100{background-color:#d1c4e9 !important}.mdl-color-text--deep-purple-200{color:#b39ddb !important}.mdl-color--deep-purple-200{background-color:#b39ddb !important}.mdl-color-text--deep-purple-300{color:#9575cd !important}.mdl-color--deep-purple-300{background-color:#9575cd !important}.mdl-color-text--deep-purple-400{color:#7e57c2 !important}.mdl-color--deep-purple-400{background-color:#7e57c2 !important}.mdl-color-text--deep-purple-500{color:#673ab7 !important}.mdl-color--deep-purple-500{background-color:#673ab7 !important}.mdl-color-text--deep-purple-600{color:#5e35b1 !important}.mdl-color--deep-purple-600{background-color:#5e35b1 !important}.mdl-color-text--deep-purple-700{color:#512da8 !important}.mdl-color--deep-purple-700{background-color:#512da8 !important}.mdl-color-text--deep-purple-800{color:#4527a0 !important}.mdl-color--deep-purple-800{background-color:#4527a0 !important}.mdl-color-text--deep-purple-900{color:#311b92 !important}.mdl-color--deep-purple-900{background-color:#311b92 !important}.mdl-color-text--deep-purple-A100{color:#b388ff !important}.mdl-color--deep-purple-A100{background-color:#b388ff !important}.mdl-color-text--deep-purple-A200{color:#7c4dff !important}.mdl-color--deep-purple-A200{background-color:#7c4dff !important}.mdl-color-text--deep-purple-A400{color:#651fff !important}.mdl-color--deep-purple-A400{background-color:#651fff !important}.mdl-color-text--deep-purple-A700{color:#6200ea !important}.mdl-color--deep-purple-A700{background-color:#6200ea !important}.mdl-color-text--indigo{color:#3f51b5 !important}.mdl-color--indigo{background-color:#3f51b5 !important}.mdl-color-text--indigo-50{color:#e8eaf6 !important}.mdl-color--indigo-50{background-color:#e8eaf6 !important}.mdl-color-text--indigo-100{color:#c5cae9 !important}.mdl-color--indigo-100{background-color:#c5cae9 !important}.mdl-color-text--indigo-200{color:#9fa8da !important}.mdl-color--indigo-200{background-color:#9fa8da !important}.mdl-color-text--indigo-300{color:#7986cb !important}.mdl-color--indigo-300{background-color:#7986cb !important}.mdl-color-text--indigo-400{color:#5c6bc0 !important}.mdl-color--indigo-400{background-color:#5c6bc0 !important}.mdl-color-text--indigo-500{color:#3f51b5 !important}.mdl-color--indigo-500{background-color:#3f51b5 !important}.mdl-color-text--indigo-600{color:#3949ab !important}.mdl-color--indigo-600{background-color:#3949ab !important}.mdl-color-text--indigo-700{color:#303f9f !important}.mdl-color--indigo-700{background-color:#303f9f !important}.mdl-color-text--indigo-800{color:#283593 !important}.mdl-color--indigo-800{background-color:#283593 !important}.mdl-color-text--indigo-900{color:#1a237e !important}.mdl-color--indigo-900{background-color:#1a237e !important}.mdl-color-text--indigo-A100{color:#8c9eff !important}.mdl-color--indigo-A100{background-color:#8c9eff !important}.mdl-color-text--indigo-A200{color:#536dfe !important}.mdl-color--indigo-A200{background-color:#536dfe !important}.mdl-color-text--indigo-A400{color:#3d5afe !important}.mdl-color--indigo-A400{background-color:#3d5afe !important}.mdl-color-text--indigo-A700{color:#304ffe !important}.mdl-color--indigo-A700{background-color:#304ffe !important}.mdl-color-text--blue{color:#2196f3 !important}.mdl-color--blue{background-color:#2196f3 !important}.mdl-color-text--blue-50{color:#e3f2fd !important}.mdl-color--blue-50{background-color:#e3f2fd !important}.mdl-color-text--blue-100{color:#bbdefb !important}.mdl-color--blue-100{background-color:#bbdefb !important}.mdl-color-text--blue-200{color:#90caf9 !important}.mdl-color--blue-200{background-color:#90caf9 !important}.mdl-color-text--blue-300{color:#64b5f6 !important}.mdl-color--blue-300{background-color:#64b5f6 !important}.mdl-color-text--blue-400{color:#42a5f5 !important}.mdl-color--blue-400{background-color:#42a5f5 !important}.mdl-color-text--blue-500{color:#2196f3 !important}.mdl-color--blue-500{background-color:#2196f3 !important}.mdl-color-text--blue-600{color:#1e88e5 !important}.mdl-color--blue-600{background-color:#1e88e5 !important}.mdl-color-text--blue-700{color:#1976d2 !important}.mdl-color--blue-700{background-color:#1976d2 !important}.mdl-color-text--blue-800{color:#1565c0 !important}.mdl-color--blue-800{background-color:#1565c0 !important}.mdl-color-text--blue-900{color:#0d47a1 !important}.mdl-color--blue-900{background-color:#0d47a1 !important}.mdl-color-text--blue-A100{color:#82b1ff !important}.mdl-color--blue-A100{background-color:#82b1ff !important}.mdl-color-text--blue-A200{color:#448aff !important}.mdl-color--blue-A200{background-color:#448aff !important}.mdl-color-text--blue-A400{color:#2979ff !important}.mdl-color--blue-A400{background-color:#2979ff !important}.mdl-color-text--blue-A700{color:#2962ff !important}.mdl-color--blue-A700{background-color:#2962ff !important}.mdl-color-text--light-blue{color:#03a9f4 !important}.mdl-color--light-blue{background-color:#03a9f4 !important}.mdl-color-text--light-blue-50{color:#e1f5fe !important}.mdl-color--light-blue-50{background-color:#e1f5fe !important}.mdl-color-text--light-blue-100{color:#b3e5fc !important}.mdl-color--light-blue-100{background-color:#b3e5fc !important}.mdl-color-text--light-blue-200{color:#81d4fa !important}.mdl-color--light-blue-200{background-color:#81d4fa !important}.mdl-color-text--light-blue-300{color:#4fc3f7 !important}.mdl-color--light-blue-300{background-color:#4fc3f7 !important}.mdl-color-text--light-blue-400{color:#29b6f6 !important}.mdl-color--light-blue-400{background-color:#29b6f6 !important}.mdl-color-text--light-blue-500{color:#03a9f4 !important}.mdl-color--light-blue-500{background-color:#03a9f4 !important}.mdl-color-text--light-blue-600{color:#039be5 !important}.mdl-color--light-blue-600{background-color:#039be5 !important}.mdl-color-text--light-blue-700{color:#0288d1 !important}.mdl-color--light-blue-700{background-color:#0288d1 !important}.mdl-color-text--light-blue-800{color:#0277bd !important}.mdl-color--light-blue-800{background-color:#0277bd !important}.mdl-color-text--light-blue-900{color:#01579b !important}.mdl-color--light-blue-900{background-color:#01579b !important}.mdl-color-text--light-blue-A100{color:#80d8ff !important}.mdl-color--light-blue-A100{background-color:#80d8ff !important}.mdl-color-text--light-blue-A200{color:#40c4ff !important}.mdl-color--light-blue-A200{background-color:#40c4ff !important}.mdl-color-text--light-blue-A400{color:#00b0ff !important}.mdl-color--light-blue-A400{background-color:#00b0ff !important}.mdl-color-text--light-blue-A700{color:#0091ea !important}.mdl-color--light-blue-A700{background-color:#0091ea !important}.mdl-color-text--cyan{color:#00bcd4 !important}.mdl-color--cyan{background-color:#00bcd4 !important}.mdl-color-text--cyan-50{color:#e0f7fa !important}.mdl-color--cyan-50{background-color:#e0f7fa !important}.mdl-color-text--cyan-100{color:#b2ebf2 !important}.mdl-color--cyan-100{background-color:#b2ebf2 !important}.mdl-color-text--cyan-200{color:#80deea !important}.mdl-color--cyan-200{background-color:#80deea !important}.mdl-color-text--cyan-300{color:#4dd0e1 !important}.mdl-color--cyan-300{background-color:#4dd0e1 !important}.mdl-color-text--cyan-400{color:#26c6da !important}.mdl-color--cyan-400{background-color:#26c6da !important}.mdl-color-text--cyan-500{color:#00bcd4 !important}.mdl-color--cyan-500{background-color:#00bcd4 !important}.mdl-color-text--cyan-600{color:#00acc1 !important}.mdl-color--cyan-600{background-color:#00acc1 !important}.mdl-color-text--cyan-700{color:#0097a7 !important}.mdl-color--cyan-700{background-color:#0097a7 !important}.mdl-color-text--cyan-800{color:#00838f !important}.mdl-color--cyan-800{background-color:#00838f !important}.mdl-color-text--cyan-900{color:#006064 !important}.mdl-color--cyan-900{background-color:#006064 !important}.mdl-color-text--cyan-A100{color:#84ffff !important}.mdl-color--cyan-A100{background-color:#84ffff !important}.mdl-color-text--cyan-A200{color:#18ffff !important}.mdl-color--cyan-A200{background-color:#18ffff !important}.mdl-color-text--cyan-A400{color:#00e5ff !important}.mdl-color--cyan-A400{background-color:#00e5ff !important}.mdl-color-text--cyan-A700{color:#00b8d4 !important}.mdl-color--cyan-A700{background-color:#00b8d4 !important}.mdl-color-text--teal{color:#009688 !important}.mdl-color--teal{background-color:#009688 !important}.mdl-color-text--teal-50{color:#e0f2f1 !important}.mdl-color--teal-50{background-color:#e0f2f1 !important}.mdl-color-text--teal-100{color:#b2dfdb !important}.mdl-color--teal-100{background-color:#b2dfdb !important}.mdl-color-text--teal-200{color:#80cbc4 !important}.mdl-color--teal-200{background-color:#80cbc4 !important}.mdl-color-text--teal-300{color:#4db6ac !important}.mdl-color--teal-300{background-color:#4db6ac !important}.mdl-color-text--teal-400{color:#26a69a !important}.mdl-color--teal-400{background-color:#26a69a !important}.mdl-color-text--teal-500{color:#009688 !important}.mdl-color--teal-500{background-color:#009688 !important}.mdl-color-text--teal-600{color:#00897b !important}.mdl-color--teal-600{background-color:#00897b !important}.mdl-color-text--teal-700{color:#00796b !important}.mdl-color--teal-700{background-color:#00796b !important}.mdl-color-text--teal-800{color:#00695c !important}.mdl-color--teal-800{background-color:#00695c !important}.mdl-color-text--teal-900{color:#004d40 !important}.mdl-color--teal-900{background-color:#004d40 !important}.mdl-color-text--teal-A100{color:#a7ffeb !important}.mdl-color--teal-A100{background-color:#a7ffeb !important}.mdl-color-text--teal-A200{color:#64ffda !important}.mdl-color--teal-A200{background-color:#64ffda !important}.mdl-color-text--teal-A400{color:#1de9b6 !important}.mdl-color--teal-A400{background-color:#1de9b6 !important}.mdl-color-text--teal-A700{color:#00bfa5 !important}.mdl-color--teal-A700{background-color:#00bfa5 !important}.mdl-color-text--green{color:#4caf50 !important}.mdl-color--green{background-color:#4caf50 !important}.mdl-color-text--green-50{color:#e8f5e9 !important}.mdl-color--green-50{background-color:#e8f5e9 !important}.mdl-color-text--green-100{color:#c8e6c9 !important}.mdl-color--green-100{background-color:#c8e6c9 !important}.mdl-color-text--green-200{color:#a5d6a7 !important}.mdl-color--green-200{background-color:#a5d6a7 !important}.mdl-color-text--green-300{color:#81c784 !important}.mdl-color--green-300{background-color:#81c784 !important}.mdl-color-text--green-400{color:#66bb6a !important}.mdl-color--green-400{background-color:#66bb6a !important}.mdl-color-text--green-500{color:#4caf50 !important}.mdl-color--green-500{background-color:#4caf50 !important}.mdl-color-text--green-600{color:#43a047 !important}.mdl-color--green-600{background-color:#43a047 !important}.mdl-color-text--green-700{color:#388e3c !important}.mdl-color--green-700{background-color:#388e3c !important}.mdl-color-text--green-800{color:#2e7d32 !important}.mdl-color--green-800{background-color:#2e7d32 !important}.mdl-color-text--green-900{color:#1b5e20 !important}.mdl-color--green-900{background-color:#1b5e20 !important}.mdl-color-text--green-A100{color:#b9f6ca !important}.mdl-color--green-A100{background-color:#b9f6ca !important}.mdl-color-text--green-A200{color:#69f0ae !important}.mdl-color--green-A200{background-color:#69f0ae !important}.mdl-color-text--green-A400{color:#00e676 !important}.mdl-color--green-A400{background-color:#00e676 !important}.mdl-color-text--green-A700{color:#00c853 !important}.mdl-color--green-A700{background-color:#00c853 !important}.mdl-color-text--light-green{color:#8bc34a !important}.mdl-color--light-green{background-color:#8bc34a !important}.mdl-color-text--light-green-50{color:#f1f8e9 !important}.mdl-color--light-green-50{background-color:#f1f8e9 !important}.mdl-color-text--light-green-100{color:#dcedc8 !important}.mdl-color--light-green-100{background-color:#dcedc8 !important}.mdl-color-text--light-green-200{color:#c5e1a5 !important}.mdl-color--light-green-200{background-color:#c5e1a5 !important}.mdl-color-text--light-green-300{color:#aed581 !important}.mdl-color--light-green-300{background-color:#aed581 !important}.mdl-color-text--light-green-400{color:#9ccc65 !important}.mdl-color--light-green-400{background-color:#9ccc65 !important}.mdl-color-text--light-green-500{color:#8bc34a !important}.mdl-color--light-green-500{background-color:#8bc34a !important}.mdl-color-text--light-green-600{color:#7cb342 !important}.mdl-color--light-green-600{background-color:#7cb342 !important}.mdl-color-text--light-green-700{color:#689f38 !important}.mdl-color--light-green-700{background-color:#689f38 !important}.mdl-color-text--light-green-800{color:#558b2f !important}.mdl-color--light-green-800{background-color:#558b2f !important}.mdl-color-text--light-green-900{color:#33691e !important}.mdl-color--light-green-900{background-color:#33691e !important}.mdl-color-text--light-green-A100{color:#ccff90 !important}.mdl-color--light-green-A100{background-color:#ccff90 !important}.mdl-color-text--light-green-A200{color:#b2ff59 !important}.mdl-color--light-green-A200{background-color:#b2ff59 !important}.mdl-color-text--light-green-A400{color:#76ff03 !important}.mdl-color--light-green-A400{background-color:#76ff03 !important}.mdl-color-text--light-green-A700{color:#64dd17 !important}.mdl-color--light-green-A700{background-color:#64dd17 !important}.mdl-color-text--lime{color:#cddc39 !important}.mdl-color--lime{background-color:#cddc39 !important}.mdl-color-text--lime-50{color:#f9fbe7 !important}.mdl-color--lime-50{background-color:#f9fbe7 !important}.mdl-color-text--lime-100{color:#f0f4c3 !important}.mdl-color--lime-100{background-color:#f0f4c3 !important}.mdl-color-text--lime-200{color:#e6ee9c !important}.mdl-color--lime-200{background-color:#e6ee9c !important}.mdl-color-text--lime-300{color:#dce775 !important}.mdl-color--lime-300{background-color:#dce775 !important}.mdl-color-text--lime-400{color:#d4e157 !important}.mdl-color--lime-400{background-color:#d4e157 !important}.mdl-color-text--lime-500{color:#cddc39 !important}.mdl-color--lime-500{background-color:#cddc39 !important}.mdl-color-text--lime-600{color:#c0ca33 !important}.mdl-color--lime-600{background-color:#c0ca33 !important}.mdl-color-text--lime-700{color:#afb42b !important}.mdl-color--lime-700{background-color:#afb42b !important}.mdl-color-text--lime-800{color:#9e9d24 !important}.mdl-color--lime-800{background-color:#9e9d24 !important}.mdl-color-text--lime-900{color:#827717 !important}.mdl-color--lime-900{background-color:#827717 !important}.mdl-color-text--lime-A100{color:#f4ff81 !important}.mdl-color--lime-A100{background-color:#f4ff81 !important}.mdl-color-text--lime-A200{color:#eeff41 !important}.mdl-color--lime-A200{background-color:#eeff41 !important}.mdl-color-text--lime-A400{color:#c6ff00 !important}.mdl-color--lime-A400{background-color:#c6ff00 !important}.mdl-color-text--lime-A700{color:#aeea00 !important}.mdl-color--lime-A700{background-color:#aeea00 !important}.mdl-color-text--yellow{color:#ffeb3b !important}.mdl-color--yellow{background-color:#ffeb3b !important}.mdl-color-text--yellow-50{color:#fffde7 !important}.mdl-color--yellow-50{background-color:#fffde7 !important}.mdl-color-text--yellow-100{color:#fff9c4 !important}.mdl-color--yellow-100{background-color:#fff9c4 !important}.mdl-color-text--yellow-200{color:#fff59d !important}.mdl-color--yellow-200{background-color:#fff59d !important}.mdl-color-text--yellow-300{color:#fff176 !important}.mdl-color--yellow-300{background-color:#fff176 !important}.mdl-color-text--yellow-400{color:#ffee58 !important}.mdl-color--yellow-400{background-color:#ffee58 !important}.mdl-color-text--yellow-500{color:#ffeb3b !important}.mdl-color--yellow-500{background-color:#ffeb3b !important}.mdl-color-text--yellow-600{color:#fdd835 !important}.mdl-color--yellow-600{background-color:#fdd835 !important}.mdl-color-text--yellow-700{color:#fbc02d !important}.mdl-color--yellow-700{background-color:#fbc02d !important}.mdl-color-text--yellow-800{color:#f9a825 !important}.mdl-color--yellow-800{background-color:#f9a825 !important}.mdl-color-text--yellow-900{color:#f57f17 !important}.mdl-color--yellow-900{background-color:#f57f17 !important}.mdl-color-text--yellow-A100{color:#ffff8d !important}.mdl-color--yellow-A100{background-color:#ffff8d !important}.mdl-color-text--yellow-A200{color:#ff0 !important}.mdl-color--yellow-A200{background-color:#ff0 !important}.mdl-color-text--yellow-A400{color:#ffea00 !important}.mdl-color--yellow-A400{background-color:#ffea00 !important}.mdl-color-text--yellow-A700{color:#ffd600 !important}.mdl-color--yellow-A700{background-color:#ffd600 !important}.mdl-color-text--amber{color:#ffc107 !important}.mdl-color--amber{background-color:#ffc107 !important}.mdl-color-text--amber-50{color:#fff8e1 !important}.mdl-color--amber-50{background-color:#fff8e1 !important}.mdl-color-text--amber-100{color:#ffecb3 !important}.mdl-color--amber-100{background-color:#ffecb3 !important}.mdl-color-text--amber-200{color:#ffe082 !important}.mdl-color--amber-200{background-color:#ffe082 !important}.mdl-color-text--amber-300{color:#ffd54f !important}.mdl-color--amber-300{background-color:#ffd54f !important}.mdl-color-text--amber-400{color:#ffca28 !important}.mdl-color--amber-400{background-color:#ffca28 !important}.mdl-color-text--amber-500{color:#ffc107 !important}.mdl-color--amber-500{background-color:#ffc107 !important}.mdl-color-text--amber-600{color:#ffb300 !important}.mdl-color--amber-600{background-color:#ffb300 !important}.mdl-color-text--amber-700{color:#ffa000 !important}.mdl-color--amber-700{background-color:#ffa000 !important}.mdl-color-text--amber-800{color:#ff8f00 !important}.mdl-color--amber-800{background-color:#ff8f00 !important}.mdl-color-text--amber-900{color:#ff6f00 !important}.mdl-color--amber-900{background-color:#ff6f00 !important}.mdl-color-text--amber-A100{color:#ffe57f !important}.mdl-color--amber-A100{background-color:#ffe57f !important}.mdl-color-text--amber-A200{color:#ffd740 !important}.mdl-color--amber-A200{background-color:#ffd740 !important}.mdl-color-text--amber-A400{color:#ffc400 !important}.mdl-color--amber-A400{background-color:#ffc400 !important}.mdl-color-text--amber-A700{color:#ffab00 !important}.mdl-color--amber-A700{background-color:#ffab00 !important}.mdl-color-text--orange{color:#ff9800 !important}.mdl-color--orange{background-color:#ff9800 !important}.mdl-color-text--orange-50{color:#fff3e0 !important}.mdl-color--orange-50{background-color:#fff3e0 !important}.mdl-color-text--orange-100{color:#ffe0b2 !important}.mdl-color--orange-100{background-color:#ffe0b2 !important}.mdl-color-text--orange-200{color:#ffcc80 !important}.mdl-color--orange-200{background-color:#ffcc80 !important}.mdl-color-text--orange-300{color:#ffb74d !important}.mdl-color--orange-300{background-color:#ffb74d !important}.mdl-color-text--orange-400{color:#ffa726 !important}.mdl-color--orange-400{background-color:#ffa726 !important}.mdl-color-text--orange-500{color:#ff9800 !important}.mdl-color--orange-500{background-color:#ff9800 !important}.mdl-color-text--orange-600{color:#fb8c00 !important}.mdl-color--orange-600{background-color:#fb8c00 !important}.mdl-color-text--orange-700{color:#f57c00 !important}.mdl-color--orange-700{background-color:#f57c00 !important}.mdl-color-text--orange-800{color:#ef6c00 !important}.mdl-color--orange-800{background-color:#ef6c00 !important}.mdl-color-text--orange-900{color:#e65100 !important}.mdl-color--orange-900{background-color:#e65100 !important}.mdl-color-text--orange-A100{color:#ffd180 !important}.mdl-color--orange-A100{background-color:#ffd180 !important}.mdl-color-text--orange-A200{color:#ffab40 !important}.mdl-color--orange-A200{background-color:#ffab40 !important}.mdl-color-text--orange-A400{color:#ff9100 !important}.mdl-color--orange-A400{background-color:#ff9100 !important}.mdl-color-text--orange-A700{color:#ff6d00 !important}.mdl-color--orange-A700{background-color:#ff6d00 !important}.mdl-color-text--deep-orange{color:#ff5722 !important}.mdl-color--deep-orange{background-color:#ff5722 !important}.mdl-color-text--deep-orange-50{color:#fbe9e7 !important}.mdl-color--deep-orange-50{background-color:#fbe9e7 !important}.mdl-color-text--deep-orange-100{color:#ffccbc !important}.mdl-color--deep-orange-100{background-color:#ffccbc !important}.mdl-color-text--deep-orange-200{color:#ffab91 !important}.mdl-color--deep-orange-200{background-color:#ffab91 !important}.mdl-color-text--deep-orange-300{color:#ff8a65 !important}.mdl-color--deep-orange-300{background-color:#ff8a65 !important}.mdl-color-text--deep-orange-400{color:#ff7043 !important}.mdl-color--deep-orange-400{background-color:#ff7043 !important}.mdl-color-text--deep-orange-500{color:#ff5722 !important}.mdl-color--deep-orange-500{background-color:#ff5722 !important}.mdl-color-text--deep-orange-600{color:#f4511e !important}.mdl-color--deep-orange-600{background-color:#f4511e !important}.mdl-color-text--deep-orange-700{color:#e64a19 !important}.mdl-color--deep-orange-700{background-color:#e64a19 !important}.mdl-color-text--deep-orange-800{color:#d84315 !important}.mdl-color--deep-orange-800{background-color:#d84315 !important}.mdl-color-text--deep-orange-900{color:#bf360c !important}.mdl-color--deep-orange-900{background-color:#bf360c !important}.mdl-color-text--deep-orange-A100{color:#ff9e80 !important}.mdl-color--deep-orange-A100{background-color:#ff9e80 !important}.mdl-color-text--deep-orange-A200{color:#ff6e40 !important}.mdl-color--deep-orange-A200{background-color:#ff6e40 !important}.mdl-color-text--deep-orange-A400{color:#ff3d00 !important}.mdl-color--deep-orange-A400{background-color:#ff3d00 !important}.mdl-color-text--deep-orange-A700{color:#dd2c00 !important}.mdl-color--deep-orange-A700{background-color:#dd2c00 !important}.mdl-color-text--brown{color:#795548 !important}.mdl-color--brown{background-color:#795548 !important}.mdl-color-text--brown-50{color:#efebe9 !important}.mdl-color--brown-50{background-color:#efebe9 !important}.mdl-color-text--brown-100{color:#d7ccc8 !important}.mdl-color--brown-100{background-color:#d7ccc8 !important}.mdl-color-text--brown-200{color:#bcaaa4 !important}.mdl-color--brown-200{background-color:#bcaaa4 !important}.mdl-color-text--brown-300{color:#a1887f !important}.mdl-color--brown-300{background-color:#a1887f !important}.mdl-color-text--brown-400{color:#8d6e63 !important}.mdl-color--brown-400{background-color:#8d6e63 !important}.mdl-color-text--brown-500{color:#795548 !important}.mdl-color--brown-500{background-color:#795548 !important}.mdl-color-text--brown-600{color:#6d4c41 !important}.mdl-color--brown-600{background-color:#6d4c41 !important}.mdl-color-text--brown-700{color:#5d4037 !important}.mdl-color--brown-700{background-color:#5d4037 !important}.mdl-color-text--brown-800{color:#4e342e !important}.mdl-color--brown-800{background-color:#4e342e !important}.mdl-color-text--brown-900{color:#3e2723 !important}.mdl-color--brown-900{background-color:#3e2723 !important}.mdl-color-text--grey{color:#9e9e9e !important}.mdl-color--grey{background-color:#9e9e9e !important}.mdl-color-text--grey-50{color:#fafafa !important}.mdl-color--grey-50{background-color:#fafafa !important}.mdl-color-text--grey-100{color:#f5f5f5 !important}.mdl-color--grey-100{background-color:#f5f5f5 !important}.mdl-color-text--grey-200{color:#eee !important}.mdl-color--grey-200{background-color:#eee !important}.mdl-color-text--grey-300{color:#e0e0e0 !important}.mdl-color--grey-300{background-color:#e0e0e0 !important}.mdl-color-text--grey-400{color:#bdbdbd !important}.mdl-color--grey-400{background-color:#bdbdbd !important}.mdl-color-text--grey-500{color:#9e9e9e !important}.mdl-color--grey-500{background-color:#9e9e9e !important}.mdl-color-text--grey-600{color:#757575 !important}.mdl-color--grey-600{background-color:#757575 !important}.mdl-color-text--grey-700{color:#616161 !important}.mdl-color--grey-700{background-color:#616161 !important}.mdl-color-text--grey-800{color:#424242 !important}.mdl-color--grey-800{background-color:#424242 !important}.mdl-color-text--grey-900{color:#212121 !important}.mdl-color--grey-900{background-color:#212121 !important}.mdl-color-text--blue-grey{color:#607d8b !important}.mdl-color--blue-grey{background-color:#607d8b !important}.mdl-color-text--blue-grey-50{color:#eceff1 !important}.mdl-color--blue-grey-50{background-color:#eceff1 !important}.mdl-color-text--blue-grey-100{color:#cfd8dc !important}.mdl-color--blue-grey-100{background-color:#cfd8dc !important}.mdl-color-text--blue-grey-200{color:#b0bec5 !important}.mdl-color--blue-grey-200{background-color:#b0bec5 !important}.mdl-color-text--blue-grey-300{color:#90a4ae !important}.mdl-color--blue-grey-300{background-color:#90a4ae !important}.mdl-color-text--blue-grey-400{color:#78909c !important}.mdl-color--blue-grey-400{background-color:#78909c !important}.mdl-color-text--blue-grey-500{color:#607d8b !important}.mdl-color--blue-grey-500{background-color:#607d8b !important}.mdl-color-text--blue-grey-600{color:#546e7a !important}.mdl-color--blue-grey-600{background-color:#546e7a !important}.mdl-color-text--blue-grey-700{color:#455a64 !important}.mdl-color--blue-grey-700{background-color:#455a64 !important}.mdl-color-text--blue-grey-800{color:#37474f !important}.mdl-color--blue-grey-800{background-color:#37474f !important}.mdl-color-text--blue-grey-900{color:#263238 !important}.mdl-color--blue-grey-900{background-color:#263238 !important}.mdl-color--black{background-color:#000 !important}.mdl-color-text--black{color:#000 !important}.mdl-color--white{background-color:#fff !important}.mdl-color-text--white{color:#fff !important}.mdl-color--primary{background-color:rgb(255,152,0)!important}.mdl-color--primary-contrast{background-color:rgb(66,66,66)!important}.mdl-color--primary-dark{background-color:rgb(245,124,0)!important}.mdl-color--accent{background-color:rgb(68,138,255)!important}.mdl-color--accent-contrast{background-color:rgb(255,255,255)!important}.mdl-color-text--primary{color:rgb(255,152,0)!important}.mdl-color-text--primary-contrast{color:rgb(66,66,66)!important}.mdl-color-text--primary-dark{color:rgb(245,124,0)!important}.mdl-color-text--accent{color:rgb(68,138,255)!important}.mdl-color-text--accent-contrast{color:rgb(255,255,255)!important}.mdl-ripple{background:#000;border-radius:50%;height:50px;left:0;opacity:0;pointer-events:none;position:absolute;top:0;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:50px;overflow:hidden}.mdl-ripple.is-animating{transition:transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1);transition:transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1),-webkit-transform .3s cubic-bezier(0,0,.2,1)}.mdl-ripple.is-visible{opacity:.3}.mdl-animation--default,.mdl-animation--fast-out-slow-in{transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-animation--linear-out-slow-in{transition-timing-function:cubic-bezier(0,0,.2,1)}.mdl-animation--fast-out-linear-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.mdl-badge{position:relative;white-space:nowrap;margin-right:24px}.mdl-badge:not([data-badge]){margin-right:auto}.mdl-badge[data-badge]:after{content:attr(data-badge);display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:absolute;top:-11px;right:-24px;font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:600;font-size:12px;width:22px;height:22px;border-radius:50%;background:rgb(68,138,255);color:rgb(255,255,255)}.mdl-button .mdl-badge[data-badge]:after{top:-10px;right:-5px}.mdl-badge.mdl-badge--no-background[data-badge]:after{color:rgb(68,138,255);background:rgba(255,255,255,.2);box-shadow:0 0 1px gray}.mdl-badge.mdl-badge--overlap{margin-right:10px}.mdl-badge.mdl-badge--overlap:after{right:-10px}.mdl-button{background:0 0;border:none;border-radius:2px;color:#000;position:relative;height:36px;margin:0;min-width:64px;padding:0 16px;display:inline-block;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;letter-spacing:0;overflow:hidden;will-change:box-shadow;transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);outline:none;cursor:pointer;text-decoration:none;text-align:center;line-height:36px;vertical-align:middle}.mdl-button::-moz-focus-inner{border:0}.mdl-button:hover{background-color:rgba(158,158,158,.2)}.mdl-button:focus:not(:active){background-color:rgba(0,0,0,.12)}.mdl-button:active{background-color:rgba(158,158,158,.4)}.mdl-button.mdl-button--colored{color:rgb(255,152,0)}.mdl-button.mdl-button--colored:focus:not(:active){background-color:rgba(0,0,0,.12)}input.mdl-button[type="submit"]{-webkit-appearance:none}.mdl-button--raised{background:rgba(158,158,158,.2);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-button--raised:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:rgba(158,158,158,.4)}.mdl-button--raised:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:rgba(158,158,158,.4)}.mdl-button--raised.mdl-button--colored{background:rgb(255,152,0);color:rgb(66,66,66)}.mdl-button--raised.mdl-button--colored:hover{background-color:rgb(255,152,0)}.mdl-button--raised.mdl-button--colored:active{background-color:rgb(255,152,0)}.mdl-button--raised.mdl-button--colored:focus:not(:active){background-color:rgb(255,152,0)}.mdl-button--raised.mdl-button--colored .mdl-ripple{background:rgb(66,66,66)}.mdl-button--fab{border-radius:50%;font-size:24px;height:56px;margin:auto;min-width:56px;width:56px;padding:0;overflow:hidden;background:rgba(158,158,158,.2);box-shadow:0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);position:relative;line-height:normal}.mdl-button--fab .material-icons{position:absolute;top:50%;left:50%;-webkit-transform:translate(-12px,-12px);transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--fab.mdl-button--mini-fab{height:40px;min-width:40px;width:40px}.mdl-button--fab .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button--fab:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:rgba(158,158,158,.4)}.mdl-button--fab:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:rgba(158,158,158,.4)}.mdl-button--fab.mdl-button--colored{background:rgb(68,138,255);color:rgb(255,255,255)}.mdl-button--fab.mdl-button--colored:hover{background-color:rgb(68,138,255)}.mdl-button--fab.mdl-button--colored:focus:not(:active){background-color:rgb(68,138,255)}.mdl-button--fab.mdl-button--colored:active{background-color:rgb(68,138,255)}.mdl-button--fab.mdl-button--colored .mdl-ripple{background:rgb(255,255,255)}.mdl-button--icon{border-radius:50%;font-size:24px;height:32px;margin-left:0;margin-right:0;min-width:32px;width:32px;padding:0;overflow:hidden;color:inherit;line-height:normal}.mdl-button--icon .material-icons{position:absolute;top:50%;left:50%;-webkit-transform:translate(-12px,-12px);transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--icon.mdl-button--mini-icon{height:24px;min-width:24px;width:24px}.mdl-button--icon.mdl-button--mini-icon .material-icons{top:0;left:0}.mdl-button--icon .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button__ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.mdl-button[disabled] .mdl-button__ripple-container .mdl-ripple,.mdl-button.mdl-button--disabled .mdl-button__ripple-container .mdl-ripple{background-color:transparent}.mdl-button--primary.mdl-button--primary{color:rgb(255,152,0)}.mdl-button--primary.mdl-button--primary .mdl-ripple{background:rgb(66,66,66)}.mdl-button--primary.mdl-button--primary.mdl-button--raised,.mdl-button--primary.mdl-button--primary.mdl-button--fab{color:rgb(66,66,66);background-color:rgb(255,152,0)}.mdl-button--accent.mdl-button--accent{color:rgb(68,138,255)}.mdl-button--accent.mdl-button--accent .mdl-ripple{background:rgb(255,255,255)}.mdl-button--accent.mdl-button--accent.mdl-button--raised,.mdl-button--accent.mdl-button--accent.mdl-button--fab{color:rgb(255,255,255);background-color:rgb(68,138,255)}.mdl-button[disabled][disabled],.mdl-button.mdl-button--disabled.mdl-button--disabled{color:rgba(0,0,0,.26);cursor:default;background-color:transparent}.mdl-button--fab[disabled][disabled],.mdl-button--fab.mdl-button--disabled.mdl-button--disabled{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26)}.mdl-button--raised[disabled][disabled],.mdl-button--raised.mdl-button--disabled.mdl-button--disabled{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26);box-shadow:none}.mdl-button--colored[disabled][disabled],.mdl-button--colored.mdl-button--disabled.mdl-button--disabled{color:rgba(0,0,0,.26)}.mdl-button .material-icons{vertical-align:middle}.mdl-card{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;font-size:16px;font-weight:400;min-height:200px;overflow:hidden;width:330px;z-index:1;position:relative;background:#fff;border-radius:2px;box-sizing:border-box}.mdl-card__media{background-color:rgb(68,138,255);background-repeat:repeat;background-position:50% 50%;background-size:cover;background-origin:padding-box;background-attachment:scroll;box-sizing:border-box}.mdl-card__title{-webkit-align-items:center;-ms-flex-align:center;align-items:center;color:#000;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:stretch;-ms-flex-pack:stretch;justify-content:stretch;line-height:normal;padding:16px;-webkit-perspective-origin:165px 56px;perspective-origin:165px 56px;-webkit-transform-origin:165px 56px;transform-origin:165px 56px;box-sizing:border-box}.mdl-card__title.mdl-card--border{border-bottom:1px solid rgba(0,0,0,.1)}.mdl-card__title-text{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;color:inherit;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:24px;font-weight:300;line-height:normal;overflow:hidden;-webkit-transform-origin:149px 48px;transform-origin:149px 48px;margin:0}.mdl-card__subtitle-text{font-size:14px;color:rgba(0,0,0,.54);margin:0}.mdl-card__supporting-text{color:rgba(0,0,0,.54);font-size:1rem;line-height:18px;overflow:hidden;padding:16px;width:90%}.mdl-card__actions{font-size:16px;line-height:normal;width:100%;background-color:transparent;padding:8px;box-sizing:border-box}.mdl-card__actions.mdl-card--border{border-top:1px solid rgba(0,0,0,.1)}.mdl-card--expand{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.mdl-card__menu{position:absolute;right:16px;top:16px}.mdl-checkbox{position:relative;z-index:1;vertical-align:middle;display:inline-block;box-sizing:border-box;width:100%;height:24px;margin:0;padding:0}.mdl-checkbox.is-upgraded{padding-left:24px}.mdl-checkbox__input{line-height:24px}.mdl-checkbox.is-upgraded .mdl-checkbox__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-checkbox__box-outline{position:absolute;top:3px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;margin:0;cursor:pointer;overflow:hidden;border:2px solid rgba(0,0,0,.54);border-radius:2px;z-index:2}.mdl-checkbox.is-checked .mdl-checkbox__box-outline{border:2px solid rgb(255,152,0)}fieldset[disabled] .mdl-checkbox .mdl-checkbox__box-outline,.mdl-checkbox.is-disabled .mdl-checkbox__box-outline{border:2px solid rgba(0,0,0,.26);cursor:auto}.mdl-checkbox__focus-helper{position:absolute;top:3px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;border-radius:50%;background-color:transparent}.mdl-checkbox.is-focused .mdl-checkbox__focus-helper{box-shadow:0 0 0 8px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.mdl-checkbox.is-focused.is-checked .mdl-checkbox__focus-helper{box-shadow:0 0 0 8px rgba(255,152,0,.26);background-color:rgba(255,152,0,.26)}.mdl-checkbox__tick-outline{position:absolute;top:0;left:0;height:100%;width:100%;-webkit-mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8ZGVmcz4KICAgIDxjbGlwUGF0aCBpZD0iY2xpcCI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Ik0gMCwwIDAsMSAxLDEgMSwwIDAsMCB6IE0gMC44NTM0Mzc1LDAuMTY3MTg3NSAwLjk1OTY4NzUsMC4yNzMxMjUgMC40MjkzNzUsMC44MDM0Mzc1IDAuMzIzMTI1LDAuOTA5Njg3NSAwLjIxNzE4NzUsMC44MDM0Mzc1IDAuMDQwMzEyNSwwLjYyNjg3NSAwLjE0NjU2MjUsMC41MjA2MjUgMC4zMjMxMjUsMC42OTc1IDAuODUzNDM3NSwwLjE2NzE4NzUgeiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgICA8bWFzayBpZD0ibWFzayIgbWFza1VuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgbWFza0NvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0CiAgICAgd2lkdGg9IjEiCiAgICAgaGVpZ2h0PSIxIgogICAgIHg9IjAiCiAgICAgeT0iMCIKICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KPC9zdmc+Cg==");mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8ZGVmcz4KICAgIDxjbGlwUGF0aCBpZD0iY2xpcCI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Ik0gMCwwIDAsMSAxLDEgMSwwIDAsMCB6IE0gMC44NTM0Mzc1LDAuMTY3MTg3NSAwLjk1OTY4NzUsMC4yNzMxMjUgMC40MjkzNzUsMC44MDM0Mzc1IDAuMzIzMTI1LDAuOTA5Njg3NSAwLjIxNzE4NzUsMC44MDM0Mzc1IDAuMDQwMzEyNSwwLjYyNjg3NSAwLjE0NjU2MjUsMC41MjA2MjUgMC4zMjMxMjUsMC42OTc1IDAuODUzNDM3NSwwLjE2NzE4NzUgeiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgICA8bWFzayBpZD0ibWFzayIgbWFza1VuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgbWFza0NvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0CiAgICAgd2lkdGg9IjEiCiAgICAgaGVpZ2h0PSIxIgogICAgIHg9IjAiCiAgICAgeT0iMCIKICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KPC9zdmc+Cg==");background:0 0;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background}.mdl-checkbox.is-checked .mdl-checkbox__tick-outline{background:rgb(255,152,0)url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")}fieldset[disabled] .mdl-checkbox.is-checked .mdl-checkbox__tick-outline,.mdl-checkbox.is-checked.is-disabled .mdl-checkbox__tick-outline{background:rgba(0,0,0,.26)url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")}.mdl-checkbox__label{position:relative;cursor:pointer;font-size:16px;line-height:24px;margin:0}fieldset[disabled] .mdl-checkbox .mdl-checkbox__label,.mdl-checkbox.is-disabled .mdl-checkbox__label{color:rgba(0,0,0,.26);cursor:auto}.mdl-checkbox__ripple-container{position:absolute;z-index:2;top:-6px;left:-10px;box-sizing:border-box;width:36px;height:36px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-checkbox__ripple-container .mdl-ripple{background:rgb(255,152,0)}fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container,.mdl-checkbox.is-disabled .mdl-checkbox__ripple-container{cursor:auto}fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container .mdl-ripple,.mdl-checkbox.is-disabled .mdl-checkbox__ripple-container .mdl-ripple{background:0 0}.mdl-data-table{position:relative;border:1px solid rgba(0,0,0,.12);border-collapse:collapse;white-space:nowrap;font-size:13px;background-color:#fff}.mdl-data-table thead{padding-bottom:3px}.mdl-data-table thead .mdl-data-table__select{margin-top:0}.mdl-data-table tbody tr{position:relative;height:48px;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background-color}.mdl-data-table tbody tr.is-selected{background-color:#e0e0e0}.mdl-data-table tbody tr:hover{background-color:#eee}.mdl-data-table td{text-align:right}.mdl-data-table th{padding:0 18px 12px 18px;text-align:right}.mdl-data-table td:first-of-type,.mdl-data-table th:first-of-type{padding-left:24px}.mdl-data-table td:last-of-type,.mdl-data-table th:last-of-type{padding-right:24px}.mdl-data-table td{position:relative;height:48px;border-top:1px solid rgba(0,0,0,.12);border-bottom:1px solid rgba(0,0,0,.12);padding:12px 18px;box-sizing:border-box}.mdl-data-table td,.mdl-data-table td .mdl-data-table__select{vertical-align:middle}.mdl-data-table th{position:relative;vertical-align:bottom;text-overflow:ellipsis;font-weight:700;line-height:24px;letter-spacing:0;height:48px;font-size:12px;color:rgba(0,0,0,.54);padding-bottom:8px;box-sizing:border-box}.mdl-data-table th.mdl-data-table__header--sorted-ascending,.mdl-data-table th.mdl-data-table__header--sorted-descending{color:rgba(0,0,0,.87)}.mdl-data-table th.mdl-data-table__header--sorted-ascending:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:before{font-family:'Material Icons';font-weight:400;font-style:normal;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;word-wrap:normal;-moz-font-feature-settings:'liga';font-feature-settings:'liga';-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased;font-size:16px;content:"\e5d8";margin-right:5px;vertical-align:sub}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover{cursor:pointer}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover:before{color:rgba(0,0,0,.26)}.mdl-data-table th.mdl-data-table__header--sorted-descending:before{content:"\e5db"}.mdl-data-table__select{width:16px}.mdl-data-table__cell--non-numeric.mdl-data-table__cell--non-numeric{text-align:left}.mdl-dialog{border:none;box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2);width:280px}.mdl-dialog__title{padding:24px 24px 0;margin:0;font-size:2.5rem}.mdl-dialog__actions{padding:8px 8px 8px 24px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.mdl-dialog__actions>*{margin-right:8px;height:36px}.mdl-dialog__actions>*:first-child{margin-right:0}.mdl-dialog__actions--full-width{padding:0 0 8px}.mdl-dialog__actions--full-width>*{height:48px;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;padding-right:16px;margin-right:0;text-align:right}.mdl-dialog__content{padding:20px 24px 24px;color:rgba(0,0,0,.54)}.mdl-mega-footer{padding:16px 40px;color:#9e9e9e;background-color:#424242}.mdl-mega-footer--top-section:after,.mdl-mega-footer--middle-section:after,.mdl-mega-footer--bottom-section:after,.mdl-mega-footer__top-section:after,.mdl-mega-footer__middle-section:after,.mdl-mega-footer__bottom-section:after{content:'';display:block;clear:both}.mdl-mega-footer--left-section,.mdl-mega-footer__left-section,.mdl-mega-footer--right-section,.mdl-mega-footer__right-section{margin-bottom:16px}.mdl-mega-footer--right-section a,.mdl-mega-footer__right-section a{display:block;margin-bottom:16px;color:inherit;text-decoration:none}@media screen and (min-width:760px){.mdl-mega-footer--left-section,.mdl-mega-footer__left-section{float:left}.mdl-mega-footer--right-section,.mdl-mega-footer__right-section{float:right}.mdl-mega-footer--right-section a,.mdl-mega-footer__right-section a{display:inline-block;margin-left:16px;line-height:36px;vertical-align:middle}}.mdl-mega-footer--social-btn,.mdl-mega-footer__social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.mdl-mega-footer--drop-down-section,.mdl-mega-footer__drop-down-section{display:block;position:relative}@media screen and (min-width:760px){.mdl-mega-footer--drop-down-section,.mdl-mega-footer__drop-down-section{width:33%}.mdl-mega-footer--drop-down-section:nth-child(1),.mdl-mega-footer--drop-down-section:nth-child(2),.mdl-mega-footer__drop-down-section:nth-child(1),.mdl-mega-footer__drop-down-section:nth-child(2){float:left}.mdl-mega-footer--drop-down-section:nth-child(3),.mdl-mega-footer__drop-down-section:nth-child(3){float:right}.mdl-mega-footer--drop-down-section:nth-child(3):after,.mdl-mega-footer__drop-down-section:nth-child(3):after{clear:right}.mdl-mega-footer--drop-down-section:nth-child(4),.mdl-mega-footer__drop-down-section:nth-child(4){clear:right;float:right}.mdl-mega-footer--middle-section:after,.mdl-mega-footer__middle-section:after{content:'';display:block;clear:both}.mdl-mega-footer--bottom-section,.mdl-mega-footer__bottom-section{padding-top:0}}@media screen and (min-width:1024px){.mdl-mega-footer--drop-down-section,.mdl-mega-footer--drop-down-section:nth-child(3),.mdl-mega-footer--drop-down-section:nth-child(4),.mdl-mega-footer__drop-down-section,.mdl-mega-footer__drop-down-section:nth-child(3),.mdl-mega-footer__drop-down-section:nth-child(4){width:24%;float:left}}.mdl-mega-footer--heading-checkbox,.mdl-mega-footer__heading-checkbox{position:absolute;width:100%;height:55.8px;padding:32px;margin:-16px 0 0;cursor:pointer;z-index:1;opacity:0}.mdl-mega-footer--heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer__heading:after{font-family:'Material Icons';content:'\E5CE'}.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list{display:none}.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading:after{font-family:'Material Icons';content:'\E5CF'}.mdl-mega-footer--heading,.mdl-mega-footer__heading{position:relative;width:100%;padding-right:39.8px;margin-bottom:16px;box-sizing:border-box;font-size:14px;line-height:23.8px;font-weight:500;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;color:#e0e0e0}.mdl-mega-footer--heading:after,.mdl-mega-footer__heading:after{content:'';position:absolute;top:0;right:0;display:block;width:23.8px;height:23.8px;background-size:cover}.mdl-mega-footer--link-list,.mdl-mega-footer__link-list{list-style:none;padding:0;margin:0 0 32px}.mdl-mega-footer--link-list:after,.mdl-mega-footer__link-list:after{clear:both;display:block;content:''}.mdl-mega-footer--link-list li,.mdl-mega-footer__link-list li{font-size:14px;font-weight:400;letter-spacing:0;line-height:20px}.mdl-mega-footer--link-list a,.mdl-mega-footer__link-list a{color:inherit;text-decoration:none;white-space:nowrap}@media screen and (min-width:760px){.mdl-mega-footer--heading-checkbox,.mdl-mega-footer__heading-checkbox{display:none}.mdl-mega-footer--heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer__heading:after{content:''}.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list{display:block}.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading:after{content:''}}.mdl-mega-footer--bottom-section,.mdl-mega-footer__bottom-section{padding-top:16px;margin-bottom:16px}.mdl-logo{margin-bottom:16px;color:#fff}.mdl-mega-footer--bottom-section .mdl-mega-footer--link-list li,.mdl-mega-footer__bottom-section .mdl-mega-footer__link-list li{float:left;margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.mdl-logo{float:left;margin-bottom:0;margin-right:16px}}.mdl-mini-footer{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:32px 16px;color:#9e9e9e;background-color:#424242}.mdl-mini-footer:after{content:'';display:block}.mdl-mini-footer .mdl-logo{line-height:36px}.mdl-mini-footer--link-list,.mdl-mini-footer__link-list{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap;list-style:none;margin:0;padding:0}.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li{margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li{line-height:36px}}.mdl-mini-footer--link-list a,.mdl-mini-footer__link-list a{color:inherit;text-decoration:none;white-space:nowrap}.mdl-mini-footer--left-section,.mdl-mini-footer__left-section{display:inline-block;-webkit-order:0;-ms-flex-order:0;order:0}.mdl-mini-footer--right-section,.mdl-mini-footer__right-section{display:inline-block;-webkit-order:1;-ms-flex-order:1;order:1}.mdl-mini-footer--social-btn,.mdl-mini-footer__social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.mdl-icon-toggle{position:relative;z-index:1;vertical-align:middle;display:inline-block;height:32px;margin:0;padding:0}.mdl-icon-toggle__input{line-height:32px}.mdl-icon-toggle.is-upgraded .mdl-icon-toggle__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-icon-toggle__label{display:inline-block;position:relative;cursor:pointer;height:32px;width:32px;min-width:32px;color:#616161;border-radius:50%;padding:0;margin-left:0;margin-right:0;text-align:center;background-color:transparent;will-change:background-color;transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.mdl-icon-toggle__label.material-icons{line-height:32px;font-size:24px}.mdl-icon-toggle.is-checked .mdl-icon-toggle__label{color:rgb(255,152,0)}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__label{color:rgba(0,0,0,.26);cursor:auto;transition:none}.mdl-icon-toggle.is-focused .mdl-icon-toggle__label{background-color:rgba(0,0,0,.12)}.mdl-icon-toggle.is-focused.is-checked .mdl-icon-toggle__label{background-color:rgba(255,152,0,.26)}.mdl-icon-toggle__ripple-container{position:absolute;z-index:2;top:-2px;left:-2px;box-sizing:border-box;width:36px;height:36px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-icon-toggle__ripple-container .mdl-ripple{background:#616161}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container{cursor:auto}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container .mdl-ripple{background:0 0}.mdl-list{display:block;padding:8px 0;list-style:none}.mdl-list__item{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:16px;font-weight:400;letter-spacing:.04em;line-height:1;min-height:48px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;padding:16px;cursor:default;color:rgba(0,0,0,.87);overflow:hidden}.mdl-list__item,.mdl-list__item .mdl-list__item-primary-content{box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.mdl-list__item .mdl-list__item-primary-content{-webkit-order:0;-ms-flex-order:0;order:0;-webkit-flex-grow:2;-ms-flex-positive:2;flex-grow:2;text-decoration:none}.mdl-list__item .mdl-list__item-primary-content .mdl-list__item-icon{margin-right:32px}.mdl-list__item .mdl-list__item-primary-content .mdl-list__item-avatar{margin-right:16px}.mdl-list__item .mdl-list__item-secondary-content{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:column;-ms-flex-flow:column;flex-flow:column;-webkit-align-items:flex-end;-ms-flex-align:end;align-items:flex-end;margin-left:16px}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-secondary-action label{display:inline}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-secondary-info{font-size:12px;font-weight:400;line-height:1;letter-spacing:0;color:rgba(0,0,0,.54)}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-sub-header{padding:0 0 0 16px}.mdl-list__item-icon,.mdl-list__item-icon.material-icons{height:24px;width:24px;font-size:24px;box-sizing:border-box;color:#757575}.mdl-list__item-avatar,.mdl-list__item-avatar.material-icons{height:40px;width:40px;box-sizing:border-box;border-radius:50%;background-color:#757575;font-size:40px;color:#fff}.mdl-list__item--two-line{height:72px}.mdl-list__item--two-line .mdl-list__item-primary-content{height:36px;line-height:20px;display:block}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-avatar{float:left}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-icon{float:left;margin-top:6px}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-secondary-content{height:36px}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-sub-title{font-size:14px;font-weight:400;letter-spacing:0;line-height:18px;color:rgba(0,0,0,.54);display:block;padding:0}.mdl-list__item--three-line{height:88px}.mdl-list__item--three-line .mdl-list__item-primary-content{height:52px;line-height:20px;display:block}.mdl-list__item--three-line .mdl-list__item-primary-content .mdl-list__item-avatar,.mdl-list__item--three-line .mdl-list__item-primary-content .mdl-list__item-icon{float:left}.mdl-list__item--three-line .mdl-list__item-secondary-content{height:52px}.mdl-list__item--three-line .mdl-list__item-text-body{font-size:14px;font-weight:400;letter-spacing:0;line-height:18px;height:52px;color:rgba(0,0,0,.54);display:block;padding:0}.mdl-menu__container{display:block;margin:0;padding:0;border:none;position:absolute;overflow:visible;height:0;width:0;visibility:hidden;z-index:-1}.mdl-menu__container.is-visible,.mdl-menu__container.is-animating{z-index:999;visibility:visible}.mdl-menu__outline{display:block;background:#fff;margin:0;padding:0;border:none;border-radius:2px;position:absolute;top:0;left:0;overflow:hidden;opacity:0;-webkit-transform:scale(0);transform:scale(0);-webkit-transform-origin:0 0;transform-origin:0 0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);will-change:transform;transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1);transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1),-webkit-transform .3s cubic-bezier(.4,0,.2,1);z-index:-1}.mdl-menu__container.is-visible .mdl-menu__outline{opacity:1;-webkit-transform:scale(1);transform:scale(1);z-index:999}.mdl-menu__outline.mdl-menu--bottom-right{-webkit-transform-origin:100% 0;transform-origin:100% 0}.mdl-menu__outline.mdl-menu--top-left{-webkit-transform-origin:0 100%;transform-origin:0 100%}.mdl-menu__outline.mdl-menu--top-right{-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.mdl-menu{position:absolute;list-style:none;top:0;left:0;height:auto;width:auto;min-width:124px;padding:8px 0;margin:0;opacity:0;clip:rect(0 0 0 0);z-index:-1}.mdl-menu__container.is-visible .mdl-menu{opacity:1;z-index:999}.mdl-menu.is-animating{transition:opacity .2s cubic-bezier(.4,0,.2,1),clip .3s cubic-bezier(.4,0,.2,1)}.mdl-menu.mdl-menu--bottom-right{left:auto;right:0}.mdl-menu.mdl-menu--top-left{top:auto;bottom:0}.mdl-menu.mdl-menu--top-right{top:auto;left:auto;bottom:0;right:0}.mdl-menu.mdl-menu--unaligned{top:auto;left:auto}.mdl-menu__item{display:block;border:none;color:rgba(0,0,0,.87);background-color:transparent;text-align:left;margin:0;padding:0 16px;outline-color:#bdbdbd;position:relative;overflow:hidden;font-size:14px;font-weight:400;letter-spacing:0;text-decoration:none;cursor:pointer;height:48px;line-height:48px;white-space:nowrap;opacity:0;transition:opacity .2s cubic-bezier(.4,0,.2,1);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-menu__container.is-visible .mdl-menu__item{opacity:1}.mdl-menu__item::-moz-focus-inner{border:0}.mdl-menu__item--full-bleed-divider{border-bottom:1px solid rgba(0,0,0,.12)}.mdl-menu__item[disabled],.mdl-menu__item[data-mdl-disabled]{color:#bdbdbd;background-color:transparent;cursor:auto}.mdl-menu__item[disabled]:hover,.mdl-menu__item[data-mdl-disabled]:hover{background-color:transparent}.mdl-menu__item[disabled]:focus,.mdl-menu__item[data-mdl-disabled]:focus{background-color:transparent}.mdl-menu__item[disabled] .mdl-ripple,.mdl-menu__item[data-mdl-disabled] .mdl-ripple{background:0 0}.mdl-menu__item:hover{background-color:#eee}.mdl-menu__item:focus{outline:none;background-color:#eee}.mdl-menu__item:active{background-color:#e0e0e0}.mdl-menu__item--ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.mdl-progress{display:block;position:relative;height:4px;width:500px;max-width:100%}.mdl-progress>.bar{display:block;position:absolute;top:0;bottom:0;width:0%;transition:width .2s cubic-bezier(.4,0,.2,1)}.mdl-progress>.progressbar{background-color:rgb(255,152,0);z-index:1;left:0}.mdl-progress>.bufferbar{background-image:linear-gradient(to right,rgba(66,66,66,.7),rgba(66,66,66,.7)),linear-gradient(to right,rgb(255,152,0),rgb(255,152,0));z-index:0;left:0}.mdl-progress>.auxbar{right:0}@supports (-webkit-appearance:none){.mdl-progress:not(.mdl-progress--indeterminate):not(.mdl-progress--indeterminate)>.auxbar,.mdl-progress:not(.mdl-progress__indeterminate):not(.mdl-progress__indeterminate)>.auxbar{background-image:linear-gradient(to right,rgba(66,66,66,.7),rgba(66,66,66,.7)),linear-gradient(to right,rgb(255,152,0),rgb(255,152,0));-webkit-mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyIiBoZWlnaHQ9IjQiIHZpZXdQb3J0PSIwIDAgMTIgNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxlbGxpcHNlIGN4PSIyIiBjeT0iMiIgcng9IjIiIHJ5PSIyIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogIDwvZWxsaXBzZT4KICA8ZWxsaXBzZSBjeD0iMTQiIGN5PSIyIiByeD0iMiIgcnk9IjIiIGNsYXNzPSJsb2FkZXIiPgogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICA8L2VsbGlwc2U+Cjwvc3ZnPgo=");mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyIiBoZWlnaHQ9IjQiIHZpZXdQb3J0PSIwIDAgMTIgNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxlbGxpcHNlIGN4PSIyIiBjeT0iMiIgcng9IjIiIHJ5PSIyIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogIDwvZWxsaXBzZT4KICA8ZWxsaXBzZSBjeD0iMTQiIGN5PSIyIiByeD0iMiIgcnk9IjIiIGNsYXNzPSJsb2FkZXIiPgogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICA8L2VsbGlwc2U+Cjwvc3ZnPgo=")}}.mdl-progress:not(.mdl-progress--indeterminate)>.auxbar,.mdl-progress:not(.mdl-progress__indeterminate)>.auxbar{background-image:linear-gradient(to right,rgba(66,66,66,.9),rgba(66,66,66,.9)),linear-gradient(to right,rgb(255,152,0),rgb(255,152,0))}.mdl-progress.mdl-progress--indeterminate>.bar1,.mdl-progress.mdl-progress__indeterminate>.bar1{-webkit-animation-name:indeterminate1;animation-name:indeterminate1}.mdl-progress.mdl-progress--indeterminate>.bar1,.mdl-progress.mdl-progress__indeterminate>.bar1,.mdl-progress.mdl-progress--indeterminate>.bar3,.mdl-progress.mdl-progress__indeterminate>.bar3{background-color:rgb(255,152,0);-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:linear;animation-timing-function:linear}.mdl-progress.mdl-progress--indeterminate>.bar3,.mdl-progress.mdl-progress__indeterminate>.bar3{background-image:none;-webkit-animation-name:indeterminate2;animation-name:indeterminate2}@-webkit-keyframes indeterminate1{0%{left:0%;width:0%}50%{left:25%;width:75%}75%{left:100%;width:0%}}@keyframes indeterminate1{0%{left:0%;width:0%}50%{left:25%;width:75%}75%{left:100%;width:0%}}@-webkit-keyframes indeterminate2{0%,50%{left:0%;width:0%}75%{left:0%;width:25%}100%{left:100%;width:0%}}@keyframes indeterminate2{0%,50%{left:0%;width:0%}75%{left:0%;width:25%}100%{left:100%;width:0%}}.mdl-navigation{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;box-sizing:border-box}.mdl-navigation__link{color:#424242;text-decoration:none;margin:0;font-size:14px;font-weight:400;line-height:24px;letter-spacing:0;opacity:.87}.mdl-navigation__link .material-icons{vertical-align:middle}.mdl-layout{width:100%;height:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow-y:auto;overflow-x:hidden;position:relative;-webkit-overflow-scrolling:touch}.mdl-layout.is-small-screen .mdl-layout--large-screen-only{display:none}.mdl-layout:not(.is-small-screen) .mdl-layout--small-screen-only{display:none}.mdl-layout__container{position:absolute;width:100%;height:100%}.mdl-layout__title,.mdl-layout-title{display:block;position:relative;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:20px;line-height:1;letter-spacing:.02em;font-weight:400;box-sizing:border-box}.mdl-layout-spacer{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.mdl-layout__drawer{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;width:240px;height:100%;max-height:100%;position:absolute;top:0;left:0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);box-sizing:border-box;border-right:1px solid #e0e0e0;background:#fafafa;-webkit-transform:translateX(-250px);transform:translateX(-250px);-webkit-transform-style:preserve-3d;transform-style:preserve-3d;will-change:transform;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:transform;transition-property:transform,-webkit-transform;color:#424242;overflow:visible;overflow-y:auto;z-index:5}.mdl-layout__drawer.is-visible{-webkit-transform:translateX(0);transform:translateX(0)}.mdl-layout__drawer.is-visible~.mdl-layout__content.mdl-layout__content{overflow:hidden}.mdl-layout__drawer>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.mdl-layout__drawer>.mdl-layout__title,.mdl-layout__drawer>.mdl-layout-title{line-height:64px;padding-left:40px}@media screen and (max-width:1024px){.mdl-layout__drawer>.mdl-layout__title,.mdl-layout__drawer>.mdl-layout-title{line-height:56px;padding-left:16px}}.mdl-layout__drawer .mdl-navigation{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:stretch;-ms-flex-align:stretch;-ms-grid-row-align:stretch;align-items:stretch;padding-top:16px}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link{display:block;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;padding:16px 40px;margin:0;color:#757575}@media screen and (max-width:1024px){.mdl-layout__drawer .mdl-navigation .mdl-navigation__link{padding:16px}}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link:hover{background-color:#e0e0e0}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link--current{background-color:#000;color:#e0e0e0}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__drawer{-webkit-transform:translateX(0);transform:translateX(0)}}.mdl-layout__drawer-button{display:block;position:absolute;height:48px;width:48px;border:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden;text-align:center;cursor:pointer;font-size:26px;line-height:50px;font-family:Helvetica,Arial,sans-serif;margin:10px 12px;top:0;left:0;color:rgb(66,66,66);z-index:4}.mdl-layout__header .mdl-layout__drawer-button{position:absolute;color:rgb(255,255,255);background-color:inherit}@media screen and (max-width:1024px){.mdl-layout__header .mdl-layout__drawer-button{margin:4px}}@media screen and (max-width:1024px){.mdl-layout__drawer-button{margin:4px;color:rgba(0,0,0,.5)}}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__drawer-button,.mdl-layout--no-desktop-drawer-button .mdl-layout__drawer-button{display:none}}.mdl-layout--no-drawer-button .mdl-layout__drawer-button{display:none}.mdl-layout__header{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;box-sizing:border-box;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;width:100%;margin:0;padding:0;border:none;min-height:64px;max-height:1000px;z-index:3;background-color:rgb(31,188,210);color:rgb(255,255,255);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:max-height,box-shadow}@media screen and (max-width:1024px){.mdl-layout__header{min-height:56px}}.mdl-layout--fixed-drawer.is-upgraded:not(.is-small-screen)>.mdl-layout__header{margin-left:240px;width:calc(100% - 240px)}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__header .mdl-layout__header-row{padding-left:40px}}.mdl-layout__header>.mdl-layout-icon{position:absolute;left:40px;top:16px;height:32px;width:32px;overflow:hidden;z-index:3;display:block}@media screen and (max-width:1024px){.mdl-layout__header>.mdl-layout-icon{left:16px;top:12px}}.mdl-layout.has-drawer .mdl-layout__header>.mdl-layout-icon{display:none}.mdl-layout__header.is-compact{max-height:64px}@media screen and (max-width:1024px){.mdl-layout__header.is-compact{max-height:56px}}.mdl-layout__header.is-compact.has-tabs{height:112px}@media screen and (max-width:1024px){.mdl-layout__header.is-compact.has-tabs{min-height:104px}}@media screen and (max-width:1024px){.mdl-layout__header{display:none}.mdl-layout--fixed-header>.mdl-layout__header{display:-webkit-flex;display:-ms-flexbox;display:flex}}.mdl-layout__header--transparent.mdl-layout__header--transparent{background-color:transparent;box-shadow:none}.mdl-layout__header--seamed,.mdl-layout__header--scroll{box-shadow:none}.mdl-layout__header--waterfall{box-shadow:none;overflow:hidden}.mdl-layout__header--waterfall.is-casting-shadow{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-layout__header--waterfall.mdl-layout__header--waterfall-hide-top{-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end}.mdl-layout__header-row{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;box-sizing:border-box;-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:64px;margin:0;padding:0 40px 0 80px}.mdl-layout--no-drawer-button .mdl-layout__header-row{padding-left:40px}@media screen and (min-width:1025px){.mdl-layout--no-desktop-drawer-button .mdl-layout__header-row{padding-left:40px}}@media screen and (max-width:1024px){.mdl-layout__header-row{height:56px;padding:0 16px 0 72px}.mdl-layout--no-drawer-button .mdl-layout__header-row{padding-left:16px}}.mdl-layout__header-row>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.mdl-layout__header--scroll .mdl-layout__header-row{width:100%}.mdl-layout__header-row .mdl-navigation{margin:0;padding:0;height:64px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-ms-flex-align:center;-ms-grid-row-align:center;align-items:center}@media screen and (max-width:1024px){.mdl-layout__header-row .mdl-navigation{height:56px}}.mdl-layout__header-row .mdl-navigation__link{display:block;color:rgb(255,255,255);line-height:64px;padding:0 24px}@media screen and (max-width:1024px){.mdl-layout__header-row .mdl-navigation__link{line-height:56px;padding:0 16px}}.mdl-layout__obfuscator{background-color:transparent;position:absolute;top:0;left:0;height:100%;width:100%;z-index:4;visibility:hidden;transition-property:background-color;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-layout__obfuscator.is-visible{background-color:rgba(0,0,0,.5);visibility:visible}@supports (pointer-events:auto){.mdl-layout__obfuscator{background-color:rgba(0,0,0,.5);opacity:0;transition-property:opacity;visibility:visible;pointer-events:none}.mdl-layout__obfuscator.is-visible{pointer-events:auto;opacity:1}}.mdl-layout__content{-ms-flex:0 1 auto;position:relative;display:inline-block;overflow-y:auto;overflow-x:hidden;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;z-index:1;-webkit-overflow-scrolling:touch}.mdl-layout--fixed-drawer>.mdl-layout__content{margin-left:240px}.mdl-layout__container.has-scrolling-header .mdl-layout__content{overflow:visible}@media screen and (max-width:1024px){.mdl-layout--fixed-drawer>.mdl-layout__content{margin-left:0}.mdl-layout__container.has-scrolling-header .mdl-layout__content{overflow-y:auto;overflow-x:hidden}}.mdl-layout__tab-bar{height:96px;margin:0;width:calc(100% - 112px);padding:0 0 0 56px;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:rgb(255,152,0);overflow-y:hidden;overflow-x:scroll}.mdl-layout__tab-bar::-webkit-scrollbar{display:none}.mdl-layout--no-drawer-button .mdl-layout__tab-bar{padding-left:16px;width:calc(100% - 32px)}@media screen and (min-width:1025px){.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar{padding-left:16px;width:calc(100% - 32px)}}@media screen and (max-width:1024px){.mdl-layout__tab-bar{width:calc(100% - 60px);padding:0 0 0 60px}.mdl-layout--no-drawer-button .mdl-layout__tab-bar{width:calc(100% - 8px);padding-left:4px}}.mdl-layout--fixed-tabs .mdl-layout__tab-bar{padding:0;overflow:hidden;width:100%}.mdl-layout__tab-bar-container{position:relative;height:48px;width:100%;border:none;margin:0;z-index:2;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden}.mdl-layout__container>.mdl-layout__tab-bar-container{position:absolute;top:0;left:0}.mdl-layout__tab-bar-button{display:inline-block;position:absolute;top:0;height:48px;width:56px;z-index:4;text-align:center;background-color:rgb(255,152,0);color:transparent;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar-button,.mdl-layout--no-drawer-button .mdl-layout__tab-bar-button{width:16px}.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar-button .material-icons,.mdl-layout--no-drawer-button .mdl-layout__tab-bar-button .material-icons{position:relative;left:-4px}@media screen and (max-width:1024px){.mdl-layout__tab-bar-button{display:none;width:60px}}.mdl-layout--fixed-tabs .mdl-layout__tab-bar-button{display:none}.mdl-layout__tab-bar-button .material-icons{line-height:48px}.mdl-layout__tab-bar-button.is-active{color:rgb(66,66,66)}.mdl-layout__tab-bar-left-button{left:0}.mdl-layout__tab-bar-right-button{right:0}.mdl-layout__tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;text-decoration:none;height:48px;line-height:48px;text-align:center;font-weight:500;font-size:14px;text-transform:uppercase;color:rgba(66,66,66,.6);overflow:hidden}@media screen and (max-width:1024px){.mdl-layout__tab{padding:0 12px}}.mdl-layout--fixed-tabs .mdl-layout__tab{float:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0}.mdl-layout.is-upgraded .mdl-layout__tab.is-active{color:rgb(66,66,66)}.mdl-layout.is-upgraded .mdl-layout__tab.is-active::after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:rgb(68,138,255);-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;transition:all 1s cubic-bezier(.4,0,1,1)}.mdl-layout__tab .mdl-layout__tab-ripple-container{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.mdl-layout__tab .mdl-layout__tab-ripple-container .mdl-ripple{background-color:rgb(66,66,66)}.mdl-layout__tab-panel{display:block}.mdl-layout.is-upgraded .mdl-layout__tab-panel{display:none}.mdl-layout.is-upgraded .mdl-layout__tab-panel.is-active{display:block}.mdl-radio{position:relative;font-size:16px;line-height:24px;display:inline-block;box-sizing:border-box;margin:0;padding-left:0}.mdl-radio.is-upgraded{padding-left:24px}.mdl-radio__button{line-height:24px}.mdl-radio.is-upgraded .mdl-radio__button{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-radio__outer-circle{position:absolute;top:4px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;margin:0;cursor:pointer;border:2px solid rgba(0,0,0,.54);border-radius:50%;z-index:2}.mdl-radio.is-checked .mdl-radio__outer-circle{border:2px solid rgb(255,152,0)}.mdl-radio__outer-circle fieldset[disabled] .mdl-radio,.mdl-radio.is-disabled .mdl-radio__outer-circle{border:2px solid rgba(0,0,0,.26);cursor:auto}.mdl-radio__inner-circle{position:absolute;z-index:1;margin:0;top:8px;left:4px;box-sizing:border-box;width:8px;height:8px;cursor:pointer;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:transform;transition-property:transform,-webkit-transform;-webkit-transform:scale3d(0,0,0);transform:scale3d(0,0,0);border-radius:50%;background:rgb(255,152,0)}.mdl-radio.is-checked .mdl-radio__inner-circle{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}fieldset[disabled] .mdl-radio .mdl-radio__inner-circle,.mdl-radio.is-disabled .mdl-radio__inner-circle{background:rgba(0,0,0,.26);cursor:auto}.mdl-radio.is-focused .mdl-radio__inner-circle{box-shadow:0 0 0 10px rgba(0,0,0,.1)}.mdl-radio__label{cursor:pointer}fieldset[disabled] .mdl-radio .mdl-radio__label,.mdl-radio.is-disabled .mdl-radio__label{color:rgba(0,0,0,.26);cursor:auto}.mdl-radio__ripple-container{position:absolute;z-index:2;top:-9px;left:-13px;box-sizing:border-box;width:42px;height:42px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-radio__ripple-container .mdl-ripple{background:rgb(255,152,0)}fieldset[disabled] .mdl-radio .mdl-radio__ripple-container,.mdl-radio.is-disabled .mdl-radio__ripple-container{cursor:auto}fieldset[disabled] .mdl-radio .mdl-radio__ripple-container .mdl-ripple,.mdl-radio.is-disabled .mdl-radio__ripple-container .mdl-ripple{background:0 0}_:-ms-input-placeholder,:root .mdl-slider.mdl-slider.is-upgraded{-ms-appearance:none;height:32px;margin:0}.mdl-slider{width:calc(100% - 40px);margin:0 20px}.mdl-slider.is-upgraded{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:2px;background:0 0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;outline:0;padding:0;color:rgb(255,152,0);-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;z-index:1;cursor:pointer}.mdl-slider.is-upgraded::-moz-focus-outer{border:0}.mdl-slider.is-upgraded::-ms-tooltip{display:none}.mdl-slider.is-upgraded::-webkit-slider-runnable-track{background:0 0}.mdl-slider.is-upgraded::-moz-range-track{background:0 0;border:none}.mdl-slider.is-upgraded::-ms-track{background:0 0;color:transparent;height:2px;width:100%;border:none}.mdl-slider.is-upgraded::-ms-fill-lower{padding:0;background:linear-gradient(to right,transparent,transparent 16px,rgb(255,152,0)16px,rgb(255,152,0)0)}.mdl-slider.is-upgraded::-ms-fill-upper{padding:0;background:linear-gradient(to left,transparent,transparent 16px,rgba(0,0,0,.26)16px,rgba(0,0,0,.26)0)}.mdl-slider.is-upgraded::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background:rgb(255,152,0);border:none;transition:transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1)}.mdl-slider.is-upgraded::-moz-range-thumb{-moz-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background-image:none;background:rgb(255,152,0);border:none}.mdl-slider.is-upgraded:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(255,152,0,.26)}.mdl-slider.is-upgraded:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(255,152,0,.26)}.mdl-slider.is-upgraded:active::-webkit-slider-thumb{background-image:none;background:rgb(255,152,0);-webkit-transform:scale(1.5);transform:scale(1.5)}.mdl-slider.is-upgraded:active::-moz-range-thumb{background-image:none;background:rgb(255,152,0);transform:scale(1.5)}.mdl-slider.is-upgraded::-ms-thumb{width:32px;height:32px;border:none;border-radius:50%;background:rgb(255,152,0);transform:scale(.375);transition:transform .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1)}.mdl-slider.is-upgraded:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,rgb(255,152,0)0%,rgb(255,152,0)37.5%,rgba(255,152,0,.26)37.5%,rgba(255,152,0,.26)100%);transform:scale(1)}.mdl-slider.is-upgraded:active::-ms-thumb{background:rgb(255,152,0);transform:scale(.5625)}.mdl-slider.is-upgraded.is-lowest-value::-webkit-slider-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.mdl-slider.is-upgraded.is-lowest-value::-moz-range-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.mdl-slider.is-upgraded.is-lowest-value+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.mdl-slider.is-upgraded.is-lowest-value:active::-webkit-slider-thumb{border:1.6px solid rgba(0,0,0,.26);-webkit-transform:scale(1.5);transform:scale(1.5)}.mdl-slider.is-upgraded.is-lowest-value:active+.mdl-slider__background-flex>.mdl-slider__background-upper{left:9px}.mdl-slider.is-upgraded.is-lowest-value:active::-moz-range-thumb{border:1.5px solid rgba(0,0,0,.26);transform:scale(1.5)}.mdl-slider.is-upgraded.is-lowest-value::-ms-thumb{background:radial-gradient(circle closest-side,transparent 0%,transparent 66.67%,rgba(0,0,0,.26)66.67%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,rgba(0,0,0,.12)0%,rgba(0,0,0,.12)25%,rgba(0,0,0,.26)25%,rgba(0,0,0,.26)37.5%,rgba(0,0,0,.12)37.5%,rgba(0,0,0,.12)100%);transform:scale(1)}.mdl-slider.is-upgraded.is-lowest-value:active::-ms-thumb{transform:scale(.5625);background:radial-gradient(circle closest-side,transparent 0%,transparent 77.78%,rgba(0,0,0,.26)77.78%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-lower{background:0 0}.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-upper{margin-left:6px}.mdl-slider.is-upgraded.is-lowest-value:active::-ms-fill-upper{margin-left:9px}.mdl-slider.is-upgraded:disabled:focus::-webkit-slider-thumb,.mdl-slider.is-upgraded:disabled:active::-webkit-slider-thumb,.mdl-slider.is-upgraded:disabled::-webkit-slider-thumb{-webkit-transform:scale(.667);transform:scale(.667);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded:disabled:focus::-moz-range-thumb,.mdl-slider.is-upgraded:disabled:active::-moz-range-thumb,.mdl-slider.is-upgraded:disabled::-moz-range-thumb{transform:scale(.667);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded:disabled+.mdl-slider__background-flex>.mdl-slider__background-lower{background-color:rgba(0,0,0,.26);left:-6px}.mdl-slider.is-upgraded:disabled+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-webkit-slider-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-webkit-slider-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-webkit-slider-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;-webkit-transform:scale(.667);transform:scale(.667)}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-moz-range-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-moz-range-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-moz-range-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;transform:scale(.667)}.mdl-slider.is-upgraded.is-lowest-value:disabled:active+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded:disabled:focus::-ms-thumb,.mdl-slider.is-upgraded:disabled:active::-ms-thumb,.mdl-slider.is-upgraded:disabled::-ms-thumb{transform:scale(.25);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-ms-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-ms-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-ms-thumb{transform:scale(.25);background:radial-gradient(circle closest-side,transparent 0%,transparent 50%,rgba(0,0,0,.26)50%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded:disabled::-ms-fill-lower{margin-right:6px;background:linear-gradient(to right,transparent,transparent 25px,rgba(0,0,0,.26)25px,rgba(0,0,0,.26)0)}.mdl-slider.is-upgraded:disabled::-ms-fill-upper{margin-left:6px}.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-ms-fill-upper{margin-left:6px}.mdl-slider__ie-container{height:18px;overflow:visible;border:none;margin:none;padding:none}.mdl-slider__container{height:18px;position:relative;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.mdl-slider__container,.mdl-slider__background-flex{background:0 0;display:-webkit-flex;display:-ms-flexbox;display:flex}.mdl-slider__background-flex{position:absolute;height:2px;width:calc(100% - 52px);top:50%;left:0;margin:0 26px;overflow:hidden;border:0;padding:0;-webkit-transform:translate(0,-1px);transform:translate(0,-1px)}.mdl-slider__background-lower{background:rgb(255,152,0)}.mdl-slider__background-lower,.mdl-slider__background-upper{-webkit-flex:0;-ms-flex:0;flex:0;position:relative;border:0;padding:0}.mdl-slider__background-upper{background:rgba(0,0,0,.26);transition:left .18s cubic-bezier(.4,0,.2,1)}.mdl-snackbar{position:fixed;bottom:0;left:50%;cursor:default;background-color:#323232;z-index:3;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;font-family:"Roboto","Helvetica","Arial",sans-serif;will-change:transform;-webkit-transform:translate(0,80px);transform:translate(0,80px);transition:transform .25s cubic-bezier(.4,0,1,1);transition:transform .25s cubic-bezier(.4,0,1,1),-webkit-transform .25s cubic-bezier(.4,0,1,1);pointer-events:none}@media (max-width:479px){.mdl-snackbar{width:100%;left:0;min-height:48px;max-height:80px}}@media (min-width:480px){.mdl-snackbar{min-width:288px;max-width:568px;border-radius:2px;-webkit-transform:translate(-50%,80px);transform:translate(-50%,80px)}}.mdl-snackbar--active{-webkit-transform:translate(0,0);transform:translate(0,0);pointer-events:auto;transition:transform .25s cubic-bezier(0,0,.2,1);transition:transform .25s cubic-bezier(0,0,.2,1),-webkit-transform .25s cubic-bezier(0,0,.2,1)}@media (min-width:480px){.mdl-snackbar--active{-webkit-transform:translate(-50%,0);transform:translate(-50%,0)}}.mdl-snackbar__text{padding:14px 12px 14px 24px;vertical-align:middle;color:#fff;float:left}.mdl-snackbar__action{background:0 0;border:none;color:rgb(68,138,255);float:right;padding:14px 24px 14px 12px;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;line-height:1;letter-spacing:0;overflow:hidden;outline:none;opacity:0;pointer-events:none;cursor:pointer;text-decoration:none;text-align:center;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.mdl-snackbar__action::-moz-focus-inner{border:0}.mdl-snackbar__action:not([aria-hidden]){opacity:1;pointer-events:auto}.mdl-spinner{display:inline-block;position:relative;width:28px;height:28px}.mdl-spinner:not(.is-upgraded).is-active:after{content:"Loading..."}.mdl-spinner.is-upgraded.is-active{-webkit-animation:mdl-spinner__container-rotate 1568.23529412ms linear infinite;animation:mdl-spinner__container-rotate 1568.23529412ms linear infinite}@-webkit-keyframes mdl-spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes mdl-spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.mdl-spinner__layer{position:absolute;width:100%;height:100%;opacity:0}.mdl-spinner__layer-1{border-color:#42a5f5}.mdl-spinner--single-color .mdl-spinner__layer-1{border-color:rgb(255,152,0)}.mdl-spinner.is-active .mdl-spinner__layer-1{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-2{border-color:#f44336}.mdl-spinner--single-color .mdl-spinner__layer-2{border-color:rgb(255,152,0)}.mdl-spinner.is-active .mdl-spinner__layer-2{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-3{border-color:#fdd835}.mdl-spinner--single-color .mdl-spinner__layer-3{border-color:rgb(255,152,0)}.mdl-spinner.is-active .mdl-spinner__layer-3{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-4{border-color:#4caf50}.mdl-spinner--single-color .mdl-spinner__layer-4{border-color:rgb(255,152,0)}.mdl-spinner.is-active .mdl-spinner__layer-4{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}@-webkit-keyframes mdl-spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@keyframes mdl-spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes mdl-spinner__layer-1-fade-in-out{from,25%{opacity:.99}26%,89%{opacity:0}90%,100%{opacity:.99}}@keyframes mdl-spinner__layer-1-fade-in-out{from,25%{opacity:.99}26%,89%{opacity:0}90%,100%{opacity:.99}}@-webkit-keyframes mdl-spinner__layer-2-fade-in-out{from,15%{opacity:0}25%,50%{opacity:.99}51%{opacity:0}}@keyframes mdl-spinner__layer-2-fade-in-out{from,15%{opacity:0}25%,50%{opacity:.99}51%{opacity:0}}@-webkit-keyframes mdl-spinner__layer-3-fade-in-out{from,40%{opacity:0}50%,75%{opacity:.99}76%{opacity:0}}@keyframes mdl-spinner__layer-3-fade-in-out{from,40%{opacity:0}50%,75%{opacity:.99}76%{opacity:0}}@-webkit-keyframes mdl-spinner__layer-4-fade-in-out{from,65%{opacity:0}75%,90%{opacity:.99}100%{opacity:0}}@keyframes mdl-spinner__layer-4-fade-in-out{from,65%{opacity:0}75%,90%{opacity:.99}100%{opacity:0}}.mdl-spinner__gap-patch{position:absolute;box-sizing:border-box;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.mdl-spinner__gap-patch .mdl-spinner__circle{width:1000%;left:-450%}.mdl-spinner__circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.mdl-spinner__circle-clipper .mdl-spinner__circle{width:200%}.mdl-spinner__circle{box-sizing:border-box;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent!important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0;left:0}.mdl-spinner__left .mdl-spinner__circle{border-right-color:transparent!important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.mdl-spinner.is-active .mdl-spinner__left .mdl-spinner__circle{-webkit-animation:mdl-spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__right .mdl-spinner__circle{left:-100%;border-left-color:transparent!important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.mdl-spinner.is-active .mdl-spinner__right .mdl-spinner__circle{-webkit-animation:mdl-spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both}@-webkit-keyframes mdl-spinner__left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@keyframes mdl-spinner__left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@-webkit-keyframes mdl-spinner__right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}@keyframes mdl-spinner__right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}.mdl-switch{position:relative;z-index:1;vertical-align:middle;display:inline-block;box-sizing:border-box;width:100%;height:24px;margin:0;padding:0;overflow:visible;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-switch.is-upgraded{padding-left:28px}.mdl-switch__input{line-height:24px}.mdl-switch.is-upgraded .mdl-switch__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-switch__track{background:rgba(0,0,0,.26);position:absolute;left:0;top:5px;height:14px;width:36px;border-radius:14px;cursor:pointer}.mdl-switch.is-checked .mdl-switch__track{background:rgba(255,152,0,.5)}.mdl-switch__track fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__track{background:rgba(0,0,0,.12);cursor:auto}.mdl-switch__thumb{background:#fafafa;position:absolute;left:0;top:2px;height:20px;width:20px;border-radius:50%;cursor:pointer;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:left}.mdl-switch.is-checked .mdl-switch__thumb{background:rgb(255,152,0);left:16px;box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.mdl-switch__thumb fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__thumb{background:#bdbdbd;cursor:auto}.mdl-switch__focus-helper{position:absolute;top:50%;left:50%;-webkit-transform:translate(-4px,-4px);transform:translate(-4px,-4px);display:inline-block;box-sizing:border-box;width:8px;height:8px;border-radius:50%;background-color:transparent}.mdl-switch.is-focused .mdl-switch__focus-helper{box-shadow:0 0 0 20px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.mdl-switch.is-focused.is-checked .mdl-switch__focus-helper{box-shadow:0 0 0 20px rgba(255,152,0,.26);background-color:rgba(255,152,0,.26)}.mdl-switch__label{position:relative;cursor:pointer;font-size:16px;line-height:24px;margin:0;left:24px}.mdl-switch__label fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__label{color:#bdbdbd;cursor:auto}.mdl-switch__ripple-container{position:absolute;z-index:2;top:-12px;left:-14px;box-sizing:border-box;width:48px;height:48px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000);transition-duration:.4s;transition-timing-function:step-end;transition-property:left}.mdl-switch__ripple-container .mdl-ripple{background:rgb(255,152,0)}.mdl-switch__ripple-container fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__ripple-container{cursor:auto}fieldset[disabled] .mdl-switch .mdl-switch__ripple-container .mdl-ripple,.mdl-switch.is-disabled .mdl-switch__ripple-container .mdl-ripple{background:0 0}.mdl-switch.is-checked .mdl-switch__ripple-container{left:2px}.mdl-tabs{display:block;width:100%}.mdl-tabs__tab-bar{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:space-between;-ms-flex-line-pack:justify;align-content:space-between;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;height:48px;padding:0;margin:0;border-bottom:1px solid #e0e0e0}.mdl-tabs__tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;text-decoration:none;height:48px;line-height:48px;text-align:center;font-weight:500;font-size:14px;text-transform:uppercase;color:rgba(0,0,0,.54);overflow:hidden}.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active{color:rgba(0,0,0,.87)}.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active:after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:rgb(255,152,0);-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;transition:all 1s cubic-bezier(.4,0,1,1)}.mdl-tabs__tab .mdl-tabs__ripple-container{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.mdl-tabs__tab .mdl-tabs__ripple-container .mdl-ripple{background:rgb(255,152,0)}.mdl-tabs__panel{display:block}.mdl-tabs.is-upgraded .mdl-tabs__panel{display:none}.mdl-tabs.is-upgraded .mdl-tabs__panel.is-active{display:block}@-webkit-keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}@keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}.mdl-textfield{position:relative;font-size:16px;display:inline-block;box-sizing:border-box;width:300px;max-width:100%;margin:0;padding:20px 0}.mdl-textfield .mdl-button{position:absolute;bottom:20px}.mdl-textfield--align-right{text-align:right}.mdl-textfield--full-width{width:100%}.mdl-textfield--expandable{min-width:32px;width:auto;min-height:32px}.mdl-textfield__input{border:none;border-bottom:1px solid rgba(0,0,0,.12);display:block;font-size:16px;font-family:"Helvetica","Arial",sans-serif;margin:0;padding:4px 0;width:100%;background:0 0;text-align:left;color:inherit}.mdl-textfield__input[type="number"]{-moz-appearance:textfield}.mdl-textfield__input[type="number"]::-webkit-inner-spin-button,.mdl-textfield__input[type="number"]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.mdl-textfield.is-focused .mdl-textfield__input{outline:none}.mdl-textfield.is-invalid .mdl-textfield__input{border-color:#d50000;box-shadow:none}fieldset[disabled] .mdl-textfield .mdl-textfield__input,.mdl-textfield.is-disabled .mdl-textfield__input{background-color:transparent;border-bottom:1px dotted rgba(0,0,0,.12);color:rgba(0,0,0,.26)}.mdl-textfield textarea.mdl-textfield__input{display:block}.mdl-textfield__label{bottom:0;color:rgba(0,0,0,.26);font-size:16px;left:0;right:0;pointer-events:none;position:absolute;display:block;top:24px;width:100%;overflow:hidden;white-space:nowrap;text-align:left}.mdl-textfield.is-dirty .mdl-textfield__label,.mdl-textfield.has-placeholder .mdl-textfield__label{visibility:hidden}.mdl-textfield--floating-label .mdl-textfield__label{transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-textfield--floating-label.has-placeholder .mdl-textfield__label{transition:none}fieldset[disabled] .mdl-textfield .mdl-textfield__label,.mdl-textfield.is-disabled.is-disabled .mdl-textfield__label{color:rgba(0,0,0,.26)}.mdl-textfield--floating-label.is-focused .mdl-textfield__label,.mdl-textfield--floating-label.is-dirty .mdl-textfield__label,.mdl-textfield--floating-label.has-placeholder .mdl-textfield__label{color:rgb(255,152,0);font-size:12px;top:4px;visibility:visible}.mdl-textfield--floating-label.is-focused .mdl-textfield__expandable-holder .mdl-textfield__label,.mdl-textfield--floating-label.is-dirty .mdl-textfield__expandable-holder .mdl-textfield__label,.mdl-textfield--floating-label.has-placeholder .mdl-textfield__expandable-holder .mdl-textfield__label{top:-16px}.mdl-textfield--floating-label.is-invalid .mdl-textfield__label{color:#d50000;font-size:12px}.mdl-textfield__label:after{background-color:rgb(255,152,0);bottom:20px;content:'';height:2px;left:45%;position:absolute;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);visibility:hidden;width:10px}.mdl-textfield.is-focused .mdl-textfield__label:after{left:0;visibility:visible;width:100%}.mdl-textfield.is-invalid .mdl-textfield__label:after{background-color:#d50000}.mdl-textfield__error{color:#d50000;position:absolute;font-size:12px;margin-top:3px;visibility:hidden;display:block}.mdl-textfield.is-invalid .mdl-textfield__error{visibility:visible}.mdl-textfield__expandable-holder{display:inline-block;position:relative;margin-left:32px;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:inline-block;max-width:.1px}.mdl-textfield.is-focused .mdl-textfield__expandable-holder,.mdl-textfield.is-dirty .mdl-textfield__expandable-holder{max-width:600px}.mdl-textfield__expandable-holder .mdl-textfield__label:after{bottom:0}.mdl-tooltip{-webkit-transform:scale(0);transform:scale(0);-webkit-transform-origin:top center;transform-origin:top center;will-change:transform;z-index:999;background:rgba(97,97,97,.9);border-radius:2px;color:#fff;display:inline-block;font-size:10px;font-weight:500;line-height:14px;max-width:170px;position:fixed;top:-500px;left:-500px;padding:8px;text-align:center}.mdl-tooltip.is-active{-webkit-animation:pulse 200ms cubic-bezier(0,0,.2,1)forwards;animation:pulse 200ms cubic-bezier(0,0,.2,1)forwards}.mdl-tooltip--large{line-height:14px;font-size:14px;padding:16px}@-webkit-keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}@keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}.mdl-shadow--2dp{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-shadow--3dp{box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.mdl-shadow--4dp{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.mdl-shadow--6dp{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2)}.mdl-shadow--8dp{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2)}.mdl-shadow--16dp{box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.2)}.mdl-shadow--24dp{box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2)}.mdl-grid{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;margin:0 auto;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch}.mdl-grid.mdl-grid--no-spacing{padding:0}.mdl-cell{box-sizing:border-box}.mdl-cell--top{-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}.mdl-cell--middle{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.mdl-cell--bottom{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end}.mdl-cell--stretch{-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch}.mdl-grid.mdl-grid--no-spacing>.mdl-cell{margin:0}.mdl-cell--order-1{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12{-webkit-order:12;-ms-flex-order:12;order:12}@media (max-width:479px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:100%}.mdl-cell--hide-phone{display:none!important}.mdl-cell--order-1-phone.mdl-cell--order-1-phone{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-phone.mdl-cell--order-2-phone{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-phone.mdl-cell--order-3-phone{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-phone.mdl-cell--order-4-phone{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-phone.mdl-cell--order-5-phone{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-phone.mdl-cell--order-6-phone{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-phone.mdl-cell--order-7-phone{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-phone.mdl-cell--order-8-phone{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-phone.mdl-cell--order-9-phone{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-phone.mdl-cell--order-10-phone{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-phone.mdl-cell--order-11-phone{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-phone.mdl-cell--order-12-phone{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-phone.mdl-cell--1-col-phone{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-phone.mdl-cell--1-col-phone{width:25%}.mdl-cell--2-col,.mdl-cell--2-col-phone.mdl-cell--2-col-phone{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-phone.mdl-cell--2-col-phone{width:50%}.mdl-cell--3-col,.mdl-cell--3-col-phone.mdl-cell--3-col-phone{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-phone.mdl-cell--3-col-phone{width:75%}.mdl-cell--4-col,.mdl-cell--4-col-phone.mdl-cell--4-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-phone.mdl-cell--4-col-phone{width:100%}.mdl-cell--5-col,.mdl-cell--5-col-phone.mdl-cell--5-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-phone.mdl-cell--5-col-phone{width:100%}.mdl-cell--6-col,.mdl-cell--6-col-phone.mdl-cell--6-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-phone.mdl-cell--6-col-phone{width:100%}.mdl-cell--7-col,.mdl-cell--7-col-phone.mdl-cell--7-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-phone.mdl-cell--7-col-phone{width:100%}.mdl-cell--8-col,.mdl-cell--8-col-phone.mdl-cell--8-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-phone.mdl-cell--8-col-phone{width:100%}.mdl-cell--9-col,.mdl-cell--9-col-phone.mdl-cell--9-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-phone.mdl-cell--9-col-phone{width:100%}.mdl-cell--10-col,.mdl-cell--10-col-phone.mdl-cell--10-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-phone.mdl-cell--10-col-phone{width:100%}.mdl-cell--11-col,.mdl-cell--11-col-phone.mdl-cell--11-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-phone.mdl-cell--11-col-phone{width:100%}.mdl-cell--12-col,.mdl-cell--12-col-phone.mdl-cell--12-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-phone.mdl-cell--12-col-phone{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-phone.mdl-cell--1-offset-phone{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-phone.mdl-cell--1-offset-phone{margin-left:25%}.mdl-cell--2-offset,.mdl-cell--2-offset-phone.mdl-cell--2-offset-phone{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-phone.mdl-cell--2-offset-phone{margin-left:50%}.mdl-cell--3-offset,.mdl-cell--3-offset-phone.mdl-cell--3-offset-phone{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-phone.mdl-cell--3-offset-phone{margin-left:75%}}@media (min-width:480px) and (max-width:839px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:50%}.mdl-cell--hide-tablet{display:none!important}.mdl-cell--order-1-tablet.mdl-cell--order-1-tablet{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-tablet.mdl-cell--order-2-tablet{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-tablet.mdl-cell--order-3-tablet{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-tablet.mdl-cell--order-4-tablet{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-tablet.mdl-cell--order-5-tablet{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-tablet.mdl-cell--order-6-tablet{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-tablet.mdl-cell--order-7-tablet{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-tablet.mdl-cell--order-8-tablet{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-tablet.mdl-cell--order-9-tablet{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-tablet.mdl-cell--order-10-tablet{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-tablet.mdl-cell--order-11-tablet{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-tablet.mdl-cell--order-12-tablet{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-tablet.mdl-cell--1-col-tablet{width:calc(12.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-tablet.mdl-cell--1-col-tablet{width:12.5%}.mdl-cell--2-col,.mdl-cell--2-col-tablet.mdl-cell--2-col-tablet{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-tablet.mdl-cell--2-col-tablet{width:25%}.mdl-cell--3-col,.mdl-cell--3-col-tablet.mdl-cell--3-col-tablet{width:calc(37.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-tablet.mdl-cell--3-col-tablet{width:37.5%}.mdl-cell--4-col,.mdl-cell--4-col-tablet.mdl-cell--4-col-tablet{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-tablet.mdl-cell--4-col-tablet{width:50%}.mdl-cell--5-col,.mdl-cell--5-col-tablet.mdl-cell--5-col-tablet{width:calc(62.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-tablet.mdl-cell--5-col-tablet{width:62.5%}.mdl-cell--6-col,.mdl-cell--6-col-tablet.mdl-cell--6-col-tablet{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-tablet.mdl-cell--6-col-tablet{width:75%}.mdl-cell--7-col,.mdl-cell--7-col-tablet.mdl-cell--7-col-tablet{width:calc(87.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-tablet.mdl-cell--7-col-tablet{width:87.5%}.mdl-cell--8-col,.mdl-cell--8-col-tablet.mdl-cell--8-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-tablet.mdl-cell--8-col-tablet{width:100%}.mdl-cell--9-col,.mdl-cell--9-col-tablet.mdl-cell--9-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-tablet.mdl-cell--9-col-tablet{width:100%}.mdl-cell--10-col,.mdl-cell--10-col-tablet.mdl-cell--10-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-tablet.mdl-cell--10-col-tablet{width:100%}.mdl-cell--11-col,.mdl-cell--11-col-tablet.mdl-cell--11-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-tablet.mdl-cell--11-col-tablet{width:100%}.mdl-cell--12-col,.mdl-cell--12-col-tablet.mdl-cell--12-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-tablet.mdl-cell--12-col-tablet{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-tablet.mdl-cell--1-offset-tablet{margin-left:calc(12.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-tablet.mdl-cell--1-offset-tablet{margin-left:12.5%}.mdl-cell--2-offset,.mdl-cell--2-offset-tablet.mdl-cell--2-offset-tablet{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-tablet.mdl-cell--2-offset-tablet{margin-left:25%}.mdl-cell--3-offset,.mdl-cell--3-offset-tablet.mdl-cell--3-offset-tablet{margin-left:calc(37.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-tablet.mdl-cell--3-offset-tablet{margin-left:37.5%}.mdl-cell--4-offset,.mdl-cell--4-offset-tablet.mdl-cell--4-offset-tablet{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset-tablet.mdl-cell--4-offset-tablet{margin-left:50%}.mdl-cell--5-offset,.mdl-cell--5-offset-tablet.mdl-cell--5-offset-tablet{margin-left:calc(62.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset-tablet.mdl-cell--5-offset-tablet{margin-left:62.5%}.mdl-cell--6-offset,.mdl-cell--6-offset-tablet.mdl-cell--6-offset-tablet{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset-tablet.mdl-cell--6-offset-tablet{margin-left:75%}.mdl-cell--7-offset,.mdl-cell--7-offset-tablet.mdl-cell--7-offset-tablet{margin-left:calc(87.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset-tablet.mdl-cell--7-offset-tablet{margin-left:87.5%}}@media (min-width:840px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(33.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:33.3333333333%}.mdl-cell--hide-desktop{display:none!important}.mdl-cell--order-1-desktop.mdl-cell--order-1-desktop{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-desktop.mdl-cell--order-2-desktop{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-desktop.mdl-cell--order-3-desktop{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-desktop.mdl-cell--order-4-desktop{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-desktop.mdl-cell--order-5-desktop{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-desktop.mdl-cell--order-6-desktop{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-desktop.mdl-cell--order-7-desktop{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-desktop.mdl-cell--order-8-desktop{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-desktop.mdl-cell--order-9-desktop{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-desktop.mdl-cell--order-10-desktop{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-desktop.mdl-cell--order-11-desktop{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-desktop.mdl-cell--order-12-desktop{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-desktop.mdl-cell--1-col-desktop{width:calc(8.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-desktop.mdl-cell--1-col-desktop{width:8.3333333333%}.mdl-cell--2-col,.mdl-cell--2-col-desktop.mdl-cell--2-col-desktop{width:calc(16.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-desktop.mdl-cell--2-col-desktop{width:16.6666666667%}.mdl-cell--3-col,.mdl-cell--3-col-desktop.mdl-cell--3-col-desktop{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-desktop.mdl-cell--3-col-desktop{width:25%}.mdl-cell--4-col,.mdl-cell--4-col-desktop.mdl-cell--4-col-desktop{width:calc(33.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-desktop.mdl-cell--4-col-desktop{width:33.3333333333%}.mdl-cell--5-col,.mdl-cell--5-col-desktop.mdl-cell--5-col-desktop{width:calc(41.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-desktop.mdl-cell--5-col-desktop{width:41.6666666667%}.mdl-cell--6-col,.mdl-cell--6-col-desktop.mdl-cell--6-col-desktop{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-desktop.mdl-cell--6-col-desktop{width:50%}.mdl-cell--7-col,.mdl-cell--7-col-desktop.mdl-cell--7-col-desktop{width:calc(58.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-desktop.mdl-cell--7-col-desktop{width:58.3333333333%}.mdl-cell--8-col,.mdl-cell--8-col-desktop.mdl-cell--8-col-desktop{width:calc(66.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-desktop.mdl-cell--8-col-desktop{width:66.6666666667%}.mdl-cell--9-col,.mdl-cell--9-col-desktop.mdl-cell--9-col-desktop{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-desktop.mdl-cell--9-col-desktop{width:75%}.mdl-cell--10-col,.mdl-cell--10-col-desktop.mdl-cell--10-col-desktop{width:calc(83.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-desktop.mdl-cell--10-col-desktop{width:83.3333333333%}.mdl-cell--11-col,.mdl-cell--11-col-desktop.mdl-cell--11-col-desktop{width:calc(91.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-desktop.mdl-cell--11-col-desktop{width:91.6666666667%}.mdl-cell--12-col,.mdl-cell--12-col-desktop.mdl-cell--12-col-desktop{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-desktop.mdl-cell--12-col-desktop{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-desktop.mdl-cell--1-offset-desktop{margin-left:calc(8.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-desktop.mdl-cell--1-offset-desktop{margin-left:8.3333333333%}.mdl-cell--2-offset,.mdl-cell--2-offset-desktop.mdl-cell--2-offset-desktop{margin-left:calc(16.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-desktop.mdl-cell--2-offset-desktop{margin-left:16.6666666667%}.mdl-cell--3-offset,.mdl-cell--3-offset-desktop.mdl-cell--3-offset-desktop{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-desktop.mdl-cell--3-offset-desktop{margin-left:25%}.mdl-cell--4-offset,.mdl-cell--4-offset-desktop.mdl-cell--4-offset-desktop{margin-left:calc(33.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset-desktop.mdl-cell--4-offset-desktop{margin-left:33.3333333333%}.mdl-cell--5-offset,.mdl-cell--5-offset-desktop.mdl-cell--5-offset-desktop{margin-left:calc(41.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset-desktop.mdl-cell--5-offset-desktop{margin-left:41.6666666667%}.mdl-cell--6-offset,.mdl-cell--6-offset-desktop.mdl-cell--6-offset-desktop{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset-desktop.mdl-cell--6-offset-desktop{margin-left:50%}.mdl-cell--7-offset,.mdl-cell--7-offset-desktop.mdl-cell--7-offset-desktop{margin-left:calc(58.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset-desktop.mdl-cell--7-offset-desktop{margin-left:58.3333333333%}.mdl-cell--8-offset,.mdl-cell--8-offset-desktop.mdl-cell--8-offset-desktop{margin-left:calc(66.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--8-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--8-offset-desktop.mdl-cell--8-offset-desktop{margin-left:66.6666666667%}.mdl-cell--9-offset,.mdl-cell--9-offset-desktop.mdl-cell--9-offset-desktop{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--9-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--9-offset-desktop.mdl-cell--9-offset-desktop{margin-left:75%}.mdl-cell--10-offset,.mdl-cell--10-offset-desktop.mdl-cell--10-offset-desktop{margin-left:calc(83.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--10-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--10-offset-desktop.mdl-cell--10-offset-desktop{margin-left:83.3333333333%}.mdl-cell--11-offset,.mdl-cell--11-offset-desktop.mdl-cell--11-offset-desktop{margin-left:calc(91.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--11-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--11-offset-desktop.mdl-cell--11-offset-desktop{margin-left:91.6666666667%}}body{margin:0}.styleguide-demo h1{margin:48px 24px 0}.styleguide-demo h1:after{content:'';display:block;width:100%;border-bottom:1px solid rgba(0,0,0,.5);margin-top:24px}.styleguide-demo{opacity:0;transition:opacity .6s ease}.styleguide-masthead{height:256px;background:#212121;padding:115px 16px 0}.styleguide-container{position:relative;max-width:960px;width:100%}.styleguide-title{color:#fff;bottom:auto;position:relative;font-size:56px;font-weight:300;line-height:1;letter-spacing:-.02em}.styleguide-title:after{border-bottom:0}.styleguide-title span{font-weight:300}.mdl-styleguide .mdl-layout__drawer .mdl-navigation__link{padding:10px 24px}.demosLoaded .styleguide-demo{opacity:1}iframe{display:block;width:100%;border:none}iframe.heightSet{overflow:hidden}.demo-wrapper{margin:24px}.demo-wrapper iframe{border:1px solid rgba(0,0,0,.5)} \ No newline at end of file +@charset "UTF-8";html{color:rgba(0,0,0,.87)}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}.browserupgrade{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.hidden{display:none!important}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}@media print{*,*:before,*:after,*:first-letter{background:transparent!important;color:#000!important;box-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}}a,.mdl-accordion,.mdl-button,.mdl-card,.mdl-checkbox,.mdl-dropdown-menu,.mdl-icon-toggle,.mdl-item,.mdl-radio,.mdl-slider,.mdl-switch,.mdl-tabs__tab{-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:rgba(255,255,255,0)}html{width:100%;height:100%;-ms-touch-action:manipulation;touch-action:manipulation}body{width:100%;min-height:100%}main{display:block}*[hidden]{display:none!important}html,body{font-family:"Helvetica","Arial",sans-serif;font-size:14px;font-weight:400;line-height:20px}h1,h2,h3,h4,h5,h6,p{padding:0}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400;line-height:1.35;letter-spacing:-.02em;opacity:.54;font-size:.6em}h1{font-size:56px;line-height:1.35;letter-spacing:-.02em;margin:24px 0}h1,h2{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400}h2{font-size:45px;line-height:48px}h2,h3{margin:24px 0}h3{font-size:34px;line-height:40px}h3,h4{font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:400}h4{font-size:24px;line-height:32px;-moz-osx-font-smoothing:grayscale;margin:24px 0 16px}h5{font-size:20px;font-weight:500;line-height:1;letter-spacing:.02em}h5,h6{font-family:"Roboto","Helvetica","Arial",sans-serif;margin:24px 0 16px}h6{font-size:16px;letter-spacing:.04em}h6,p{font-weight:400;line-height:24px}p{font-size:14px;letter-spacing:0;margin:0 0 16px}a{color:rgb(68,138,255);font-weight:500}blockquote{font-family:"Roboto","Helvetica","Arial",sans-serif;position:relative;font-size:24px;font-weight:300;font-style:italic;line-height:1.35;letter-spacing:.08em}blockquote:before{position:absolute;left:-.5em;content:'“'}blockquote:after{content:'”';margin-left:-.05em}mark{background-color:#f4ff81}dt{font-weight:700}address{font-size:12px;line-height:1;font-style:normal}address,ul,ol{font-weight:400;letter-spacing:0}ul,ol{font-size:14px;line-height:24px}.mdl-typography--display-4,.mdl-typography--display-4-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:112px;font-weight:300;line-height:1;letter-spacing:-.04em}.mdl-typography--display-4-color-contrast{opacity:.54}.mdl-typography--display-3,.mdl-typography--display-3-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:56px;font-weight:400;line-height:1.35;letter-spacing:-.02em}.mdl-typography--display-3-color-contrast{opacity:.54}.mdl-typography--display-2,.mdl-typography--display-2-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:45px;font-weight:400;line-height:48px}.mdl-typography--display-2-color-contrast{opacity:.54}.mdl-typography--display-1,.mdl-typography--display-1-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:34px;font-weight:400;line-height:40px}.mdl-typography--display-1-color-contrast{opacity:.54}.mdl-typography--headline,.mdl-typography--headline-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:24px;font-weight:400;line-height:32px;-moz-osx-font-smoothing:grayscale}.mdl-typography--headline-color-contrast{opacity:.87}.mdl-typography--title,.mdl-typography--title-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:20px;font-weight:500;line-height:1;letter-spacing:.02em}.mdl-typography--title-color-contrast{opacity:.87}.mdl-typography--subhead,.mdl-typography--subhead-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:16px;font-weight:400;line-height:24px;letter-spacing:.04em}.mdl-typography--subhead-color-contrast{opacity:.87}.mdl-typography--body-2,.mdl-typography--body-2-color-contrast{font-size:14px;font-weight:700;line-height:24px;letter-spacing:0}.mdl-typography--body-2-color-contrast{opacity:.87}.mdl-typography--body-1,.mdl-typography--body-1-color-contrast{font-size:14px;font-weight:400;line-height:24px;letter-spacing:0}.mdl-typography--body-1-color-contrast{opacity:.87}.mdl-typography--body-2-force-preferred-font,.mdl-typography--body-2-force-preferred-font-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;line-height:24px;letter-spacing:0}.mdl-typography--body-2-force-preferred-font-color-contrast{opacity:.87}.mdl-typography--body-1-force-preferred-font,.mdl-typography--body-1-force-preferred-font-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:400;line-height:24px;letter-spacing:0}.mdl-typography--body-1-force-preferred-font-color-contrast{opacity:.87}.mdl-typography--caption,.mdl-typography--caption-force-preferred-font{font-size:12px;font-weight:400;line-height:1;letter-spacing:0}.mdl-typography--caption-force-preferred-font{font-family:"Roboto","Helvetica","Arial",sans-serif}.mdl-typography--caption-color-contrast,.mdl-typography--caption-force-preferred-font-color-contrast{font-size:12px;font-weight:400;line-height:1;letter-spacing:0;opacity:.54}.mdl-typography--caption-force-preferred-font-color-contrast,.mdl-typography--menu{font-family:"Roboto","Helvetica","Arial",sans-serif}.mdl-typography--menu{font-size:14px;font-weight:500;line-height:1;letter-spacing:0}.mdl-typography--menu-color-contrast{opacity:.87}.mdl-typography--menu-color-contrast,.mdl-typography--button,.mdl-typography--button-color-contrast{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;line-height:1;letter-spacing:0}.mdl-typography--button,.mdl-typography--button-color-contrast{text-transform:uppercase}.mdl-typography--button-color-contrast{opacity:.87}.mdl-typography--text-left{text-align:left}.mdl-typography--text-right{text-align:right}.mdl-typography--text-center{text-align:center}.mdl-typography--text-justify{text-align:justify}.mdl-typography--text-nowrap{white-space:nowrap}.mdl-typography--text-lowercase{text-transform:lowercase}.mdl-typography--text-uppercase{text-transform:uppercase}.mdl-typography--text-capitalize{text-transform:capitalize}.mdl-typography--font-thin{font-weight:200!important}.mdl-typography--font-light{font-weight:300!important}.mdl-typography--font-regular{font-weight:400!important}.mdl-typography--font-medium{font-weight:500!important}.mdl-typography--font-bold{font-weight:700!important}.mdl-typography--font-black{font-weight:900!important}.material-icons{font-family:'Material Icons';font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;word-wrap:normal;-moz-font-feature-settings:'liga';font-feature-settings:'liga';-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased}.mdl-color-text--red{color:#f44336 !important}.mdl-color--red{background-color:#f44336 !important}.mdl-color-text--red-50{color:#ffebee !important}.mdl-color--red-50{background-color:#ffebee !important}.mdl-color-text--red-100{color:#ffcdd2 !important}.mdl-color--red-100{background-color:#ffcdd2 !important}.mdl-color-text--red-200{color:#ef9a9a !important}.mdl-color--red-200{background-color:#ef9a9a !important}.mdl-color-text--red-300{color:#e57373 !important}.mdl-color--red-300{background-color:#e57373 !important}.mdl-color-text--red-400{color:#ef5350 !important}.mdl-color--red-400{background-color:#ef5350 !important}.mdl-color-text--red-500{color:#f44336 !important}.mdl-color--red-500{background-color:#f44336 !important}.mdl-color-text--red-600{color:#e53935 !important}.mdl-color--red-600{background-color:#e53935 !important}.mdl-color-text--red-700{color:#d32f2f !important}.mdl-color--red-700{background-color:#d32f2f !important}.mdl-color-text--red-800{color:#c62828 !important}.mdl-color--red-800{background-color:#c62828 !important}.mdl-color-text--red-900{color:#b71c1c !important}.mdl-color--red-900{background-color:#b71c1c !important}.mdl-color-text--red-A100{color:#ff8a80 !important}.mdl-color--red-A100{background-color:#ff8a80 !important}.mdl-color-text--red-A200{color:#ff5252 !important}.mdl-color--red-A200{background-color:#ff5252 !important}.mdl-color-text--red-A400{color:#ff1744 !important}.mdl-color--red-A400{background-color:#ff1744 !important}.mdl-color-text--red-A700{color:#d50000 !important}.mdl-color--red-A700{background-color:#d50000 !important}.mdl-color-text--pink{color:#e91e63 !important}.mdl-color--pink{background-color:#e91e63 !important}.mdl-color-text--pink-50{color:#fce4ec !important}.mdl-color--pink-50{background-color:#fce4ec !important}.mdl-color-text--pink-100{color:#f8bbd0 !important}.mdl-color--pink-100{background-color:#f8bbd0 !important}.mdl-color-text--pink-200{color:#f48fb1 !important}.mdl-color--pink-200{background-color:#f48fb1 !important}.mdl-color-text--pink-300{color:#f06292 !important}.mdl-color--pink-300{background-color:#f06292 !important}.mdl-color-text--pink-400{color:#ec407a !important}.mdl-color--pink-400{background-color:#ec407a !important}.mdl-color-text--pink-500{color:#e91e63 !important}.mdl-color--pink-500{background-color:#e91e63 !important}.mdl-color-text--pink-600{color:#d81b60 !important}.mdl-color--pink-600{background-color:#d81b60 !important}.mdl-color-text--pink-700{color:#c2185b !important}.mdl-color--pink-700{background-color:#c2185b !important}.mdl-color-text--pink-800{color:#ad1457 !important}.mdl-color--pink-800{background-color:#ad1457 !important}.mdl-color-text--pink-900{color:#880e4f !important}.mdl-color--pink-900{background-color:#880e4f !important}.mdl-color-text--pink-A100{color:#ff80ab !important}.mdl-color--pink-A100{background-color:#ff80ab !important}.mdl-color-text--pink-A200{color:#ff4081 !important}.mdl-color--pink-A200{background-color:#ff4081 !important}.mdl-color-text--pink-A400{color:#f50057 !important}.mdl-color--pink-A400{background-color:#f50057 !important}.mdl-color-text--pink-A700{color:#c51162 !important}.mdl-color--pink-A700{background-color:#c51162 !important}.mdl-color-text--purple{color:#9c27b0 !important}.mdl-color--purple{background-color:#9c27b0 !important}.mdl-color-text--purple-50{color:#f3e5f5 !important}.mdl-color--purple-50{background-color:#f3e5f5 !important}.mdl-color-text--purple-100{color:#e1bee7 !important}.mdl-color--purple-100{background-color:#e1bee7 !important}.mdl-color-text--purple-200{color:#ce93d8 !important}.mdl-color--purple-200{background-color:#ce93d8 !important}.mdl-color-text--purple-300{color:#ba68c8 !important}.mdl-color--purple-300{background-color:#ba68c8 !important}.mdl-color-text--purple-400{color:#ab47bc !important}.mdl-color--purple-400{background-color:#ab47bc !important}.mdl-color-text--purple-500{color:#9c27b0 !important}.mdl-color--purple-500{background-color:#9c27b0 !important}.mdl-color-text--purple-600{color:#8e24aa !important}.mdl-color--purple-600{background-color:#8e24aa !important}.mdl-color-text--purple-700{color:#7b1fa2 !important}.mdl-color--purple-700{background-color:#7b1fa2 !important}.mdl-color-text--purple-800{color:#6a1b9a !important}.mdl-color--purple-800{background-color:#6a1b9a !important}.mdl-color-text--purple-900{color:#4a148c !important}.mdl-color--purple-900{background-color:#4a148c !important}.mdl-color-text--purple-A100{color:#ea80fc !important}.mdl-color--purple-A100{background-color:#ea80fc !important}.mdl-color-text--purple-A200{color:#e040fb !important}.mdl-color--purple-A200{background-color:#e040fb !important}.mdl-color-text--purple-A400{color:#d500f9 !important}.mdl-color--purple-A400{background-color:#d500f9 !important}.mdl-color-text--purple-A700{color:#a0f !important}.mdl-color--purple-A700{background-color:#a0f !important}.mdl-color-text--deep-purple{color:#673ab7 !important}.mdl-color--deep-purple{background-color:#673ab7 !important}.mdl-color-text--deep-purple-50{color:#ede7f6 !important}.mdl-color--deep-purple-50{background-color:#ede7f6 !important}.mdl-color-text--deep-purple-100{color:#d1c4e9 !important}.mdl-color--deep-purple-100{background-color:#d1c4e9 !important}.mdl-color-text--deep-purple-200{color:#b39ddb !important}.mdl-color--deep-purple-200{background-color:#b39ddb !important}.mdl-color-text--deep-purple-300{color:#9575cd !important}.mdl-color--deep-purple-300{background-color:#9575cd !important}.mdl-color-text--deep-purple-400{color:#7e57c2 !important}.mdl-color--deep-purple-400{background-color:#7e57c2 !important}.mdl-color-text--deep-purple-500{color:#673ab7 !important}.mdl-color--deep-purple-500{background-color:#673ab7 !important}.mdl-color-text--deep-purple-600{color:#5e35b1 !important}.mdl-color--deep-purple-600{background-color:#5e35b1 !important}.mdl-color-text--deep-purple-700{color:#512da8 !important}.mdl-color--deep-purple-700{background-color:#512da8 !important}.mdl-color-text--deep-purple-800{color:#4527a0 !important}.mdl-color--deep-purple-800{background-color:#4527a0 !important}.mdl-color-text--deep-purple-900{color:#311b92 !important}.mdl-color--deep-purple-900{background-color:#311b92 !important}.mdl-color-text--deep-purple-A100{color:#b388ff !important}.mdl-color--deep-purple-A100{background-color:#b388ff !important}.mdl-color-text--deep-purple-A200{color:#7c4dff !important}.mdl-color--deep-purple-A200{background-color:#7c4dff !important}.mdl-color-text--deep-purple-A400{color:#651fff !important}.mdl-color--deep-purple-A400{background-color:#651fff !important}.mdl-color-text--deep-purple-A700{color:#6200ea !important}.mdl-color--deep-purple-A700{background-color:#6200ea !important}.mdl-color-text--indigo{color:#3f51b5 !important}.mdl-color--indigo{background-color:#3f51b5 !important}.mdl-color-text--indigo-50{color:#e8eaf6 !important}.mdl-color--indigo-50{background-color:#e8eaf6 !important}.mdl-color-text--indigo-100{color:#c5cae9 !important}.mdl-color--indigo-100{background-color:#c5cae9 !important}.mdl-color-text--indigo-200{color:#9fa8da !important}.mdl-color--indigo-200{background-color:#9fa8da !important}.mdl-color-text--indigo-300{color:#7986cb !important}.mdl-color--indigo-300{background-color:#7986cb !important}.mdl-color-text--indigo-400{color:#5c6bc0 !important}.mdl-color--indigo-400{background-color:#5c6bc0 !important}.mdl-color-text--indigo-500{color:#3f51b5 !important}.mdl-color--indigo-500{background-color:#3f51b5 !important}.mdl-color-text--indigo-600{color:#3949ab !important}.mdl-color--indigo-600{background-color:#3949ab !important}.mdl-color-text--indigo-700{color:#303f9f !important}.mdl-color--indigo-700{background-color:#303f9f !important}.mdl-color-text--indigo-800{color:#283593 !important}.mdl-color--indigo-800{background-color:#283593 !important}.mdl-color-text--indigo-900{color:#1a237e !important}.mdl-color--indigo-900{background-color:#1a237e !important}.mdl-color-text--indigo-A100{color:#8c9eff !important}.mdl-color--indigo-A100{background-color:#8c9eff !important}.mdl-color-text--indigo-A200{color:#536dfe !important}.mdl-color--indigo-A200{background-color:#536dfe !important}.mdl-color-text--indigo-A400{color:#3d5afe !important}.mdl-color--indigo-A400{background-color:#3d5afe !important}.mdl-color-text--indigo-A700{color:#304ffe !important}.mdl-color--indigo-A700{background-color:#304ffe !important}.mdl-color-text--blue{color:#2196f3 !important}.mdl-color--blue{background-color:#2196f3 !important}.mdl-color-text--blue-50{color:#e3f2fd !important}.mdl-color--blue-50{background-color:#e3f2fd !important}.mdl-color-text--blue-100{color:#bbdefb !important}.mdl-color--blue-100{background-color:#bbdefb !important}.mdl-color-text--blue-200{color:#90caf9 !important}.mdl-color--blue-200{background-color:#90caf9 !important}.mdl-color-text--blue-300{color:#64b5f6 !important}.mdl-color--blue-300{background-color:#64b5f6 !important}.mdl-color-text--blue-400{color:#42a5f5 !important}.mdl-color--blue-400{background-color:#42a5f5 !important}.mdl-color-text--blue-500{color:#2196f3 !important}.mdl-color--blue-500{background-color:#2196f3 !important}.mdl-color-text--blue-600{color:#1e88e5 !important}.mdl-color--blue-600{background-color:#1e88e5 !important}.mdl-color-text--blue-700{color:#1976d2 !important}.mdl-color--blue-700{background-color:#1976d2 !important}.mdl-color-text--blue-800{color:#1565c0 !important}.mdl-color--blue-800{background-color:#1565c0 !important}.mdl-color-text--blue-900{color:#0d47a1 !important}.mdl-color--blue-900{background-color:#0d47a1 !important}.mdl-color-text--blue-A100{color:#82b1ff !important}.mdl-color--blue-A100{background-color:#82b1ff !important}.mdl-color-text--blue-A200{color:#448aff !important}.mdl-color--blue-A200{background-color:#448aff !important}.mdl-color-text--blue-A400{color:#2979ff !important}.mdl-color--blue-A400{background-color:#2979ff !important}.mdl-color-text--blue-A700{color:#2962ff !important}.mdl-color--blue-A700{background-color:#2962ff !important}.mdl-color-text--light-blue{color:#03a9f4 !important}.mdl-color--light-blue{background-color:#03a9f4 !important}.mdl-color-text--light-blue-50{color:#e1f5fe !important}.mdl-color--light-blue-50{background-color:#e1f5fe !important}.mdl-color-text--light-blue-100{color:#b3e5fc !important}.mdl-color--light-blue-100{background-color:#b3e5fc !important}.mdl-color-text--light-blue-200{color:#81d4fa !important}.mdl-color--light-blue-200{background-color:#81d4fa !important}.mdl-color-text--light-blue-300{color:#4fc3f7 !important}.mdl-color--light-blue-300{background-color:#4fc3f7 !important}.mdl-color-text--light-blue-400{color:#29b6f6 !important}.mdl-color--light-blue-400{background-color:#29b6f6 !important}.mdl-color-text--light-blue-500{color:#03a9f4 !important}.mdl-color--light-blue-500{background-color:#03a9f4 !important}.mdl-color-text--light-blue-600{color:#039be5 !important}.mdl-color--light-blue-600{background-color:#039be5 !important}.mdl-color-text--light-blue-700{color:#0288d1 !important}.mdl-color--light-blue-700{background-color:#0288d1 !important}.mdl-color-text--light-blue-800{color:#0277bd !important}.mdl-color--light-blue-800{background-color:#0277bd !important}.mdl-color-text--light-blue-900{color:#01579b !important}.mdl-color--light-blue-900{background-color:#01579b !important}.mdl-color-text--light-blue-A100{color:#80d8ff !important}.mdl-color--light-blue-A100{background-color:#80d8ff !important}.mdl-color-text--light-blue-A200{color:#40c4ff !important}.mdl-color--light-blue-A200{background-color:#40c4ff !important}.mdl-color-text--light-blue-A400{color:#00b0ff !important}.mdl-color--light-blue-A400{background-color:#00b0ff !important}.mdl-color-text--light-blue-A700{color:#0091ea !important}.mdl-color--light-blue-A700{background-color:#0091ea !important}.mdl-color-text--cyan{color:#00bcd4 !important}.mdl-color--cyan{background-color:#00bcd4 !important}.mdl-color-text--cyan-50{color:#e0f7fa !important}.mdl-color--cyan-50{background-color:#e0f7fa !important}.mdl-color-text--cyan-100{color:#b2ebf2 !important}.mdl-color--cyan-100{background-color:#b2ebf2 !important}.mdl-color-text--cyan-200{color:#80deea !important}.mdl-color--cyan-200{background-color:#80deea !important}.mdl-color-text--cyan-300{color:#4dd0e1 !important}.mdl-color--cyan-300{background-color:#4dd0e1 !important}.mdl-color-text--cyan-400{color:#26c6da !important}.mdl-color--cyan-400{background-color:#26c6da !important}.mdl-color-text--cyan-500{color:#00bcd4 !important}.mdl-color--cyan-500{background-color:#00bcd4 !important}.mdl-color-text--cyan-600{color:#00acc1 !important}.mdl-color--cyan-600{background-color:#00acc1 !important}.mdl-color-text--cyan-700{color:#0097a7 !important}.mdl-color--cyan-700{background-color:#0097a7 !important}.mdl-color-text--cyan-800{color:#00838f !important}.mdl-color--cyan-800{background-color:#00838f !important}.mdl-color-text--cyan-900{color:#006064 !important}.mdl-color--cyan-900{background-color:#006064 !important}.mdl-color-text--cyan-A100{color:#84ffff !important}.mdl-color--cyan-A100{background-color:#84ffff !important}.mdl-color-text--cyan-A200{color:#18ffff !important}.mdl-color--cyan-A200{background-color:#18ffff !important}.mdl-color-text--cyan-A400{color:#00e5ff !important}.mdl-color--cyan-A400{background-color:#00e5ff !important}.mdl-color-text--cyan-A700{color:#00b8d4 !important}.mdl-color--cyan-A700{background-color:#00b8d4 !important}.mdl-color-text--teal{color:#009688 !important}.mdl-color--teal{background-color:#009688 !important}.mdl-color-text--teal-50{color:#e0f2f1 !important}.mdl-color--teal-50{background-color:#e0f2f1 !important}.mdl-color-text--teal-100{color:#b2dfdb !important}.mdl-color--teal-100{background-color:#b2dfdb !important}.mdl-color-text--teal-200{color:#80cbc4 !important}.mdl-color--teal-200{background-color:#80cbc4 !important}.mdl-color-text--teal-300{color:#4db6ac !important}.mdl-color--teal-300{background-color:#4db6ac !important}.mdl-color-text--teal-400{color:#26a69a !important}.mdl-color--teal-400{background-color:#26a69a !important}.mdl-color-text--teal-500{color:#009688 !important}.mdl-color--teal-500{background-color:#009688 !important}.mdl-color-text--teal-600{color:#00897b !important}.mdl-color--teal-600{background-color:#00897b !important}.mdl-color-text--teal-700{color:#00796b !important}.mdl-color--teal-700{background-color:#00796b !important}.mdl-color-text--teal-800{color:#00695c !important}.mdl-color--teal-800{background-color:#00695c !important}.mdl-color-text--teal-900{color:#004d40 !important}.mdl-color--teal-900{background-color:#004d40 !important}.mdl-color-text--teal-A100{color:#a7ffeb !important}.mdl-color--teal-A100{background-color:#a7ffeb !important}.mdl-color-text--teal-A200{color:#64ffda !important}.mdl-color--teal-A200{background-color:#64ffda !important}.mdl-color-text--teal-A400{color:#1de9b6 !important}.mdl-color--teal-A400{background-color:#1de9b6 !important}.mdl-color-text--teal-A700{color:#00bfa5 !important}.mdl-color--teal-A700{background-color:#00bfa5 !important}.mdl-color-text--green{color:#4caf50 !important}.mdl-color--green{background-color:#4caf50 !important}.mdl-color-text--green-50{color:#e8f5e9 !important}.mdl-color--green-50{background-color:#e8f5e9 !important}.mdl-color-text--green-100{color:#c8e6c9 !important}.mdl-color--green-100{background-color:#c8e6c9 !important}.mdl-color-text--green-200{color:#a5d6a7 !important}.mdl-color--green-200{background-color:#a5d6a7 !important}.mdl-color-text--green-300{color:#81c784 !important}.mdl-color--green-300{background-color:#81c784 !important}.mdl-color-text--green-400{color:#66bb6a !important}.mdl-color--green-400{background-color:#66bb6a !important}.mdl-color-text--green-500{color:#4caf50 !important}.mdl-color--green-500{background-color:#4caf50 !important}.mdl-color-text--green-600{color:#43a047 !important}.mdl-color--green-600{background-color:#43a047 !important}.mdl-color-text--green-700{color:#388e3c !important}.mdl-color--green-700{background-color:#388e3c !important}.mdl-color-text--green-800{color:#2e7d32 !important}.mdl-color--green-800{background-color:#2e7d32 !important}.mdl-color-text--green-900{color:#1b5e20 !important}.mdl-color--green-900{background-color:#1b5e20 !important}.mdl-color-text--green-A100{color:#b9f6ca !important}.mdl-color--green-A100{background-color:#b9f6ca !important}.mdl-color-text--green-A200{color:#69f0ae !important}.mdl-color--green-A200{background-color:#69f0ae !important}.mdl-color-text--green-A400{color:#00e676 !important}.mdl-color--green-A400{background-color:#00e676 !important}.mdl-color-text--green-A700{color:#00c853 !important}.mdl-color--green-A700{background-color:#00c853 !important}.mdl-color-text--light-green{color:#8bc34a !important}.mdl-color--light-green{background-color:#8bc34a !important}.mdl-color-text--light-green-50{color:#f1f8e9 !important}.mdl-color--light-green-50{background-color:#f1f8e9 !important}.mdl-color-text--light-green-100{color:#dcedc8 !important}.mdl-color--light-green-100{background-color:#dcedc8 !important}.mdl-color-text--light-green-200{color:#c5e1a5 !important}.mdl-color--light-green-200{background-color:#c5e1a5 !important}.mdl-color-text--light-green-300{color:#aed581 !important}.mdl-color--light-green-300{background-color:#aed581 !important}.mdl-color-text--light-green-400{color:#9ccc65 !important}.mdl-color--light-green-400{background-color:#9ccc65 !important}.mdl-color-text--light-green-500{color:#8bc34a !important}.mdl-color--light-green-500{background-color:#8bc34a !important}.mdl-color-text--light-green-600{color:#7cb342 !important}.mdl-color--light-green-600{background-color:#7cb342 !important}.mdl-color-text--light-green-700{color:#689f38 !important}.mdl-color--light-green-700{background-color:#689f38 !important}.mdl-color-text--light-green-800{color:#558b2f !important}.mdl-color--light-green-800{background-color:#558b2f !important}.mdl-color-text--light-green-900{color:#33691e !important}.mdl-color--light-green-900{background-color:#33691e !important}.mdl-color-text--light-green-A100{color:#ccff90 !important}.mdl-color--light-green-A100{background-color:#ccff90 !important}.mdl-color-text--light-green-A200{color:#b2ff59 !important}.mdl-color--light-green-A200{background-color:#b2ff59 !important}.mdl-color-text--light-green-A400{color:#76ff03 !important}.mdl-color--light-green-A400{background-color:#76ff03 !important}.mdl-color-text--light-green-A700{color:#64dd17 !important}.mdl-color--light-green-A700{background-color:#64dd17 !important}.mdl-color-text--lime{color:#cddc39 !important}.mdl-color--lime{background-color:#cddc39 !important}.mdl-color-text--lime-50{color:#f9fbe7 !important}.mdl-color--lime-50{background-color:#f9fbe7 !important}.mdl-color-text--lime-100{color:#f0f4c3 !important}.mdl-color--lime-100{background-color:#f0f4c3 !important}.mdl-color-text--lime-200{color:#e6ee9c !important}.mdl-color--lime-200{background-color:#e6ee9c !important}.mdl-color-text--lime-300{color:#dce775 !important}.mdl-color--lime-300{background-color:#dce775 !important}.mdl-color-text--lime-400{color:#d4e157 !important}.mdl-color--lime-400{background-color:#d4e157 !important}.mdl-color-text--lime-500{color:#cddc39 !important}.mdl-color--lime-500{background-color:#cddc39 !important}.mdl-color-text--lime-600{color:#c0ca33 !important}.mdl-color--lime-600{background-color:#c0ca33 !important}.mdl-color-text--lime-700{color:#afb42b !important}.mdl-color--lime-700{background-color:#afb42b !important}.mdl-color-text--lime-800{color:#9e9d24 !important}.mdl-color--lime-800{background-color:#9e9d24 !important}.mdl-color-text--lime-900{color:#827717 !important}.mdl-color--lime-900{background-color:#827717 !important}.mdl-color-text--lime-A100{color:#f4ff81 !important}.mdl-color--lime-A100{background-color:#f4ff81 !important}.mdl-color-text--lime-A200{color:#eeff41 !important}.mdl-color--lime-A200{background-color:#eeff41 !important}.mdl-color-text--lime-A400{color:#c6ff00 !important}.mdl-color--lime-A400{background-color:#c6ff00 !important}.mdl-color-text--lime-A700{color:#aeea00 !important}.mdl-color--lime-A700{background-color:#aeea00 !important}.mdl-color-text--yellow{color:#ffeb3b !important}.mdl-color--yellow{background-color:#ffeb3b !important}.mdl-color-text--yellow-50{color:#fffde7 !important}.mdl-color--yellow-50{background-color:#fffde7 !important}.mdl-color-text--yellow-100{color:#fff9c4 !important}.mdl-color--yellow-100{background-color:#fff9c4 !important}.mdl-color-text--yellow-200{color:#fff59d !important}.mdl-color--yellow-200{background-color:#fff59d !important}.mdl-color-text--yellow-300{color:#fff176 !important}.mdl-color--yellow-300{background-color:#fff176 !important}.mdl-color-text--yellow-400{color:#ffee58 !important}.mdl-color--yellow-400{background-color:#ffee58 !important}.mdl-color-text--yellow-500{color:#ffeb3b !important}.mdl-color--yellow-500{background-color:#ffeb3b !important}.mdl-color-text--yellow-600{color:#fdd835 !important}.mdl-color--yellow-600{background-color:#fdd835 !important}.mdl-color-text--yellow-700{color:#fbc02d !important}.mdl-color--yellow-700{background-color:#fbc02d !important}.mdl-color-text--yellow-800{color:#f9a825 !important}.mdl-color--yellow-800{background-color:#f9a825 !important}.mdl-color-text--yellow-900{color:#f57f17 !important}.mdl-color--yellow-900{background-color:#f57f17 !important}.mdl-color-text--yellow-A100{color:#ffff8d !important}.mdl-color--yellow-A100{background-color:#ffff8d !important}.mdl-color-text--yellow-A200{color:#ff0 !important}.mdl-color--yellow-A200{background-color:#ff0 !important}.mdl-color-text--yellow-A400{color:#ffea00 !important}.mdl-color--yellow-A400{background-color:#ffea00 !important}.mdl-color-text--yellow-A700{color:#ffd600 !important}.mdl-color--yellow-A700{background-color:#ffd600 !important}.mdl-color-text--amber{color:#ffc107 !important}.mdl-color--amber{background-color:#ffc107 !important}.mdl-color-text--amber-50{color:#fff8e1 !important}.mdl-color--amber-50{background-color:#fff8e1 !important}.mdl-color-text--amber-100{color:#ffecb3 !important}.mdl-color--amber-100{background-color:#ffecb3 !important}.mdl-color-text--amber-200{color:#ffe082 !important}.mdl-color--amber-200{background-color:#ffe082 !important}.mdl-color-text--amber-300{color:#ffd54f !important}.mdl-color--amber-300{background-color:#ffd54f !important}.mdl-color-text--amber-400{color:#ffca28 !important}.mdl-color--amber-400{background-color:#ffca28 !important}.mdl-color-text--amber-500{color:#ffc107 !important}.mdl-color--amber-500{background-color:#ffc107 !important}.mdl-color-text--amber-600{color:#ffb300 !important}.mdl-color--amber-600{background-color:#ffb300 !important}.mdl-color-text--amber-700{color:#ffa000 !important}.mdl-color--amber-700{background-color:#ffa000 !important}.mdl-color-text--amber-800{color:#ff8f00 !important}.mdl-color--amber-800{background-color:#ff8f00 !important}.mdl-color-text--amber-900{color:#ff6f00 !important}.mdl-color--amber-900{background-color:#ff6f00 !important}.mdl-color-text--amber-A100{color:#ffe57f !important}.mdl-color--amber-A100{background-color:#ffe57f !important}.mdl-color-text--amber-A200{color:#ffd740 !important}.mdl-color--amber-A200{background-color:#ffd740 !important}.mdl-color-text--amber-A400{color:#ffc400 !important}.mdl-color--amber-A400{background-color:#ffc400 !important}.mdl-color-text--amber-A700{color:#ffab00 !important}.mdl-color--amber-A700{background-color:#ffab00 !important}.mdl-color-text--orange{color:#ff9800 !important}.mdl-color--orange{background-color:#ff9800 !important}.mdl-color-text--orange-50{color:#fff3e0 !important}.mdl-color--orange-50{background-color:#fff3e0 !important}.mdl-color-text--orange-100{color:#ffe0b2 !important}.mdl-color--orange-100{background-color:#ffe0b2 !important}.mdl-color-text--orange-200{color:#ffcc80 !important}.mdl-color--orange-200{background-color:#ffcc80 !important}.mdl-color-text--orange-300{color:#ffb74d !important}.mdl-color--orange-300{background-color:#ffb74d !important}.mdl-color-text--orange-400{color:#ffa726 !important}.mdl-color--orange-400{background-color:#ffa726 !important}.mdl-color-text--orange-500{color:#ff9800 !important}.mdl-color--orange-500{background-color:#ff9800 !important}.mdl-color-text--orange-600{color:#fb8c00 !important}.mdl-color--orange-600{background-color:#fb8c00 !important}.mdl-color-text--orange-700{color:#f57c00 !important}.mdl-color--orange-700{background-color:#f57c00 !important}.mdl-color-text--orange-800{color:#ef6c00 !important}.mdl-color--orange-800{background-color:#ef6c00 !important}.mdl-color-text--orange-900{color:#e65100 !important}.mdl-color--orange-900{background-color:#e65100 !important}.mdl-color-text--orange-A100{color:#ffd180 !important}.mdl-color--orange-A100{background-color:#ffd180 !important}.mdl-color-text--orange-A200{color:#ffab40 !important}.mdl-color--orange-A200{background-color:#ffab40 !important}.mdl-color-text--orange-A400{color:#ff9100 !important}.mdl-color--orange-A400{background-color:#ff9100 !important}.mdl-color-text--orange-A700{color:#ff6d00 !important}.mdl-color--orange-A700{background-color:#ff6d00 !important}.mdl-color-text--deep-orange{color:#ff5722 !important}.mdl-color--deep-orange{background-color:#ff5722 !important}.mdl-color-text--deep-orange-50{color:#fbe9e7 !important}.mdl-color--deep-orange-50{background-color:#fbe9e7 !important}.mdl-color-text--deep-orange-100{color:#ffccbc !important}.mdl-color--deep-orange-100{background-color:#ffccbc !important}.mdl-color-text--deep-orange-200{color:#ffab91 !important}.mdl-color--deep-orange-200{background-color:#ffab91 !important}.mdl-color-text--deep-orange-300{color:#ff8a65 !important}.mdl-color--deep-orange-300{background-color:#ff8a65 !important}.mdl-color-text--deep-orange-400{color:#ff7043 !important}.mdl-color--deep-orange-400{background-color:#ff7043 !important}.mdl-color-text--deep-orange-500{color:#ff5722 !important}.mdl-color--deep-orange-500{background-color:#ff5722 !important}.mdl-color-text--deep-orange-600{color:#f4511e !important}.mdl-color--deep-orange-600{background-color:#f4511e !important}.mdl-color-text--deep-orange-700{color:#e64a19 !important}.mdl-color--deep-orange-700{background-color:#e64a19 !important}.mdl-color-text--deep-orange-800{color:#d84315 !important}.mdl-color--deep-orange-800{background-color:#d84315 !important}.mdl-color-text--deep-orange-900{color:#bf360c !important}.mdl-color--deep-orange-900{background-color:#bf360c !important}.mdl-color-text--deep-orange-A100{color:#ff9e80 !important}.mdl-color--deep-orange-A100{background-color:#ff9e80 !important}.mdl-color-text--deep-orange-A200{color:#ff6e40 !important}.mdl-color--deep-orange-A200{background-color:#ff6e40 !important}.mdl-color-text--deep-orange-A400{color:#ff3d00 !important}.mdl-color--deep-orange-A400{background-color:#ff3d00 !important}.mdl-color-text--deep-orange-A700{color:#dd2c00 !important}.mdl-color--deep-orange-A700{background-color:#dd2c00 !important}.mdl-color-text--brown{color:#795548 !important}.mdl-color--brown{background-color:#795548 !important}.mdl-color-text--brown-50{color:#efebe9 !important}.mdl-color--brown-50{background-color:#efebe9 !important}.mdl-color-text--brown-100{color:#d7ccc8 !important}.mdl-color--brown-100{background-color:#d7ccc8 !important}.mdl-color-text--brown-200{color:#bcaaa4 !important}.mdl-color--brown-200{background-color:#bcaaa4 !important}.mdl-color-text--brown-300{color:#a1887f !important}.mdl-color--brown-300{background-color:#a1887f !important}.mdl-color-text--brown-400{color:#8d6e63 !important}.mdl-color--brown-400{background-color:#8d6e63 !important}.mdl-color-text--brown-500{color:#795548 !important}.mdl-color--brown-500{background-color:#795548 !important}.mdl-color-text--brown-600{color:#6d4c41 !important}.mdl-color--brown-600{background-color:#6d4c41 !important}.mdl-color-text--brown-700{color:#5d4037 !important}.mdl-color--brown-700{background-color:#5d4037 !important}.mdl-color-text--brown-800{color:#4e342e !important}.mdl-color--brown-800{background-color:#4e342e !important}.mdl-color-text--brown-900{color:#3e2723 !important}.mdl-color--brown-900{background-color:#3e2723 !important}.mdl-color-text--grey{color:#9e9e9e !important}.mdl-color--grey{background-color:#9e9e9e !important}.mdl-color-text--grey-50{color:#fafafa !important}.mdl-color--grey-50{background-color:#fafafa !important}.mdl-color-text--grey-100{color:#f5f5f5 !important}.mdl-color--grey-100{background-color:#f5f5f5 !important}.mdl-color-text--grey-200{color:#eee !important}.mdl-color--grey-200{background-color:#eee !important}.mdl-color-text--grey-300{color:#e0e0e0 !important}.mdl-color--grey-300{background-color:#e0e0e0 !important}.mdl-color-text--grey-400{color:#bdbdbd !important}.mdl-color--grey-400{background-color:#bdbdbd !important}.mdl-color-text--grey-500{color:#9e9e9e !important}.mdl-color--grey-500{background-color:#9e9e9e !important}.mdl-color-text--grey-600{color:#757575 !important}.mdl-color--grey-600{background-color:#757575 !important}.mdl-color-text--grey-700{color:#616161 !important}.mdl-color--grey-700{background-color:#616161 !important}.mdl-color-text--grey-800{color:#424242 !important}.mdl-color--grey-800{background-color:#424242 !important}.mdl-color-text--grey-900{color:#212121 !important}.mdl-color--grey-900{background-color:#212121 !important}.mdl-color-text--blue-grey{color:#607d8b !important}.mdl-color--blue-grey{background-color:#607d8b !important}.mdl-color-text--blue-grey-50{color:#eceff1 !important}.mdl-color--blue-grey-50{background-color:#eceff1 !important}.mdl-color-text--blue-grey-100{color:#cfd8dc !important}.mdl-color--blue-grey-100{background-color:#cfd8dc !important}.mdl-color-text--blue-grey-200{color:#b0bec5 !important}.mdl-color--blue-grey-200{background-color:#b0bec5 !important}.mdl-color-text--blue-grey-300{color:#90a4ae !important}.mdl-color--blue-grey-300{background-color:#90a4ae !important}.mdl-color-text--blue-grey-400{color:#78909c !important}.mdl-color--blue-grey-400{background-color:#78909c !important}.mdl-color-text--blue-grey-500{color:#607d8b !important}.mdl-color--blue-grey-500{background-color:#607d8b !important}.mdl-color-text--blue-grey-600{color:#546e7a !important}.mdl-color--blue-grey-600{background-color:#546e7a !important}.mdl-color-text--blue-grey-700{color:#455a64 !important}.mdl-color--blue-grey-700{background-color:#455a64 !important}.mdl-color-text--blue-grey-800{color:#37474f !important}.mdl-color--blue-grey-800{background-color:#37474f !important}.mdl-color-text--blue-grey-900{color:#263238 !important}.mdl-color--blue-grey-900{background-color:#263238 !important}.mdl-color--black{background-color:#000 !important}.mdl-color-text--black{color:#000 !important}.mdl-color--white{background-color:#fff !important}.mdl-color-text--white{color:#fff !important}.mdl-color--primary{background-color:rgb(255,152,0)!important}.mdl-color--primary-contrast{background-color:rgb(66,66,66)!important}.mdl-color--primary-dark{background-color:rgb(245,124,0)!important}.mdl-color--accent{background-color:rgb(68,138,255)!important}.mdl-color--accent-contrast{background-color:rgb(255,255,255)!important}.mdl-color-text--primary{color:rgb(255,152,0)!important}.mdl-color-text--primary-contrast{color:rgb(66,66,66)!important}.mdl-color-text--primary-dark{color:rgb(245,124,0)!important}.mdl-color-text--accent{color:rgb(68,138,255)!important}.mdl-color-text--accent-contrast{color:rgb(255,255,255)!important}.mdl-ripple{background:#000;border-radius:50%;height:50px;left:0;opacity:0;pointer-events:none;position:absolute;top:0;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:50px;overflow:hidden}.mdl-ripple.is-animating{transition:transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1);transition:transform .3s cubic-bezier(0,0,.2,1),width .3s cubic-bezier(0,0,.2,1),height .3s cubic-bezier(0,0,.2,1),opacity .6s cubic-bezier(0,0,.2,1),-webkit-transform .3s cubic-bezier(0,0,.2,1)}.mdl-ripple.is-visible{opacity:.3}.mdl-animation--default,.mdl-animation--fast-out-slow-in{transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-animation--linear-out-slow-in{transition-timing-function:cubic-bezier(0,0,.2,1)}.mdl-animation--fast-out-linear-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.mdl-badge{position:relative;white-space:nowrap;margin-right:24px}.mdl-badge:not([data-badge]){margin-right:auto}.mdl-badge[data-badge]:after{content:attr(data-badge);display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:absolute;top:-11px;right:-24px;font-family:"Roboto","Helvetica","Arial",sans-serif;font-weight:600;font-size:12px;width:22px;height:22px;border-radius:50%;background:rgb(68,138,255);color:rgb(255,255,255)}.mdl-button .mdl-badge[data-badge]:after{top:-10px;right:-5px}.mdl-badge.mdl-badge--no-background[data-badge]:after{color:rgb(68,138,255);background:rgba(255,255,255,.2);box-shadow:0 0 1px gray}.mdl-badge.mdl-badge--overlap{margin-right:10px}.mdl-badge.mdl-badge--overlap:after{right:-10px}.mdl-button{background:0 0;border:none;border-radius:2px;color:#000;position:relative;height:36px;margin:0;min-width:64px;padding:0 16px;display:inline-block;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;letter-spacing:0;overflow:hidden;will-change:box-shadow;transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);outline:none;cursor:pointer;text-decoration:none;text-align:center;line-height:36px;vertical-align:middle}.mdl-button::-moz-focus-inner{border:0}.mdl-button:hover{background-color:rgba(158,158,158,.2)}.mdl-button:focus:not(:active){background-color:rgba(0,0,0,.12)}.mdl-button:active{background-color:rgba(158,158,158,.4)}.mdl-button.mdl-button--colored{color:rgb(255,152,0)}.mdl-button.mdl-button--colored:focus:not(:active){background-color:rgba(0,0,0,.12)}input.mdl-button[type="submit"]{-webkit-appearance:none}.mdl-button--raised{background:rgba(158,158,158,.2);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-button--raised:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:rgba(158,158,158,.4)}.mdl-button--raised:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:rgba(158,158,158,.4)}.mdl-button--raised.mdl-button--colored{background:rgb(255,152,0);color:rgb(66,66,66)}.mdl-button--raised.mdl-button--colored:hover{background-color:rgb(255,152,0)}.mdl-button--raised.mdl-button--colored:active{background-color:rgb(255,152,0)}.mdl-button--raised.mdl-button--colored:focus:not(:active){background-color:rgb(255,152,0)}.mdl-button--raised.mdl-button--colored .mdl-ripple{background:rgb(66,66,66)}.mdl-button--fab{border-radius:50%;font-size:24px;height:56px;margin:auto;min-width:56px;width:56px;padding:0;overflow:hidden;background:rgba(158,158,158,.2);box-shadow:0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);position:relative;line-height:normal}.mdl-button--fab .material-icons{position:absolute;top:50%;left:50%;-webkit-transform:translate(-12px,-12px);transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--fab.mdl-button--mini-fab{height:40px;min-width:40px;width:40px}.mdl-button--fab .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button--fab:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:rgba(158,158,158,.4)}.mdl-button--fab:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:rgba(158,158,158,.4)}.mdl-button--fab.mdl-button--colored{background:rgb(68,138,255);color:rgb(255,255,255)}.mdl-button--fab.mdl-button--colored:hover{background-color:rgb(68,138,255)}.mdl-button--fab.mdl-button--colored:focus:not(:active){background-color:rgb(68,138,255)}.mdl-button--fab.mdl-button--colored:active{background-color:rgb(68,138,255)}.mdl-button--fab.mdl-button--colored .mdl-ripple{background:rgb(255,255,255)}.mdl-button--icon{border-radius:50%;font-size:24px;height:32px;margin-left:0;margin-right:0;min-width:32px;width:32px;padding:0;overflow:hidden;color:inherit;line-height:normal}.mdl-button--icon .material-icons{position:absolute;top:50%;left:50%;-webkit-transform:translate(-12px,-12px);transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--icon.mdl-button--mini-icon{height:24px;min-width:24px;width:24px}.mdl-button--icon.mdl-button--mini-icon .material-icons{top:0;left:0}.mdl-button--icon .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button__ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.mdl-button[disabled] .mdl-button__ripple-container .mdl-ripple,.mdl-button.mdl-button--disabled .mdl-button__ripple-container .mdl-ripple{background-color:transparent}.mdl-button--primary.mdl-button--primary{color:rgb(255,152,0)}.mdl-button--primary.mdl-button--primary .mdl-ripple{background:rgb(66,66,66)}.mdl-button--primary.mdl-button--primary.mdl-button--raised,.mdl-button--primary.mdl-button--primary.mdl-button--fab{color:rgb(66,66,66);background-color:rgb(255,152,0)}.mdl-button--accent.mdl-button--accent{color:rgb(68,138,255)}.mdl-button--accent.mdl-button--accent .mdl-ripple{background:rgb(255,255,255)}.mdl-button--accent.mdl-button--accent.mdl-button--raised,.mdl-button--accent.mdl-button--accent.mdl-button--fab{color:rgb(255,255,255);background-color:rgb(68,138,255)}.mdl-button[disabled][disabled],.mdl-button.mdl-button--disabled.mdl-button--disabled{color:rgba(0,0,0,.26);cursor:default;background-color:transparent}.mdl-button--fab[disabled][disabled],.mdl-button--fab.mdl-button--disabled.mdl-button--disabled{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26)}.mdl-button--raised[disabled][disabled],.mdl-button--raised.mdl-button--disabled.mdl-button--disabled{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26);box-shadow:none}.mdl-button--colored[disabled][disabled],.mdl-button--colored.mdl-button--disabled.mdl-button--disabled{color:rgba(0,0,0,.26)}.mdl-button .material-icons{vertical-align:middle}.mdl-card{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;font-size:16px;font-weight:400;min-height:200px;overflow:hidden;width:330px;z-index:1;position:relative;background:#fff;border-radius:2px;box-sizing:border-box}.mdl-card__media{background-color:rgb(68,138,255);background-repeat:repeat;background-position:50% 50%;background-size:cover;background-origin:padding-box;background-attachment:scroll;box-sizing:border-box}.mdl-card__title{-webkit-align-items:center;-ms-flex-align:center;align-items:center;color:#000;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:stretch;-ms-flex-pack:stretch;justify-content:stretch;line-height:normal;padding:16px;-webkit-perspective-origin:165px 56px;perspective-origin:165px 56px;-webkit-transform-origin:165px 56px;transform-origin:165px 56px;box-sizing:border-box}.mdl-card__title.mdl-card--border{border-bottom:1px solid rgba(0,0,0,.1)}.mdl-card__title-text{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;color:inherit;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:24px;font-weight:300;line-height:normal;overflow:hidden;-webkit-transform-origin:149px 48px;transform-origin:149px 48px;margin:0}.mdl-card__subtitle-text{font-size:14px;color:rgba(0,0,0,.54);margin:0}.mdl-card__supporting-text{color:rgba(0,0,0,.54);font-size:1rem;line-height:18px;overflow:hidden;padding:16px;width:90%}.mdl-card__supporting-text.mdl-card--border{border-bottom:1px solid rgba(0,0,0,.1)}.mdl-card__actions{font-size:16px;line-height:normal;width:100%;background-color:transparent;padding:8px;box-sizing:border-box}.mdl-card__actions.mdl-card--border{border-top:1px solid rgba(0,0,0,.1)}.mdl-card--expand{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.mdl-card__menu{position:absolute;right:16px;top:16px}.mdl-checkbox{position:relative;z-index:1;vertical-align:middle;display:inline-block;box-sizing:border-box;width:100%;height:24px;margin:0;padding:0}.mdl-checkbox.is-upgraded{padding-left:24px}.mdl-checkbox__input{line-height:24px}.mdl-checkbox.is-upgraded .mdl-checkbox__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-checkbox__box-outline{position:absolute;top:3px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;margin:0;cursor:pointer;overflow:hidden;border:2px solid rgba(0,0,0,.54);border-radius:2px;z-index:2}.mdl-checkbox.is-checked .mdl-checkbox__box-outline{border:2px solid rgb(255,152,0)}fieldset[disabled] .mdl-checkbox .mdl-checkbox__box-outline,.mdl-checkbox.is-disabled .mdl-checkbox__box-outline{border:2px solid rgba(0,0,0,.26);cursor:auto}.mdl-checkbox__focus-helper{position:absolute;top:3px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;border-radius:50%;background-color:transparent}.mdl-checkbox.is-focused .mdl-checkbox__focus-helper{box-shadow:0 0 0 8px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.mdl-checkbox.is-focused.is-checked .mdl-checkbox__focus-helper{box-shadow:0 0 0 8px rgba(255,152,0,.26);background-color:rgba(255,152,0,.26)}.mdl-checkbox__tick-outline{position:absolute;top:0;left:0;height:100%;width:100%;-webkit-mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8ZGVmcz4KICAgIDxjbGlwUGF0aCBpZD0iY2xpcCI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Ik0gMCwwIDAsMSAxLDEgMSwwIDAsMCB6IE0gMC44NTM0Mzc1LDAuMTY3MTg3NSAwLjk1OTY4NzUsMC4yNzMxMjUgMC40MjkzNzUsMC44MDM0Mzc1IDAuMzIzMTI1LDAuOTA5Njg3NSAwLjIxNzE4NzUsMC44MDM0Mzc1IDAuMDQwMzEyNSwwLjYyNjg3NSAwLjE0NjU2MjUsMC41MjA2MjUgMC4zMjMxMjUsMC42OTc1IDAuODUzNDM3NSwwLjE2NzE4NzUgeiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgICA8bWFzayBpZD0ibWFzayIgbWFza1VuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgbWFza0NvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0CiAgICAgd2lkdGg9IjEiCiAgICAgaGVpZ2h0PSIxIgogICAgIHg9IjAiCiAgICAgeT0iMCIKICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KPC9zdmc+Cg==");mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8ZGVmcz4KICAgIDxjbGlwUGF0aCBpZD0iY2xpcCI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Ik0gMCwwIDAsMSAxLDEgMSwwIDAsMCB6IE0gMC44NTM0Mzc1LDAuMTY3MTg3NSAwLjk1OTY4NzUsMC4yNzMxMjUgMC40MjkzNzUsMC44MDM0Mzc1IDAuMzIzMTI1LDAuOTA5Njg3NSAwLjIxNzE4NzUsMC44MDM0Mzc1IDAuMDQwMzEyNSwwLjYyNjg3NSAwLjE0NjU2MjUsMC41MjA2MjUgMC4zMjMxMjUsMC42OTc1IDAuODUzNDM3NSwwLjE2NzE4NzUgeiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgICA8bWFzayBpZD0ibWFzayIgbWFza1VuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgbWFza0NvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0CiAgICAgd2lkdGg9IjEiCiAgICAgaGVpZ2h0PSIxIgogICAgIHg9IjAiCiAgICAgeT0iMCIKICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KPC9zdmc+Cg==");background:0 0;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background}.mdl-checkbox.is-checked .mdl-checkbox__tick-outline{background:rgb(255,152,0)url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")}fieldset[disabled] .mdl-checkbox.is-checked .mdl-checkbox__tick-outline,.mdl-checkbox.is-checked.is-disabled .mdl-checkbox__tick-outline{background:rgba(0,0,0,.26)url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")}.mdl-checkbox__label{position:relative;cursor:pointer;font-size:16px;line-height:24px;margin:0}fieldset[disabled] .mdl-checkbox .mdl-checkbox__label,.mdl-checkbox.is-disabled .mdl-checkbox__label{color:rgba(0,0,0,.26);cursor:auto}.mdl-checkbox__ripple-container{position:absolute;z-index:2;top:-6px;left:-10px;box-sizing:border-box;width:36px;height:36px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-checkbox__ripple-container .mdl-ripple{background:rgb(255,152,0)}fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container,.mdl-checkbox.is-disabled .mdl-checkbox__ripple-container{cursor:auto}fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container .mdl-ripple,.mdl-checkbox.is-disabled .mdl-checkbox__ripple-container .mdl-ripple{background:0 0}.mdl-chip{height:32px;font-family:"Roboto","Helvetica","Arial",sans-serif;line-height:32px;padding:0 12px;border:0;border-radius:16px;background-color:#dedede;display:inline-block;color:rgba(0,0,0,.87);margin:2px 0;font-size:0;white-space:nowrap}.mdl-chip__text{font-size:13px;vertical-align:middle;display:inline-block}.mdl-chip__action{height:24px;width:24px;background:0 0;opacity:.54;cursor:pointer;padding:0;margin:0 0 0 4px;font-size:13px;text-decoration:none;color:rgba(0,0,0,.87);border:none;outline:none}.mdl-chip__action,.mdl-chip__contact{display:inline-block;vertical-align:middle;overflow:hidden;text-align:center}.mdl-chip__contact{height:32px;width:32px;border-radius:16px;margin-right:8px;font-size:18px;line-height:32px}.mdl-chip:focus{outline:0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-chip:active{background-color:#d6d6d6}.mdl-chip--deletable{padding-right:4px}.mdl-chip--contact{padding-left:0}.mdl-data-table{position:relative;border:1px solid rgba(0,0,0,.12);border-collapse:collapse;white-space:nowrap;font-size:13px;background-color:#fff}.mdl-data-table thead{padding-bottom:3px}.mdl-data-table thead .mdl-data-table__select{margin-top:0}.mdl-data-table tbody tr{position:relative;height:48px;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background-color}.mdl-data-table tbody tr.is-selected{background-color:#e0e0e0}.mdl-data-table tbody tr:hover{background-color:#eee}.mdl-data-table td{text-align:right}.mdl-data-table th{padding:0 18px 12px 18px;text-align:right}.mdl-data-table td:first-of-type,.mdl-data-table th:first-of-type{padding-left:24px}.mdl-data-table td:last-of-type,.mdl-data-table th:last-of-type{padding-right:24px}.mdl-data-table td{position:relative;height:48px;border-top:1px solid rgba(0,0,0,.12);border-bottom:1px solid rgba(0,0,0,.12);padding:12px 18px;box-sizing:border-box}.mdl-data-table td,.mdl-data-table td .mdl-data-table__select{vertical-align:middle}.mdl-data-table th{position:relative;vertical-align:bottom;text-overflow:ellipsis;font-weight:700;line-height:24px;letter-spacing:0;height:48px;font-size:12px;color:rgba(0,0,0,.54);padding-bottom:8px;box-sizing:border-box}.mdl-data-table th.mdl-data-table__header--sorted-ascending,.mdl-data-table th.mdl-data-table__header--sorted-descending{color:rgba(0,0,0,.87)}.mdl-data-table th.mdl-data-table__header--sorted-ascending:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:before{font-family:'Material Icons';font-weight:400;font-style:normal;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;word-wrap:normal;-moz-font-feature-settings:'liga';font-feature-settings:'liga';-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased;font-size:16px;content:"\e5d8";margin-right:5px;vertical-align:sub}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover{cursor:pointer}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover:before{color:rgba(0,0,0,.26)}.mdl-data-table th.mdl-data-table__header--sorted-descending:before{content:"\e5db"}.mdl-data-table__select{width:16px}.mdl-data-table__cell--non-numeric.mdl-data-table__cell--non-numeric{text-align:left}.mdl-dialog{border:none;box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2);width:280px}.mdl-dialog__title{padding:24px 24px 0;margin:0;font-size:2.5rem}.mdl-dialog__actions{padding:8px 8px 8px 24px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.mdl-dialog__actions>*{margin-right:8px;height:36px}.mdl-dialog__actions>*:first-child{margin-right:0}.mdl-dialog__actions--full-width{padding:0 0 8px}.mdl-dialog__actions--full-width>*{height:48px;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;padding-right:16px;margin-right:0;text-align:right}.mdl-dialog__content{padding:20px 24px 24px;color:rgba(0,0,0,.54)}.mdl-mega-footer{padding:16px 40px;color:#9e9e9e;background-color:#424242}.mdl-mega-footer--top-section:after,.mdl-mega-footer--middle-section:after,.mdl-mega-footer--bottom-section:after,.mdl-mega-footer__top-section:after,.mdl-mega-footer__middle-section:after,.mdl-mega-footer__bottom-section:after{content:'';display:block;clear:both}.mdl-mega-footer--left-section,.mdl-mega-footer__left-section,.mdl-mega-footer--right-section,.mdl-mega-footer__right-section{margin-bottom:16px}.mdl-mega-footer--right-section a,.mdl-mega-footer__right-section a{display:block;margin-bottom:16px;color:inherit;text-decoration:none}@media screen and (min-width:760px){.mdl-mega-footer--left-section,.mdl-mega-footer__left-section{float:left}.mdl-mega-footer--right-section,.mdl-mega-footer__right-section{float:right}.mdl-mega-footer--right-section a,.mdl-mega-footer__right-section a{display:inline-block;margin-left:16px;line-height:36px;vertical-align:middle}}.mdl-mega-footer--social-btn,.mdl-mega-footer__social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.mdl-mega-footer--drop-down-section,.mdl-mega-footer__drop-down-section{display:block;position:relative}@media screen and (min-width:760px){.mdl-mega-footer--drop-down-section,.mdl-mega-footer__drop-down-section{width:33%}.mdl-mega-footer--drop-down-section:nth-child(1),.mdl-mega-footer--drop-down-section:nth-child(2),.mdl-mega-footer__drop-down-section:nth-child(1),.mdl-mega-footer__drop-down-section:nth-child(2){float:left}.mdl-mega-footer--drop-down-section:nth-child(3),.mdl-mega-footer__drop-down-section:nth-child(3){float:right}.mdl-mega-footer--drop-down-section:nth-child(3):after,.mdl-mega-footer__drop-down-section:nth-child(3):after{clear:right}.mdl-mega-footer--drop-down-section:nth-child(4),.mdl-mega-footer__drop-down-section:nth-child(4){clear:right;float:right}.mdl-mega-footer--middle-section:after,.mdl-mega-footer__middle-section:after{content:'';display:block;clear:both}.mdl-mega-footer--bottom-section,.mdl-mega-footer__bottom-section{padding-top:0}}@media screen and (min-width:1024px){.mdl-mega-footer--drop-down-section,.mdl-mega-footer--drop-down-section:nth-child(3),.mdl-mega-footer--drop-down-section:nth-child(4),.mdl-mega-footer__drop-down-section,.mdl-mega-footer__drop-down-section:nth-child(3),.mdl-mega-footer__drop-down-section:nth-child(4){width:24%;float:left}}.mdl-mega-footer--heading-checkbox,.mdl-mega-footer__heading-checkbox{position:absolute;width:100%;height:55.8px;padding:32px;margin:-16px 0 0;cursor:pointer;z-index:1;opacity:0}.mdl-mega-footer--heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer__heading:after{font-family:'Material Icons';content:'\E5CE'}.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list{display:none}.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading:after{font-family:'Material Icons';content:'\E5CF'}.mdl-mega-footer--heading,.mdl-mega-footer__heading{position:relative;width:100%;padding-right:39.8px;margin-bottom:16px;box-sizing:border-box;font-size:14px;line-height:23.8px;font-weight:500;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;color:#e0e0e0}.mdl-mega-footer--heading:after,.mdl-mega-footer__heading:after{content:'';position:absolute;top:0;right:0;display:block;width:23.8px;height:23.8px;background-size:cover}.mdl-mega-footer--link-list,.mdl-mega-footer__link-list{list-style:none;padding:0;margin:0 0 32px}.mdl-mega-footer--link-list:after,.mdl-mega-footer__link-list:after{clear:both;display:block;content:''}.mdl-mega-footer--link-list li,.mdl-mega-footer__link-list li{font-size:14px;font-weight:400;letter-spacing:0;line-height:20px}.mdl-mega-footer--link-list a,.mdl-mega-footer__link-list a{color:inherit;text-decoration:none;white-space:nowrap}@media screen and (min-width:760px){.mdl-mega-footer--heading-checkbox,.mdl-mega-footer__heading-checkbox{display:none}.mdl-mega-footer--heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox+.mdl-mega-footer__heading:after{content:''}.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer--link-list,.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list{display:block}.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading:after,.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading:after{content:''}}.mdl-mega-footer--bottom-section,.mdl-mega-footer__bottom-section{padding-top:16px;margin-bottom:16px}.mdl-logo{margin-bottom:16px;color:#fff}.mdl-mega-footer--bottom-section .mdl-mega-footer--link-list li,.mdl-mega-footer__bottom-section .mdl-mega-footer__link-list li{float:left;margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.mdl-logo{float:left;margin-bottom:0;margin-right:16px}}.mdl-mini-footer{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:32px 16px;color:#9e9e9e;background-color:#424242}.mdl-mini-footer:after{content:'';display:block}.mdl-mini-footer .mdl-logo{line-height:36px}.mdl-mini-footer--link-list,.mdl-mini-footer__link-list{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap;list-style:none;margin:0;padding:0}.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li{margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li{line-height:36px}}.mdl-mini-footer--link-list a,.mdl-mini-footer__link-list a{color:inherit;text-decoration:none;white-space:nowrap}.mdl-mini-footer--left-section,.mdl-mini-footer__left-section{display:inline-block;-webkit-order:0;-ms-flex-order:0;order:0}.mdl-mini-footer--right-section,.mdl-mini-footer__right-section{display:inline-block;-webkit-order:1;-ms-flex-order:1;order:1}.mdl-mini-footer--social-btn,.mdl-mini-footer__social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.mdl-icon-toggle{position:relative;z-index:1;vertical-align:middle;display:inline-block;height:32px;margin:0;padding:0}.mdl-icon-toggle__input{line-height:32px}.mdl-icon-toggle.is-upgraded .mdl-icon-toggle__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-icon-toggle__label{display:inline-block;position:relative;cursor:pointer;height:32px;width:32px;min-width:32px;color:#616161;border-radius:50%;padding:0;margin-left:0;margin-right:0;text-align:center;background-color:transparent;will-change:background-color;transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.mdl-icon-toggle__label.material-icons{line-height:32px;font-size:24px}.mdl-icon-toggle.is-checked .mdl-icon-toggle__label{color:rgb(255,152,0)}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__label{color:rgba(0,0,0,.26);cursor:auto;transition:none}.mdl-icon-toggle.is-focused .mdl-icon-toggle__label{background-color:rgba(0,0,0,.12)}.mdl-icon-toggle.is-focused.is-checked .mdl-icon-toggle__label{background-color:rgba(255,152,0,.26)}.mdl-icon-toggle__ripple-container{position:absolute;z-index:2;top:-2px;left:-2px;box-sizing:border-box;width:36px;height:36px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-icon-toggle__ripple-container .mdl-ripple{background:#616161}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container{cursor:auto}.mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container .mdl-ripple{background:0 0}.mdl-list{display:block;padding:8px 0;list-style:none}.mdl-list__item{font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:16px;font-weight:400;letter-spacing:.04em;line-height:1;min-height:48px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;padding:16px;cursor:default;color:rgba(0,0,0,.87);overflow:hidden}.mdl-list__item,.mdl-list__item .mdl-list__item-primary-content{box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.mdl-list__item .mdl-list__item-primary-content{-webkit-order:0;-ms-flex-order:0;order:0;-webkit-flex-grow:2;-ms-flex-positive:2;flex-grow:2;text-decoration:none}.mdl-list__item .mdl-list__item-primary-content .mdl-list__item-icon{margin-right:32px}.mdl-list__item .mdl-list__item-primary-content .mdl-list__item-avatar{margin-right:16px}.mdl-list__item .mdl-list__item-secondary-content{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:column;-ms-flex-flow:column;flex-flow:column;-webkit-align-items:flex-end;-ms-flex-align:end;align-items:flex-end;margin-left:16px}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-secondary-action label{display:inline}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-secondary-info{font-size:12px;font-weight:400;line-height:1;letter-spacing:0;color:rgba(0,0,0,.54)}.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-sub-header{padding:0 0 0 16px}.mdl-list__item-icon,.mdl-list__item-icon.material-icons{height:24px;width:24px;font-size:24px;box-sizing:border-box;color:#757575}.mdl-list__item-avatar,.mdl-list__item-avatar.material-icons{height:40px;width:40px;box-sizing:border-box;border-radius:50%;background-color:#757575;font-size:40px;color:#fff}.mdl-list__item--two-line{height:72px}.mdl-list__item--two-line .mdl-list__item-primary-content{height:36px;line-height:20px;display:block}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-avatar{float:left}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-icon{float:left;margin-top:6px}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-secondary-content{height:36px}.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-sub-title{font-size:14px;font-weight:400;letter-spacing:0;line-height:18px;color:rgba(0,0,0,.54);display:block;padding:0}.mdl-list__item--three-line{height:88px}.mdl-list__item--three-line .mdl-list__item-primary-content{height:52px;line-height:20px;display:block}.mdl-list__item--three-line .mdl-list__item-primary-content .mdl-list__item-avatar,.mdl-list__item--three-line .mdl-list__item-primary-content .mdl-list__item-icon{float:left}.mdl-list__item--three-line .mdl-list__item-secondary-content{height:52px}.mdl-list__item--three-line .mdl-list__item-text-body{font-size:14px;font-weight:400;letter-spacing:0;line-height:18px;height:52px;color:rgba(0,0,0,.54);display:block;padding:0}.mdl-menu__container{display:block;margin:0;padding:0;border:none;position:absolute;overflow:visible;height:0;width:0;visibility:hidden;z-index:-1}.mdl-menu__container.is-visible,.mdl-menu__container.is-animating{z-index:999;visibility:visible}.mdl-menu__outline{display:block;background:#fff;margin:0;padding:0;border:none;border-radius:2px;position:absolute;top:0;left:0;overflow:hidden;opacity:0;-webkit-transform:scale(0);transform:scale(0);-webkit-transform-origin:0 0;transform-origin:0 0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);will-change:transform;transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1);transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1),-webkit-transform .3s cubic-bezier(.4,0,.2,1);z-index:-1}.mdl-menu__container.is-visible .mdl-menu__outline{opacity:1;-webkit-transform:scale(1);transform:scale(1);z-index:999}.mdl-menu__outline.mdl-menu--bottom-right{-webkit-transform-origin:100% 0;transform-origin:100% 0}.mdl-menu__outline.mdl-menu--top-left{-webkit-transform-origin:0 100%;transform-origin:0 100%}.mdl-menu__outline.mdl-menu--top-right{-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.mdl-menu{position:absolute;list-style:none;top:0;left:0;height:auto;width:auto;min-width:124px;padding:8px 0;margin:0;opacity:0;clip:rect(0 0 0 0);z-index:-1}.mdl-menu__container.is-visible .mdl-menu{opacity:1;z-index:999}.mdl-menu.is-animating{transition:opacity .2s cubic-bezier(.4,0,.2,1),clip .3s cubic-bezier(.4,0,.2,1)}.mdl-menu.mdl-menu--bottom-right{left:auto;right:0}.mdl-menu.mdl-menu--top-left{top:auto;bottom:0}.mdl-menu.mdl-menu--top-right{top:auto;left:auto;bottom:0;right:0}.mdl-menu.mdl-menu--unaligned{top:auto;left:auto}.mdl-menu__item{display:block;border:none;color:rgba(0,0,0,.87);background-color:transparent;text-align:left;margin:0;padding:0 16px;outline-color:#bdbdbd;position:relative;overflow:hidden;font-size:14px;font-weight:400;letter-spacing:0;text-decoration:none;cursor:pointer;height:48px;line-height:48px;white-space:nowrap;opacity:0;transition:opacity .2s cubic-bezier(.4,0,.2,1);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-menu__container.is-visible .mdl-menu__item{opacity:1}.mdl-menu__item::-moz-focus-inner{border:0}.mdl-menu__item--full-bleed-divider{border-bottom:1px solid rgba(0,0,0,.12)}.mdl-menu__item[disabled],.mdl-menu__item[data-mdl-disabled]{color:#bdbdbd;background-color:transparent;cursor:auto}.mdl-menu__item[disabled]:hover,.mdl-menu__item[data-mdl-disabled]:hover{background-color:transparent}.mdl-menu__item[disabled]:focus,.mdl-menu__item[data-mdl-disabled]:focus{background-color:transparent}.mdl-menu__item[disabled] .mdl-ripple,.mdl-menu__item[data-mdl-disabled] .mdl-ripple{background:0 0}.mdl-menu__item:hover{background-color:#eee}.mdl-menu__item:focus{outline:none;background-color:#eee}.mdl-menu__item:active{background-color:#e0e0e0}.mdl-menu__item--ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.mdl-progress{display:block;position:relative;height:4px;width:500px;max-width:100%}.mdl-progress>.bar{display:block;position:absolute;top:0;bottom:0;width:0%;transition:width .2s cubic-bezier(.4,0,.2,1)}.mdl-progress>.progressbar{background-color:rgb(255,152,0);z-index:1;left:0}.mdl-progress>.bufferbar{background-image:linear-gradient(to right,rgba(66,66,66,.7),rgba(66,66,66,.7)),linear-gradient(to right,rgb(255,152,0),rgb(255,152,0));z-index:0;left:0}.mdl-progress>.auxbar{right:0}@supports (-webkit-appearance:none){.mdl-progress:not(.mdl-progress--indeterminate):not(.mdl-progress--indeterminate)>.auxbar,.mdl-progress:not(.mdl-progress__indeterminate):not(.mdl-progress__indeterminate)>.auxbar{background-image:linear-gradient(to right,rgba(66,66,66,.7),rgba(66,66,66,.7)),linear-gradient(to right,rgb(255,152,0),rgb(255,152,0));-webkit-mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyIiBoZWlnaHQ9IjQiIHZpZXdQb3J0PSIwIDAgMTIgNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxlbGxpcHNlIGN4PSIyIiBjeT0iMiIgcng9IjIiIHJ5PSIyIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogIDwvZWxsaXBzZT4KICA8ZWxsaXBzZSBjeD0iMTQiIGN5PSIyIiByeD0iMiIgcnk9IjIiIGNsYXNzPSJsb2FkZXIiPgogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICA8L2VsbGlwc2U+Cjwvc3ZnPgo=");mask:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyIiBoZWlnaHQ9IjQiIHZpZXdQb3J0PSIwIDAgMTIgNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxlbGxpcHNlIGN4PSIyIiBjeT0iMiIgcng9IjIiIHJ5PSIyIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogIDwvZWxsaXBzZT4KICA8ZWxsaXBzZSBjeD0iMTQiIGN5PSIyIiByeD0iMiIgcnk9IjIiIGNsYXNzPSJsb2FkZXIiPgogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICA8L2VsbGlwc2U+Cjwvc3ZnPgo=")}}.mdl-progress:not(.mdl-progress--indeterminate)>.auxbar,.mdl-progress:not(.mdl-progress__indeterminate)>.auxbar{background-image:linear-gradient(to right,rgba(66,66,66,.9),rgba(66,66,66,.9)),linear-gradient(to right,rgb(255,152,0),rgb(255,152,0))}.mdl-progress.mdl-progress--indeterminate>.bar1,.mdl-progress.mdl-progress__indeterminate>.bar1{-webkit-animation-name:indeterminate1;animation-name:indeterminate1}.mdl-progress.mdl-progress--indeterminate>.bar1,.mdl-progress.mdl-progress__indeterminate>.bar1,.mdl-progress.mdl-progress--indeterminate>.bar3,.mdl-progress.mdl-progress__indeterminate>.bar3{background-color:rgb(255,152,0);-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:linear;animation-timing-function:linear}.mdl-progress.mdl-progress--indeterminate>.bar3,.mdl-progress.mdl-progress__indeterminate>.bar3{background-image:none;-webkit-animation-name:indeterminate2;animation-name:indeterminate2}@-webkit-keyframes indeterminate1{0%{left:0%;width:0%}50%{left:25%;width:75%}75%{left:100%;width:0%}}@keyframes indeterminate1{0%{left:0%;width:0%}50%{left:25%;width:75%}75%{left:100%;width:0%}}@-webkit-keyframes indeterminate2{0%,50%{left:0%;width:0%}75%{left:0%;width:25%}100%{left:100%;width:0%}}@keyframes indeterminate2{0%,50%{left:0%;width:0%}75%{left:0%;width:25%}100%{left:100%;width:0%}}.mdl-navigation{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;box-sizing:border-box}.mdl-navigation__link{color:#424242;text-decoration:none;margin:0;font-size:14px;font-weight:400;line-height:24px;letter-spacing:0;opacity:.87}.mdl-navigation__link .material-icons{vertical-align:middle}.mdl-layout{width:100%;height:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow-y:auto;overflow-x:hidden;position:relative;-webkit-overflow-scrolling:touch}.mdl-layout.is-small-screen .mdl-layout--large-screen-only{display:none}.mdl-layout:not(.is-small-screen) .mdl-layout--small-screen-only{display:none}.mdl-layout__container{position:absolute;width:100%;height:100%}.mdl-layout__title,.mdl-layout-title{display:block;position:relative;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:20px;line-height:1;letter-spacing:.02em;font-weight:400;box-sizing:border-box}.mdl-layout-spacer{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.mdl-layout__drawer{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;width:240px;height:100%;max-height:100%;position:absolute;top:0;left:0;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);box-sizing:border-box;border-right:1px solid #e0e0e0;background:#fafafa;-webkit-transform:translateX(-250px);transform:translateX(-250px);-webkit-transform-style:preserve-3d;transform-style:preserve-3d;will-change:transform;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:transform;transition-property:transform,-webkit-transform;color:#424242;overflow:visible;overflow-y:auto;z-index:5}.mdl-layout__drawer.is-visible{-webkit-transform:translateX(0);transform:translateX(0)}.mdl-layout__drawer.is-visible~.mdl-layout__content.mdl-layout__content{overflow:hidden}.mdl-layout__drawer>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.mdl-layout__drawer>.mdl-layout__title,.mdl-layout__drawer>.mdl-layout-title{line-height:64px;padding-left:40px}@media screen and (max-width:1024px){.mdl-layout__drawer>.mdl-layout__title,.mdl-layout__drawer>.mdl-layout-title{line-height:56px;padding-left:16px}}.mdl-layout__drawer .mdl-navigation{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;padding-top:16px}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link{display:block;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;padding:16px 40px;margin:0;color:#757575}@media screen and (max-width:1024px){.mdl-layout__drawer .mdl-navigation .mdl-navigation__link{padding:16px}}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link:hover{background-color:#e0e0e0}.mdl-layout__drawer .mdl-navigation .mdl-navigation__link--current{background-color:#e0e0e0;color:#000}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__drawer{-webkit-transform:translateX(0);transform:translateX(0)}}.mdl-layout__drawer-button{display:block;position:absolute;height:48px;width:48px;border:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden;text-align:center;cursor:pointer;font-size:26px;line-height:56px;font-family:Helvetica,Arial,sans-serif;margin:8px 12px;top:0;left:0;color:rgb(66,66,66);z-index:4}.mdl-layout__header .mdl-layout__drawer-button{position:absolute;color:rgb(66,66,66);background-color:inherit}@media screen and (max-width:1024px){.mdl-layout__header .mdl-layout__drawer-button{margin:4px}}@media screen and (max-width:1024px){.mdl-layout__drawer-button{margin:4px;color:rgba(0,0,0,.5)}}@media screen and (min-width:1025px){.mdl-layout__drawer-button{line-height:54px}.mdl-layout--no-desktop-drawer-button .mdl-layout__drawer-button,.mdl-layout--fixed-drawer>.mdl-layout__drawer-button,.mdl-layout--no-drawer-button .mdl-layout__drawer-button{display:none}}.mdl-layout__header{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;box-sizing:border-box;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;width:100%;margin:0;padding:0;border:none;min-height:64px;max-height:1000px;z-index:3;background-color:rgb(255,152,0);color:rgb(66,66,66);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:max-height,box-shadow}@media screen and (max-width:1024px){.mdl-layout__header{min-height:56px}}.mdl-layout--fixed-drawer.is-upgraded:not(.is-small-screen)>.mdl-layout__header{margin-left:240px;width:calc(100% - 240px)}@media screen and (min-width:1025px){.mdl-layout--fixed-drawer>.mdl-layout__header .mdl-layout__header-row{padding-left:40px}}.mdl-layout__header>.mdl-layout-icon{position:absolute;left:40px;top:16px;height:32px;width:32px;overflow:hidden;z-index:3;display:block}@media screen and (max-width:1024px){.mdl-layout__header>.mdl-layout-icon{left:16px;top:12px}}.mdl-layout.has-drawer .mdl-layout__header>.mdl-layout-icon{display:none}.mdl-layout__header.is-compact{max-height:64px}@media screen and (max-width:1024px){.mdl-layout__header.is-compact{max-height:56px}}.mdl-layout__header.is-compact.has-tabs{height:112px}@media screen and (max-width:1024px){.mdl-layout__header.is-compact.has-tabs{min-height:104px}}@media screen and (max-width:1024px){.mdl-layout__header{display:none}.mdl-layout--fixed-header>.mdl-layout__header{display:-webkit-flex;display:-ms-flexbox;display:flex}}.mdl-layout__header--transparent.mdl-layout__header--transparent{background-color:transparent;box-shadow:none}.mdl-layout__header--seamed,.mdl-layout__header--scroll{box-shadow:none}.mdl-layout__header--waterfall{box-shadow:none;overflow:hidden}.mdl-layout__header--waterfall.is-casting-shadow{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-layout__header--waterfall.mdl-layout__header--waterfall-hide-top{-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end}.mdl-layout__header-row{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;box-sizing:border-box;-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:64px;margin:0;padding:0 40px 0 80px}.mdl-layout--no-drawer-button .mdl-layout__header-row{padding-left:40px}@media screen and (min-width:1025px){.mdl-layout--no-desktop-drawer-button .mdl-layout__header-row{padding-left:40px}}@media screen and (max-width:1024px){.mdl-layout__header-row{height:56px;padding:0 16px 0 72px}.mdl-layout--no-drawer-button .mdl-layout__header-row{padding-left:16px}}.mdl-layout__header-row>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.mdl-layout__header--scroll .mdl-layout__header-row{width:100%}.mdl-layout__header-row .mdl-navigation{margin:0;padding:0;height:64px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-ms-flex-align:center;align-items:center}@media screen and (max-width:1024px){.mdl-layout__header-row .mdl-navigation{height:56px}}.mdl-layout__header-row .mdl-navigation__link{display:block;color:rgb(66,66,66);line-height:64px;padding:0 24px}@media screen and (max-width:1024px){.mdl-layout__header-row .mdl-navigation__link{line-height:56px;padding:0 16px}}.mdl-layout__obfuscator{background-color:transparent;position:absolute;top:0;left:0;height:100%;width:100%;z-index:4;visibility:hidden;transition-property:background-color;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-layout__obfuscator.is-visible{background-color:rgba(0,0,0,.5);visibility:visible}@supports (pointer-events:auto){.mdl-layout__obfuscator{background-color:rgba(0,0,0,.5);opacity:0;transition-property:opacity;visibility:visible;pointer-events:none}.mdl-layout__obfuscator.is-visible{pointer-events:auto;opacity:1}}.mdl-layout__content{-ms-flex:0 1 auto;position:relative;display:inline-block;overflow-y:auto;overflow-x:hidden;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;z-index:1;-webkit-overflow-scrolling:touch}.mdl-layout--fixed-drawer>.mdl-layout__content{margin-left:240px}.mdl-layout__container.has-scrolling-header .mdl-layout__content{overflow:visible}@media screen and (max-width:1024px){.mdl-layout--fixed-drawer>.mdl-layout__content{margin-left:0}.mdl-layout__container.has-scrolling-header .mdl-layout__content{overflow-y:auto;overflow-x:hidden}}.mdl-layout__tab-bar{height:96px;margin:0;width:calc(100% - 112px);padding:0 0 0 56px;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:rgb(255,152,0);overflow-y:hidden;overflow-x:scroll}.mdl-layout__tab-bar::-webkit-scrollbar{display:none}.mdl-layout--no-drawer-button .mdl-layout__tab-bar{padding-left:16px;width:calc(100% - 32px)}@media screen and (min-width:1025px){.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar{padding-left:16px;width:calc(100% - 32px)}}@media screen and (max-width:1024px){.mdl-layout__tab-bar{width:calc(100% - 60px);padding:0 0 0 60px}.mdl-layout--no-drawer-button .mdl-layout__tab-bar{width:calc(100% - 8px);padding-left:4px}}.mdl-layout--fixed-tabs .mdl-layout__tab-bar{padding:0;overflow:hidden;width:100%}.mdl-layout__tab-bar-container{position:relative;height:48px;width:100%;border:none;margin:0;z-index:2;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;overflow:hidden}.mdl-layout__container>.mdl-layout__tab-bar-container{position:absolute;top:0;left:0}.mdl-layout__tab-bar-button{display:inline-block;position:absolute;top:0;height:48px;width:56px;z-index:4;text-align:center;background-color:rgb(255,152,0);color:transparent;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar-button,.mdl-layout--no-drawer-button .mdl-layout__tab-bar-button{width:16px}.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar-button .material-icons,.mdl-layout--no-drawer-button .mdl-layout__tab-bar-button .material-icons{position:relative;left:-4px}@media screen and (max-width:1024px){.mdl-layout__tab-bar-button{width:60px}}.mdl-layout--fixed-tabs .mdl-layout__tab-bar-button{display:none}.mdl-layout__tab-bar-button .material-icons{line-height:48px}.mdl-layout__tab-bar-button.is-active{color:rgb(66,66,66)}.mdl-layout__tab-bar-left-button{left:0}.mdl-layout__tab-bar-right-button{right:0}.mdl-layout__tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;text-decoration:none;height:48px;line-height:48px;text-align:center;font-weight:500;font-size:14px;text-transform:uppercase;color:rgba(66,66,66,.6);overflow:hidden}@media screen and (max-width:1024px){.mdl-layout__tab{padding:0 12px}}.mdl-layout--fixed-tabs .mdl-layout__tab{float:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0}.mdl-layout.is-upgraded .mdl-layout__tab.is-active{color:rgb(66,66,66)}.mdl-layout.is-upgraded .mdl-layout__tab.is-active::after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:rgb(68,138,255);-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;transition:all 1s cubic-bezier(.4,0,1,1)}.mdl-layout__tab .mdl-layout__tab-ripple-container{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.mdl-layout__tab .mdl-layout__tab-ripple-container .mdl-ripple{background-color:rgb(66,66,66)}.mdl-layout__tab-panel{display:block}.mdl-layout.is-upgraded .mdl-layout__tab-panel{display:none}.mdl-layout.is-upgraded .mdl-layout__tab-panel.is-active{display:block}.mdl-radio{position:relative;font-size:16px;line-height:24px;display:inline-block;vertical-align:middle;box-sizing:border-box;height:24px;margin:0;padding-left:0}.mdl-radio.is-upgraded{padding-left:24px}.mdl-radio__button{line-height:24px}.mdl-radio.is-upgraded .mdl-radio__button{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-radio__outer-circle{position:absolute;top:4px;left:0;display:inline-block;box-sizing:border-box;width:16px;height:16px;margin:0;cursor:pointer;border:2px solid rgba(0,0,0,.54);border-radius:50%;z-index:2}.mdl-radio.is-checked .mdl-radio__outer-circle{border:2px solid rgb(255,152,0)}.mdl-radio__outer-circle fieldset[disabled] .mdl-radio,.mdl-radio.is-disabled .mdl-radio__outer-circle{border:2px solid rgba(0,0,0,.26);cursor:auto}.mdl-radio__inner-circle{position:absolute;z-index:1;margin:0;top:8px;left:4px;box-sizing:border-box;width:8px;height:8px;cursor:pointer;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:transform;transition-property:transform,-webkit-transform;-webkit-transform:scale(0,0);transform:scale(0,0);border-radius:50%;background:rgb(255,152,0)}.mdl-radio.is-checked .mdl-radio__inner-circle{-webkit-transform:scale(1,1);transform:scale(1,1)}fieldset[disabled] .mdl-radio .mdl-radio__inner-circle,.mdl-radio.is-disabled .mdl-radio__inner-circle{background:rgba(0,0,0,.26);cursor:auto}.mdl-radio.is-focused .mdl-radio__inner-circle{box-shadow:0 0 0 10px rgba(0,0,0,.1)}.mdl-radio__label{cursor:pointer}fieldset[disabled] .mdl-radio .mdl-radio__label,.mdl-radio.is-disabled .mdl-radio__label{color:rgba(0,0,0,.26);cursor:auto}.mdl-radio__ripple-container{position:absolute;z-index:2;top:-9px;left:-13px;box-sizing:border-box;width:42px;height:42px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-radio__ripple-container .mdl-ripple{background:rgb(255,152,0)}fieldset[disabled] .mdl-radio .mdl-radio__ripple-container,.mdl-radio.is-disabled .mdl-radio__ripple-container{cursor:auto}fieldset[disabled] .mdl-radio .mdl-radio__ripple-container .mdl-ripple,.mdl-radio.is-disabled .mdl-radio__ripple-container .mdl-ripple{background:0 0}_:-ms-input-placeholder,:root .mdl-slider.mdl-slider.is-upgraded{-ms-appearance:none;height:32px;margin:0}.mdl-slider{width:calc(100% - 40px);margin:0 20px}.mdl-slider.is-upgraded{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:2px;background:0 0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;outline:0;padding:0;color:rgb(255,152,0);-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;z-index:1;cursor:pointer}.mdl-slider.is-upgraded::-moz-focus-outer{border:0}.mdl-slider.is-upgraded::-ms-tooltip{display:none}.mdl-slider.is-upgraded::-webkit-slider-runnable-track{background:0 0}.mdl-slider.is-upgraded::-moz-range-track{background:0 0;border:none}.mdl-slider.is-upgraded::-ms-track{background:0 0;color:transparent;height:2px;width:100%;border:none}.mdl-slider.is-upgraded::-ms-fill-lower{padding:0;background:linear-gradient(to right,transparent,transparent 16px,rgb(255,152,0)16px,rgb(255,152,0)0)}.mdl-slider.is-upgraded::-ms-fill-upper{padding:0;background:linear-gradient(to left,transparent,transparent 16px,rgba(0,0,0,.26)16px,rgba(0,0,0,.26)0)}.mdl-slider.is-upgraded::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background:rgb(255,152,0);border:none;transition:transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),border .18s cubic-bezier(.4,0,.2,1),box-shadow .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1)}.mdl-slider.is-upgraded::-moz-range-thumb{-moz-appearance:none;width:12px;height:12px;box-sizing:border-box;border-radius:50%;background-image:none;background:rgb(255,152,0);border:none}.mdl-slider.is-upgraded:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(255,152,0,.26)}.mdl-slider.is-upgraded:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(255,152,0,.26)}.mdl-slider.is-upgraded:active::-webkit-slider-thumb{background-image:none;background:rgb(255,152,0);-webkit-transform:scale(1.5);transform:scale(1.5)}.mdl-slider.is-upgraded:active::-moz-range-thumb{background-image:none;background:rgb(255,152,0);transform:scale(1.5)}.mdl-slider.is-upgraded::-ms-thumb{width:32px;height:32px;border:none;border-radius:50%;background:rgb(255,152,0);transform:scale(.375);transition:transform .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),background .28s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1)}.mdl-slider.is-upgraded:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,rgb(255,152,0)0%,rgb(255,152,0)37.5%,rgba(255,152,0,.26)37.5%,rgba(255,152,0,.26)100%);transform:scale(1)}.mdl-slider.is-upgraded:active::-ms-thumb{background:rgb(255,152,0);transform:scale(.5625)}.mdl-slider.is-upgraded.is-lowest-value::-webkit-slider-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.mdl-slider.is-upgraded.is-lowest-value::-moz-range-thumb{border:2px solid rgba(0,0,0,.26);background:0 0}.mdl-slider.is-upgraded.is-lowest-value+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(0,0,0,.12);background:rgba(0,0,0,.12)}.mdl-slider.is-upgraded.is-lowest-value:active::-webkit-slider-thumb{border:1.6px solid rgba(0,0,0,.26);-webkit-transform:scale(1.5);transform:scale(1.5)}.mdl-slider.is-upgraded.is-lowest-value:active+.mdl-slider__background-flex>.mdl-slider__background-upper{left:9px}.mdl-slider.is-upgraded.is-lowest-value:active::-moz-range-thumb{border:1.5px solid rgba(0,0,0,.26);transform:scale(1.5)}.mdl-slider.is-upgraded.is-lowest-value::-ms-thumb{background:radial-gradient(circle closest-side,transparent 0%,transparent 66.67%,rgba(0,0,0,.26)66.67%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-ms-thumb{background:radial-gradient(circle closest-side,rgba(0,0,0,.12)0%,rgba(0,0,0,.12)25%,rgba(0,0,0,.26)25%,rgba(0,0,0,.26)37.5%,rgba(0,0,0,.12)37.5%,rgba(0,0,0,.12)100%);transform:scale(1)}.mdl-slider.is-upgraded.is-lowest-value:active::-ms-thumb{transform:scale(.5625);background:radial-gradient(circle closest-side,transparent 0%,transparent 77.78%,rgba(0,0,0,.26)77.78%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-lower{background:0 0}.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-upper{margin-left:6px}.mdl-slider.is-upgraded.is-lowest-value:active::-ms-fill-upper{margin-left:9px}.mdl-slider.is-upgraded:disabled:focus::-webkit-slider-thumb,.mdl-slider.is-upgraded:disabled:active::-webkit-slider-thumb,.mdl-slider.is-upgraded:disabled::-webkit-slider-thumb{-webkit-transform:scale(.667);transform:scale(.667);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded:disabled:focus::-moz-range-thumb,.mdl-slider.is-upgraded:disabled:active::-moz-range-thumb,.mdl-slider.is-upgraded:disabled::-moz-range-thumb{transform:scale(.667);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded:disabled+.mdl-slider__background-flex>.mdl-slider__background-lower{background-color:rgba(0,0,0,.26);left:-6px}.mdl-slider.is-upgraded:disabled+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-webkit-slider-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-webkit-slider-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-webkit-slider-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;-webkit-transform:scale(.667);transform:scale(.667)}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-moz-range-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-moz-range-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-moz-range-thumb{border:3px solid rgba(0,0,0,.26);background:0 0;transform:scale(.667)}.mdl-slider.is-upgraded.is-lowest-value:disabled:active+.mdl-slider__background-flex>.mdl-slider__background-upper{left:6px}.mdl-slider.is-upgraded:disabled:focus::-ms-thumb,.mdl-slider.is-upgraded:disabled:active::-ms-thumb,.mdl-slider.is-upgraded:disabled::-ms-thumb{transform:scale(.25);background:rgba(0,0,0,.26)}.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-ms-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-ms-thumb,.mdl-slider.is-upgraded.is-lowest-value:disabled::-ms-thumb{transform:scale(.25);background:radial-gradient(circle closest-side,transparent 0%,transparent 50%,rgba(0,0,0,.26)50%,rgba(0,0,0,.26)100%)}.mdl-slider.is-upgraded:disabled::-ms-fill-lower{margin-right:6px;background:linear-gradient(to right,transparent,transparent 25px,rgba(0,0,0,.26)25px,rgba(0,0,0,.26)0)}.mdl-slider.is-upgraded:disabled::-ms-fill-upper{margin-left:6px}.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-ms-fill-upper{margin-left:6px}.mdl-slider__ie-container{height:18px;overflow:visible;border:none;margin:none;padding:none}.mdl-slider__container{height:18px;position:relative;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.mdl-slider__container,.mdl-slider__background-flex{background:0 0;display:-webkit-flex;display:-ms-flexbox;display:flex}.mdl-slider__background-flex{position:absolute;height:2px;width:calc(100% - 52px);top:50%;left:0;margin:0 26px;overflow:hidden;border:0;padding:0;-webkit-transform:translate(0,-1px);transform:translate(0,-1px)}.mdl-slider__background-lower{background:rgb(255,152,0)}.mdl-slider__background-lower,.mdl-slider__background-upper{-webkit-flex:0;-ms-flex:0;flex:0;position:relative;border:0;padding:0}.mdl-slider__background-upper{background:rgba(0,0,0,.26);transition:left .18s cubic-bezier(.4,0,.2,1)}.mdl-snackbar{position:fixed;bottom:0;left:50%;cursor:default;background-color:#323232;z-index:3;display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;font-family:"Roboto","Helvetica","Arial",sans-serif;will-change:transform;-webkit-transform:translate(0,80px);transform:translate(0,80px);transition:transform .25s cubic-bezier(.4,0,1,1);transition:transform .25s cubic-bezier(.4,0,1,1),-webkit-transform .25s cubic-bezier(.4,0,1,1);pointer-events:none}@media (max-width:479px){.mdl-snackbar{width:100%;left:0;min-height:48px;max-height:80px}}@media (min-width:480px){.mdl-snackbar{min-width:288px;max-width:568px;border-radius:2px;-webkit-transform:translate(-50%,80px);transform:translate(-50%,80px)}}.mdl-snackbar--active{-webkit-transform:translate(0,0);transform:translate(0,0);pointer-events:auto;transition:transform .25s cubic-bezier(0,0,.2,1);transition:transform .25s cubic-bezier(0,0,.2,1),-webkit-transform .25s cubic-bezier(0,0,.2,1)}@media (min-width:480px){.mdl-snackbar--active{-webkit-transform:translate(-50%,0);transform:translate(-50%,0)}}.mdl-snackbar__text{padding:14px 12px 14px 24px;vertical-align:middle;color:#fff;float:left}.mdl-snackbar__action{background:0 0;border:none;color:rgb(68,138,255);float:right;padding:14px 24px 14px 12px;font-family:"Roboto","Helvetica","Arial",sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;line-height:1;letter-spacing:0;overflow:hidden;outline:none;opacity:0;pointer-events:none;cursor:pointer;text-decoration:none;text-align:center;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.mdl-snackbar__action::-moz-focus-inner{border:0}.mdl-snackbar__action:not([aria-hidden]){opacity:1;pointer-events:auto}.mdl-spinner{display:inline-block;position:relative;width:28px;height:28px}.mdl-spinner:not(.is-upgraded).is-active:after{content:"Loading..."}.mdl-spinner.is-upgraded.is-active{-webkit-animation:mdl-spinner__container-rotate 1568.23529412ms linear infinite;animation:mdl-spinner__container-rotate 1568.23529412ms linear infinite}@-webkit-keyframes mdl-spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes mdl-spinner__container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.mdl-spinner__layer{position:absolute;width:100%;height:100%;opacity:0}.mdl-spinner__layer-1{border-color:#42a5f5}.mdl-spinner--single-color .mdl-spinner__layer-1{border-color:rgb(255,152,0)}.mdl-spinner.is-active .mdl-spinner__layer-1{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-2{border-color:#f44336}.mdl-spinner--single-color .mdl-spinner__layer-2{border-color:rgb(255,152,0)}.mdl-spinner.is-active .mdl-spinner__layer-2{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-3{border-color:#fdd835}.mdl-spinner--single-color .mdl-spinner__layer-3{border-color:rgb(255,152,0)}.mdl-spinner.is-active .mdl-spinner__layer-3{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__layer-4{border-color:#4caf50}.mdl-spinner--single-color .mdl-spinner__layer-4{border-color:rgb(255,152,0)}.mdl-spinner.is-active .mdl-spinner__layer-4{-webkit-animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1)infinite both,mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4,0,.2,1)infinite both}@-webkit-keyframes mdl-spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@keyframes mdl-spinner__fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes mdl-spinner__layer-1-fade-in-out{from,25%{opacity:.99}26%,89%{opacity:0}90%,100%{opacity:.99}}@keyframes mdl-spinner__layer-1-fade-in-out{from,25%{opacity:.99}26%,89%{opacity:0}90%,100%{opacity:.99}}@-webkit-keyframes mdl-spinner__layer-2-fade-in-out{from,15%{opacity:0}25%,50%{opacity:.99}51%{opacity:0}}@keyframes mdl-spinner__layer-2-fade-in-out{from,15%{opacity:0}25%,50%{opacity:.99}51%{opacity:0}}@-webkit-keyframes mdl-spinner__layer-3-fade-in-out{from,40%{opacity:0}50%,75%{opacity:.99}76%{opacity:0}}@keyframes mdl-spinner__layer-3-fade-in-out{from,40%{opacity:0}50%,75%{opacity:.99}76%{opacity:0}}@-webkit-keyframes mdl-spinner__layer-4-fade-in-out{from,65%{opacity:0}75%,90%{opacity:.99}100%{opacity:0}}@keyframes mdl-spinner__layer-4-fade-in-out{from,65%{opacity:0}75%,90%{opacity:.99}100%{opacity:0}}.mdl-spinner__gap-patch{position:absolute;box-sizing:border-box;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.mdl-spinner__gap-patch .mdl-spinner__circle{width:1000%;left:-450%}.mdl-spinner__circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.mdl-spinner__circle-clipper.mdl-spinner__left{float:left}.mdl-spinner__circle-clipper.mdl-spinner__right{float:right}.mdl-spinner__circle-clipper .mdl-spinner__circle{width:200%}.mdl-spinner__circle{box-sizing:border-box;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent!important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0;left:0}.mdl-spinner__left .mdl-spinner__circle{border-right-color:transparent!important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.mdl-spinner.is-active .mdl-spinner__left .mdl-spinner__circle{-webkit-animation:mdl-spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__left-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both}.mdl-spinner__right .mdl-spinner__circle{left:-100%;border-left-color:transparent!important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.mdl-spinner.is-active .mdl-spinner__right .mdl-spinner__circle{-webkit-animation:mdl-spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both;animation:mdl-spinner__right-spin 1333ms cubic-bezier(.4,0,.2,1)infinite both}@-webkit-keyframes mdl-spinner__left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@keyframes mdl-spinner__left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@-webkit-keyframes mdl-spinner__right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}@keyframes mdl-spinner__right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}.mdl-switch{position:relative;z-index:1;vertical-align:middle;display:inline-block;box-sizing:border-box;width:100%;height:24px;margin:0;padding:0;overflow:visible;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mdl-switch.is-upgraded{padding-left:28px}.mdl-switch__input{line-height:24px}.mdl-switch.is-upgraded .mdl-switch__input{position:absolute;width:0;height:0;margin:0;padding:0;opacity:0;-ms-appearance:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none}.mdl-switch__track{background:rgba(0,0,0,.26);position:absolute;left:0;top:5px;height:14px;width:36px;border-radius:14px;cursor:pointer}.mdl-switch.is-checked .mdl-switch__track{background:rgba(255,152,0,.5)}.mdl-switch__track fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__track{background:rgba(0,0,0,.12);cursor:auto}.mdl-switch__thumb{background:#fafafa;position:absolute;left:0;top:2px;height:20px;width:20px;border-radius:50%;cursor:pointer;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:left}.mdl-switch.is-checked .mdl-switch__thumb{background:rgb(255,152,0);left:16px;box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.mdl-switch__thumb fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__thumb{background:#bdbdbd;cursor:auto}.mdl-switch__focus-helper{position:absolute;top:50%;left:50%;-webkit-transform:translate(-4px,-4px);transform:translate(-4px,-4px);display:inline-block;box-sizing:border-box;width:8px;height:8px;border-radius:50%;background-color:transparent}.mdl-switch.is-focused .mdl-switch__focus-helper{box-shadow:0 0 0 20px rgba(0,0,0,.1);background-color:rgba(0,0,0,.1)}.mdl-switch.is-focused.is-checked .mdl-switch__focus-helper{box-shadow:0 0 0 20px rgba(255,152,0,.26);background-color:rgba(255,152,0,.26)}.mdl-switch__label{position:relative;cursor:pointer;font-size:16px;line-height:24px;margin:0;left:24px}.mdl-switch__label fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__label{color:#bdbdbd;cursor:auto}.mdl-switch__ripple-container{position:absolute;z-index:2;top:-12px;left:-14px;box-sizing:border-box;width:48px;height:48px;border-radius:50%;cursor:pointer;overflow:hidden;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000);transition-duration:.4s;transition-timing-function:step-end;transition-property:left}.mdl-switch__ripple-container .mdl-ripple{background:rgb(255,152,0)}.mdl-switch__ripple-container fieldset[disabled] .mdl-switch,.mdl-switch.is-disabled .mdl-switch__ripple-container{cursor:auto}fieldset[disabled] .mdl-switch .mdl-switch__ripple-container .mdl-ripple,.mdl-switch.is-disabled .mdl-switch__ripple-container .mdl-ripple{background:0 0}.mdl-switch.is-checked .mdl-switch__ripple-container{left:2px}.mdl-tabs{display:block;width:100%}.mdl-tabs__tab-bar{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:space-between;-ms-flex-line-pack:justify;align-content:space-between;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;height:48px;padding:0;margin:0;border-bottom:1px solid #e0e0e0}.mdl-tabs__tab{margin:0;border:none;padding:0 24px;float:left;position:relative;display:block;text-decoration:none;height:48px;line-height:48px;text-align:center;font-weight:500;font-size:14px;text-transform:uppercase;color:rgba(0,0,0,.54);overflow:hidden}.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active{color:rgba(0,0,0,.87)}.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active:after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:rgb(255,152,0);-webkit-animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;animation:border-expand .2s cubic-bezier(.4,0,.4,1).01s alternate forwards;transition:all 1s cubic-bezier(.4,0,1,1)}.mdl-tabs__tab .mdl-tabs__ripple-container{display:block;position:absolute;height:100%;width:100%;left:0;top:0;z-index:1;overflow:hidden}.mdl-tabs__tab .mdl-tabs__ripple-container .mdl-ripple{background:rgb(255,152,0)}.mdl-tabs__panel{display:block}.mdl-tabs.is-upgraded .mdl-tabs__panel{display:none}.mdl-tabs.is-upgraded .mdl-tabs__panel.is-active{display:block}@-webkit-keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}@keyframes border-expand{0%{opacity:0;width:0}100%{opacity:1;width:100%}}.mdl-textfield{position:relative;font-size:16px;display:inline-block;box-sizing:border-box;width:300px;max-width:100%;margin:0;padding:20px 0}.mdl-textfield .mdl-button{position:absolute;bottom:20px}.mdl-textfield--align-right{text-align:right}.mdl-textfield--full-width{width:100%}.mdl-textfield--expandable{min-width:32px;width:auto;min-height:32px}.mdl-textfield--expandable .mdl-button--icon{top:16px}.mdl-textfield__input{border:none;border-bottom:1px solid rgba(0,0,0,.12);display:block;font-size:16px;font-family:"Helvetica","Arial",sans-serif;margin:0;padding:4px 0;width:100%;background:0 0;text-align:left;color:inherit}.mdl-textfield__input[type="number"]{-moz-appearance:textfield}.mdl-textfield__input[type="number"]::-webkit-inner-spin-button,.mdl-textfield__input[type="number"]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.mdl-textfield.is-focused .mdl-textfield__input{outline:none}.mdl-textfield.is-invalid .mdl-textfield__input{border-color:#d50000;box-shadow:none}fieldset[disabled] .mdl-textfield .mdl-textfield__input,.mdl-textfield.is-disabled .mdl-textfield__input{background-color:transparent;border-bottom:1px dotted rgba(0,0,0,.12);color:rgba(0,0,0,.26)}.mdl-textfield textarea.mdl-textfield__input{display:block}.mdl-textfield__label{bottom:0;color:rgba(0,0,0,.26);font-size:16px;left:0;right:0;pointer-events:none;position:absolute;display:block;top:24px;width:100%;overflow:hidden;white-space:nowrap;text-align:left}.mdl-textfield.is-dirty .mdl-textfield__label,.mdl-textfield.has-placeholder .mdl-textfield__label{visibility:hidden}.mdl-textfield--floating-label .mdl-textfield__label{transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.mdl-textfield--floating-label.has-placeholder .mdl-textfield__label{transition:none}fieldset[disabled] .mdl-textfield .mdl-textfield__label,.mdl-textfield.is-disabled.is-disabled .mdl-textfield__label{color:rgba(0,0,0,.26)}.mdl-textfield--floating-label.is-focused .mdl-textfield__label,.mdl-textfield--floating-label.is-dirty .mdl-textfield__label,.mdl-textfield--floating-label.has-placeholder .mdl-textfield__label{color:rgb(255,152,0);font-size:12px;top:4px;visibility:visible}.mdl-textfield--floating-label.is-focused .mdl-textfield__expandable-holder .mdl-textfield__label,.mdl-textfield--floating-label.is-dirty .mdl-textfield__expandable-holder .mdl-textfield__label,.mdl-textfield--floating-label.has-placeholder .mdl-textfield__expandable-holder .mdl-textfield__label{top:-16px}.mdl-textfield--floating-label.is-invalid .mdl-textfield__label{color:#d50000;font-size:12px}.mdl-textfield__label:after{background-color:rgb(255,152,0);bottom:20px;content:'';height:2px;left:45%;position:absolute;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);visibility:hidden;width:10px}.mdl-textfield.is-focused .mdl-textfield__label:after{left:0;visibility:visible;width:100%}.mdl-textfield.is-invalid .mdl-textfield__label:after{background-color:#d50000}.mdl-textfield__error{color:#d50000;position:absolute;font-size:12px;margin-top:3px;visibility:hidden;display:block}.mdl-textfield.is-invalid .mdl-textfield__error{visibility:visible}.mdl-textfield__expandable-holder{display:inline-block;position:relative;margin-left:32px;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:inline-block;max-width:.1px}.mdl-textfield.is-focused .mdl-textfield__expandable-holder,.mdl-textfield.is-dirty .mdl-textfield__expandable-holder{max-width:600px}.mdl-textfield__expandable-holder .mdl-textfield__label:after{bottom:0}.mdl-tooltip{-webkit-transform:scale(0);transform:scale(0);-webkit-transform-origin:top center;transform-origin:top center;z-index:999;background:rgba(97,97,97,.9);border-radius:2px;color:#fff;display:inline-block;font-size:10px;font-weight:500;line-height:14px;max-width:170px;position:fixed;top:-500px;left:-500px;padding:8px;text-align:center}.mdl-tooltip.is-active{-webkit-animation:pulse 200ms cubic-bezier(0,0,.2,1)forwards;animation:pulse 200ms cubic-bezier(0,0,.2,1)forwards}.mdl-tooltip--large{line-height:14px;font-size:14px;padding:16px}@-webkit-keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}@keyframes pulse{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0}50%{-webkit-transform:scale(.99);transform:scale(.99)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}}.mdl-shadow--2dp{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-shadow--3dp{box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.mdl-shadow--4dp{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.mdl-shadow--6dp{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2)}.mdl-shadow--8dp{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2)}.mdl-shadow--16dp{box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.2)}.mdl-shadow--24dp{box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2)}.mdl-grid{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;margin:0 auto;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch}.mdl-grid.mdl-grid--no-spacing{padding:0}.mdl-cell{box-sizing:border-box}.mdl-cell--top{-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}.mdl-cell--middle{-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.mdl-cell--bottom{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end}.mdl-cell--stretch{-webkit-align-self:stretch;-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch}.mdl-grid.mdl-grid--no-spacing>.mdl-cell{margin:0}.mdl-cell--order-1{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12{-webkit-order:12;-ms-flex-order:12;order:12}@media (max-width:479px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:100%}.mdl-cell--hide-phone{display:none!important}.mdl-cell--order-1-phone.mdl-cell--order-1-phone{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-phone.mdl-cell--order-2-phone{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-phone.mdl-cell--order-3-phone{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-phone.mdl-cell--order-4-phone{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-phone.mdl-cell--order-5-phone{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-phone.mdl-cell--order-6-phone{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-phone.mdl-cell--order-7-phone{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-phone.mdl-cell--order-8-phone{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-phone.mdl-cell--order-9-phone{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-phone.mdl-cell--order-10-phone{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-phone.mdl-cell--order-11-phone{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-phone.mdl-cell--order-12-phone{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-phone.mdl-cell--1-col-phone{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-phone.mdl-cell--1-col-phone{width:25%}.mdl-cell--2-col,.mdl-cell--2-col-phone.mdl-cell--2-col-phone{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-phone.mdl-cell--2-col-phone{width:50%}.mdl-cell--3-col,.mdl-cell--3-col-phone.mdl-cell--3-col-phone{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-phone.mdl-cell--3-col-phone{width:75%}.mdl-cell--4-col,.mdl-cell--4-col-phone.mdl-cell--4-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-phone.mdl-cell--4-col-phone{width:100%}.mdl-cell--5-col,.mdl-cell--5-col-phone.mdl-cell--5-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-phone.mdl-cell--5-col-phone{width:100%}.mdl-cell--6-col,.mdl-cell--6-col-phone.mdl-cell--6-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-phone.mdl-cell--6-col-phone{width:100%}.mdl-cell--7-col,.mdl-cell--7-col-phone.mdl-cell--7-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-phone.mdl-cell--7-col-phone{width:100%}.mdl-cell--8-col,.mdl-cell--8-col-phone.mdl-cell--8-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-phone.mdl-cell--8-col-phone{width:100%}.mdl-cell--9-col,.mdl-cell--9-col-phone.mdl-cell--9-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-phone.mdl-cell--9-col-phone{width:100%}.mdl-cell--10-col,.mdl-cell--10-col-phone.mdl-cell--10-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-phone.mdl-cell--10-col-phone{width:100%}.mdl-cell--11-col,.mdl-cell--11-col-phone.mdl-cell--11-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-phone.mdl-cell--11-col-phone{width:100%}.mdl-cell--12-col,.mdl-cell--12-col-phone.mdl-cell--12-col-phone{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-phone.mdl-cell--12-col-phone{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-phone.mdl-cell--1-offset-phone{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-phone.mdl-cell--1-offset-phone{margin-left:25%}.mdl-cell--2-offset,.mdl-cell--2-offset-phone.mdl-cell--2-offset-phone{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-phone.mdl-cell--2-offset-phone{margin-left:50%}.mdl-cell--3-offset,.mdl-cell--3-offset-phone.mdl-cell--3-offset-phone{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-phone.mdl-cell--3-offset-phone{margin-left:75%}}@media (min-width:480px) and (max-width:839px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:50%}.mdl-cell--hide-tablet{display:none!important}.mdl-cell--order-1-tablet.mdl-cell--order-1-tablet{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-tablet.mdl-cell--order-2-tablet{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-tablet.mdl-cell--order-3-tablet{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-tablet.mdl-cell--order-4-tablet{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-tablet.mdl-cell--order-5-tablet{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-tablet.mdl-cell--order-6-tablet{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-tablet.mdl-cell--order-7-tablet{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-tablet.mdl-cell--order-8-tablet{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-tablet.mdl-cell--order-9-tablet{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-tablet.mdl-cell--order-10-tablet{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-tablet.mdl-cell--order-11-tablet{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-tablet.mdl-cell--order-12-tablet{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-tablet.mdl-cell--1-col-tablet{width:calc(12.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-tablet.mdl-cell--1-col-tablet{width:12.5%}.mdl-cell--2-col,.mdl-cell--2-col-tablet.mdl-cell--2-col-tablet{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-tablet.mdl-cell--2-col-tablet{width:25%}.mdl-cell--3-col,.mdl-cell--3-col-tablet.mdl-cell--3-col-tablet{width:calc(37.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-tablet.mdl-cell--3-col-tablet{width:37.5%}.mdl-cell--4-col,.mdl-cell--4-col-tablet.mdl-cell--4-col-tablet{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-tablet.mdl-cell--4-col-tablet{width:50%}.mdl-cell--5-col,.mdl-cell--5-col-tablet.mdl-cell--5-col-tablet{width:calc(62.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-tablet.mdl-cell--5-col-tablet{width:62.5%}.mdl-cell--6-col,.mdl-cell--6-col-tablet.mdl-cell--6-col-tablet{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-tablet.mdl-cell--6-col-tablet{width:75%}.mdl-cell--7-col,.mdl-cell--7-col-tablet.mdl-cell--7-col-tablet{width:calc(87.5% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-tablet.mdl-cell--7-col-tablet{width:87.5%}.mdl-cell--8-col,.mdl-cell--8-col-tablet.mdl-cell--8-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-tablet.mdl-cell--8-col-tablet{width:100%}.mdl-cell--9-col,.mdl-cell--9-col-tablet.mdl-cell--9-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-tablet.mdl-cell--9-col-tablet{width:100%}.mdl-cell--10-col,.mdl-cell--10-col-tablet.mdl-cell--10-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-tablet.mdl-cell--10-col-tablet{width:100%}.mdl-cell--11-col,.mdl-cell--11-col-tablet.mdl-cell--11-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-tablet.mdl-cell--11-col-tablet{width:100%}.mdl-cell--12-col,.mdl-cell--12-col-tablet.mdl-cell--12-col-tablet{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-tablet.mdl-cell--12-col-tablet{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-tablet.mdl-cell--1-offset-tablet{margin-left:calc(12.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-tablet.mdl-cell--1-offset-tablet{margin-left:12.5%}.mdl-cell--2-offset,.mdl-cell--2-offset-tablet.mdl-cell--2-offset-tablet{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-tablet.mdl-cell--2-offset-tablet{margin-left:25%}.mdl-cell--3-offset,.mdl-cell--3-offset-tablet.mdl-cell--3-offset-tablet{margin-left:calc(37.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-tablet.mdl-cell--3-offset-tablet{margin-left:37.5%}.mdl-cell--4-offset,.mdl-cell--4-offset-tablet.mdl-cell--4-offset-tablet{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset-tablet.mdl-cell--4-offset-tablet{margin-left:50%}.mdl-cell--5-offset,.mdl-cell--5-offset-tablet.mdl-cell--5-offset-tablet{margin-left:calc(62.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset-tablet.mdl-cell--5-offset-tablet{margin-left:62.5%}.mdl-cell--6-offset,.mdl-cell--6-offset-tablet.mdl-cell--6-offset-tablet{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset-tablet.mdl-cell--6-offset-tablet{margin-left:75%}.mdl-cell--7-offset,.mdl-cell--7-offset-tablet.mdl-cell--7-offset-tablet{margin-left:calc(87.5% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset-tablet.mdl-cell--7-offset-tablet{margin-left:87.5%}}@media (min-width:840px){.mdl-grid{padding:8px}.mdl-cell{margin:8px;width:calc(33.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell{width:33.3333333333%}.mdl-cell--hide-desktop{display:none!important}.mdl-cell--order-1-desktop.mdl-cell--order-1-desktop{-webkit-order:1;-ms-flex-order:1;order:1}.mdl-cell--order-2-desktop.mdl-cell--order-2-desktop{-webkit-order:2;-ms-flex-order:2;order:2}.mdl-cell--order-3-desktop.mdl-cell--order-3-desktop{-webkit-order:3;-ms-flex-order:3;order:3}.mdl-cell--order-4-desktop.mdl-cell--order-4-desktop{-webkit-order:4;-ms-flex-order:4;order:4}.mdl-cell--order-5-desktop.mdl-cell--order-5-desktop{-webkit-order:5;-ms-flex-order:5;order:5}.mdl-cell--order-6-desktop.mdl-cell--order-6-desktop{-webkit-order:6;-ms-flex-order:6;order:6}.mdl-cell--order-7-desktop.mdl-cell--order-7-desktop{-webkit-order:7;-ms-flex-order:7;order:7}.mdl-cell--order-8-desktop.mdl-cell--order-8-desktop{-webkit-order:8;-ms-flex-order:8;order:8}.mdl-cell--order-9-desktop.mdl-cell--order-9-desktop{-webkit-order:9;-ms-flex-order:9;order:9}.mdl-cell--order-10-desktop.mdl-cell--order-10-desktop{-webkit-order:10;-ms-flex-order:10;order:10}.mdl-cell--order-11-desktop.mdl-cell--order-11-desktop{-webkit-order:11;-ms-flex-order:11;order:11}.mdl-cell--order-12-desktop.mdl-cell--order-12-desktop{-webkit-order:12;-ms-flex-order:12;order:12}.mdl-cell--1-col,.mdl-cell--1-col-desktop.mdl-cell--1-col-desktop{width:calc(8.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--1-col,.mdl-grid--no-spacing>.mdl-cell--1-col-desktop.mdl-cell--1-col-desktop{width:8.3333333333%}.mdl-cell--2-col,.mdl-cell--2-col-desktop.mdl-cell--2-col-desktop{width:calc(16.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--2-col,.mdl-grid--no-spacing>.mdl-cell--2-col-desktop.mdl-cell--2-col-desktop{width:16.6666666667%}.mdl-cell--3-col,.mdl-cell--3-col-desktop.mdl-cell--3-col-desktop{width:calc(25% - 16px)}.mdl-grid--no-spacing>.mdl-cell--3-col,.mdl-grid--no-spacing>.mdl-cell--3-col-desktop.mdl-cell--3-col-desktop{width:25%}.mdl-cell--4-col,.mdl-cell--4-col-desktop.mdl-cell--4-col-desktop{width:calc(33.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--4-col,.mdl-grid--no-spacing>.mdl-cell--4-col-desktop.mdl-cell--4-col-desktop{width:33.3333333333%}.mdl-cell--5-col,.mdl-cell--5-col-desktop.mdl-cell--5-col-desktop{width:calc(41.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--5-col,.mdl-grid--no-spacing>.mdl-cell--5-col-desktop.mdl-cell--5-col-desktop{width:41.6666666667%}.mdl-cell--6-col,.mdl-cell--6-col-desktop.mdl-cell--6-col-desktop{width:calc(50% - 16px)}.mdl-grid--no-spacing>.mdl-cell--6-col,.mdl-grid--no-spacing>.mdl-cell--6-col-desktop.mdl-cell--6-col-desktop{width:50%}.mdl-cell--7-col,.mdl-cell--7-col-desktop.mdl-cell--7-col-desktop{width:calc(58.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--7-col,.mdl-grid--no-spacing>.mdl-cell--7-col-desktop.mdl-cell--7-col-desktop{width:58.3333333333%}.mdl-cell--8-col,.mdl-cell--8-col-desktop.mdl-cell--8-col-desktop{width:calc(66.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--8-col,.mdl-grid--no-spacing>.mdl-cell--8-col-desktop.mdl-cell--8-col-desktop{width:66.6666666667%}.mdl-cell--9-col,.mdl-cell--9-col-desktop.mdl-cell--9-col-desktop{width:calc(75% - 16px)}.mdl-grid--no-spacing>.mdl-cell--9-col,.mdl-grid--no-spacing>.mdl-cell--9-col-desktop.mdl-cell--9-col-desktop{width:75%}.mdl-cell--10-col,.mdl-cell--10-col-desktop.mdl-cell--10-col-desktop{width:calc(83.3333333333% - 16px)}.mdl-grid--no-spacing>.mdl-cell--10-col,.mdl-grid--no-spacing>.mdl-cell--10-col-desktop.mdl-cell--10-col-desktop{width:83.3333333333%}.mdl-cell--11-col,.mdl-cell--11-col-desktop.mdl-cell--11-col-desktop{width:calc(91.6666666667% - 16px)}.mdl-grid--no-spacing>.mdl-cell--11-col,.mdl-grid--no-spacing>.mdl-cell--11-col-desktop.mdl-cell--11-col-desktop{width:91.6666666667%}.mdl-cell--12-col,.mdl-cell--12-col-desktop.mdl-cell--12-col-desktop{width:calc(100% - 16px)}.mdl-grid--no-spacing>.mdl-cell--12-col,.mdl-grid--no-spacing>.mdl-cell--12-col-desktop.mdl-cell--12-col-desktop{width:100%}.mdl-cell--1-offset,.mdl-cell--1-offset-desktop.mdl-cell--1-offset-desktop{margin-left:calc(8.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-desktop.mdl-cell--1-offset-desktop{margin-left:8.3333333333%}.mdl-cell--2-offset,.mdl-cell--2-offset-desktop.mdl-cell--2-offset-desktop{margin-left:calc(16.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-desktop.mdl-cell--2-offset-desktop{margin-left:16.6666666667%}.mdl-cell--3-offset,.mdl-cell--3-offset-desktop.mdl-cell--3-offset-desktop{margin-left:calc(25% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-desktop.mdl-cell--3-offset-desktop{margin-left:25%}.mdl-cell--4-offset,.mdl-cell--4-offset-desktop.mdl-cell--4-offset-desktop{margin-left:calc(33.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset-desktop.mdl-cell--4-offset-desktop{margin-left:33.3333333333%}.mdl-cell--5-offset,.mdl-cell--5-offset-desktop.mdl-cell--5-offset-desktop{margin-left:calc(41.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset-desktop.mdl-cell--5-offset-desktop{margin-left:41.6666666667%}.mdl-cell--6-offset,.mdl-cell--6-offset-desktop.mdl-cell--6-offset-desktop{margin-left:calc(50% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset-desktop.mdl-cell--6-offset-desktop{margin-left:50%}.mdl-cell--7-offset,.mdl-cell--7-offset-desktop.mdl-cell--7-offset-desktop{margin-left:calc(58.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset-desktop.mdl-cell--7-offset-desktop{margin-left:58.3333333333%}.mdl-cell--8-offset,.mdl-cell--8-offset-desktop.mdl-cell--8-offset-desktop{margin-left:calc(66.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--8-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--8-offset-desktop.mdl-cell--8-offset-desktop{margin-left:66.6666666667%}.mdl-cell--9-offset,.mdl-cell--9-offset-desktop.mdl-cell--9-offset-desktop{margin-left:calc(75% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--9-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--9-offset-desktop.mdl-cell--9-offset-desktop{margin-left:75%}.mdl-cell--10-offset,.mdl-cell--10-offset-desktop.mdl-cell--10-offset-desktop{margin-left:calc(83.3333333333% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--10-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--10-offset-desktop.mdl-cell--10-offset-desktop{margin-left:83.3333333333%}.mdl-cell--11-offset,.mdl-cell--11-offset-desktop.mdl-cell--11-offset-desktop{margin-left:calc(91.6666666667% + 8px)}.mdl-grid.mdl-grid--no-spacing>.mdl-cell--11-offset,.mdl-grid.mdl-grid--no-spacing>.mdl-cell--11-offset-desktop.mdl-cell--11-offset-desktop{margin-left:91.6666666667%}}body{margin:0}.styleguide-demo h1{margin:48px 24px 0}.styleguide-demo h1:after{content:'';display:block;width:100%;border-bottom:1px solid rgba(0,0,0,.5);margin-top:24px}.styleguide-demo{opacity:0;transition:opacity .6s ease}.styleguide-masthead{height:256px;background:#212121;padding:115px 16px 0}.styleguide-container{position:relative;max-width:960px;width:100%}.styleguide-title{color:#fff;bottom:auto;position:relative;font-size:56px;font-weight:300;line-height:1;letter-spacing:-.02em}.styleguide-title:after{border-bottom:0}.styleguide-title span{font-weight:300}.mdl-styleguide .mdl-layout__drawer .mdl-navigation__link{padding:10px 24px}.demosLoaded .styleguide-demo{opacity:1}iframe{display:block;width:100%;border:none}iframe.heightSet{overflow:hidden}.demo-wrapper{margin:24px}.demo-wrapper iframe{border:1px solid rgba(0,0,0,.5)} \ No newline at end of file diff --git a/ng2-components/ng2-activiti-analytics/README.md b/ng2-components/ng2-activiti-analytics/README.md index 166bf6e17c9..108952f7023 100644 --- a/ng2-components/ng2-activiti-analytics/README.md +++ b/ng2-components/ng2-activiti-analytics/README.md @@ -69,6 +69,9 @@ Follow the 3 steps below: + + + diff --git a/ng2-components/ng2-activiti-analytics/demo/package.json b/ng2-components/ng2-activiti-analytics/demo/package.json index 17a7b119eb0..4f5c516807f 100644 --- a/ng2-components/ng2-activiti-analytics/demo/package.json +++ b/ng2-components/ng2-activiti-analytics/demo/package.json @@ -39,6 +39,7 @@ "@angular/http": "2.2.2", "@angular/platform-browser": "2.2.2", "@angular/platform-browser-dynamic": "2.2.2", + "@angular/material": "2.0.0-beta.1", "@angular/router": "3.2.2", "@angular/upgrade": "2.2.2", "core-js": "^2.4.1", @@ -57,10 +58,10 @@ "moment": "2.15.1", "raphael": "^2.2.6", "ng2-translate": "2.5.0", - "alfresco-js-api": "^1.0.0", - "ng2-alfresco-core": "1.0.0", - "ng2-activiti-diagrams": "1.0.0", - "ng2-activiti-analytics": "^1.0.0" + "alfresco-js-api": "~1.1.0", + "ng2-alfresco-core": "1.1.0", + "ng2-activiti-diagrams": "1.1.0", + "ng2-activiti-analytics": "^1.1.0" }, "devDependencies": { "@types/jasmine": "^2.2.33", diff --git a/ng2-components/ng2-activiti-analytics/demo/src/main.ts b/ng2-components/ng2-activiti-analytics/demo/src/main.ts index 67e19a017fb..5127ffd5d75 100644 --- a/ng2-components/ng2-activiti-analytics/demo/src/main.ts +++ b/ng2-components/ng2-activiti-analytics/demo/src/main.ts @@ -18,51 +18,49 @@ import { NgModule, Component, OnInit } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService, StorageService } from 'ng2-alfresco-core'; +import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService, StorageService, LogService } from 'ng2-alfresco-core'; import { AnalyticsModule } from 'ng2-activiti-analytics'; @Component({ selector: 'alfresco-app-demo', template: ` -
-
-
-

-
- Authentication failed to ip {{ host }} with user: admin, admin, you can still try to add a valid ticket to perform - operations. -
-
- -
-
- -
-
- -
-
- +
+
+
+

+
+ Authentication failed to ip {{ host }} with user: admin, admin, you can still try to add a valid ticket to perform + operations. +
+
+ +
+
+ +
+
+ +
+
+ +
-
` + ` }) export class AnalyticsDemoComponent implements OnInit { appId: number; - report: any; - authenticated: boolean; - host: string = 'http://localhost:9999'; - ticket: string; constructor(private authService: AlfrescoAuthenticationService, private settingsService: AlfrescoSettingsService, - private storage: StorageService) { + private storage: StorageService, + private logService: LogService) { settingsService.bpmHost = this.host; settingsService.setProviders('BPM'); @@ -91,12 +89,12 @@ export class AnalyticsDemoComponent implements OnInit { login() { this.authService.login('admin', 'admin').subscribe( ticket => { - console.log(ticket); + this.logService.log(ticket); this.ticket = this.authService.getTicketBpm(); this.authenticated = true; }, error => { - console.log(error); + this.logService.error(error); this.authenticated = false; }); } diff --git a/ng2-components/ng2-activiti-analytics/index.ts b/ng2-components/ng2-activiti-analytics/index.ts index c56527241de..bdc34240d02 100644 --- a/ng2-components/ng2-activiti-analytics/index.ts +++ b/ng2-components/ng2-activiti-analytics/index.ts @@ -22,6 +22,7 @@ import { DiagramsModule } from 'ng2-activiti-diagrams'; import { AnalyticsReportListComponent } from './src/components/analytics-report-list.component'; import { AnalyticsReportParametersComponent } from './src/components/analytics-report-parameters.component'; import { AnalyticsComponent } from './src/components/analytics.component'; +import { AnalyticsGeneratorComponent } from './src/components/analytics-generator.component'; import { AnalyticsReportHeatMapComponent } from './src/components/analytics-report-heat-map.component'; import { AnalyticsService } from './src/services/analytics.service'; import { CHART_DIRECTIVES } from 'ng2-charts/ng2-charts'; @@ -29,6 +30,7 @@ import { CHART_DIRECTIVES } from 'ng2-charts/ng2-charts'; import { WIDGET_DIRECTIVES } from './src/components/widgets/index'; export * from './src/components/analytics.component'; +export * from './src/components/analytics-generator.component'; export * from './src/components/analytics-report-list.component'; export * from './src/components/analytics-report-parameters.component'; export * from './src/services/analytics.service'; @@ -38,6 +40,7 @@ export const ANALYTICS_DIRECTIVES: any[] = [ AnalyticsComponent, AnalyticsReportListComponent, AnalyticsReportParametersComponent, + AnalyticsGeneratorComponent, AnalyticsReportHeatMapComponent, WIDGET_DIRECTIVES ]; diff --git a/ng2-components/ng2-activiti-analytics/karma-test-shim.js b/ng2-components/ng2-activiti-analytics/karma-test-shim.js index 4d66211142a..50673b05cbb 100644 --- a/ng2-components/ng2-activiti-analytics/karma-test-shim.js +++ b/ng2-components/ng2-activiti-analytics/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; @@ -39,6 +46,8 @@ var map = { '@angular/http': 'npm:@angular/http/bundles/http.umd.js', '@angular/router': 'npm:@angular/router/bundles/router.umd.js', '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/material': 'npm:@angular/material/bundles/material.umd.js', + // testing '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js', '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js', diff --git a/ng2-components/ng2-activiti-analytics/package.json b/ng2-components/ng2-activiti-analytics/package.json index 4db8b4ea3eb..b588f155aee 100644 --- a/ng2-components/ng2-activiti-analytics/package.json +++ b/ng2-components/ng2-activiti-analytics/package.json @@ -1,13 +1,13 @@ { "name": "ng2-activiti-analytics", "description": "Activiti Angular2 Analytics Component", - "version": "1.0.0", + "version": "1.1.0", "author": "Alfresco Software, Ltd.", "scripts": { "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings", "clean-build": "rimraf index.js index.js.map index.d.ts'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts' bundles", "build": "npm run clean-build && npm run tslint && rimraf dist && tsc && license-check && npm run build.umd", - "build:w": "npm run clean-build && npm run tslint && rimraf dist && tsc:w && license-check npm run build.umd", + "build:w": "npm run clean-build && npm run tslint && rimraf dist && npm run tsc:w && license-check && npm run build.umd", "tslint": "tslint -c tslint.json 'src/{,**/}**.ts' 'index.ts' -e '{,**/}**.d.ts' -e './gulpfile.ts'", "tsc": "tsc", "tsc:w": "tsc -w", @@ -16,7 +16,7 @@ "test-browser": "npm run build && concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", "posttest": "remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html && remap-istanbul -i coverage/report/coverage-final.json -o coverage/report/coverage-final.json", "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report", - "prepublish": "npm run build", + "prepublish": "npm run test", "travis": "npm link ng2-alfresco-core ng2-activiti-diagrams", "gulp": "gulp", "build.umd": "gulp build.prod --color --env-config prod --build-type prod", @@ -51,24 +51,26 @@ "@angular/http": "2.0.0", "@angular/platform-browser": "2.0.0", "@angular/platform-browser-dynamic": "2.0.0", + "@angular/material": "2.0.0-beta.1", "core-js": "^2.4.1", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.12", "systemjs": "0.19.27", "zone.js": "^0.6.23", - "chart.js": "^2.1.4", + "chart.js": "2.3.0", "md-date-time-picker": "^2.2.0", "ng2-charts": "1.1.0", "moment": "2.15.1", "raphael": "^2.2.6", - "alfresco-js-api": "^1.0.0", + "alfresco-js-api": "~1.1.0", "ng2-translate": "2.5.0", - "ng2-alfresco-core": "1.0.0", - "ng2-activiti-diagrams": "1.0.0" + "ng2-alfresco-core": "1.1.0", + "ng2-activiti-diagrams": "1.1.0" }, "devDependencies": { "@types/jasmine": "^2.2.33", "@types/node": "^6.0.42", + "autoprefixer": "^6.5.4", "concurrently": "^2.2.0", "cpx": "1.3.1", "cssnano": "^3.8.1", @@ -87,6 +89,7 @@ "gulp-template": "^4.0.0", "gulp-typescript": "^3.1.3", "gulp-uglify": "^2.0.0", + "gulp-util": "^3.0.7", "intl": "^1.2.5", "jasmine-core": "2.4.1", "karma": "0.13.22", @@ -97,6 +100,7 @@ "karma-jasmine-html-reporter": "0.2.0", "karma-mocha-reporter": "2.0.3", "license-check": "1.1.5", + "merge-stream": "^1.0.1", "remap-istanbul": "0.6.3", "rimraf": "2.5.2", "run-sequence": "^1.2.2", diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.css b/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.css new file mode 100644 index 00000000000..e0c64c5d755 --- /dev/null +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.css @@ -0,0 +1,5 @@ +.chart {display: block; width: 100%;} + +.analytics-row__entry { + cursor: pointer; +} diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.html b/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.html new file mode 100644 index 00000000000..633e2d7c66b --- /dev/null +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.html @@ -0,0 +1,92 @@ +
+
+

{{report.title}}

+
+
+
+
{{'ANALYTICS.MESSAGES.NO-DATA-FOUND' | translate}}
+
+
{{'ANALYTICS.MESSAGES.ZERO-DATA-FOUND' | translate}}
+ +
+
+
+
+
{{'ANALYTICS.MESSAGES.NO-DATA-FOUND' | translate}}
+
+ + + + + + + +
{{label | translate}}
{{row | translate }}
+
+
+
+
{{'ANALYTICS.MESSAGES.NO-DATA-FOUND' | translate}}
+
+ + + + + + + +
{{label | translate}}
{{row | translate }}
+
+
+ + + + + + + +
{{label | translate}}
{{row | translate }}
+
+
+
+
+
{{'ANALYTICS.MESSAGES.NO-DATA-FOUND' | translate}}
+ +
+
+
+
+
{{'ANALYTICS.MESSAGES.NO-DATA-FOUND' | translate}}
+
+ + +
+
+
+
+ +
+
+ {{'ANALYTICS.MESSAGES.UNKNOWN-WIDGET-TYPE' | translate}}: {{report.type}} +
+
+
+
+


+
{{'ANALYTICS.MESSAGES.FILL-PARAMETER' | translate}}
diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.spec.ts new file mode 100644 index 00000000000..77313de50d8 --- /dev/null +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.spec.ts @@ -0,0 +1,230 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { DebugElement } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; +import { CHART_DIRECTIVES } from 'ng2-charts/ng2-charts'; +import { CoreModule, AlfrescoTranslationService } from 'ng2-alfresco-core'; +import { DiagramsModule } from 'ng2-activiti-diagrams'; + +import { AnalyticsReportListComponent } from '../components/analytics-report-list.component'; +import { AnalyticsGeneratorComponent } from '../components/analytics-generator.component'; +import { AnalyticsReportParametersComponent } from '../components/analytics-report-parameters.component'; +import { AnalyticsReportHeatMapComponent } from '../components/analytics-report-heat-map.component'; +import { WIDGET_DIRECTIVES } from '../components/widgets/index'; +import { Chart } from '../models/chart.model'; +import { AnalyticsService } from '../services/analytics.service'; +import { ReportQuery } from '../models/report.model'; +import * as analyticMock from '../assets/analyticsComponent.mock'; + +export const ANALYTICS_DIRECTIVES: any[] = [ + AnalyticsGeneratorComponent, + AnalyticsReportParametersComponent, + AnalyticsReportListComponent, + AnalyticsReportHeatMapComponent, + WIDGET_DIRECTIVES +]; +export const ANALYTICS_PROVIDERS: any[] = [ + AnalyticsService +]; + +declare let jasmine: any; +declare let mdDateTimePicker: any; + +describe('AnalyticsGeneratorComponent', () => { + + let component: any; + let fixture: ComponentFixture; + let debug: DebugElement; + let element: HTMLElement; + + let componentHandler: any; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + CoreModule.forRoot(), + DiagramsModule.forRoot() + ], + declarations: [ + ...ANALYTICS_DIRECTIVES, + ...CHART_DIRECTIVES + ], + providers: [ + ...ANALYTICS_PROVIDERS + ] + }).compileComponents(); + + let translateService = TestBed.get(AlfrescoTranslationService); + spyOn(translateService, 'addTranslationFolder').and.stub(); + spyOn(translateService, 'get').and.callFake((key) => { return Observable.of(key); }); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AnalyticsGeneratorComponent); + component = fixture.componentInstance; + debug = fixture.debugElement; + element = fixture.nativeElement; + fixture.detectChanges(); + componentHandler = jasmine.createSpyObj('componentHandler', [ + 'upgradeAllRegistered' + ]); + window['componentHandler'] = componentHandler; + }); + + describe('Rendering tests', () => { + beforeEach(() => { + jasmine.Ajax.install(); + }); + + afterEach(() => { + jasmine.Ajax.uninstall(); + }); + + it('Should render the Process definition overview report ', (done) => { + component.onSuccess.subscribe((res) => { + expect(res).toBeDefined(); + expect(res.length).toEqual(3); + + expect(res[0]).toBeDefined(); + expect(res[0].type).toEqual('table'); + expect(res[0].datasets).toBeDefined(); + expect(res[0].datasets.length).toEqual(4); + expect(res[0].datasets[0][0]).toEqual('__KEY_REPORTING.DEFAULT-REPORTS.PROCESS-DEFINITION-OVERVIEW.GENERAL-TABLE-TOTAL-PROCESS-DEFINITIONS'); + expect(res[0].datasets[0][1]).toEqual('9'); + expect(res[0].datasets[1][0]).toEqual('__KEY_REPORTING.DEFAULT-REPORTS.PROCESS-DEFINITION-OVERVIEW.GENERAL-TABLE-TOTAL-PROCESS-INSTANCES'); + expect(res[0].datasets[1][1]).toEqual('41'); + expect(res[0].datasets[2][0]).toEqual('__KEY_REPORTING.DEFAULT-REPORTS.PROCESS-DEFINITION-OVERVIEW.GENERAL-TABLE-ACTIVE-PROCESS-INSTANCES'); + expect(res[0].datasets[2][1]).toEqual('3'); + expect(res[0].datasets[3][0]).toEqual('__KEY_REPORTING.DEFAULT-REPORTS.PROCESS-DEFINITION-OVERVIEW.GENERAL-TABLE-COMPLETED-PROCESS-INSTANCES'); + expect(res[0].datasets[3][1]).toEqual('38'); + + expect(res[1]).toBeDefined(); + expect(res[1].type).toEqual('pie'); + + expect(res[2]).toBeDefined(); + expect(res[2].type).toEqual('table'); + + done(); + }); + + let reportId = 1001; + let reportParamQuery = new ReportQuery({status: 'All'}); + + component.generateReport(reportId, reportParamQuery); + + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: analyticMock.chartProcessDefOverview + }); + }); + + it('Should render the Task overview report ', (done) => { + component.onSuccess.subscribe((res) => { + expect(res).toBeDefined(); + expect(res.length).toEqual(3); + + expect(res[0]).toBeDefined(); + expect(res[0].type).toEqual('bar'); + expect(res[0].labels).toBeDefined(); + expect(res[0].labels.length).toEqual(2); + expect(res[0].labels[0]).toEqual('2016-09-30T00:00:00.000+0000'); + expect(res[0].labels[1]).toEqual('2016-10-04T00:00:00.000+0000'); + expect(res[0].datasets[0].label).toEqual('series1'); + expect(res[0].datasets[0].data[0]).toEqual(3); + expect(res[0].datasets[0].data[1]).toEqual(1); + + expect(res[1]).toBeDefined(); + expect(res[1].type).toEqual('masterDetailTable'); + expect(res[1].datasets).toBeDefined(); + expect(res[1].datasets.length).toEqual(2); + expect(res[1].datasets[0][0]).toEqual('fake 1 user task'); + expect(res[1].datasets[0][1]).toEqual('1'); + expect(res[1].datasets[0][2]).toEqual('2.0'); + expect(res[1].datasets[0][3]).toEqual('3.0'); + expect(res[1].datasets[0][4]).toEqual('4.0'); + expect(res[1].datasets[0][5]).toEqual('5.0'); + expect(res[1].datasets[0][6]).toEqual('6.0'); + expect(res[1].datasets[1][0]).toEqual('fake 2 user task'); + expect(res[1].datasets[1][1]).toEqual('1'); + expect(res[1].datasets[1][2]).toEqual('2.0'); + expect(res[1].datasets[1][3]).toEqual('3.0'); + expect(res[1].datasets[1][4]).toEqual('4.0'); + expect(res[1].datasets[1][5]).toEqual('5.0'); + expect(res[1].datasets[1][6]).toEqual('6.0'); + + expect(res[2]).toBeDefined(); + expect(res[2].type).toEqual('multiBar'); + expect(res[2].labels).toBeDefined(); + expect(res[2].labels.length).toEqual(3); + expect(res[2].labels[0]).toEqual(1); + expect(res[2].labels[1]).toEqual(2); + expect(res[2].labels[2]).toEqual(3); + expect(res[2].datasets[0].label).toEqual('averages'); + expect(res[2].datasets[0].data[0]).toEqual(0); + expect(res[2].datasets[0].data[1]).toEqual(5); + expect(res[2].datasets[0].data[2]).toEqual(2); + expect(res[2].datasets[1].label).toEqual('minima'); + expect(res[2].datasets[1].data[0]).toEqual(0); + expect(res[2].datasets[1].data[1]).toEqual(0); + expect(res[2].datasets[1].data[2]).toEqual(0); + expect(res[2].datasets[2].label).toEqual('maxima'); + expect(res[2].datasets[2].data[0]).toEqual(0); + expect(res[2].datasets[2].data[1]).toEqual(29); + expect(res[2].datasets[2].data[2]).toEqual(29); + + done(); + }); + + let reportParamQuery = new ReportQuery({status: 'All'}); + component.reportId = 1; + component.generateReport(reportParamQuery); + + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: analyticMock.chartTaskOverview + }); + }); + + it('Should reset the reports when the onChanged is call', () => { + component.reports = [ new Chart({id: 'fake', type: 'fake-type'})]; + component.reportId = 1; + component.ngOnChanges(); + expect(component.reports).toBeUndefined(); + }); + + it('Should emit onError event with a 404 response ', (done) => { + component.onError.subscribe((err) => { + expect(err).toBeDefined(); + done(); + }); + + let reportParamQuery = new ReportQuery({status: 'All'}); + component.reportId = 1; + component.generateReport(reportParamQuery); + + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 404, + contentType: 'json', + responseText: [] + }); + }); + }); +}); diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.ts new file mode 100644 index 00000000000..09097365c87 --- /dev/null +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-generator.component.ts @@ -0,0 +1,119 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, EventEmitter, OnChanges, Input, Output, SimpleChanges } from '@angular/core'; +import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core'; +import { AnalyticsService } from '../services/analytics.service'; +import { ReportQuery } from '../models/report.model'; +import { Chart } from '../models/chart.model'; + +@Component({ + moduleId: module.id, + selector: 'activiti-analytics-generator', + templateUrl: './analytics-generator.component.html', + styleUrls: ['./analytics-generator.component.css'] +}) +export class AnalyticsGeneratorComponent implements OnChanges { + + @Input() + reportId: number; + + @Input() + reportParamQuery: ReportQuery = undefined; + + @Output() + onSuccess = new EventEmitter(); + + @Output() + onError = new EventEmitter(); + + reports: Chart[]; + + showDetails: boolean = false; + + public barChartOptions: any = { + responsive: true, + scales: { + yAxes: [{ + ticks: { + beginAtZero: true, + stepSize: 1 + } + }], + xAxes: [{ + ticks: { + }, + stacked: true + }] + } + }; + + constructor(private translateService: AlfrescoTranslationService, + private analyticsService: AnalyticsService, + private logService: LogService) { + logService.info('AnalyticsGeneratorComponent'); + if (translateService) { + translateService.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/src'); + } + } + + ngOnChanges(changes: SimpleChanges) { + if (this.reportId && this.reportParamQuery) { + this.generateReport(this.reportId, this.reportParamQuery); + } else { + this.reset(); + } + } + + public generateReport(reportId, reportParamQuery) { + this.analyticsService.getReportsByParams(reportId, reportParamQuery).subscribe( + (res: Chart[]) => { + this.reports = res; + this.onSuccess.emit(res); + }, + (err: any) => { + this.onError.emit(err); + this.logService.error(err); + } + ); + } + + public reset() { + if (this.reports) { + this.reports = undefined; + } + } + + public refresh(report): void { + /** + * (My guess), for Angular to recognize the change in the dataset + * it has to change the dataset variable directly, + * so one way around it, is to clone the data, change it and then + * assign it; + */ + let clone = JSON.parse(JSON.stringify(report)); + report.datasets = clone.datasets; + } + + toggleDetailsTable() { + this.showDetails = !this.showDetails; + } + + isShowDetails(): boolean { + return this.showDetails; + } +} diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.spec.ts index bb02e9a5e98..b5baa073f89 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.spec.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.spec.ts @@ -15,17 +15,18 @@ * limitations under the License. */ +import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { CoreModule } from 'ng2-alfresco-core'; +import { Observable } from 'rxjs/Rx'; +import { CoreModule, AlfrescoTranslationService } from 'ng2-alfresco-core'; import { DiagramsModule } from 'ng2-activiti-diagrams'; import { AnalyticsReportHeatMapComponent } from '../components/analytics-report-heat-map.component'; import { WIDGET_DIRECTIVES } from '../components/widgets/index'; import { AnalyticsService } from '../services/analytics.service'; -import { DebugElement } from '@angular/core'; declare let jasmine: any; -describe('Test ng2-activiti-analytics-report-heat-map', () => { +describe('AnalyticsReportHeatMapComponent', () => { let componentHandler: any; let component: any; @@ -44,8 +45,8 @@ describe('Test ng2-activiti-analytics-report-heat-map', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - CoreModule, - DiagramsModule + CoreModule.forRoot(), + DiagramsModule.forRoot() ], declarations: [ AnalyticsReportHeatMapComponent, @@ -55,6 +56,11 @@ describe('Test ng2-activiti-analytics-report-heat-map', () => { AnalyticsService ] }).compileComponents(); + + let translateService = TestBed.get(AlfrescoTranslationService); + spyOn(translateService, 'addTranslationFolder').and.stub(); + spyOn(translateService, 'get').and.callFake((key) => { return Observable.of(key); }); + })); beforeEach(() => { diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.ts index 064b4a04c26..df9c81455ac 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.ts @@ -43,11 +43,11 @@ export class AnalyticsReportHeatMapComponent implements OnInit { currentMetricColors: string; metricType: string; - constructor(private translate: AlfrescoTranslationService, + constructor(private translateService: AlfrescoTranslationService, private analyticsService: AnalyticsService, private formBuilder: FormBuilder) { - if (translate) { - translate.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/src'); + if (translateService) { + translateService.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/src'); } } diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.spec.ts index ce2cf64a8ff..c437ab7342e 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.spec.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.spec.ts @@ -15,15 +15,16 @@ * limitations under the License. */ +import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { CoreModule } from 'ng2-alfresco-core'; +import { Observable } from 'rxjs/Rx'; +import { CoreModule, AlfrescoTranslationService } from 'ng2-alfresco-core'; import { AnalyticsReportListComponent } from '../components/analytics-report-list.component'; import { AnalyticsService } from '../services/analytics.service'; -import { DebugElement } from '@angular/core'; declare let jasmine: any; -describe('Test ng2-activiti-analytics Report list', () => { +describe('AnalyticsReportListComponent', () => { let reportList = [ {'id': 2002, 'name': 'Fake Test Process definition heat map'}, @@ -35,7 +36,7 @@ describe('Test ng2-activiti-analytics Report list', () => { let reportSelected = {'id': 2003, 'name': 'Fake Test Process definition overview'}; - let component: any; + let component: AnalyticsReportListComponent; let fixture: ComponentFixture; let debug: DebugElement; let element: HTMLElement; @@ -43,7 +44,7 @@ describe('Test ng2-activiti-analytics Report list', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - CoreModule + CoreModule.forRoot() ], declarations: [ AnalyticsReportListComponent @@ -52,6 +53,10 @@ describe('Test ng2-activiti-analytics Report list', () => { AnalyticsService ] }).compileComponents(); + + let translateService = TestBed.get(AlfrescoTranslationService); + spyOn(translateService, 'addTranslationFolder').and.stub(); + spyOn(translateService, 'get').and.callFake((key) => { return Observable.of(key); }); })); beforeEach(() => { diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.ts index 47ce38c21bc..ca2649f2304 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.ts @@ -16,11 +16,10 @@ */ import { Component, EventEmitter, OnInit, Output } from '@angular/core'; -import { AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { Observer, Observable } from 'rxjs/Rx'; +import { LogService } from 'ng2-alfresco-core'; import { AnalyticsService } from '../services/analytics.service'; import { ReportParametersModel } from '../models/report.model'; -import { Observer } from 'rxjs/Observer'; -import { Observable } from 'rxjs/Observable'; @Component({ moduleId: module.id, @@ -46,9 +45,8 @@ export class AnalyticsReportListComponent implements OnInit { reports: ReportParametersModel[] = []; - constructor(private auth: AlfrescoAuthenticationService, - private analyticsService: AnalyticsService) { - + constructor(private analyticsService: AnalyticsService, + private logService: LogService) { this.report$ = new Observable(observer => this.reportObserver = observer).share(); } @@ -85,7 +83,7 @@ export class AnalyticsReportListComponent implements OnInit { }, (err: any) => { this.onError.emit(err); - console.log(err); + this.logService.error(err); } ); } diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css index 344b6e05256..07f935cbb94 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css @@ -48,3 +48,18 @@ .icon-small:hover .material-icons { display: block; } + +.is-hide { + height: 0px; + overflow: hidden; + transition: height 0.5s; +} + +.report-container { + border: solid 1px rgb(212, 212, 212); + padding: 10px 10px 10px 10px; +} + +.report-container-setting { + padding-left: 10px; +} diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html index 7c277338bb2..98939ea4427 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html @@ -1,75 +1,83 @@ -
-
-
-
- -
-
- - mode_edit -

{{reportParameters.name}}

-
-

-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
- {{'ANALYTICS.MESSAGES.UNKNOWN-WIDGET-TYPE' | translate}}: {{field.type}} +
+ + + {{'ANALYTICS.MESSAGES.SETTING-TITLE' | translate}} + +
+
+ +
+ +
+
+ + mode_edit +

{{reportParameters.name}}

+
+

+
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+ {{'ANALYTICS.MESSAGES.UNKNOWN-WIDGET-TYPE' | translate}}: {{field.type}} +
+
+

ReportForm valid : {{ reportForm.valid }}

+

ReportForm status : {{ reportForm.errors | json }}

+

ReportForm FormGroup valid : {{reportForm && reportForm.controls.dateRange.valid | json }}

+
+
-
-

ReportForm valid : {{ reportForm.valid }}

-

ReportForm status : {{ reportForm.errors | json }}

-

ReportForm FormGroup valid : {{reportForm && reportForm.controls.dateRange.valid | json }}

-
-
diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts index 74eb9075ee6..4354d1bb259 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts @@ -16,25 +16,23 @@ */ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { - CoreModule -} from 'ng2-alfresco-core'; +import { DebugElement, SimpleChange } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; +import * as moment from 'moment'; +import { CoreModule, AlfrescoTranslationService } from 'ng2-alfresco-core'; import { AnalyticsReportParametersComponent } from '../components/analytics-report-parameters.component'; import { WIDGET_DIRECTIVES } from '../components/widgets/index'; - import { AnalyticsService } from '../services/analytics.service'; import { ReportParametersModel } from '../models/report.model'; -import * as moment from 'moment'; -import { DebugElement, SimpleChange } from '@angular/core'; import * as analyticParamsMock from '../assets/analyticsParamsReportComponent.mock'; declare let jasmine: any; declare let mdDateTimePicker: any; -describe('Test ng2-analytics-report-parameters Report Parameters ', () => { +describe('AnalyticsReportParametersComponent', () => { - let component: any; + let component: AnalyticsReportParametersComponent; let fixture: ComponentFixture; let debug: DebugElement; let element: HTMLElement; @@ -44,7 +42,7 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - CoreModule + CoreModule.forRoot() ], declarations: [ AnalyticsReportParametersComponent, @@ -54,6 +52,15 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { AnalyticsService ] }).compileComponents(); + + let translateService = TestBed.get(AlfrescoTranslationService); + spyOn(translateService, 'addTranslationFolder').and.stub(); + spyOn(translateService, 'get').and.callFake((key) => { return Observable.of(key); }); + + componentHandler = jasmine.createSpyObj('componentHandler', [ + 'upgradeAllRegistered' + ]); + window['componentHandler'] = componentHandler; })); beforeEach(() => { @@ -62,10 +69,6 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { debug = fixture.debugElement; element = fixture.nativeElement; fixture.detectChanges(); - componentHandler = jasmine.createSpyObj('componentHandler', [ - 'upgradeAllRegistered' - ]); - window['componentHandler'] = componentHandler; }); describe('Rendering tests', () => { @@ -323,9 +326,9 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { responseText: analyticParamsMock.reportDefParamProcessDefOptionsApp }); - let appId = 1; + let appId = '1'; component.appId = appId; - component.reportId = 1; + component.reportId = '1'; let change = new SimpleChange(null, appId); component.ngOnChanges({ 'appId': change }); @@ -341,7 +344,7 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { expect(res[1].name).toEqual('Fake task name 2'); }); - component.reportId = 100; + component.reportId = '100'; component.reportParameters = new ReportParametersModel(analyticParamsMock.reportDefParamTask); component.onProcessDefinitionChanges(analyticParamsMock.fieldProcessDef); @@ -392,10 +395,10 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { responseText: [] }); }); - }); - it('Should convert a string in number', () => { - let numberConvert = component.convertNumber('2'); - expect(numberConvert).toEqual(2); + it('Should convert a string in number', () => { + let numberConvert = component.convertNumber('2'); + expect(numberConvert).toEqual(2); + }); }); }); diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts index cd9b7366e22..b1e32973280 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts @@ -15,12 +15,29 @@ * limitations under the License. */ -import { Component, EventEmitter, OnInit, OnChanges, Input, Output, SimpleChanges } from '@angular/core'; -import { AlfrescoTranslationService } from 'ng2-alfresco-core'; -import { AnalyticsService } from '../services/analytics.service'; -import { ReportParametersModel, ReportQuery, ParameterValueModel, ReportParameterDetailsModel } from '../models/report.model'; +import { + Component, + EventEmitter, + OnInit, + OnChanges, + Input, + Output, + SimpleChanges, + OnDestroy, + AfterViewChecked +} from '@angular/core'; import { FormGroup, FormBuilder, FormControl } from '@angular/forms'; import * as moment from 'moment'; +import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core'; +import { AnalyticsService } from '../services/analytics.service'; +import { + ReportParametersModel, + ReportQuery, + ParameterValueModel, + ReportParameterDetailsModel +} from '../models/report.model'; + +declare var componentHandler; @Component({ moduleId: module.id, @@ -28,7 +45,7 @@ import * as moment from 'moment'; templateUrl: './analytics-report-parameters.component.html', styleUrls: ['./analytics-report-parameters.component.css'] }) -export class AnalyticsReportParametersComponent implements OnInit, OnChanges { +export class AnalyticsReportParametersComponent implements OnInit, OnChanges, OnDestroy, AfterViewChecked { public static FORMAT_DATE_ACTIVITI: string = 'YYYY-MM-DD'; @@ -67,12 +84,14 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges { private reportParamsSub; private paramOpts; private isEditable: boolean = false; + private hideParameters: boolean = true; - constructor(private translate: AlfrescoTranslationService, + constructor(private translateService: AlfrescoTranslationService, private analyticsService: AnalyticsService, - private formBuilder: FormBuilder ) { - if (translate) { - translate.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/src'); + private formBuilder: FormBuilder, + private logService: LogService) { + if (translateService) { + translateService.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/src'); } } @@ -146,7 +165,7 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges { } }, (err: any) => { - console.log(err); + this.logService.error(err); this.onError.emit(err); } ); @@ -160,7 +179,7 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges { this.onSuccessParamOpt.emit(opts); }, (err: any) => { - console.log(err); + this.logService.error(err); this.onError.emit(err); } ); @@ -231,9 +250,24 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges { this.onEdit.emit(this.reportParameters.name); }, (err: any) => { - console.log(err); + this.logService.error(err); this.onError.emit(err); } ); } + + ngAfterViewChecked() { + // workaround for MDL issues with dynamic components + if (componentHandler) { + componentHandler.upgradeAllRegistered(); + } + } + + toggleParameters() { + this.hideParameters = !this.hideParameters; + } + + isParametersHide() { + return this.hideParameters; + } } diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.css b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.css index 096757598aa..552ee0cc18e 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.css +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.css @@ -1,25 +1 @@ .chart {display: block; width: 100%;} - -.dropdown-widget { - width: 100%; -} - -.dropdown-widget__select { - width: 100%; -} - -.dropdown-widget__invalid .dropdown-widget__select { - border-color: #d50000; -} - -.dropdown-widget__invalid .dropdown-widget__label { - color: #d50000; -} - -.dropdown-widget__invalid .dropdown-widget__label:after { - background-color: #d50000; -} - -.dropdown-widget__invalid .mdl-textfield__error { - visibility: visible !important; -} diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html index a52b7480c71..0cfae9ccdcf 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html @@ -5,83 +5,8 @@ (onEdit)="onEditReport($event)"> -
-
-

{{report.title}}

-
-
-
-
{{'ANALYTICS.MESSAGES.NO-DATA-FOUND' | translate}}
- -
-
-
-
{{'ANALYTICS.MESSAGES.NO-DATA-FOUND' | translate}}
-
- - - - - - - -
{{label | translate}}
{{row | translate }}
-
-
-
-
{{'ANALYTICS.MESSAGES.NO-DATA-FOUND' | translate}}
-
- - - - - - - -
{{label | translate}}
{{row | translate }}
-
-
-
-
-
{{'ANALYTICS.MESSAGES.NO-DATA-FOUND' | translate}}
- -
-
-
-
-
{{'ANALYTICS.MESSAGES.NO-DATA-FOUND' | translate}}
-
- - -
-
-
-
- -
-
- {{'ANALYTICS.MESSAGES.UNKNOWN-WIDGET-TYPE' | translate}}: {{report.type}} -
-
-
-
-


-
{{'ANALYTICS.MESSAGES.FILL-PARAMETER' | translate}}
-
\ No newline at end of file + + +
diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.spec.ts index 4adbcbbed88..a61ec1074a1 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.spec.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.spec.ts @@ -16,25 +16,23 @@ */ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { - CoreModule -} from 'ng2-alfresco-core'; +import { DebugElement } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; +import { CHART_DIRECTIVES } from 'ng2-charts/ng2-charts'; +import { CoreModule, AlfrescoTranslationService } from 'ng2-alfresco-core'; import { DiagramsModule } from 'ng2-activiti-diagrams'; import { AnalyticsReportListComponent } from '../components/analytics-report-list.component'; import { AnalyticsComponent } from '../components/analytics.component'; +import { AnalyticsGeneratorComponent } from '../components/analytics-generator.component'; import { AnalyticsReportParametersComponent } from '../components/analytics-report-parameters.component'; import { AnalyticsReportHeatMapComponent } from '../components/analytics-report-heat-map.component'; import { WIDGET_DIRECTIVES } from '../components/widgets/index'; -import { CHART_DIRECTIVES } from 'ng2-charts/ng2-charts'; -import { Chart } from '../models/chart.model'; import { AnalyticsService } from '../services/analytics.service'; -import { ReportQuery } from '../models/report.model'; -import { DebugElement, SimpleChange } from '@angular/core'; -import * as analyticMock from '../assets/analyticsComponent.mock'; export const ANALYTICS_DIRECTIVES: any[] = [ AnalyticsComponent, + AnalyticsGeneratorComponent, AnalyticsReportParametersComponent, AnalyticsReportListComponent, AnalyticsReportHeatMapComponent, @@ -47,7 +45,7 @@ export const ANALYTICS_PROVIDERS: any[] = [ declare let jasmine: any; declare let mdDateTimePicker: any; -describe('Test ng2-activiti-analytics Report ', () => { +describe('AnalyticsComponent', () => { let component: any; let fixture: ComponentFixture; @@ -59,8 +57,8 @@ describe('Test ng2-activiti-analytics Report ', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - CoreModule, - DiagramsModule + CoreModule.forRoot(), + DiagramsModule.forRoot() ], declarations: [ ...ANALYTICS_DIRECTIVES, @@ -70,6 +68,10 @@ describe('Test ng2-activiti-analytics Report ', () => { ...ANALYTICS_PROVIDERS ] }).compileComponents(); + + let translateService = TestBed.get(AlfrescoTranslationService); + spyOn(translateService, 'addTranslationFolder').and.stub(); + spyOn(translateService, 'get').and.callFake((key) => { return Observable.of(key); }); })); beforeEach(() => { @@ -93,136 +95,5 @@ describe('Test ng2-activiti-analytics Report ', () => { jasmine.Ajax.uninstall(); }); - it('Should render the Process definition overview report ', (done) => { - component.onSuccess.subscribe((res) => { - expect(res).toBeDefined(); - expect(res.length).toEqual(3); - - expect(res[0]).toBeDefined(); - expect(res[0].type).toEqual('table'); - expect(res[0].datasets).toBeDefined(); - expect(res[0].datasets.length).toEqual(4); - expect(res[0].datasets[0][0]).toEqual('__KEY_REPORTING.DEFAULT-REPORTS.PROCESS-DEFINITION-OVERVIEW.GENERAL-TABLE-TOTAL-PROCESS-DEFINITIONS'); - expect(res[0].datasets[0][1]).toEqual('9'); - expect(res[0].datasets[1][0]).toEqual('__KEY_REPORTING.DEFAULT-REPORTS.PROCESS-DEFINITION-OVERVIEW.GENERAL-TABLE-TOTAL-PROCESS-INSTANCES'); - expect(res[0].datasets[1][1]).toEqual('41'); - expect(res[0].datasets[2][0]).toEqual('__KEY_REPORTING.DEFAULT-REPORTS.PROCESS-DEFINITION-OVERVIEW.GENERAL-TABLE-ACTIVE-PROCESS-INSTANCES'); - expect(res[0].datasets[2][1]).toEqual('3'); - expect(res[0].datasets[3][0]).toEqual('__KEY_REPORTING.DEFAULT-REPORTS.PROCESS-DEFINITION-OVERVIEW.GENERAL-TABLE-COMPLETED-PROCESS-INSTANCES'); - expect(res[0].datasets[3][1]).toEqual('38'); - - expect(res[1]).toBeDefined(); - expect(res[1].type).toEqual('pie'); - - expect(res[2]).toBeDefined(); - expect(res[2].type).toEqual('table'); - - done(); - }); - - let reportParamQuery = new ReportQuery({status: 'All'}); - component.appId = 1; - component.reportId = 1001; - component.showReport(reportParamQuery); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: analyticMock.chartProcessDefOverview - }); - }); - - it('Should render the Task overview report ', (done) => { - component.onSuccess.subscribe((res) => { - expect(res).toBeDefined(); - expect(res.length).toEqual(3); - - expect(res[0]).toBeDefined(); - expect(res[0].type).toEqual('bar'); - expect(res[0].labels).toBeDefined(); - expect(res[0].labels.length).toEqual(2); - expect(res[0].labels[0]).toEqual('2016-09-30T00:00:00.000+0000'); - expect(res[0].labels[1]).toEqual('2016-10-04T00:00:00.000+0000'); - expect(res[0].datasets[0].label).toEqual('series1'); - expect(res[0].datasets[0].data[0]).toEqual(3); - expect(res[0].datasets[0].data[1]).toEqual(1); - - expect(res[1]).toBeDefined(); - expect(res[1].type).toEqual('table'); - expect(res[1].datasets).toBeDefined(); - expect(res[1].datasets.length).toEqual(2); - expect(res[1].datasets[0][0]).toEqual('fake 1 user task'); - expect(res[1].datasets[0][1]).toEqual('1'); - expect(res[1].datasets[0][2]).toEqual('2.0'); - expect(res[1].datasets[0][3]).toEqual('3.0'); - expect(res[1].datasets[0][4]).toEqual('4.0'); - expect(res[1].datasets[0][5]).toEqual('5.0'); - expect(res[1].datasets[0][6]).toEqual('6.0'); - expect(res[1].datasets[1][0]).toEqual('fake 2 user task'); - expect(res[1].datasets[1][1]).toEqual('1'); - expect(res[1].datasets[1][2]).toEqual('2.0'); - expect(res[1].datasets[1][3]).toEqual('3.0'); - expect(res[1].datasets[1][4]).toEqual('4.0'); - expect(res[1].datasets[1][5]).toEqual('5.0'); - expect(res[1].datasets[1][6]).toEqual('6.0'); - - expect(res[2]).toBeDefined(); - expect(res[2].type).toEqual('multiBar'); - expect(res[2].labels).toBeDefined(); - expect(res[2].labels.length).toEqual(3); - expect(res[2].labels[0]).toEqual(1); - expect(res[2].labels[1]).toEqual(2); - expect(res[2].labels[2]).toEqual(3); - expect(res[2].datasets[0].label).toEqual('averages'); - expect(res[2].datasets[0].data[0]).toEqual(0); - expect(res[2].datasets[0].data[1]).toEqual(5); - expect(res[2].datasets[0].data[2]).toEqual(2); - expect(res[2].datasets[1].label).toEqual('minima'); - expect(res[2].datasets[1].data[0]).toEqual(0); - expect(res[2].datasets[1].data[1]).toEqual(0); - expect(res[2].datasets[1].data[2]).toEqual(0); - expect(res[2].datasets[2].label).toEqual('maxima'); - expect(res[2].datasets[2].data[0]).toEqual(0); - expect(res[2].datasets[2].data[1]).toEqual(29); - expect(res[2].datasets[2].data[2]).toEqual(29); - - done(); - }); - - let reportParamQuery = new ReportQuery({status: 'All'}); - component.reportId = 1; - component.showReport(reportParamQuery); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: analyticMock.chartTaskOverview - }); - }); - - it('Should reset the reports when the onChanged is call', () => { - let reportId = 1; - component.reports = [ new Chart({id: 'fake', type: 'fake-type'})]; - let change = new SimpleChange(null, reportId); - component.ngOnChanges({ 'reportId': change }); - expect(component.reports).toBeUndefined(); - }); - - it('Should emit onError event with a 404 response ', (done) => { - component.onError.subscribe((err) => { - expect(err).toBeDefined(); - done(); - }); - - let reportParamQuery = new ReportQuery({status: 'All'}); - component.reportId = 1; - component.showReport(reportParamQuery); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 404, - contentType: 'json', - responseText: [] - }); - }); }); }); diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts index 6db510d36d1..21572dd43ef 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts @@ -15,11 +15,11 @@ * limitations under the License. */ -import { Component, EventEmitter, OnChanges, Input, Output, SimpleChanges } from '@angular/core'; -import { AlfrescoTranslationService } from 'ng2-alfresco-core'; +import { Component, EventEmitter, OnChanges, Input, Output, SimpleChanges, ViewChild } from '@angular/core'; +import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core'; import { AnalyticsService } from '../services/analytics.service'; import { ReportQuery } from '../models/report.model'; -import { Chart } from '../models/chart.model'; +import { AnalyticsGeneratorComponent } from './analytics-generator.component'; @Component({ moduleId: module.id, @@ -30,7 +30,7 @@ import { Chart } from '../models/chart.model'; export class AnalyticsComponent implements OnChanges { @Input() - appId: string; + appId: number; @Input() reportId: number; @@ -38,80 +38,37 @@ export class AnalyticsComponent implements OnChanges { @Input() debug: boolean = false; - @Output() - onSuccess = new EventEmitter(); - @Output() editReport = new EventEmitter(); - @Output() - onError = new EventEmitter(); - - reportParamQuery = new ReportQuery(); - - reports: Chart[]; + @ViewChild('analyticsgenerator') + analyticsgenerator: AnalyticsGeneratorComponent; - public barChartOptions: any = { - responsive: true, - scales: { - yAxes: [{ - ticks: { - beginAtZero: true, - stepSize: 1 - } - }], - xAxes: [{ - ticks: { - }, - stacked: true - }] - } - }; + reportParamQuery: ReportQuery; - constructor(private translate: AlfrescoTranslationService, - private analyticsService: AnalyticsService) { - console.log('AnalyticsComponent'); - if (translate) { - translate.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/src'); + constructor(private translateService: AlfrescoTranslationService, + private analyticsService: AnalyticsService, + private logService: LogService) { + logService.info('AnalyticsComponent'); + if (translateService) { + translateService.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/src'); } } ngOnChanges(changes: SimpleChanges) { - this.reset(); + this.analyticsgenerator.reset(); } public showReport($event) { - this.reportParamQuery = $event; - this.analyticsService.getReportsByParams(this.reportId, this.reportParamQuery).subscribe( - (res: Chart[]) => { - this.reports = res; - this.onSuccess.emit(res); - }, - (err: any) => { - this.onError.emit(err); - console.log(err); - } - ); + this.analyticsgenerator.generateReport(this.reportId, $event); } public reset() { - if (this.reports) { - this.reports = undefined; - } - } - - public refresh(report): void { - /** - * (My guess), for Angular to recognize the change in the dataset - * it has to change the dataset variable directly, - * so one way around it, is to clone the data, change it and then - * assign it; - */ - let clone = JSON.parse(JSON.stringify(report)); - report.datasets = clone.datasets; + this.analyticsgenerator.reset(); } public onEditReport(name: string) { this.editReport.emit(name); } + } diff --git a/ng2-components/ng2-activiti-analytics/src/components/widgets/dropdown/dropdown.widget.html b/ng2-components/ng2-activiti-analytics/src/components/widgets/dropdown/dropdown.widget.html index 8ab003b892d..25d819965c7 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/widgets/dropdown/dropdown.widget.html +++ b/ng2-components/ng2-activiti-analytics/src/components/widgets/dropdown/dropdown.widget.html @@ -2,7 +2,7 @@
\ No newline at end of file diff --git a/ng2-components/ng2-activiti-analytics/src/i18n/en.json b/ng2-components/ng2-activiti-analytics/src/i18n/en.json index 1dce1a9c608..008eb48aff0 100644 --- a/ng2-components/ng2-activiti-analytics/src/i18n/en.json +++ b/ng2-components/ng2-activiti-analytics/src/i18n/en.json @@ -4,7 +4,9 @@ "MESSAGES": { "UNKNOWN-WIDGET-TYPE": "UNKNOWN WIDGET TYPE", "FILL-PARAMETER": "Fill in the parameters to generate your report", - "NO-DATA-FOUND": "No data found" + "NO-DATA-FOUND": "No data found", + "ZERO-DATA-FOUND": "There are only zero values", + "SETTING-TITLE": "Change report setting" } }, "__KEY_REPORTING": { diff --git a/ng2-components/ng2-activiti-analytics/src/i18n/it.json b/ng2-components/ng2-activiti-analytics/src/i18n/it.json index 15c05b6832c..8caf96732f1 100644 --- a/ng2-components/ng2-activiti-analytics/src/i18n/it.json +++ b/ng2-components/ng2-activiti-analytics/src/i18n/it.json @@ -1,5 +1,47 @@ { "ANALYTICS": { - "TTILE": "ANALYTICS" + "TTILE": "ANALYTICS", + "MESSAGES": { + "UNKNOWN-WIDGET-TYPE": "TIPO WIDGET SCONOSCIUTO", + "FILL-PARAMETER": "Riempi tutti i campi per generare il report", + "NO-DATA-FOUND": "Nessun valore trovato", + "ZERO-DATA-FOUND": "Ci sono solo valori che valgono zero", + "SETTING-TITLE": "Modifica i parametri del report" + } + }, + "__KEY_REPORTING": { + "DEFAULT-REPORTS": { + "PROCESS-DEFINITION-OVERVIEW": { + "GENERAL-TABLE-TOTAL-PROCESS-DEFINITIONS": "Numero totale di process definitions", + "GENERAL-TABLE-TOTAL-PROCESS-INSTANCES": "Numero totale di process instances", + "GENERAL-TABLE-ACTIVE-PROCESS-INSTANCES": "Numero totale di process instances attivi", + "GENERAL-TABLE-COMPLETED-PROCESS-INSTANCES": "Numero totale di process instances completi" + } + } + }, + "REPORTING": { + "DEFAULT-REPORTS": { + "PROCESS-HEAT-MAP": { + "TYPE-FILTERING": "Include tutti gli steps (Deselezionandolo, rimuoverai gli step come start events, gateways, etc.)?" + }, + "PROCESS-INSTANCES-OVERVIEW": { + "PROCESS-DEFINITION": "Definizione del processo", + "DATE-RANGE": "Intervallo di Date", + "SLOW-PROC-INST-NUMBER": "Quanti process instances lenti vuoi mostrare?" + }, + "TASK-OVERVIEW": { + "PROCESS-DEFINITION": "Definizione del processo", + "DATE-RANGE": "Intervallo di Date", + "DATE-RANGE-INTERVAL": "Aggrega date per" + }, + "TASK-SLA": { + "TASK": "Task", + "PROCESS-DEFINITION": "Definizione del processo", + "DATE-RANGE": "Intervallo di Date", + "SLA-DURATION": "Qual' é il tempo che questo task necessita per essere completato per rimanere nella SLA?" + } + }, + "PROCESS-STATUS": "Stato del processo", + "TASK-STATUS": "Stato del task" } } diff --git a/ng2-components/ng2-activiti-analytics/src/models/chart.model.ts b/ng2-components/ng2-activiti-analytics/src/models/chart.model.ts index 57ee906a890..5eaa1b38988 100644 --- a/ng2-components/ng2-activiti-analytics/src/models/chart.model.ts +++ b/ng2-components/ng2-activiti-analytics/src/models/chart.model.ts @@ -49,6 +49,9 @@ export class Chart { case 'processDefinitionHeatMap': chartType = 'HeatMap'; break; + case 'masterDetailTable': + chartType = 'masterDetailTable'; + break; default: chartType = 'table'; break; @@ -191,6 +194,22 @@ export class TableChart extends Chart { } } +export class DetailsTableChart extends TableChart { + detailsTable: any; + showDetails: boolean = false; + + constructor(obj?: any) { + super(obj); + if (obj.detailTables) { + this.detailsTable = new TableChart(obj.detailTables[0]); + } + } + + hasDetailsTable() { + return this.detailsTable ? true : false; + } +} + export class HeatMapChart extends Chart { avgTimePercentages: string; avgTimeValues: string; @@ -236,7 +255,20 @@ export class PieChart extends Chart { this.data.push(data); } - hasData() { + hasData(): boolean { return this.data && this.data.length > 0 ? true : false; } + + hasZeroValues(): boolean { + let isZeroValues: boolean = false; + if (this.hasData()) { + isZeroValues = true; + this.data.forEach((value) => { + if (value.toString() !== '0') { + isZeroValues = false; + } + }); + } + return isZeroValues; + } } diff --git a/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts b/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts index f1ccd7c7311..c1b3242e4d4 100644 --- a/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts +++ b/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts @@ -16,18 +16,17 @@ */ import { Injectable } from '@angular/core'; -import { AlfrescoAuthenticationService, AlfrescoSettingsService, AlfrescoApiService } from 'ng2-alfresco-core'; import { Observable } from 'rxjs/Rx'; import { Response } from '@angular/http'; +import { AlfrescoApiService, LogService } from 'ng2-alfresco-core'; import { ReportParametersModel, ParameterValueModel } from '../models/report.model'; -import { Chart, PieChart, TableChart, BarChart, HeatMapChart, MultiBarChart } from '../models/chart.model'; +import { Chart, PieChart, TableChart, BarChart, HeatMapChart, MultiBarChart, DetailsTableChart } from '../models/chart.model'; @Injectable() export class AnalyticsService { - constructor(private authService: AlfrescoAuthenticationService, - public apiService: AlfrescoApiService, - private alfrescoSettingsService: AlfrescoSettingsService) { + constructor(private apiService: AlfrescoApiService, + private logService: LogService) { } /** @@ -43,14 +42,14 @@ export class AnalyticsService { reports.push(reportModel); }); return reports; - }).catch(this.handleError); + }).catch(err => this.handleError(err)); } getReportParams(reportId: string): Observable { return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getReportParams(reportId)) .map((res: any) => { return new ReportParametersModel(res); - }).catch(this.handleError); + }).catch(err => this.handleError(err)); } getParamValuesByType(type: string, appId: string, reportId?: string, processDefinitionId?: string) { @@ -123,7 +122,7 @@ export class AnalyticsService { paramOptions.push(new ParameterValueModel(opt)); }); return paramOptions; - }).catch(this.handleError); + }).catch(err => this.handleError(err)); } getProcessDefinitionsValues(appId: string): Observable { @@ -134,7 +133,7 @@ export class AnalyticsService { paramOptions.push(new ParameterValueModel(opt)); }); return paramOptions; - }).catch(this.handleError); + }).catch(err => this.handleError(err)); } getTasksByProcessDefinitionId(reportId: string, processDefinitionId: string): Observable { @@ -145,7 +144,7 @@ export class AnalyticsService { paramOptions.push(new ParameterValueModel({ id: opt, name: opt })); }); return paramOptions; - }).catch(this.handleError); + }).catch(err => this.handleError(err)); } getReportsByParams(reportId: number, paramsQuery: any): Observable { @@ -160,7 +159,7 @@ export class AnalyticsService { } else if (chartData.type === 'processDefinitionHeatMap') { elements.push(new HeatMapChart(chartData)); } else if (chartData.type === 'masterDetailTable') { - elements.push(new TableChart(chartData)); + elements.push(new DetailsTableChart(chartData)); } else if (chartData.type === 'barChart') { elements.push(new BarChart(chartData)); } else if (chartData.type === 'multiBarChart') { @@ -169,24 +168,24 @@ export class AnalyticsService { }); return elements; - }).catch(this.handleError); + }).catch(err => this.handleError(err)); } - public createDefaultReports(): Observable { + createDefaultReports(): Observable { return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.createDefaultReports()) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } - public updateReport(reportId: number, name: string): Observable { + updateReport(reportId: number, name: string): Observable { return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.updateReport(reportId, name)) .map((res: any) => { - console.log('upload'); - }).catch(this.handleError); + this.logService.info('upload'); + }).catch(err => this.handleError(err)); } private handleError(error: Response) { - console.error(error); + this.logService.error(error); return Observable.throw(error.json().error || 'Server error'); } diff --git a/ng2-components/ng2-activiti-diagrams/README.md b/ng2-components/ng2-activiti-diagrams/README.md index 5192d5647ad..7b7586e3c8d 100644 --- a/ng2-components/ng2-activiti-diagrams/README.md +++ b/ng2-components/ng2-activiti-diagrams/README.md @@ -62,6 +62,9 @@ Follow the 3 steps below: + + + diff --git a/ng2-components/ng2-activiti-diagrams/demo/package.json b/ng2-components/ng2-activiti-diagrams/demo/package.json index d00651baa9d..4b3c4a8350b 100644 --- a/ng2-components/ng2-activiti-diagrams/demo/package.json +++ b/ng2-components/ng2-activiti-diagrams/demo/package.json @@ -39,17 +39,18 @@ "@angular/http": "2.2.2", "@angular/platform-browser": "2.2.2", "@angular/platform-browser-dynamic": "2.2.2", + "@angular/material": "2.0.0-beta.1", "@angular/router": "3.2.2", "@angular/upgrade": "2.2.2", - "alfresco-js-api": "^1.0.0", + "alfresco-js-api": "~1.1.0", "core-js": "^2.4.1", "dialog-polyfill": "^0.4.3", "element.scrollintoviewifneeded-polyfill": "^1.0.1", "intl": "1.2.4", "material-design-icons": "2.2.3", "material-design-lite": "1.2.1", - "ng2-activiti-diagrams": "^1.0.0", - "ng2-alfresco-core": "1.0.0", + "ng2-activiti-diagrams": "^1.1.0", + "ng2-alfresco-core": "1.1.0", "ng2-translate": "2.5.0", "raphael": "^2.2.6", "reflect-metadata": "^0.1.3", diff --git a/ng2-components/ng2-activiti-diagrams/demo/src/main.ts b/ng2-components/ng2-activiti-diagrams/demo/src/main.ts index cf673fabdb0..d188b528d43 100644 --- a/ng2-components/ng2-activiti-diagrams/demo/src/main.ts +++ b/ng2-components/ng2-activiti-diagrams/demo/src/main.ts @@ -19,40 +19,39 @@ import { NgModule, Component } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService, StorageService } from 'ng2-alfresco-core'; +import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService, StorageService, LogService } from 'ng2-alfresco-core'; import { DiagramsModule } from 'ng2-activiti-diagrams'; @Component({ selector: 'alfresco-app-demo', template: ` -
-
-
-

-
- Authentication failed to ip {{ host }} with user: admin, admin, you can still try to add a valid ticket to perform - operations. -
-
- -
- - ` +
+
+
+

+
+ Authentication failed to ip {{ host }} with user: admin, admin, you can still try to add a valid ticket to perform + operations. +
+
+ +
+ + + ` }) export class DiagramDemoComponent { processDefinitionId: string = 'ThirdProcess:1:15053'; - authenticated: boolean; - host: string = 'http://localhost:9999'; - ticket: string; constructor(private authService: AlfrescoAuthenticationService, private settingsService: AlfrescoSettingsService, - private storage: StorageService) { + private storage: StorageService, + private logService: LogService) { settingsService.bpmHost = this.host; settingsService.setProviders('BPM'); @@ -77,12 +76,12 @@ export class DiagramDemoComponent { login() { this.authService.login('admin', 'admin').subscribe( ticket => { - console.log(ticket); + this.logService.info(`Logged in with ticket ${ticket}`); this.ticket = this.authService.getTicketBpm(); this.authenticated = true; }, error => { - console.log(error); + this.logService.error(error); this.authenticated = false; }); } diff --git a/ng2-components/ng2-activiti-diagrams/karma-test-shim.js b/ng2-components/ng2-activiti-diagrams/karma-test-shim.js index d08f1ebd76a..085bf02f564 100644 --- a/ng2-components/ng2-activiti-diagrams/karma-test-shim.js +++ b/ng2-components/ng2-activiti-diagrams/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; @@ -39,6 +46,8 @@ var map = { '@angular/http': 'npm:@angular/http/bundles/http.umd.js', '@angular/router': 'npm:@angular/router/bundles/router.umd.js', '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/material': 'npm:@angular/material/bundles/material.umd.js', + // testing '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js', '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js', diff --git a/ng2-components/ng2-activiti-diagrams/package.json b/ng2-components/ng2-activiti-diagrams/package.json index 613f2d62381..5f85fc06c9c 100644 --- a/ng2-components/ng2-activiti-diagrams/package.json +++ b/ng2-components/ng2-activiti-diagrams/package.json @@ -1,13 +1,13 @@ { "name": "ng2-activiti-diagrams", "description": "Activiti Angular2 Diagrams Component", - "version": "1.0.0", + "version": "1.1.0", "author": "Alfresco Software, Ltd.", "scripts": { "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings", "clean-build": "rimraf index.js index.js.map index.d.ts'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts' bundles", "build": "npm run clean-build && npm run tslint && rimraf dist && tsc && license-check && npm run build.umd", - "build:w": "npm run clean-build && npm run tslint && rimraf dist && tsc:w && license-check npm run build.umd", + "build:w": "npm run clean-build && npm run tslint && rimraf dist && npm run tsc:w && license-check && npm run build.umd", "tslint": "tslint -c tslint.json 'src/{,**/}**.ts' 'index.ts' -e '{,**/}**.d.ts' -e './gulpfile.ts'", "tsc": "tsc", "tsc:w": "tsc -w", @@ -16,7 +16,7 @@ "test-browser": "npm run build && concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", "posttest": "remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html && remap-istanbul -i coverage/report/coverage-final.json -o coverage/report/coverage-final.json", "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report", - "prepublish": "npm run build", + "prepublish": "npm run test", "travis": "npm link ng2-alfresco-core", "gulp": "gulp", "build.umd": "gulp build.prod --color --env-config prod --build-type prod", @@ -47,21 +47,21 @@ "@angular/http": "2.0.0", "@angular/platform-browser": "2.0.0", "@angular/platform-browser-dynamic": "2.0.0", + "@angular/material": "2.0.0-beta.1", "core-js": "^2.4.1", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.12", "systemjs": "0.19.27", "zone.js": "^0.6.23", "raphael": "^2.2.6", - "chart.js": "^2.1.4", - "ng2-charts": "1.1.0", "ng2-translate": "2.5.0", - "alfresco-js-api": "^1.0.0", - "ng2-alfresco-core": "1.0.0" + "alfresco-js-api": "~1.1.0", + "ng2-alfresco-core": "1.1.0" }, "devDependencies": { "@types/jasmine": "^2.2.33", "@types/node": "^6.0.42", + "autoprefixer": "^6.5.4", "concurrently": "^2.2.0", "cpx": "1.3.1", "cssnano": "^3.8.1", @@ -80,6 +80,7 @@ "gulp-template": "^4.0.0", "gulp-typescript": "^3.1.3", "gulp-uglify": "^2.0.0", + "gulp-util": "^3.0.7", "intl": "^1.2.5", "jasmine-core": "2.4.1", "karma": "0.13.22", @@ -90,6 +91,7 @@ "karma-jasmine-html-reporter": "0.2.0", "karma-mocha-reporter": "2.0.3", "license-check": "1.1.5", + "merge-stream": "^1.0.1", "remap-istanbul": "0.6.3", "rimraf": "2.5.2", "run-sequence": "^1.2.2", diff --git a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.spec.ts b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.spec.ts index bacd8c1cc1b..c46b8765f99 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.spec.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.spec.ts @@ -16,10 +16,7 @@ */ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { - CoreModule, - AlfrescoTranslationService -} from 'ng2-alfresco-core'; +import { CoreModule, AlfrescoTranslationService } from 'ng2-alfresco-core'; import { DIAGRAM_DIRECTIVES, DIAGRAM_PROVIDERS } from './index'; import { RAPHAEL_DIRECTIVES, RAPHAEL_PROVIDERS } from './raphael/index'; @@ -50,7 +47,7 @@ describe('Test ng2-activiti-diagrams ', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - CoreModule + CoreModule.forRoot() ], declarations: [ ...DIAGRAM_DIRECTIVES, diff --git a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.ts index d4e78c7248d..9c64a9bcd17 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.ts @@ -16,7 +16,7 @@ */ import { Component, ElementRef, Input, Output, EventEmitter, SimpleChanges } from '@angular/core'; -import { AlfrescoTranslationService } from 'ng2-alfresco-core'; +import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core'; import { DiagramsService } from '../services/diagrams.service'; import { DiagramColorService } from '../services/diagram-color.service'; import { RaphaelService } from './raphael/raphael.service'; @@ -57,17 +57,16 @@ export class DiagramComponent { PADDING_HEIGHT: number = 60; private diagram: DiagramModel; - private elementRef: ElementRef; - constructor(elementRef: ElementRef, - private translate: AlfrescoTranslationService, + constructor(private elementRef: ElementRef, + private translateService: AlfrescoTranslationService, private diagramColorService: DiagramColorService, private raphaelService: RaphaelService, - private diagramsService: DiagramsService) { - if (translate) { - translate.addTranslationFolder('ng2-activiti-diagrams', 'node_modules/ng2-activiti-diagrams/src'); + private diagramsService: DiagramsService, + private logService: LogService) { + if (translateService) { + translateService.addTranslationFolder('ng2-activiti-diagrams', 'node_modules/ng2-activiti-diagrams/src'); } - this.elementRef = elementRef; } ngOnChanges(changes: SimpleChanges) { @@ -86,7 +85,7 @@ export class DiagramComponent { }, (err: any) => { this.onError.emit(err); - console.log(err); + this.logService.error(err); } ); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-multiline-text.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-multiline-text.component.ts index 0b294970a07..60a1961804a 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-multiline-text.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-multiline-text.component.ts @@ -16,6 +16,7 @@ */ import { Directive, OnInit, ElementRef, Input, Output, EventEmitter } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; import { Point } from './models/point'; import { RaphaelBase } from './raphael-base'; import { RaphaelService } from './raphael.service'; @@ -43,19 +44,20 @@ export class RaphaelMultilineTextDirective extends RaphaelBase implements OnInit TEXT_PADDING = 3; constructor(public elementRef: ElementRef, - raphaelService: RaphaelService) { + raphaelService: RaphaelService, + private logService: LogService) { super(elementRef, raphaelService); } ngOnInit() { - console.log(this.elementRef); + this.logService.log(this.elementRef); if (this.text === null || this.text === undefined) { this.text = ''; } this.draw(this.position, this.text); } - public draw(position: Point, text: string) { + draw(position: Point, text: string) { let textPaper = this.paper.text(position.x + this.TEXT_PADDING, position.y + this.TEXT_PADDING, text).attr({ 'text-anchor': 'middle', 'font-family': 'Arial', diff --git a/ng2-components/ng2-activiti-diagrams/src/services/diagrams.service.ts b/ng2-components/ng2-activiti-diagrams/src/services/diagrams.service.ts index d2d9201b4d2..de67d44b594 100644 --- a/ng2-components/ng2-activiti-diagrams/src/services/diagrams.service.ts +++ b/ng2-components/ng2-activiti-diagrams/src/services/diagrams.service.ts @@ -16,27 +16,28 @@ */ import { Injectable } from '@angular/core'; -import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core'; import { Observable } from 'rxjs/Rx'; import { Response, Http, Headers, RequestOptions } from '@angular/http'; +import { AlfrescoAuthenticationService, AlfrescoSettingsService, LogService } from 'ng2-alfresco-core'; @Injectable() export class DiagramsService { constructor(private authService: AlfrescoAuthenticationService, private http: Http, - private alfrescoSettingsService: AlfrescoSettingsService) { + private settingsService: AlfrescoSettingsService, + private logService: LogService) { } getProcessDefinitionModel(processDefinitionId: string): Observable { - let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/process-definitions/${processDefinitionId}/model-json`; + let url = `${this.settingsService.getBPMApiBaseUrl()}/app/rest/process-definitions/${processDefinitionId}/model-json`; let options = this.getRequestOptions(); return this.http .get(url, options) .map((res: any) => { let body = res.json(); return body; - }).catch(this.handleError); + }).catch(err => this.handleError(err)); } public getHeaders(): Headers { @@ -53,7 +54,7 @@ export class DiagramsService { } private handleError(error: Response) { - console.error(error); + this.logService.error(error); return Observable.throw(error.json().error || 'Server error'); } } diff --git a/ng2-components/ng2-activiti-form/README.md b/ng2-components/ng2-activiti-form/README.md index a3f9ec4b1b3..0a75888091f 100644 --- a/ng2-components/ng2-activiti-form/README.md +++ b/ng2-components/ng2-activiti-form/README.md @@ -31,6 +31,22 @@

+## Library Contents + +### Components + +- [ActivitiForm](#activitiform-component) +- ActivitiStartForm + +### Services + +- [FormService](#formservice) +- ActivitiAlfrescoContentService +- EcmModelService +- FormRenderingService +- NodeService +- WidgetVisibilityService + ## Prerequisites Before you start using this development framework, make sure you have installed all required software and done all the @@ -65,6 +81,9 @@ Follow the 3 steps below: + + + @@ -98,7 +117,9 @@ Follow the 3 steps below: Please refer to the following example file: [systemjs.config.js](demo/systemjs .config.js) . -## Basic usage examples +## ActivitiForm Component + +### Basic usage The component shows a Form from Activiti @@ -109,6 +130,7 @@ The component shows a Form from Activiti Usage example of this component : **main.ts** + ```ts import { NgModule, Component } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @@ -220,9 +242,9 @@ and store the form field as metadata. The param nameNode is optional. ``` -## Configuration +### Configuration -### Properties +#### Properties The recommended set of properties can be found in the following table: @@ -238,11 +260,12 @@ The recommended set of properties can be found in the following table: | `showDebugButton` | boolean | false | Toggle debug options. | | `readOnly` | boolean | false | Toggle readonly state of the form. Enforces all form widgets render readonly if enabled. | | `showRefreshButton` | boolean | true | Toggle rendering of the `Refresh` button. | +| `showValidationIcon` | boolean | true | Toggle rendering of the validation icon next form title. | | `saveMetadata` | boolean | false | Store the value of the form as metadata. | | `path` | string | | Path of the folder where to store the metadata. | | `nameNode` (optional) | string | true | Name to assign to the new node where the metadata are stored. | -#### Advanced properties +##### Advanced properties The following properties are for complex customisation purposes: @@ -251,7 +274,7 @@ The recommended set of properties can be found in the following table: | `form` | FormModel | | Underlying form model instance. | | `debugMode` | boolean | false | Toggle debug mode, allows displaying additional data for development and debugging purposes. | -### Events +#### Events | Name | Description | | --- | --- | @@ -328,6 +351,70 @@ There are two additional functions that can be of a great value when controlling **Please note that if `event.preventDefault()` is not called then default outcome behaviour will also be executed after your custom code.** +## FormService + +```ts +import { Component } from '@angular/core'; +import { FormService, FormEvent, FormFieldEvent } from 'ng2-activiti-form'; + +@Component(...) +class MyComponent { + + constructor(private formService: FormService) { + + formService.formLoaded.subscribe((e: FormEvent) => { + console.log(`Form loaded: ${e.form.id}`); + }); + + formService.formFieldValueChanged.subscribe((e: FormFieldEvent) => { + console.log(`Field value changed. Form: ${e.form.id}, Field: ${e.field.id}, Value: ${e.field.value}`); + }); + + } + +} +``` + +### Events + +| Name | Args Type | Description | +| --- | --- | --- | +| formLoaded | FormEvent | Raised when form has been loaded or reloaded | +| formFieldValueChanged | FormFieldEvent | Raised when input values change | +| taskCompleted | FormEvent | Raised when a task is completed successfully | +| taskCompletedError | FormErrorEvent | Raised when a task is completed unsuccessfully | +| taskSaved | FormEvent | Raised when a task is saved successfully | +| taskSavedError | FormErrorEvent | Raised when a task is saved unsuccessfully | + +### Methods + +| Name | Params | Returns | Description | +| --- | --- | --- | --- | +| createFormFromANode | (formName: string) | Observable\ | Create a Form with a fields for each metadata properties | +| createForm | (formName: string) | Observable\ | Create a Form | +| addFieldsToAForm | (formId: string, formModel: FormDefinitionModel) | Observable\ | Add Fileds to A form | +| searchFrom | (name: string) | Observable\ | Search For A Form by name | +| getForms | n/a | Observable\ | Get All the forms | +| getProcessDefinitions | n/a | Observable\ | Get Process Definitions | +| getTasks | n/a | Observable\ | Get All the Tasks | +| getTask | (taskId: string) | Observable\ | Get Task | +| saveTaskForm | (taskId: string, formValues: FormValues) | Observable\ | Save Task Form | +| completeTaskForm | (taskId: string, formValues: FormValues, outcome?: string) | Observable\ | Complete Task Form | +| getTaskForm | (taskId: string) | Observable\ | Get Form related to a taskId | +| getFormDefinitionById | (formId: string) | Observable\ | Get Form Definition | +| getFormDefinitionByName | (name: string) | Observable\ | Returns form definition by a given name. | +| getStartFormInstance | (processId: string) | Observable\ | Get start form instance for a given processId | +| getStartFormDefinition | (processId: string) | Observable\ | Get start form definition for a given process | +| createTemporaryRawRelatedContent | (file: any) | Observable\ | Save File | +| getRestFieldValues | (taskId: string, field: string) | Observable\ | | +| getRestFieldValuesByProcessId | (processDefinitionId: string, field: string) | Observable\ | | +| getRestFieldValuesColumnByProcessId | (processDefinitionId: string, field: string, column?: string) | Observable\ | | +| getRestFieldValuesColumn | (taskId: string, field: string, column?: string) | Observable\ | | +| getWorkflowGroups\* | (filter: string, groupId?: string) | Observable\ | | +| getWorkflowUsers\* | (filter: string, groupId?: string) | Observable\ | | + +\* _Uses private Activiti WebApp api_ + ## See also - [Form Stencils with Angular 2](docs/stencils.md) diff --git a/ng2-components/ng2-activiti-form/demo/package.json b/ng2-components/ng2-activiti-form/demo/package.json index c907bf29b10..357da84b8b9 100644 --- a/ng2-components/ng2-activiti-form/demo/package.json +++ b/ng2-components/ng2-activiti-form/demo/package.json @@ -39,6 +39,7 @@ "@angular/http": "2.2.2", "@angular/platform-browser": "2.2.2", "@angular/platform-browser-dynamic": "2.2.2", + "@angular/material": "2.0.0-beta.1", "@angular/router": "3.2.2", "@angular/upgrade": "2.2.2", "core-js": "^2.4.1", @@ -54,9 +55,9 @@ "moment": "2.15.1", "md-date-time-picker": "^2.2.0", "ng2-translate": "2.5.0", - "alfresco-js-api": "^1.0.0", - "ng2-alfresco-core": "1.0.0", - "ng2-activiti-form": "^1.0.0" + "alfresco-js-api": "~1.1.0", + "ng2-alfresco-core": "1.1.0", + "ng2-activiti-form": "^1.1.0" }, "devDependencies": { "@types/jasmine": "^2.2.33", diff --git a/ng2-components/ng2-activiti-form/demo/src/main.ts b/ng2-components/ng2-activiti-form/demo/src/main.ts index c933643a38e..71a6c79b841 100644 --- a/ng2-components/ng2-activiti-form/demo/src/main.ts +++ b/ng2-components/ng2-activiti-form/demo/src/main.ts @@ -18,40 +18,39 @@ import { NgModule, Component, OnInit } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService, StorageService } from 'ng2-alfresco-core'; +import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService, StorageService, LogService } from 'ng2-alfresco-core'; import { ActivitiFormModule } from 'ng2-activiti-form'; @Component({ selector: 'alfresco-app-demo', template: ` -
-
-
-

-
- Authentication failed to ip {{ host }} with user: admin, admin, you can still try to add a valid ticket to perform - operations. -
-
- -
- - ` +
+
+
+

+
+ Authentication failed to ip {{ host }} with user: admin, admin, you can still try to add a valid ticket to perform + operations. +
+
+ +
+ + + ` }) export class FormDemoComponent implements OnInit { taskId: number; - authenticated: boolean; - host: string = 'http://localhost:9999'; - ticket: string; constructor(private authService: AlfrescoAuthenticationService, private settingsService: AlfrescoSettingsService, - private storage: StorageService) { + private storage: StorageService, + private logService: LogService) { settingsService.bpmHost = this.host; settingsService.setProviders('BPM'); @@ -76,12 +75,12 @@ export class FormDemoComponent implements OnInit { login() { this.authService.login('admin', 'admin').subscribe( ticket => { - console.log(ticket); + this.logService.info(`Logged in with ticket ${ticket}`); this.ticket = this.authService.getTicketBpm(); this.authenticated = true; }, error => { - console.log(error); + this.logService.error(error); this.authenticated = false; }); } diff --git a/ng2-components/ng2-activiti-form/index.ts b/ng2-components/ng2-activiti-form/index.ts index 98e9d2970c2..110d843dfca 100644 --- a/ng2-components/ng2-activiti-form/index.ts +++ b/ng2-components/ng2-activiti-form/index.ts @@ -37,6 +37,7 @@ export * from './src/components/widgets/index'; export * from './src/services/ecm-model.service'; export * from './src/services/node.service'; export * from './src/services/form-rendering.service'; +export * from './src/events/index'; export const ACTIVITI_FORM_DIRECTIVES: any[] = [ ActivitiForm, diff --git a/ng2-components/ng2-activiti-form/karma-test-shim.js b/ng2-components/ng2-activiti-form/karma-test-shim.js index a02d98e315c..1751adb04e6 100644 --- a/ng2-components/ng2-activiti-form/karma-test-shim.js +++ b/ng2-components/ng2-activiti-form/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; @@ -39,6 +46,8 @@ var map = { '@angular/http': 'npm:@angular/http/bundles/http.umd.js', '@angular/router': 'npm:@angular/router/bundles/router.umd.js', '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/material': 'npm:@angular/material/bundles/material.umd.js', + // testing '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js', '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js', diff --git a/ng2-components/ng2-activiti-form/package.json b/ng2-components/ng2-activiti-form/package.json index 214d9d84156..60a605be690 100644 --- a/ng2-components/ng2-activiti-form/package.json +++ b/ng2-components/ng2-activiti-form/package.json @@ -1,13 +1,13 @@ { "name": "ng2-activiti-form", "description": "Alfresco Activiti Form Component for Angular 2", - "version": "1.0.0", + "version": "1.1.0", "author": "Alfresco Software, Ltd.", "scripts": { "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings", "clean-build": "rimraf index.js index.js.map index.d.ts'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts' bundles", "build": "npm run clean-build && npm run tslint && rimraf dist && tsc && license-check && npm run build.umd", - "build:w": "npm run clean-build && npm run tslint && rimraf dist && tsc:w && license-check npm run build.umd", + "build:w": "npm run clean-build && npm run tslint && rimraf dist && npm run tsc:w && license-check && npm run build.umd", "tslint": "tslint -c tslint.json 'src/{,**/}**.ts' 'index.ts' -e '{,**/}**.d.ts' -e './gulpfile.ts'", "tsc": "tsc", "tsc:w": "tsc -w", @@ -16,7 +16,7 @@ "test-browser": "npm run build && concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", "posttest": "remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html && remap-istanbul -i coverage/report/coverage-final.json -o coverage/report/coverage-final.json", "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report", - "prepublish": "npm run build", + "prepublish": "npm run test", "travis": "npm link ng2-alfresco-core", "gulp": "gulp", "build.umd": "gulp build.prod --color --env-config prod --build-type prod", @@ -54,6 +54,7 @@ "@angular/http": "2.0.0", "@angular/platform-browser": "2.0.0", "@angular/platform-browser-dynamic": "2.0.0", + "@angular/material": "2.0.0-beta.1", "core-js": "^2.4.1", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.12", @@ -62,13 +63,13 @@ "moment": "2.15.1", "md-date-time-picker": "^2.2.0", "ng2-translate": "2.5.0", - "alfresco-js-api": "^1.0.0", - "ng2-alfresco-core": "1.0.0" + "alfresco-js-api": "~1.1.0", + "ng2-alfresco-core": "1.1.0" }, "devDependencies": { "@types/jasmine": "^2.2.33", "@types/node": "^6.0.42", - "autoprefixer": "^6.5.1", + "autoprefixer": "^6.5.4", "concurrently": "^2.2.0", "cpx": "^1.3.1", "cssnano": "^3.8.1", @@ -87,6 +88,7 @@ "gulp-template": "^4.0.0", "gulp-typescript": "^3.1.3", "gulp-uglify": "^2.0.0", + "gulp-util": "^3.0.7", "intl": "^1.2.5", "jasmine-ajax": "^3.2.0", "jasmine-core": "2.4.1", @@ -98,6 +100,7 @@ "karma-jasmine-html-reporter": "^0.2.0", "karma-mocha-reporter": "^2.0.3", "license-check": "^1.0.4", + "merge-stream": "^1.0.1", "remap-istanbul": "^0.6.3", "rimraf": "2.5.2", "run-sequence": "^1.2.2", diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html index 48411ae3933..e6cbc5d8e96 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html @@ -5,7 +5,7 @@

Please select a Task

- {{ form.isValid ? 'event_available' : 'event_busy' }} + {{ form.isValid ? 'event_available' : 'event_busy' }}

{{form.taskName}}

@@ -24,7 +24,7 @@

{{form.taskName}}

alfresco-mdl-button [disabled]="!isOutcomeButtonEnabled(outcome)" [class.mdl-button--colored]="!outcome.isSystem" - [class.activiti-form-hide-button]="!isOutcomeButtonVisible(outcome)" + [class.activiti-form-hide-button]="!isOutcomeButtonVisible(outcome, form.readOnly)" (click)="onOutcomeClicked(outcome, $event)"> {{outcome.name}} diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts index 3e6eca3be65..79b6d1e18e1 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts @@ -17,6 +17,7 @@ import { Observable } from 'rxjs/Rx'; import { SimpleChange } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; import { ActivitiForm } from './activiti-form.component'; import { FormModel, FormOutcomeModel, FormFieldModel, FormOutcomeEvent, FormFieldTypes } from './widgets/index'; import { FormService } from './../services/form.service'; @@ -30,6 +31,7 @@ describe('ActivitiForm', () => { let formComponent: ActivitiForm; let visibilityService: WidgetVisibilityService; let nodeService: NodeService; + let logService: LogService; beforeEach(() => { componentHandler = jasmine.createSpyObj('componentHandler', [ @@ -37,11 +39,12 @@ describe('ActivitiForm', () => { ]); window['componentHandler'] = componentHandler; - visibilityService = new WidgetVisibilityService(null); + logService = new LogService(); + visibilityService = new WidgetVisibilityService(null, logService); spyOn(visibilityService, 'refreshVisibility').and.stub(); - formService = new FormService(null, null); - nodeService = new NodeService(null, null); - formComponent = new ActivitiForm(formService, visibilityService, null, nodeService); + formService = new FormService(null, null, logService); + nodeService = new NodeService(null); + formComponent = new ActivitiForm(formService, visibilityService, null, nodeService, logService); }); it('should upgrade MDL content on view checked', () => { @@ -98,35 +101,73 @@ describe('ActivitiForm', () => { }); it('should not enable outcome button when model missing', () => { - expect(formComponent.isOutcomeButtonVisible(null)).toBeFalsy(); + expect(formComponent.isOutcomeButtonVisible(null, false)).toBeFalsy(); }); it('should enable custom outcome buttons', () => { let formModel = new FormModel(); + formComponent.form = formModel; let outcome = new FormOutcomeModel(formModel, {id: 'action1', name: 'Action 1'}); - expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy(); + expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy(); }); it('should allow controlling [complete] button visibility', () => { let formModel = new FormModel(); + formComponent.form = formModel; let outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.SAVE_ACTION}); formComponent.showSaveButton = true; - expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy(); + expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy(); formComponent.showSaveButton = false; - expect(formComponent.isOutcomeButtonVisible(outcome)).toBeFalsy(); + expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy(); + }); + + it('should show only [complete] button with readOnly form ', () => { + let formModel = new FormModel(); + formModel.readOnly = true; + formComponent.form = formModel; + let outcome = new FormOutcomeModel(formModel, {id: '$complete', name: FormOutcomeModel.COMPLETE_ACTION}); + + formComponent.showCompleteButton = true; + expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy(); + }); + + it('should not show [save] button with readOnly form ', () => { + let formModel = new FormModel(); + formModel.readOnly = true; + formComponent.form = formModel; + let outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.SAVE_ACTION}); + + formComponent.showSaveButton = true; + expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy(); + }); + + it('should show [custom-outcome] button with readOnly form and selected custom-outcome', () => { + let formModel = new FormModel({selectedOutcome: 'custom-outcome'}); + formModel.readOnly = true; + formComponent.form = formModel; + let outcome = new FormOutcomeModel(formModel, {id: '$customoutome', name: 'custom-outcome'}); + + formComponent.showCompleteButton = true; + formComponent.showSaveButton = true; + expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy(); + + outcome = new FormOutcomeModel(formModel, {id: '$customoutome2', name: 'custom-outcome2'}); + expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy(); }); it('should allow controlling [save] button visibility', () => { let formModel = new FormModel(); + formModel.readOnly = false; + formComponent.form = formModel; let outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.COMPLETE_ACTION}); formComponent.showCompleteButton = true; - expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy(); + expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeTruthy(); formComponent.showCompleteButton = false; - expect(formComponent.isOutcomeButtonVisible(outcome)).toBeFalsy(); + expect(formComponent.isOutcomeButtonVisible(outcome, formComponent.form.readOnly)).toBeFalsy(); }); it('should load form on refresh', () => { @@ -560,13 +601,6 @@ describe('ActivitiForm', () => { expect(formService.completeTaskForm).not.toHaveBeenCalled(); }); - it('should log error to console by default', () => { - const error = 'Error'; - spyOn(console, 'log').and.stub(); - formComponent.handleError(error); - expect(console.log).toHaveBeenCalledWith(error); - }); - it('should complete form form and raise corresponding event', () => { spyOn(formService, 'completeTaskForm').and.callFake(() => { return Observable.create(observer => { diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts index e515d5f0ac3..45a3837244b 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts @@ -15,18 +15,13 @@ * limitations under the License. */ -import { - Component, - OnInit, AfterViewChecked, OnChanges, - SimpleChanges, - Input, - Output, - EventEmitter -} from '@angular/core'; +import { Component, OnInit, AfterViewChecked, OnChanges, SimpleChanges, Input, Output, EventEmitter } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; import { EcmModelService } from './../services/ecm-model.service'; import { FormService } from './../services/form.service'; import { NodeService } from './../services/node.service'; import { FormModel, FormOutcomeModel, FormValues, FormFieldModel, FormOutcomeEvent } from './widgets/core/index'; +import { FormEvent, FormErrorEvent } from './../events/index'; import { WidgetVisibilityService } from './../services/widget-visibility.service'; @@ -85,6 +80,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { static SAVE_OUTCOME_ID: string = '$save'; static COMPLETE_OUTCOME_ID: string = '$complete'; + static START_PROCESS_OUTCOME_ID: string = '$startProcess'; static CUSTOM_OUTCOME_ID: string = '$custom'; @Input() @@ -129,6 +125,9 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { @Input() showRefreshButton: boolean = true; + @Input() + showValidationIcon: boolean = true; + @Output() formSaved: EventEmitter = new EventEmitter(); @@ -149,9 +148,10 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { debugMode: boolean = false; constructor(protected formService: FormService, - public visibilityService: WidgetVisibilityService, + protected visibilityService: WidgetVisibilityService, private ecmModelService: EcmModelService, - private nodeService: NodeService) { + private nodeService: NodeService, + private logService: LogService) { } hasForm(): boolean { @@ -182,14 +182,20 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { return false; } - isOutcomeButtonVisible(outcome: FormOutcomeModel): boolean { + isOutcomeButtonVisible(outcome: FormOutcomeModel, isFormReadOnly: boolean): boolean { if (outcome && outcome.name) { if (outcome.name === FormOutcomeModel.COMPLETE_ACTION) { return this.showCompleteButton; } + if (isFormReadOnly) { + return outcome.isSelected ; + } if (outcome.name === FormOutcomeModel.SAVE_ACTION) { return this.showSaveButton; } + if (outcome.name === FormOutcomeModel.START_PROCESS_ACTION) { + return false; + } return true; } return false; @@ -252,15 +258,20 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { return true; } + if (outcome.id === ActivitiForm.START_PROCESS_OUTCOME_ID) { + this.completeTaskForm(); + return true; + } + if (outcome.id === ActivitiForm.CUSTOM_OUTCOME_ID) { - this.formSaved.emit(this.form); + this.onTaskSaved(this.form); this.storeFormAsMetadata(); return true; } } else { // Note: Activiti is using NAME field rather than ID for outcomes if (outcome.name) { - this.formSaved.emit(this.form); + this.onTaskSaved(this.form); this.completeTaskForm(outcome.name); return true; } @@ -326,8 +337,8 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { .getTaskForm(taskId) .subscribe( form => { - this.form = new FormModel(form, data, this.readOnly); - this.formLoaded.emit(this.form); + this.form = new FormModel(form, data, this.readOnly, this.formService); + this.onFormLoaded(this.form); }, (error) => { this.handleError(error); @@ -342,7 +353,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { form => { this.formName = form.name; this.form = this.parseForm(form); - this.formLoaded.emit(this.form); + this.onFormLoaded(this.form); }, (error) => { this.handleError(error); @@ -357,9 +368,8 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { id => { this.formService.getFormDefinitionById(id).subscribe( form => { - // console.log('Get Form By Form definition Name', form); this.form = this.parseForm(form); - this.formLoaded.emit(this.form); + this.onFormLoaded(this.form); }, (error) => { this.handleError(error); @@ -378,12 +388,10 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { .saveTaskForm(this.form.taskId, this.form.values) .subscribe( () => { - this.formSaved.emit(this.form); + this.onTaskSaved(this.form); this.storeFormAsMetadata(); }, - (error) => { - this.handleError(error); - } + error => this.onTaskSavedError(this.form, error) ); } } @@ -394,24 +402,22 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { .completeTaskForm(this.form.taskId, this.form.values, outcome) .subscribe( () => { - this.formCompleted.emit(this.form); + this.onTaskCompleted(this.form); this.storeFormAsMetadata(); }, - (error) => { - this.handleError(error); - } + error => this.onTaskCompletedError(this.form, error) ); } } handleError(err: any): any { - console.log(err); + this.logService.error(err); this.onError.emit(err); } parseForm(json: any): FormModel { if (json) { - let form = new FormModel(json, this.data, this.readOnly); + let form = new FormModel(json, this.data, this.readOnly, this.formService); if (!json.fields) { form.outcomes = this.getFormDefinitionOutcomes(form); } @@ -427,7 +433,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { */ getFormDefinitionOutcomes(form: FormModel): FormOutcomeModel[] { return [ - new FormOutcomeModel(form, {id: '$custom', name: FormOutcomeModel.SAVE_ACTION, isSystem: true}) + new FormOutcomeModel(form, { id: '$custom', name: FormOutcomeModel.SAVE_ACTION, isSystem: true }) ]; } @@ -478,4 +484,29 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { ); } } + + protected onFormLoaded(form: FormModel) { + this.formLoaded.emit(form); + this.formService.formLoaded.next(new FormEvent(form)); + } + + protected onTaskSaved(form: FormModel) { + this.formSaved.emit(form); + this.formService.taskSaved.next(new FormEvent(form)); + } + + protected onTaskSavedError(form: FormModel, error: any) { + this.handleError(error); + this.formService.taskSavedError.next(new FormErrorEvent(form, error)); + } + + protected onTaskCompleted(form: FormModel) { + this.formCompleted.emit(form); + this.formService.taskCompleted.next(new FormEvent(form)); + } + + protected onTaskCompletedError(form: FormModel, error: any) { + this.handleError(error); + this.formService.taskCompletedError.next(new FormErrorEvent(form, error)); + } } diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.html b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.html index 5914fefde0f..04c6311f781 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.html +++ b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.html @@ -21,7 +21,7 @@

{{form.taskName}}

alfresco-mdl-button [disabled]="!isOutcomeButtonEnabled(outcome)" [class.mdl-button--colored]="!outcome.isSystem" - [class.activiti-form-hide-button]="!isOutcomeButtonVisible(outcome)" + [class.activiti-form-hide-button]="!isOutcomeButtonVisible(outcome, form.readOnly)" (click)="onOutcomeClicked(outcome, $event)"> {{outcome.name}} diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts index cf835494e0a..7fff2105c53 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts @@ -41,7 +41,7 @@ describe('ActivitiStartForm', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [CoreModule], + imports: [CoreModule.forRoot()], declarations: [ ActivitiStartForm, FormFieldComponent, diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.ts b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.ts index ad4e5b74df3..f20ee6c2573 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.ts @@ -17,7 +17,8 @@ import { Component, - AfterViewChecked, OnChanges, + AfterViewChecked, + OnChanges, SimpleChanges, Input, ViewChild, @@ -25,10 +26,11 @@ import { Output, EventEmitter } from '@angular/core'; -import { AlfrescoTranslationService } from 'ng2-alfresco-core'; +import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core'; import { ActivitiForm } from './activiti-form.component'; import { FormService } from './../services/form.service'; import { WidgetVisibilityService } from './../services/widget-visibility.service'; +import { FormOutcomeModel } from './widgets/core/index'; /** * Displays the start form for a named process definition, which can be used to retrieve values to start a new process. @@ -67,6 +69,9 @@ export class ActivitiStartForm extends ActivitiForm implements AfterViewChecked, @Input() showRefreshButton: boolean = true; + @Input() + readOnlyForm: boolean = false; + @Output() outcomeClick: EventEmitter = new EventEmitter(); @@ -75,12 +80,15 @@ export class ActivitiStartForm extends ActivitiForm implements AfterViewChecked, constructor(private translate: AlfrescoTranslationService, formService: FormService, - visibilityService: WidgetVisibilityService) { - super(formService, visibilityService, null, null); + visibilityService: WidgetVisibilityService, + logService: LogService) { + super(formService, visibilityService, null, null, logService); if (this.translate) { this.translate.addTranslationFolder('ng2-activiti-form', 'node_modules/ng2-activiti-form/src'); } + + this.showTitle = false; } ngOnChanges(changes: SimpleChanges) { @@ -107,12 +115,11 @@ export class ActivitiStartForm extends ActivitiForm implements AfterViewChecked, this.formName = form.name; form.processDefinitionId = this.processDefinitionId; this.form = this.parseForm(form); + this.form.readOnly = this.readOnlyForm; // this.form.processDefinitionId = this.processDefinitionId; this.formLoaded.emit(this.form); }, - (error) => { - this.handleError(error); - } + error => this.handleError(error) ); } @@ -123,15 +130,38 @@ export class ActivitiStartForm extends ActivitiForm implements AfterViewChecked, form => { this.formName = form.processDefinitionName; this.form = this.parseForm(form); + this.form.readOnly = this.readOnlyForm; this.formLoaded.emit(this.form); }, - (error) => { - this.handleError(error); - } + error => this.handleError(error) ); } + /** @override */ + isOutcomeButtonVisible(outcome: FormOutcomeModel, isFormReadOnly: boolean): boolean { + if (outcome && outcome.isSystem && ( outcome.name === FormOutcomeModel.SAVE_ACTION || + outcome.name === FormOutcomeModel.COMPLETE_ACTION )) { + return false; + } else if (outcome && outcome.name === FormOutcomeModel.START_PROCESS_ACTION) { + return true; + } + return super.isOutcomeButtonVisible(outcome, isFormReadOnly); + } + + /** @override */ saveTaskForm() { + // do nothing + } + + /** @override */ + onRefreshClicked() { + if (this.processDefinitionId) { + this.visibilityService.cleanProcessVariable(); + this.getStartFormDefinition(this.processDefinitionId); + } else if (this.processId) { + this.visibilityService.cleanProcessVariable(); + this.loadStartForm(this.processId); + } } completeTaskForm(outcome?: string) { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.spec.ts index de78edfa128..2d767db20b2 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.spec.ts @@ -16,6 +16,7 @@ */ import { Observable } from 'rxjs/Rx'; +import { LogServiceMock } from 'ng2-alfresco-core'; import { AttachWidget } from './attach.widget'; import { ActivitiAlfrescoContentService } from '../../../services/activiti-alfresco.service'; import { FormFieldModel } from './../core/form-field.model'; @@ -28,10 +29,12 @@ describe('AttachWidget', () => { let widget: AttachWidget; let contentService: ActivitiAlfrescoContentService; let dialogPolyfill: any; + let logService: LogServiceMock; beforeEach(() => { - contentService = new ActivitiAlfrescoContentService(null, null); - widget = new AttachWidget(contentService); + logService = new LogServiceMock(); + contentService = new ActivitiAlfrescoContentService(null, logService); + widget = new AttachWidget(contentService, logService); dialogPolyfill = { registerDialog(obj: any) { @@ -268,9 +271,9 @@ describe('AttachWidget', () => { Observable.throw(error) ); - spyOn(console, 'log').and.stub(); + spyOn(logService, 'error').and.stub(); widget.getExternalContentNodes(); - expect(console.log).toHaveBeenCalledWith(error); + expect(logService.error).toHaveBeenCalledWith(error); }); it('should register dialog via polyfill', () => { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts index e4881ac9f93..8b6ae72cc9a 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts @@ -16,6 +16,7 @@ */ import { Component, OnInit, Input, Output, EventEmitter, ViewChild } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; import { WidgetComponent } from './../widget.component'; import { ActivitiAlfrescoContentService } from '../../../services/activiti-alfresco.service'; import { ExternalContent } from '../core/external-content'; @@ -49,7 +50,8 @@ export class AttachWidget extends WidgetComponent implements OnInit { @ViewChild('dialog') dialog: any; - constructor(private contentService: ActivitiAlfrescoContentService) { + constructor(private contentService: ActivitiAlfrescoContentService, + private logService: LogService) { super(); } @@ -97,7 +99,7 @@ export class AttachWidget extends WidgetComponent implements OnInit { this.contentService.getAlfrescoNodes(this.selectedFolderAccountId, this.selectedFolderPathId) .subscribe( nodes => this.selectedFolderNodes = nodes, - error => this.handleError(error) + error => this.logService.error(error) ); } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.css index 92502b7c0ac..c90b97272c3 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.css +++ b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.css @@ -18,3 +18,7 @@ .container-widget__header-text.collapsible { cursor: pointer; } + +.container-widget__mdl-grid { + align-items: center; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html index b876e645c25..a0c807b12f6 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html @@ -11,9 +11,9 @@ {{content.name}}
-
+
-
+
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-outcome.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-outcome.model.ts index 219ddb7a416..0d364cdb186 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-outcome.model.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-outcome.model.ts @@ -22,14 +22,17 @@ export class FormOutcomeModel extends FormWidgetModel { static SAVE_ACTION: string = 'Save'; // Activiti 'Save' action name static COMPLETE_ACTION: string = 'Complete'; // Activiti 'Complete' action name + static START_PROCESS_ACTION: string = 'Start Process'; // Activiti 'Start Process' action name isSystem: boolean = false; + isSelected: boolean = false; constructor(form: FormModel, json?: any) { super(form, json); if (json) { this.isSystem = json.isSystem ? true : false; + this.isSelected = form && json.name === form.selectedOutcome ? true : false; } } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.spec.ts index f61ab81c1c7..c48bfad2e7c 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.spec.ts @@ -270,13 +270,16 @@ describe('FormModel', () => { }; let form = new FormModel(json); - expect(form.outcomes.length).toBe(2); + expect(form.outcomes.length).toBe(3); expect(form.outcomes[0].id).toBe(FormModel.SAVE_OUTCOME); expect(form.outcomes[0].isSystem).toBeTruthy(); expect(form.outcomes[1].id).toBe(FormModel.COMPLETE_OUTCOME); expect(form.outcomes[1].isSystem).toBeTruthy(); + + expect(form.outcomes[2].id).toBe(FormModel.START_PROCESS_OUTCOME); + expect(form.outcomes[2].isSystem).toBeTruthy(); }); it('should create outcomes only when fields available', () => { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts index 73938624fbe..8741224b54e 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts @@ -23,12 +23,15 @@ import { FormOutcomeModel } from './form-outcome.model'; import { FormFieldModel } from './form-field.model'; import { FormFieldTypes } from './form-field-types'; import { FormFieldTemplates } from './form-field-templates'; +import { FormService } from './../../../services/form.service'; +import { FormFieldEvent } from './../../../events/index'; export class FormModel { static UNSET_TASK_NAME: string = 'Nameless task'; static SAVE_OUTCOME: string = '$save'; static COMPLETE_OUTCOME: string = '$complete'; + static START_PROCESS_OUTCOME: string = '$startProcess'; readonly id: string; readonly name: string; @@ -47,6 +50,7 @@ export class FormModel { fields: FormWidgetModel[] = []; outcomes: FormOutcomeModel[] = []; customFieldTemplates: FormFieldTemplates = {}; + readonly selectedOutcome: string; values: FormValues = {}; @@ -64,7 +68,7 @@ export class FormModel { return this.outcomes && this.outcomes.length > 0; } - constructor(json?: any, data?: FormValues, readOnly: boolean = false) { + constructor(json?: any, data?: FormValues, readOnly: boolean = false, protected formService?: FormService) { this.readOnly = readOnly; if (json) { @@ -76,6 +80,7 @@ export class FormModel { this.taskName = json.taskName || json.name || FormModel.UNSET_TASK_NAME; this.processDefinitionId = json.processDefinitionId; this.customFieldTemplates = json.customFieldTemplates || {}; + this.selectedOutcome = json.selectedOutcome || {}; let tabCache: FormWidgetModelCache = {}; @@ -103,11 +108,12 @@ export class FormModel { if (json.fields) { let saveOutcome = new FormOutcomeModel(this, { id: FormModel.SAVE_OUTCOME, name: 'Save', isSystem: true }); let completeOutcome = new FormOutcomeModel(this, {id: FormModel.COMPLETE_OUTCOME, name: 'Complete', isSystem: true }); + let startProcessOutcome = new FormOutcomeModel(this, { id: FormModel.START_PROCESS_OUTCOME, name: 'Start Process', isSystem: true }); let customOutcomes = (json.outcomes || []).map(obj => new FormOutcomeModel(this, obj)); this.outcomes = [saveOutcome].concat( - customOutcomes.length > 0 ? customOutcomes : [completeOutcome] + customOutcomes.length > 0 ? customOutcomes : [completeOutcome, startProcessOutcome] ); } } @@ -116,6 +122,9 @@ export class FormModel { onFormFieldChanged(field: FormFieldModel) { this.validateField(field); + if (this.formService) { + this.formService.formFieldValueChanged.next(new FormFieldEvent(this, field)); + } } // TODO: consider evaluating and caching once the form is loaded diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.css index c8d5774494f..a30807d5d26 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.css +++ b/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.css @@ -1,9 +1,21 @@ .date-widget { width: 100%; + padding-top: 10px; + padding-bottom: 10px; } .date-widget--button { - margin-top: 15px; + margin-top: 10px; +} + +.mdl-date__input{ + padding-top: 5px; + padding-bottom: 5px; +} + +.mdl-grid__date-widget{ + align-items:center; + padding: 0px; } .date-widget__invalid .mdl-textfield__input { @@ -21,3 +33,8 @@ .date-widget__invalid .mdl-textfield__error { visibility: visible !important; } + +.date-widget-button__cell{ + margin-top: 0px; + margin-bottom: 0px; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.html index 3a8652288ae..047eaef114b 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.html @@ -1,9 +1,9 @@ -
+
-
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.spec.ts index f3540dc4e91..17e3b896ef0 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.spec.ts @@ -16,7 +16,7 @@ */ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { CoreModule } from 'ng2-alfresco-core'; +import { CoreModule, LogServiceMock } from 'ng2-alfresco-core'; import { Observable } from 'rxjs/Rx'; import { DisplayValueWidget } from './display-value.widget'; import { FormService } from '../../../services/form.service'; @@ -26,20 +26,19 @@ import { FormFieldTypes } from '../core/form-field-types'; import { FormModel } from '../core/form.model'; import { DynamicTableColumn, DynamicTableRow } from './../dynamic-table/dynamic-table.widget.model'; import { WidgetVisibilityService } from '../../../services/widget-visibility.service'; -import { AlfrescoSettingsService } from 'ng2-alfresco-core'; describe('DisplayValueWidget', () => { let widget: DisplayValueWidget; let formService: FormService; let visibilityService: WidgetVisibilityService; - let settingsService: AlfrescoSettingsService; + let logService: LogServiceMock; beforeEach(() => { - settingsService = new AlfrescoSettingsService(); - formService = new FormService(null, null); - visibilityService = new WidgetVisibilityService(null); - widget = new DisplayValueWidget(formService, visibilityService, settingsService); + logService = new LogServiceMock(); + formService = new FormService(null, null, logService); + visibilityService = new WidgetVisibilityService(null, logService); + widget = new DisplayValueWidget(formService, visibilityService, logService); }); it('should require field to setup default value', () => { @@ -393,7 +392,7 @@ describe('DisplayValueWidget', () => { Observable.throw(error) ); - spyOn(console, 'log').and.stub(); + spyOn(logService, 'error').and.stub(); let form = new FormModel({taskId: ''}); @@ -409,7 +408,7 @@ describe('DisplayValueWidget', () => { }); widget.ngOnInit(); expect(formService.getRestFieldValues).toHaveBeenCalled(); - expect(console.log).toHaveBeenCalledWith(error); + expect(logService.error).toHaveBeenCalledWith(error); expect(widget.value).toBe('100'); }); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.ts index 9e5a659b72b..d9e3751c605 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.ts @@ -16,14 +16,14 @@ */ import { Component, OnInit } from '@angular/core'; +import * as moment from 'moment'; +import { LogService } from 'ng2-alfresco-core'; import { WidgetComponent } from './../widget.component'; import { FormFieldTypes } from '../core/form-field-types'; import { FormService } from '../../../services/form.service'; import { FormFieldOption } from './../core/form-field-option'; import { DynamicTableColumn, DynamicTableRow } from './../dynamic-table/dynamic-table.widget.model'; import { WidgetVisibilityService } from '../../../services/widget-visibility.service'; -import { AlfrescoSettingsService } from 'ng2-alfresco-core'; -import * as moment from 'moment'; @Component({ moduleId: module.id, @@ -51,7 +51,7 @@ export class DisplayValueWidget extends WidgetComponent implements OnInit { constructor(private formService: FormService, private visibilityService: WidgetVisibilityService, - private settingsService: AlfrescoSettingsService) { + private logService: LogService) { super(); } @@ -181,9 +181,10 @@ export class DisplayValueWidget extends WidgetComponent implements OnInit { } else { this.value = this.field.value; } + this.visibilityService.refreshVisibility(this.field.form); }, error => { - console.log(error); + this.logService.error(error); this.value = this.field.value; } ); @@ -202,9 +203,10 @@ export class DisplayValueWidget extends WidgetComponent implements OnInit { } else { this.value = this.field.value; } + this.visibilityService.refreshVisibility(this.field.form); }, error => { - console.log(error); + this.logService.error(error); this.value = this.field.value; } ); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.css index ae995ca8545..ba9a5ba21da 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.css +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.css @@ -1,9 +1,13 @@ .dropdown-widget { width: 100%; + padding-top: 20px; + padding-bottom: 20px; } .dropdown-widget__select { width: 100%; + margin-top: 5px; + margin-bottom: 5px; } .dropdown-widget__invalid .dropdown-widget__select { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts index 1d263dff8eb..1930b6abb3e 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts @@ -15,14 +15,14 @@ * limitations under the License. */ +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { Observable } from 'rxjs/Rx'; +import { CoreModule } from 'ng2-alfresco-core'; import { FormService } from '../../../services/form.service'; import { DropdownWidget } from './dropdown.widget'; import { FormModel } from './../core/form.model'; import { FormFieldModel } from './../core/form-field.model'; import { FormFieldOption } from './../core/form-field-option'; -import { CoreModule } from 'ng2-alfresco-core'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { EcmModelService } from '../../../services/ecm-model.service'; import { WidgetVisibilityService } from '../../../services/widget-visibility.service'; @@ -33,9 +33,9 @@ describe('DropdownWidget', () => { let visibilityService: WidgetVisibilityService; beforeEach(() => { - formService = new FormService(null, null); - visibilityService = new WidgetVisibilityService(null); - widget = new DropdownWidget(formService, visibilityService); + formService = new FormService(null, null, null); + visibilityService = new WidgetVisibilityService(null, null); + widget = new DropdownWidget(formService, visibilityService, null); widget.field = new FormFieldModel(new FormModel()); }); @@ -74,12 +74,6 @@ describe('DropdownWidget', () => { expect(formService.getRestFieldValues).toHaveBeenCalledWith(taskId, fieldId); }); - it('should log error to console by default', () => { - spyOn(console, 'error').and.stub(); - widget.handleError('Err'); - expect(console.error).toHaveBeenCalledWith('Err'); - }); - it('should preserve empty option when loading fields', () => { let restFieldValue: FormFieldOption = { id: '1', name: 'Option1' }; spyOn(formService, 'getRestFieldValues').and.returnValue( diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.ts index f1c56639d0a..5d1b7db5de8 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.ts @@ -16,6 +16,7 @@ */ import { Component, OnInit } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; import { FormService } from '../../../services/form.service'; import { WidgetComponent } from './../widget.component'; import { FormFieldOption } from './../core/form-field-option'; @@ -30,7 +31,8 @@ import { WidgetVisibilityService } from '../../../services/widget-visibility.ser export class DropdownWidget extends WidgetComponent implements OnInit { constructor(private formService: FormService, - private visibilityService: WidgetVisibilityService) { + private visibilityService: WidgetVisibilityService, + private logService: LogService) { super(); } @@ -59,7 +61,7 @@ export class DropdownWidget extends WidgetComponent implements OnInit { this.field.options = options.concat((result || [])); this.field.updateForm(); }, - this.handleError + err => this.handleError(err) ); } @@ -78,7 +80,7 @@ export class DropdownWidget extends WidgetComponent implements OnInit { this.field.options = options.concat((result || [])); this.field.updateForm(); }, - this.handleError + err => this.handleError(err) ); } @@ -97,7 +99,7 @@ export class DropdownWidget extends WidgetComponent implements OnInit { } handleError(error: any) { - console.error(error); + this.logService.error(error); } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.spec.ts index 2c6c33d7939..44b9a6f6723 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.spec.ts @@ -15,6 +15,7 @@ * limitations under the License. */ +import { LogServiceMock } from 'ng2-alfresco-core'; import { DynamicTableWidget } from './dynamic-table.widget'; import { DynamicTableModel, DynamicTableRow, DynamicTableColumn } from './dynamic-table.widget.model'; import { FormModel, FormFieldTypes } from './../core/index'; @@ -25,11 +26,13 @@ describe('DynamicTableWidget', () => { let widget: DynamicTableWidget; let table: DynamicTableModel; let visibilityService: WidgetVisibilityService; + let logService: LogServiceMock; beforeEach(() => { + logService = new LogServiceMock(); table = new DynamicTableModel(null); - visibilityService = new WidgetVisibilityService(null); - widget = new DynamicTableWidget(null, visibilityService); + visibilityService = new WidgetVisibilityService(null, logService); + widget = new DynamicTableWidget(null, visibilityService, logService); widget.content = table; }); @@ -192,13 +195,13 @@ describe('DynamicTableWidget', () => { }); it('should require table to save changes', () => { - spyOn(console, 'log').and.stub(); + spyOn(logService, 'error').and.stub(); widget.editMode = true; widget.content = null; widget.onSaveChanges(); expect(widget.editMode).toBeFalsy(); - expect(console.log).toHaveBeenCalledWith(widget.ERROR_MODEL_NOT_FOUND); + expect(logService.error).toHaveBeenCalledWith(widget.ERROR_MODEL_NOT_FOUND); }); it('should cancel changes', () => { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts index 324aa05a960..8abf093760d 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts @@ -16,6 +16,7 @@ */ import { Component, ElementRef, OnInit } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; import { WidgetComponent } from './../widget.component'; import { DynamicTableModel, DynamicTableRow, DynamicTableColumn } from './dynamic-table.widget.model'; import { WidgetVisibilityService } from '../../../services/widget-visibility.service'; @@ -36,7 +37,8 @@ export class DynamicTableWidget extends WidgetComponent implements OnInit { editRow: DynamicTableRow = null; constructor(private elementRef: ElementRef, - private visibilityService: WidgetVisibilityService) { + private visibilityService: WidgetVisibilityService, + private logService: LogService) { super(); } @@ -136,7 +138,7 @@ export class DynamicTableWidget extends WidgetComponent implements OnInit { } this.content.flushValue(); } else { - this.handleError(this.ERROR_MODEL_NOT_FOUND); + this.logService.error(this.ERROR_MODEL_NOT_FOUND); } this.editMode = false; } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.spec.ts index 4db043d2c34..0a355f5a71a 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.spec.ts @@ -39,7 +39,7 @@ describe('DropdownEditorComponent', () => { let row: DynamicTableRow; beforeEach(() => { - formService = new FormService(null, null); + formService = new FormService(null, null, null); row = { value: { dropdown: 'one' } }; column = { @@ -56,7 +56,7 @@ describe('DropdownEditorComponent', () => { table.rows.push(row); table.columns.push(column); - component = new DropdownEditorComponent(formService); + component = new DropdownEditorComponent(formService, null); component.table = table; component.row = row; component.column = column; diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.ts index 7a3f3496869..0bafb62d33f 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.ts @@ -16,6 +16,7 @@ */ import { Component, Input, OnInit } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; import { DynamicTableModel, DynamicTableRow, DynamicTableColumn, DynamicTableColumnOption } from './../../dynamic-table.widget.model'; import { FormService } from './../../../../../services/form.service'; @@ -39,7 +40,9 @@ export class DropdownEditorComponent implements OnInit { @Input() column: DynamicTableColumn; - constructor(private formService: FormService) {} + constructor(private formService: FormService, + private logService: LogService) { + } ngOnInit() { let field = this.table.field; @@ -98,6 +101,6 @@ export class DropdownEditorComponent implements OnInit { } handleError(error: any) { - console.error(error); + this.logService.error(error); } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/functional-group/functional-group.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/functional-group/functional-group.widget.spec.ts index e314372f74e..025445ff14e 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/functional-group/functional-group.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/functional-group/functional-group.widget.spec.ts @@ -36,7 +36,7 @@ describe('FunctionalGroupWidget', () => { ]); window['componentHandler'] = componentHandler; - formService = new FormService(null, null); + formService = new FormService(null, null, null); elementRef = new ElementRef(null); widget = new FunctionalGroupWidget(formService, elementRef); widget.field = new FormFieldModel(new FormModel()); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/people/people.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/people/people.widget.spec.ts index dc6309c1578..21d24c54682 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/people/people.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/people/people.widget.spec.ts @@ -36,7 +36,7 @@ describe('PeopleWidget', () => { ]); window['componentHandler'] = componentHandler; - formService = new FormService(null, null); + formService = new FormService(null, null, null); elementRef = new ElementRef(null); widget = new PeopleWidget(formService, elementRef); widget.field = new FormFieldModel(new FormModel()); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/radio-buttons/radio-buttons.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/radio-buttons/radio-buttons.widget.spec.ts index c21594f359b..d2a8e0927ea 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/radio-buttons/radio-buttons.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/radio-buttons/radio-buttons.widget.spec.ts @@ -15,13 +15,14 @@ * limitations under the License. */ +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { Observable } from 'rxjs/Rx'; +import { CoreModule, LogServiceMock } from 'ng2-alfresco-core'; + import { FormService } from '../../../services/form.service'; import { RadioButtonsWidget } from './radio-buttons.widget'; import { FormModel } from './../core/form.model'; import { FormFieldModel } from './../core/form-field.model'; -import { CoreModule } from 'ng2-alfresco-core'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { EcmModelService } from '../../../services/ecm-model.service'; import { WidgetVisibilityService } from '../../../services/widget-visibility.service'; import { FormFieldTypes } from '../core/form-field-types'; @@ -33,11 +34,13 @@ describe('RadioButtonsWidget', () => { let formService: FormService; let widget: RadioButtonsWidget; let visibilityService: WidgetVisibilityService; + let logService: LogServiceMock; beforeEach(() => { - formService = new FormService(null, null); - visibilityService = new WidgetVisibilityService(null); - widget = new RadioButtonsWidget(formService, visibilityService); + logService = new LogServiceMock(); + formService = new FormService(null, null, logService); + visibilityService = new WidgetVisibilityService(null, logService); + widget = new RadioButtonsWidget(formService, visibilityService, logService); widget.field = new FormFieldModel(new FormModel(), { restUrl: '' }); }); @@ -118,12 +121,12 @@ describe('RadioButtonsWidget', () => { }); it('should log error to console by default', () => { - spyOn(console, 'error').and.stub(); + spyOn(logService, 'error').and.stub(); widget.handleError('Err'); - expect(console.error).toHaveBeenCalledWith('Err'); + expect(logService.error).toHaveBeenCalledWith('Err'); }); - it('should update the field value when an option is selected', () => { + xit('should update the field value when an option is selected', () => { spyOn(widget, 'checkVisibility').and.stub(); widget.onOptionClick('fake-opt'); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/radio-buttons/radio-buttons.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/radio-buttons/radio-buttons.widget.ts index 1018bbb925a..5f1c9602414 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/radio-buttons/radio-buttons.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/radio-buttons/radio-buttons.widget.ts @@ -16,6 +16,7 @@ */ import { Component, OnInit } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; import { WidgetComponent } from './../widget.component'; import { FormService } from '../../../services/form.service'; import { FormFieldOption } from './../core/form-field-option'; @@ -30,7 +31,8 @@ import { WidgetVisibilityService } from '../../../services/widget-visibility.ser export class RadioButtonsWidget extends WidgetComponent implements OnInit { constructor(private formService: FormService, - private visibilityService: WidgetVisibilityService) { + private visibilityService: WidgetVisibilityService, + private logService: LogService) { super(); } @@ -55,7 +57,7 @@ export class RadioButtonsWidget extends WidgetComponent implements OnInit { this.field.options = result || []; this.field.updateForm(); }, - this.handleError + err => this.handleError(err) ); } @@ -70,7 +72,7 @@ export class RadioButtonsWidget extends WidgetComponent implements OnInit { this.field.options = result || []; this.field.updateForm(); }, - this.handleError + err => this.handleError(err) ); } @@ -84,7 +86,7 @@ export class RadioButtonsWidget extends WidgetComponent implements OnInit { } handleError(error: any) { - console.error(error); + this.logService.error(error); } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts index b79759c6ba1..70ef25000ad 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts @@ -15,14 +15,15 @@ * limitations under the License. */ +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { Observable } from 'rxjs/Rx'; +import { CoreModule, LogServiceMock } from 'ng2-alfresco-core'; + import { TypeaheadWidget } from './typeahead.widget'; import { FormService } from '../../../services/form.service'; import { FormModel } from '../core/form.model'; import { FormFieldModel } from '../core/form-field.model'; import { FormFieldOption } from '../core/form-field-option'; -import { CoreModule } from 'ng2-alfresco-core'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { EcmModelService } from '../../../services/ecm-model.service'; import { WidgetVisibilityService } from '../../../services/widget-visibility.service'; import { FormFieldTypes } from '../core/form-field-types'; @@ -32,11 +33,13 @@ describe('TypeaheadWidget', () => { let formService: FormService; let widget: TypeaheadWidget; let visibilityService: WidgetVisibilityService; + let logService: LogServiceMock; beforeEach(() => { - formService = new FormService(null, null); - visibilityService = new WidgetVisibilityService(null); - widget = new TypeaheadWidget(formService, visibilityService); + logService = new LogServiceMock(); + formService = new FormService(null, null, logService); + visibilityService = new WidgetVisibilityService(null, logService); + widget = new TypeaheadWidget(formService, visibilityService, logService); widget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' })); }); @@ -73,7 +76,7 @@ describe('TypeaheadWidget', () => { }); const err = 'Error'; spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.throw(err)); - spyOn(widget, 'handleError').and.callThrough(); + spyOn(widget, 'handleError').and.stub(); widget.ngOnInit(); @@ -94,7 +97,7 @@ describe('TypeaheadWidget', () => { }); const err = 'Error'; spyOn(formService, 'getRestFieldValuesByProcessId').and.returnValue(Observable.throw(err)); - spyOn(widget, 'handleError').and.callThrough(); + spyOn(widget, 'handleError').and.stub(); widget.ngOnInit(); @@ -102,12 +105,6 @@ describe('TypeaheadWidget', () => { expect(widget.handleError).toHaveBeenCalledWith(err); }); - it('should log error to console by default', () => { - spyOn(console, 'error').and.stub(); - widget.handleError('Err'); - expect(console.error).toHaveBeenCalledWith('Err'); - }); - it('should show popup on key up', () => { spyOn(widget, 'getOptions').and.returnValue([{}, {}]); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.ts index 6dd4a18a36e..37eb4ac1664 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.ts @@ -16,6 +16,7 @@ */ import { Component, OnInit } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; import { FormService } from './../../../services/form.service'; import { WidgetComponent } from './../widget.component'; import { FormFieldOption } from './../core/form-field-option'; @@ -35,7 +36,8 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit { options: FormFieldOption[] = []; constructor(private formService: FormService, - private visibilityService: WidgetVisibilityService) { + private visibilityService: WidgetVisibilityService, + private logService: LogService) { super(); } @@ -68,7 +70,7 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit { this.field.updateForm(); this.visibilityService.refreshEntityVisibility(this.field); }, - this.handleError + err => this.handleError(err) ); } @@ -93,7 +95,7 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit { this.field.updateForm(); this.visibilityService.refreshEntityVisibility(this.field); }, - this.handleError + err => this.handleError(err) ); } @@ -153,7 +155,7 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit { } handleError(error: any) { - console.error(error); + this.logService.error(error); } checkVisibility() { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/upload/upload.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/upload/upload.widget.spec.ts index 5a2bc669df3..9e1fd1ec8b7 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/upload/upload.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/upload/upload.widget.spec.ts @@ -26,8 +26,8 @@ describe('UploadWidget', () => { let formService: FormService; beforeEach(() => { - formService = new FormService(null, null); - widget = new UploadWidget(formService); + formService = new FormService(null, null, null); + widget = new UploadWidget(formService, null); }); it('should setup with field data', () => { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/upload/upload.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/upload/upload.widget.ts index f9814ba3884..2314853757c 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/upload/upload.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/upload/upload.widget.ts @@ -16,6 +16,7 @@ */ import { Component, OnInit } from '@angular/core'; +import { LogService } from 'ng2-alfresco-core'; import { WidgetComponent } from './../widget.component'; import { FormService } from '../../../services/form.service'; @@ -31,7 +32,8 @@ export class UploadWidget extends WidgetComponent implements OnInit { fileName: string; displayText: string; - constructor(private formService: FormService) { + constructor(private formService: FormService, + private logService: LogService) { super(); } @@ -60,16 +62,14 @@ export class UploadWidget extends WidgetComponent implements OnInit { onFileChanged(event: any) { let files = event.target.files; if (files && files.length > 0) { - let file = files[0]; - this.formService.createTemporaryRawRelatedContent(file) .subscribe((response: any) => { - console.log(response); + this.logService.info(response); this.field.value = [response]; this.field.json.value = [response]; }, (error: any) => { - console.error(error); + this.logService.error(error); window.alert('Error uploading file. See console output for more details.'); }); } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts b/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts index 61128348537..490f764680f 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts @@ -111,11 +111,4 @@ export class WidgetComponent implements AfterViewInit { } return null; } - - protected handleError(error: any) { - if (error) { - console.log(error); - } - } - } diff --git a/ng2-components/ng2-alfresco-core/src/services/AlfrescoApi.service.ts b/ng2-components/ng2-activiti-form/src/events/form-error.event.ts similarity index 65% rename from ng2-components/ng2-alfresco-core/src/services/AlfrescoApi.service.ts rename to ng2-components/ng2-activiti-form/src/events/form-error.event.ts index dad5f6d8e98..1e4ad50c31d 100644 --- a/ng2-components/ng2-alfresco-core/src/services/AlfrescoApi.service.ts +++ b/ng2-components/ng2-activiti-form/src/events/form-error.event.ts @@ -15,20 +15,16 @@ * limitations under the License. */ -import { Injectable } from '@angular/core'; -import { AlfrescoApi } from 'alfresco-js-api'; +import { FormEvent } from './form.event'; +import { FormModel } from './../components/widgets/core/index'; -@Injectable() -export class AlfrescoApiService { +export class FormErrorEvent extends FormEvent { - private _instance: AlfrescoApi; + readonly error: any; - public getInstance(): AlfrescoApi { - return this._instance; - } - - public setInstance(value: AlfrescoApi) { - this._instance = value; + constructor(form: FormModel, error: any) { + super(form); + this.error = error; } } diff --git a/ng2-components/ng2-activiti-form/src/events/form-field.event.ts b/ng2-components/ng2-activiti-form/src/events/form-field.event.ts new file mode 100644 index 00000000000..1189e33a647 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/events/form-field.event.ts @@ -0,0 +1,30 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FormEvent } from './form.event'; +import { FormModel, FormFieldModel } from './../components/widgets/core/index'; + +export class FormFieldEvent extends FormEvent { + + readonly field: FormFieldModel; + + constructor(form: FormModel, field: FormFieldModel) { + super(form); + this.field = field; + } + +} diff --git a/ng2-components/ng2-activiti-form/src/events/form.event.ts b/ng2-components/ng2-activiti-form/src/events/form.event.ts new file mode 100644 index 00000000000..841a12dd66e --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/events/form.event.ts @@ -0,0 +1,27 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FormModel } from './../components/widgets/core/index'; + +export class FormEvent { + + readonly form: FormModel; + + constructor(form: FormModel) { + this.form = form; + } +} diff --git a/ng2-components/ng2-activiti-form/src/events/index.ts b/ng2-components/ng2-activiti-form/src/events/index.ts new file mode 100644 index 00000000000..39a1671687a --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/events/index.ts @@ -0,0 +1,20 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './form.event'; +export * from './form-error.event'; +export * from './form-field.event'; diff --git a/ng2-components/ng2-activiti-form/src/services/activiti-alfresco.service.ts b/ng2-components/ng2-activiti-form/src/services/activiti-alfresco.service.ts index a355e462593..e7990ff80bc 100644 --- a/ng2-components/ng2-activiti-form/src/services/activiti-alfresco.service.ts +++ b/ng2-components/ng2-activiti-form/src/services/activiti-alfresco.service.ts @@ -17,7 +17,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; -import { AlfrescoAuthenticationService, AlfrescoApiService } from 'ng2-alfresco-core'; +import { AlfrescoApiService, LogService } from 'ng2-alfresco-core'; import { ExternalContent } from '../components/widgets/core/external-content'; import { ExternalContentLink } from '../components/widgets/core/external-content-link'; import { AlfrescoApi } from 'alfresco-js-api'; @@ -28,7 +28,8 @@ export class ActivitiAlfrescoContentService { static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error'; static GENERIC_ERROR_MESSAGE: string = 'Server error'; - constructor(private authService: AlfrescoAuthenticationService, private apiService: AlfrescoApiService) { + constructor(private apiService: AlfrescoApiService, + private logService: LogService) { } /** @@ -43,7 +44,7 @@ export class ActivitiAlfrescoContentService { let accountShortId = accountId.replace('alfresco-', ''); return Observable.fromPromise(apiService.activiti.alfrescoApi.getContentInFolder(accountShortId, folderId)) .map(this.toJsonArray) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** @@ -62,7 +63,7 @@ export class ActivitiAlfrescoContentService { simpleType: node.simpleType, source: accountId, sourceId: node.id + '@' + siteId - })).map(this.toJson).catch(this.handleError); + })).map(this.toJson).catch(err => this.handleError(err)); } toJson(res: any) { @@ -85,7 +86,7 @@ export class ActivitiAlfrescoContentService { errMsg = (error.message) ? error.message : error.status ? `${error.status} - ${error.statusText}` : ActivitiAlfrescoContentService.GENERIC_ERROR_MESSAGE; } - console.error(errMsg); + this.logService.error(errMsg); return Observable.throw(errMsg); } } diff --git a/ng2-components/ng2-activiti-form/src/services/ecm-model.service.spec.ts b/ng2-components/ng2-activiti-form/src/services/ecm-model.service.spec.ts index 75a2a6cdbc1..6dfe52b06e7 100644 --- a/ng2-components/ng2-activiti-form/src/services/ecm-model.service.spec.ts +++ b/ng2-components/ng2-activiti-form/src/services/ecm-model.service.spec.ts @@ -16,16 +16,10 @@ */ import { TestBed } from '@angular/core/testing'; -import { - AlfrescoAuthenticationService, - AlfrescoSettingsService, - AlfrescoApiService, - StorageService -} from 'ng2-alfresco-core'; -import { EcmModelService } from './ecm-model.service'; import { Observable } from 'rxjs/Rx'; -import { FormModel } from '../components/widgets/core/form.model'; -import { HttpModule } from '@angular/http'; +import { CoreModule } from 'ng2-alfresco-core'; +import { EcmModelService } from './ecm-model.service'; +import { FormModel } from './../components/widgets/core/form.model'; declare let jasmine: any; @@ -33,15 +27,13 @@ describe('EcmModelService', () => { let service: EcmModelService; - beforeAll(() => { + beforeEach(() => { TestBed.configureTestingModule({ - imports: [HttpModule], + imports: [ + CoreModule.forRoot() + ], providers: [ - AlfrescoSettingsService, - AlfrescoApiService, - AlfrescoAuthenticationService, - EcmModelService, - StorageService + EcmModelService ] }); service = TestBed.get(EcmModelService); diff --git a/ng2-components/ng2-activiti-form/src/services/ecm-model.service.ts b/ng2-components/ng2-activiti-form/src/services/ecm-model.service.ts index a83727a68bf..7845f8dfcc5 100644 --- a/ng2-components/ng2-activiti-form/src/services/ecm-model.service.ts +++ b/ng2-components/ng2-activiti-form/src/services/ecm-model.service.ts @@ -16,8 +16,8 @@ */ import { Injectable } from '@angular/core'; -import { AlfrescoAuthenticationService, AlfrescoApiService } from 'ng2-alfresco-core'; import { Observable } from 'rxjs/Rx'; +import { AlfrescoApiService, LogService } from 'ng2-alfresco-core'; import { FormModel } from '../components/widgets/core/form.model'; @Injectable() @@ -27,8 +27,8 @@ export class EcmModelService { public static MODEL_NAME: string = 'activitiFormsModel'; public static TYPE_MODEL: string = 'cm:folder'; - constructor(private authService: AlfrescoAuthenticationService, - public apiService: AlfrescoApiService) { + constructor(private apiService: AlfrescoApiService, + private logService: LogService) { } public createEcmTypeForActivitiForm(formName: string, form: FormModel): Observable { @@ -47,7 +47,7 @@ export class EcmModelService { }); } }, - this.handleError + err => this.handleError(err) ); }); @@ -63,19 +63,19 @@ export class EcmModelService { return Observable.create(observer => { this.createEcmModel(EcmModelService.MODEL_NAME, EcmModelService.MODEL_NAMESPACE).subscribe( model => { - console.log('model created', model); + this.logService.info('model created', model); this.activeEcmModel(EcmModelService.MODEL_NAME).subscribe( modelActive => { - console.log('model active', modelActive); + this.logService.info('model active', modelActive); this.createEcmTypeWithProperties(formName, form).subscribe(typeCreated => { observer.next(typeCreated); observer.complete(); }); }, - this.handleError + err => this.handleError(err) ); }, - this.handleError + err => this.handleError(err) ); }); } @@ -84,7 +84,7 @@ export class EcmModelService { return Observable.create(observer => { this.searchEcmType(formName, EcmModelService.MODEL_NAME).subscribe( ecmType => { - console.log('custom types', ecmType); + this.logService.info('custom types', ecmType); if (!ecmType) { this.createEcmTypeWithProperties(formName, form).subscribe(typeCreated => { observer.next(typeCreated); @@ -95,7 +95,7 @@ export class EcmModelService { observer.complete(); } }, - this.handleError + err => this.handleError(err) ); }); } @@ -104,16 +104,16 @@ export class EcmModelService { return Observable.create(observer => { this.createEcmType(formName, EcmModelService.MODEL_NAME, EcmModelService.TYPE_MODEL).subscribe( typeCreated => { - console.log('type Created', typeCreated); + this.logService.info('type Created', typeCreated); this.addPropertyToAType(EcmModelService.MODEL_NAME, formName, form).subscribe( properyAdded => { - console.log('property Added', properyAdded); + this.logService.info('property Added', properyAdded); observer.next(typeCreated); observer.complete(); }, - this.handleError); + err => this.handleError(err)); }, - this.handleError); + err => this.handleError(err)); }); } @@ -126,25 +126,25 @@ export class EcmModelService { public activeEcmModel(modelName: string): Observable { return Observable.fromPromise(this.apiService.getInstance().core.customModelApi.activateCustomModel(modelName)) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } public createEcmModel(modelName: string, nameSpace: string): Observable { return Observable.fromPromise(this.apiService.getInstance().core.customModelApi.createCustomModel('DRAFT', '', modelName, modelName, nameSpace)) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } public getEcmModels(): Observable { return Observable.fromPromise(this.apiService.getInstance().core.customModelApi.getAllCustomModel()) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } public getEcmType(modelName: string): Observable { return Observable.fromPromise(this.apiService.getInstance().core.customModelApi.getAllCustomType(modelName)) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } public createEcmType(typeName: string, modelName: string, parentType: string): Observable { @@ -152,7 +152,7 @@ export class EcmModelService { return Observable.fromPromise(this.apiService.getInstance().core.customModelApi.createCustomType(modelName, name, parentType, typeName, '')) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } public addPropertyToAType(modelName: string, typeName: string, formFields: any) { @@ -177,11 +177,11 @@ export class EcmModelService { return Observable.fromPromise(this.apiService.getInstance().core.customModelApi.addPropertyToType(modelName, name, properties)) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } - public cleanNameType(name: string): string { + cleanNameType(name: string): string { let cleanName = name; if (name.indexOf(':') !== -1) { cleanName = name.split(':')[1]; @@ -197,6 +197,6 @@ export class EcmModelService { } handleError(err: any): any { - console.log(err); + this.logService.error(err); } } diff --git a/ng2-components/ng2-activiti-form/src/services/form.service.spec.ts b/ng2-components/ng2-activiti-form/src/services/form.service.spec.ts index 42b8b7b87c9..28339b0dedd 100644 --- a/ng2-components/ng2-activiti-form/src/services/form.service.spec.ts +++ b/ng2-components/ng2-activiti-form/src/services/form.service.spec.ts @@ -16,29 +16,35 @@ */ import { TestBed } from '@angular/core/testing'; -import { CoreModule, AlfrescoApiService } from 'ng2-alfresco-core'; +import { CoreModule, AlfrescoApiService, LogService, LogServiceMock } from 'ng2-alfresco-core'; import { FormService } from './form.service'; import { EcmModelService } from './ecm-model.service'; import { FormDefinitionModel } from '../models/form-definition.model'; -import { HttpModule, Response, ResponseOptions } from '@angular/http'; +import { Response, ResponseOptions } from '@angular/http'; declare let jasmine: any; describe('FormService', () => { - let responseBody: any, service: FormService, apiService: AlfrescoApiService; + let responseBody: any; + let service: FormService; + let apiService: AlfrescoApiService; + let logService: LogService; - beforeAll(() => { + beforeEach(() => { TestBed.configureTestingModule({ - imports: [HttpModule, CoreModule], + imports: [ + CoreModule.forRoot() + ], providers: [ EcmModelService, - AlfrescoApiService, - FormService + FormService, + { provide: LogService, useClass: LogServiceMock } ] }); service = TestBed.get(FormService); apiService = TestBed.get(AlfrescoApiService); + logService = TestBed.get(LogService); }); beforeEach(() => { @@ -267,34 +273,34 @@ describe('FormService', () => { }); it('should handle error with generic message', () => { - spyOn(console, 'error').and.stub(); + spyOn(logService, 'error').and.stub(); service.handleError(null); - expect(console.error).toHaveBeenCalledWith(FormService.UNKNOWN_ERROR_MESSAGE); + expect(logService.error).toHaveBeenCalledWith(FormService.UNKNOWN_ERROR_MESSAGE); }); it('should handle error with error message', () => { - spyOn(console, 'error').and.stub(); + spyOn(logService, 'error').and.stub(); const message = ''; service.handleError({message: message}); - expect(console.error).toHaveBeenCalledWith(message); + expect(logService.error).toHaveBeenCalledWith(message); }); it('should handle error with detailed message', () => { - spyOn(console, 'error').and.stub(); + spyOn(logService, 'error').and.stub(); service.handleError({ status: '400', statusText: 'Bad request' }); - expect(console.error).toHaveBeenCalledWith('400 - Bad request'); + expect(logService.error).toHaveBeenCalledWith('400 - Bad request'); }); it('should handle error with generic message', () => { - spyOn(console, 'error').and.stub(); + spyOn(logService, 'error').and.stub(); service.handleError({}); - expect(console.error).toHaveBeenCalledWith(FormService.GENERIC_ERROR_MESSAGE); + expect(logService.error).toHaveBeenCalledWith(FormService.GENERIC_ERROR_MESSAGE); }); it('should get all the forms with modelType=2', (done) => { diff --git a/ng2-components/ng2-activiti-form/src/services/form.service.ts b/ng2-components/ng2-activiti-form/src/services/form.service.ts index bcb2ae22f2d..0ffc0156d3c 100644 --- a/ng2-components/ng2-activiti-form/src/services/form.service.ts +++ b/ng2-components/ng2-activiti-form/src/services/form.service.ts @@ -16,13 +16,14 @@ */ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; -import { AlfrescoApiService } from 'ng2-alfresco-core'; +import { Observable, Subject } from 'rxjs/Rx'; +import { AlfrescoApiService, LogService } from 'ng2-alfresco-core'; import { FormValues } from './../components/widgets/core/index'; import { FormDefinitionModel } from '../models/form-definition.model'; import { EcmModelService } from './ecm-model.service'; import { GroupModel } from './../components/widgets/core/group.model'; import { GroupUserModel } from './../components/widgets/core/group-user.model'; +import { FormEvent, FormErrorEvent, FormFieldEvent } from './../events/index'; @Injectable() export class FormService { @@ -30,8 +31,16 @@ export class FormService { static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error'; static GENERIC_ERROR_MESSAGE: string = 'Server error'; + formLoaded: Subject = new Subject(); + formFieldValueChanged: Subject = new Subject(); + taskCompleted: Subject = new Subject(); + taskCompletedError: Subject = new Subject(); + taskSaved: Subject = new Subject(); + taskSavedError: Subject = new Subject(); + constructor(private ecmModelService: EcmModelService, - private apiService: AlfrescoApiService) { + private apiService: AlfrescoApiService, + private logService: LogService) { } /** @@ -48,10 +57,11 @@ export class FormService { this.addFieldsToAForm(form.id, formDefinitionModel).subscribe(formData => { observer.next(formData); observer.complete(); - }, this.handleError); + }, err => this.handleError(err)); }, - this.handleError); - }, this.handleError); + err => this.handleError(err)); + }, + err => this.handleError(err)); }); } @@ -87,9 +97,13 @@ export class FormService { 'modelType': 2 }; - return Observable.fromPromise(this.apiService.getInstance().activiti.modelsApi.getModels(opts)).map(function (forms: any) { - return forms.data.find(formdata => formdata.name === name); - }).catch(this.handleError); + return Observable.fromPromise( + this.apiService.getInstance().activiti.modelsApi.getModels(opts)) + .map(function (forms: any) { + return forms.data.find(formdata => formdata.name === name); + }) + .catch(err => this.handleError(err) + ); } /** @@ -105,24 +119,23 @@ export class FormService { } /** - * Get Process Definition + * Get Process Definitions * @returns {Observable} */ getProcessDefinitions(): Observable { return Observable.fromPromise(this.apiService.getInstance().activiti.processApi.getProcessDefinitions({})) .map(this.toJsonArray) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** * Get All the Tasks - * @param taskId Task Id * @returns {Observable} */ getTasks(): Observable { return Observable.fromPromise(this.apiService.getInstance().activiti.taskApi.listTasks({})) .map(this.toJsonArray) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** @@ -133,7 +146,7 @@ export class FormService { getTask(taskId: string): Observable { return Observable.fromPromise(this.apiService.getInstance().activiti.taskApi.getTask(taskId)) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** @@ -146,7 +159,7 @@ export class FormService { let body = JSON.stringify({values: formValues}); return Observable.fromPromise(this.apiService.getInstance().activiti.taskApi.saveTaskForm(taskId, body)) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** @@ -164,7 +177,7 @@ export class FormService { let body = JSON.stringify(data); return Observable.fromPromise(this.apiService.getInstance().activiti.taskApi.completeTaskForm(taskId, body)) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** @@ -175,7 +188,7 @@ export class FormService { getTaskForm(taskId: string): Observable { return Observable.fromPromise(this.apiService.getInstance().activiti.taskApi.getTaskForm(taskId)) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** @@ -186,11 +199,11 @@ export class FormService { getFormDefinitionById(formId: string): Observable { return Observable.fromPromise(this.apiService.getInstance().activiti.editorApi.getForm(formId)) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** - * Returns form definition ID by a given name. + * Returns form definition by a given name. * @param name * @returns {Promise|Promise} */ @@ -203,7 +216,7 @@ export class FormService { return Observable.fromPromise(this.apiService.getInstance().activiti.modelsApi.getModels(opts)) .map(this.getFormId) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** @@ -215,7 +228,7 @@ export class FormService { return Observable.fromPromise( this.apiService.getInstance().activiti.processApi.getProcessInstanceStartForm(processId)) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** @@ -227,7 +240,7 @@ export class FormService { return Observable.fromPromise( this.apiService.getInstance().activiti.processApi.getProcessDefinitionStartForm(processId)) .map(this.toJson) - .catch(this.handleError); + .catch(err => this.handleError(err)); } /** @@ -271,11 +284,10 @@ export class FormService { if (xhr.status === 200) { let json = JSON.parse(xhr.response); let data: GroupModel[] = (json.data || []).map(item => item); - // console.log(json); observer.next(data); observer.complete(); } else { - console.error(xhr.response); + this.logService.error(xhr.response); Observable.throw(new Error(xhr.response)); } } @@ -303,11 +315,10 @@ export class FormService { if (xhr.status === 200) { let json = JSON.parse(xhr.response); let data: GroupUserModel[] = (json.data || []).map(item => item); - // console.log(json); observer.next(data); observer.complete(); } else { - console.error(xhr.response); + this.logService.error(xhr.response); Observable.throw(new Error(xhr.response)); } } @@ -324,7 +335,7 @@ export class FormService { }); } - getFormId(res: any) { + getFormId(res: any): string { let result = null; if (res && res.data && res.data.length > 0) { @@ -354,7 +365,7 @@ export class FormService { errMsg = (error.message) ? error.message : error.status ? `${error.status} - ${error.statusText}` : FormService.GENERIC_ERROR_MESSAGE; } - console.error(errMsg); + this.logService.error(errMsg); return Observable.throw(errMsg); } } diff --git a/ng2-components/ng2-activiti-form/src/services/node.service.spec.ts b/ng2-components/ng2-activiti-form/src/services/node.service.spec.ts index 9b99e3a6fbd..1313d463c66 100644 --- a/ng2-components/ng2-activiti-form/src/services/node.service.spec.ts +++ b/ng2-components/ng2-activiti-form/src/services/node.service.spec.ts @@ -19,7 +19,6 @@ import { TestBed } from '@angular/core/testing'; import { CoreModule } from 'ng2-alfresco-core'; import { NodeService } from './node.service'; import { NodeMetadata } from '../models/node-metadata.model'; -import { HttpModule } from '@angular/http'; import { EcmModelService } from './ecm-model.service'; declare let jasmine: any; @@ -28,9 +27,11 @@ describe('NodeService', () => { let service: NodeService; - beforeAll(() => { + beforeEach(() => { TestBed.configureTestingModule({ - imports: [ HttpModule, CoreModule ], + imports: [ + CoreModule.forRoot() + ], providers: [ NodeService, EcmModelService diff --git a/ng2-components/ng2-activiti-form/src/services/node.service.ts b/ng2-components/ng2-activiti-form/src/services/node.service.ts index 810188b4394..1a6958b7f64 100644 --- a/ng2-components/ng2-activiti-form/src/services/node.service.ts +++ b/ng2-components/ng2-activiti-form/src/services/node.service.ts @@ -16,14 +16,14 @@ */ import { Injectable } from '@angular/core'; -import { AlfrescoAuthenticationService, AlfrescoApiService } from 'ng2-alfresco-core'; +import { AlfrescoApiService } from 'ng2-alfresco-core'; import { Observable } from 'rxjs/Rx'; import { NodeMetadata } from '../models/node-metadata.model'; @Injectable() export class NodeService { - constructor(private authService: AlfrescoAuthenticationService, private apiService: AlfrescoApiService) { + constructor(private apiService: AlfrescoApiService) { } /** diff --git a/ng2-components/ng2-activiti-form/src/services/widget-visibility.service.spec.ts b/ng2-components/ng2-activiti-form/src/services/widget-visibility.service.spec.ts index 4b61f15094c..fffef3c959b 100644 --- a/ng2-components/ng2-activiti-form/src/services/widget-visibility.service.spec.ts +++ b/ng2-components/ng2-activiti-form/src/services/widget-visibility.service.spec.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -import { ReflectiveInjector } from '@angular/core'; -import { AlfrescoApi } from 'alfresco-js-api'; +import { TestBed } from '@angular/core/testing'; +import { CoreModule } from 'ng2-alfresco-core'; import { formTest, fakeTaskProcessVariableModels, @@ -24,41 +24,28 @@ import { fakeFormJson } from './assets/widget-visibility.service.mock'; import { WidgetVisibilityService } from './widget-visibility.service'; -import { - AlfrescoAuthenticationService, - AlfrescoSettingsService, - AlfrescoApiService, - StorageService -} from 'ng2-alfresco-core'; -import { TaskProcessVariableModel } from '../models/task-process-variable.model'; -import { WidgetVisibilityModel } from '../models/widget-visibility.model'; -import { FormModel, FormFieldModel, TabModel, ContainerModel, FormFieldTypes } from '../components/widgets/core/index'; +import { TaskProcessVariableModel } from './../models/task-process-variable.model'; +import { WidgetVisibilityModel } from './../models/widget-visibility.model'; +import { FormModel, FormFieldModel, TabModel, ContainerModel, FormFieldTypes } from './../components/widgets/core/index'; declare let jasmine: any; describe('WidgetVisibilityService', () => { - let service, injector; - let authenticationService: AlfrescoAuthenticationService; - let apiService: AlfrescoApiService; - let alfrescoApi: AlfrescoApi; + + let service: WidgetVisibilityService; let booleanResult: boolean; let stubFormWithFields = new FormModel(fakeFormJson); beforeEach(() => { - injector = ReflectiveInjector.resolveAndCreate([ - WidgetVisibilityService, - AlfrescoSettingsService, - AlfrescoApiService, - AlfrescoAuthenticationService, - StorageService - ]); - }); - - beforeEach(() => { - service = injector.get(WidgetVisibilityService); - authenticationService = injector.get(AlfrescoAuthenticationService); - apiService = injector.get(AlfrescoApiService); - alfrescoApi = apiService.getInstance(); + TestBed.configureTestingModule({ + imports: [ + CoreModule.forRoot() + ], + providers: [ + WidgetVisibilityService + ] + }); + service = TestBed.get(WidgetVisibilityService); jasmine.Ajax.install(); }); diff --git a/ng2-components/ng2-activiti-form/src/services/widget-visibility.service.ts b/ng2-components/ng2-activiti-form/src/services/widget-visibility.service.ts index df269ba529a..f8a411e9ea8 100644 --- a/ng2-components/ng2-activiti-form/src/services/widget-visibility.service.ts +++ b/ng2-components/ng2-activiti-form/src/services/widget-visibility.service.ts @@ -17,24 +17,19 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; -import { AlfrescoApiService } from 'ng2-alfresco-core'; -import { - FormModel, - FormFieldModel, - TabModel, - ContainerModel, - ContainerColumnModel -} from '../components/widgets/core/index'; +import * as moment from 'moment'; +import { AlfrescoApiService, LogService } from 'ng2-alfresco-core'; +import { FormModel, FormFieldModel, TabModel, ContainerModel, ContainerColumnModel } from '../components/widgets/core/index'; import { WidgetVisibilityModel } from '../models/widget-visibility.model'; import { TaskProcessVariableModel } from '../models/task-process-variable.model'; -import * as moment from 'moment'; @Injectable() export class WidgetVisibilityService { private processVarList: TaskProcessVariableModel[]; - constructor(private apiService: AlfrescoApiService) { + constructor(private apiService: AlfrescoApiService, + private logService: LogService) { } public refreshVisibility(form: FormModel) { @@ -201,7 +196,7 @@ export class WidgetVisibilityService { case 'or-not': return previousValue || !newValue; default: - console.error('NO valid operation! wrong op request : ' + logicOp); + this.logService.error('NO valid operation! wrong op request : ' + logicOp); break; } } @@ -225,7 +220,7 @@ export class WidgetVisibilityService { case '!empty': return leftValue ? leftValue !== '' : false; default: - console.error('NO valid operation!'); + this.logService.error('NO valid operation!'); break; } return; @@ -242,15 +237,15 @@ export class WidgetVisibilityService { this.processVarList = jsonRes; return jsonRes; }) - .catch(this.handleError); + .catch(err => this.handleError(err)); } toJson(res: any) { return res || {}; } - private handleError() { - console.error('Error while performing a call'); + private handleError(err) { + this.logService.error('Error while performing a call'); return Observable.throw('Error while performing a call - Server error'); } } diff --git a/ng2-components/ng2-activiti-form/stencils/runtime.ng1.js b/ng2-components/ng2-activiti-form/stencils/runtime.ng1.js index 411ee66cf25..c5b4de0e42c 100644 --- a/ng2-components/ng2-activiti-form/stencils/runtime.ng1.js +++ b/ng2-components/ng2-activiti-form/stencils/runtime.ng1.js @@ -5,8 +5,11 @@ window.angular = { return { controller: function (controllerName) { console.info('ng1: controller %s requested', controllerName); - return { - } + return {} + }, + directive: function (directiveName) { + console.info('ng1: directive %s requested', directiveName); + return {} } } } diff --git a/ng2-components/ng2-activiti-processlist/README.md b/ng2-components/ng2-activiti-processlist/README.md index c8f9875c4f2..26c13a18300 100644 --- a/ng2-components/ng2-activiti-processlist/README.md +++ b/ng2-components/ng2-activiti-processlist/README.md @@ -68,6 +68,9 @@ Follow the 3 steps below: + + + diff --git a/ng2-components/ng2-activiti-processlist/demo/package.json b/ng2-components/ng2-activiti-processlist/demo/package.json index 25411960767..603b378777f 100644 --- a/ng2-components/ng2-activiti-processlist/demo/package.json +++ b/ng2-components/ng2-activiti-processlist/demo/package.json @@ -32,7 +32,7 @@ "@angular/http": "2.2.2", "@angular/platform-browser": "2.2.2", "@angular/platform-browser-dynamic": "2.2.2", - "@angular/router": "3.0.0", + "@angular/material": "2.0.0-beta.1", "@angular/router": "3.2.2", "@angular/upgrade": "2.2.2", "core-js": "^2.4.1", @@ -48,11 +48,11 @@ "moment": "2.15.1", "md-date-time-picker": "^2.2.0", "ng2-translate": "2.5.0", - "alfresco-js-api": "^1.0.0", - "ng2-activiti-tasklist": "1.0.0", - "ng2-alfresco-core": "1.0.0", - "ng2-alfresco-datatable": "1.0.0", - "ng2-activiti-processlist": "^1.0.0" + "alfresco-js-api": "~1.1.0", + "ng2-activiti-tasklist": "1.1.0", + "ng2-alfresco-core": "1.1.0", + "ng2-alfresco-datatable": "1.1.0", + "ng2-activiti-processlist": "^1.1.0" }, "devDependencies": { "@types/jasmine": "^2.2.33", diff --git a/ng2-components/ng2-activiti-processlist/demo/src/main.ts b/ng2-components/ng2-activiti-processlist/demo/src/main.ts index 07aa0998385..643924cbd81 100644 --- a/ng2-components/ng2-activiti-processlist/demo/src/main.ts +++ b/ng2-components/ng2-activiti-processlist/demo/src/main.ts @@ -1,274 +1,275 @@ -/*! - * @license - * Copyright 2016 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { DebugElement, Input, NgModule, Component, OnInit, ViewChild } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { AppDefinitionRepresentationModel, ActivitiTaskListModule } from 'ng2-activiti-tasklist'; -import { CoreModule } from 'ng2-alfresco-core'; -import { - ActivitiProcessListModule, - ActivitiProcessFilters, - ActivitiProcessInstanceDetails, - ActivitiProcessInstanceListComponent, - ActivitiStartProcessInstance, - ProcessInstance -} from 'ng2-activiti-processlist'; -import { AlfrescoAuthenticationService, AlfrescoSettingsService, StorageService } from 'ng2-alfresco-core'; -import { ObjectDataTableAdapter } from 'ng2-alfresco-datatable'; - -const currentProcessIdNew = '__NEW__'; - -@Component({ - selector: 'alfresco-app-demo', - template: ` -
-
-
-

-
- Authentication failed to ip {{ host }} with user: admin, admin, you can still try to add a valid ticket to perform - operations. -
-
- -
- -
- - - - -
- -
- - - -
-
- -
-
- - - -
-
-
-
-

Process Filters

- - -
-
-

Process List

- -
-
-

Process Details

- -

Process Variables

- -
-
-

Start Process

- -
-
-
-
- -
-
-`, - styles: [` - header { - min-height: 48px; - } - h2 { - font-size: 14px; - line-height: 20px; - margin: 10px 0; - } - `] -}) -class MyDemoApp implements OnInit { - - authenticated: boolean; - - host: string = 'http://localhost:9999'; - - ticket: string; - - @ViewChild('tabmain') - tabMain: DebugElement; - - @ViewChild('tabheader') - tabHeader: DebugElement; - - @ViewChild(ActivitiProcessFilters) - activitiprocessfilter: ActivitiProcessFilters; - - @ViewChild(ActivitiProcessInstanceListComponent) - activitiprocesslist: ActivitiProcessInstanceListComponent; - - @ViewChild(ActivitiProcessInstanceDetails) - activitiprocessdetails: ActivitiProcessInstanceDetails; - - @ViewChild(ActivitiStartProcessInstance) - activitiStartProcess: ActivitiStartProcessInstance; - - @Input() - appId: number; - - processFilter: any; - - currentProcessInstanceId: string; - - dataProcesses: ObjectDataTableAdapter; - - constructor(private authService: AlfrescoAuthenticationService, - private settingsService: AlfrescoSettingsService, - private storage: StorageService) { - settingsService.bpmHost = this.host; - settingsService.setProviders('BPM'); - - if (this.authService.getTicketBpm()) { - this.ticket = this.authService.getTicketBpm(); - } - - this.dataProcesses = new ObjectDataTableAdapter( - [], - [ - {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true}, - {type: 'text', key: 'started', title: 'Started', sortable: true, cssClass: 'hidden'} - ] - ); - } - - public updateTicket(): void { - this.storage.setItem('ticket-BPM', this.ticket); - } - - public updateHost(): void { - this.settingsService.bpmHost = this.host; - this.login(); - } - - public ngOnInit(): void { - this.login(); - } - - login() { - this.authService.login('admin', 'admin').subscribe( - ticket => { - console.log(ticket); - this.ticket = this.authService.getTicketBpm(); - this.authenticated = true; - }, - error => { - console.log(error); - this.authenticated = false; - }); - } - - onAppClick(app: AppDefinitionRepresentationModel) { - this.appId = app.id; - - this.processFilter = null; - this.currentProcessInstanceId = null; - - this.changeTab('apps', 'processes'); - } - - navigateStartProcess() { - this.currentProcessInstanceId = currentProcessIdNew; - } - - onStartProcessInstance(instance: ProcessInstance) { - this.currentProcessInstanceId = instance.id; - this.activitiStartProcess.reset(); - } - - isStartProcessMode() { - return this.currentProcessInstanceId === currentProcessIdNew; - } - - onProcessFilterClick(event: any) { - this.processFilter = event; - } - - onSuccessProcessFilterList(event: any) { - this.processFilter = this.activitiprocessfilter.getCurrentFilter(); - } - - onSuccessProcessList(event: any) { - this.currentProcessInstanceId = this.activitiprocesslist.getCurrentId(); - } - - onProcessRowClick(processInstanceId) { - this.currentProcessInstanceId = processInstanceId; - } - - processCancelled(data: any) { - this.currentProcessInstanceId = null; - this.activitiprocesslist.reload(); - } - - changeTab(origin: string, destination: string) { - this.tabMain.nativeElement.children[origin].classList.remove('is-active'); - this.tabMain.nativeElement.children[destination].classList.add('is-active'); - - this.tabHeader.nativeElement.children[`${origin}-header`].classList.remove('is-active'); - this.tabHeader.nativeElement.children[`${destination}-header`].classList.add('is-active'); - } - -} - -@NgModule({ - imports: [ - BrowserModule, - CoreModule.forRoot(), - ActivitiProcessListModule, - ActivitiTaskListModule.forRoot() - ], - declarations: [MyDemoApp], - bootstrap: [MyDemoApp] -}) -export class AppModule { -} - -platformBrowserDynamic().bootstrapModule(AppModule); +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DebugElement, Input, NgModule, Component, OnInit, ViewChild } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppDefinitionRepresentationModel, ActivitiTaskListModule } from 'ng2-activiti-tasklist'; +import { CoreModule, LogService } from 'ng2-alfresco-core'; +import { + ActivitiProcessListModule, + ActivitiProcessFilters, + ActivitiProcessInstanceDetails, + ActivitiProcessInstanceListComponent, + ActivitiStartProcessInstance, + ProcessInstance +} from 'ng2-activiti-processlist'; +import { AlfrescoAuthenticationService, AlfrescoSettingsService, StorageService } from 'ng2-alfresco-core'; +import { ObjectDataTableAdapter } from 'ng2-alfresco-datatable'; + +const currentProcessIdNew = '__NEW__'; + +@Component({ + selector: 'alfresco-app-demo', + template: ` +
+
+
+

+
+ Authentication failed to ip {{ host }} with user: admin, admin, you can still try to add a valid ticket to perform + operations. +
+
+ +
+ +
+ + + + +
+ +
+ + + +
+
+ +
+
+ + + +
+
+
+
+

Process Filters

+ + +
+
+

Process List

+ +
+
+

Process Details

+ +

Process Variables

+ +
+
+

Start Process

+ +
+
+
+
+ +
+
+`, + styles: [` + header { + min-height: 48px; + } + h2 { + font-size: 14px; + line-height: 20px; + margin: 10px 0; + } + `] +}) +class MyDemoApp implements OnInit { + + authenticated: boolean; + + host: string = 'http://localhost:9999'; + + ticket: string; + + @ViewChild('tabmain') + tabMain: DebugElement; + + @ViewChild('tabheader') + tabHeader: DebugElement; + + @ViewChild(ActivitiProcessFilters) + activitiprocessfilter: ActivitiProcessFilters; + + @ViewChild(ActivitiProcessInstanceListComponent) + activitiprocesslist: ActivitiProcessInstanceListComponent; + + @ViewChild(ActivitiProcessInstanceDetails) + activitiprocessdetails: ActivitiProcessInstanceDetails; + + @ViewChild(ActivitiStartProcessInstance) + activitiStartProcess: ActivitiStartProcessInstance; + + @Input() + appId: number; + + processFilter: any; + + currentProcessInstanceId: string; + + dataProcesses: ObjectDataTableAdapter; + + constructor(private authService: AlfrescoAuthenticationService, + private settingsService: AlfrescoSettingsService, + private storage: StorageService, + private logService: LogService) { + settingsService.bpmHost = this.host; + settingsService.setProviders('BPM'); + + if (this.authService.getTicketBpm()) { + this.ticket = this.authService.getTicketBpm(); + } + + this.dataProcesses = new ObjectDataTableAdapter( + [], + [ + {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true}, + {type: 'text', key: 'started', title: 'Started', sortable: true, cssClass: 'hidden'} + ] + ); + } + + public updateTicket(): void { + this.storage.setItem('ticket-BPM', this.ticket); + } + + public updateHost(): void { + this.settingsService.bpmHost = this.host; + this.login(); + } + + public ngOnInit(): void { + this.login(); + } + + login() { + this.authService.login('admin', 'admin').subscribe( + ticket => { + this.logService.log(ticket); + this.ticket = this.authService.getTicketBpm(); + this.authenticated = true; + }, + error => { + this.logService.error(error); + this.authenticated = false; + }); + } + + onAppClick(app: AppDefinitionRepresentationModel) { + this.appId = app.id; + + this.processFilter = null; + this.currentProcessInstanceId = null; + + this.changeTab('apps', 'processes'); + } + + navigateStartProcess() { + this.currentProcessInstanceId = currentProcessIdNew; + } + + onStartProcessInstance(instance: ProcessInstance) { + this.currentProcessInstanceId = instance.id; + this.activitiStartProcess.reset(); + } + + isStartProcessMode() { + return this.currentProcessInstanceId === currentProcessIdNew; + } + + onProcessFilterClick(event: any) { + this.processFilter = event; + } + + onSuccessProcessFilterList(event: any) { + this.processFilter = this.activitiprocessfilter.getCurrentFilter(); + } + + onSuccessProcessList(event: any) { + this.currentProcessInstanceId = this.activitiprocesslist.getCurrentId(); + } + + onProcessRowClick(processInstanceId) { + this.currentProcessInstanceId = processInstanceId; + } + + processCancelled(data: any) { + this.currentProcessInstanceId = null; + this.activitiprocesslist.reload(); + } + + changeTab(origin: string, destination: string) { + this.tabMain.nativeElement.children[origin].classList.remove('is-active'); + this.tabMain.nativeElement.children[destination].classList.add('is-active'); + + this.tabHeader.nativeElement.children[`${origin}-header`].classList.remove('is-active'); + this.tabHeader.nativeElement.children[`${destination}-header`].classList.add('is-active'); + } + +} + +@NgModule({ + imports: [ + BrowserModule, + CoreModule.forRoot(), + ActivitiProcessListModule, + ActivitiTaskListModule.forRoot() + ], + declarations: [MyDemoApp], + bootstrap: [MyDemoApp] +}) +export class AppModule { +} + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/ng2-components/ng2-activiti-processlist/karma-test-shim.js b/ng2-components/ng2-activiti-processlist/karma-test-shim.js index b628e7b92b9..b3f275d74f6 100644 --- a/ng2-components/ng2-activiti-processlist/karma-test-shim.js +++ b/ng2-components/ng2-activiti-processlist/karma-test-shim.js @@ -1,7 +1,14 @@ // Tun on full stack traces in errors to help debugging Error.stackTraceLimit = Infinity; -jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +window.componentHandler = { + upgradeAllRegistered: function () { + }, + upgradeElement: function () { + } +}; __karma__.loaded = function() {}; @@ -39,6 +46,8 @@ var map = { '@angular/http': 'npm:@angular/http/bundles/http.umd.js', '@angular/router': 'npm:@angular/router/bundles/router.umd.js', '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/material': 'npm:@angular/material/bundles/material.umd.js', + // testing '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js', '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js', diff --git a/ng2-components/ng2-activiti-processlist/package.json b/ng2-components/ng2-activiti-processlist/package.json index 857c38e3179..06da47e6dca 100644 --- a/ng2-components/ng2-activiti-processlist/package.json +++ b/ng2-components/ng2-activiti-processlist/package.json @@ -1,13 +1,13 @@ { "name": "ng2-activiti-processlist", "description": "Show active processes from the Activiti BPM suite", - "version": "1.0.0", + "version": "1.1.0", "author": "Alfresco Software, Ltd.", "scripts": { "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings", "clean-build": "rimraf index.js index.js.map index.d.ts'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts' bundles", "build": "npm run clean-build && npm run tslint && rimraf dist && tsc && license-check && npm run build.umd", - "build:w": "npm run clean-build && npm run tslint && rimraf dist && tsc:w && license-check npm run build.umd", + "build:w": "npm run clean-build && npm run tslint && rimraf dist && npm run tsc:w && license-check && npm run build.umd", "tslint": "tslint -c tslint.json 'src/{,**/}**.ts' 'index.ts' -e '{,**/}**.d.ts' -e './gulpfile.ts'", "tsc": "tsc", "tsc:w": "tsc -w", @@ -16,7 +16,7 @@ "test-browser": "npm run build && concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", "posttest": "remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html && remap-istanbul -i coverage/report/coverage-final.json -o coverage/report/coverage-final.json", "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report", - "prepublish": "npm run build", + "prepublish": "npm run test", "travis": "npm link ng2-alfresco-core ng2-alfresco-datatable ng2-activiti-form ng2-activiti-tasklist", "gulp": "gulp", "build.umd": "gulp build.prod --color --env-config prod --build-type prod", @@ -53,6 +53,7 @@ "@angular/http": "2.0.0", "@angular/platform-browser": "2.0.0", "@angular/platform-browser-dynamic": "2.0.0", + "@angular/material": "2.0.0-beta.1", "core-js": "^2.4.1", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.12", @@ -61,14 +62,16 @@ "moment": "2.15.1", "md-date-time-picker": "^2.2.0", "ng2-translate": "2.5.0", - "alfresco-js-api": "^1.0.0", - "ng2-activiti-tasklist": "1.0.0", - "ng2-alfresco-core": "1.0.0", - "ng2-alfresco-datatable": "1.0.0" + "alfresco-js-api": "~1.1.0", + "ng2-activiti-form": "1.1.0", + "ng2-activiti-tasklist": "1.1.0", + "ng2-alfresco-core": "1.1.0", + "ng2-alfresco-datatable": "1.1.0" }, "devDependencies": { "@types/jasmine": "^2.2.33", "@types/node": "^6.0.42", + "autoprefixer": "^6.5.4", "concurrently": "^2.2.0", "cpx": "^1.3.1", "cssnano": "^3.8.1", @@ -87,6 +90,7 @@ "gulp-template": "^4.0.0", "gulp-typescript": "^3.1.3", "gulp-uglify": "^2.0.0", + "gulp-util": "^3.0.7", "intl": "^1.2.5", "jasmine-ajax": "^3.2.0", "jasmine-core": "2.4.1", @@ -98,6 +102,7 @@ "karma-jasmine-html-reporter": "^0.2.0", "karma-mocha-reporter": "^2.0.3", "license-check": "^1.0.4", + "merge-stream": "^1.0.1", "remap-istanbul": "^0.6.3", "rimraf": "2.5.2", "run-sequence": "^1.2.2", diff --git a/ng2-components/ng2-activiti-processlist/src/assets/activiti-process-instances-list.mock.ts b/ng2-components/ng2-activiti-processlist/src/assets/activiti-process-instances-list.mock.ts new file mode 100644 index 00000000000..1181b9df2df --- /dev/null +++ b/ng2-components/ng2-activiti-processlist/src/assets/activiti-process-instances-list.mock.ts @@ -0,0 +1,74 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ProcessInstance } from '../models/process-instance.model'; + +export var fakeProcessInstances = [ + new ProcessInstance({ + id: 1, + name: 'Process 773443333', + processDefinitionId: 'fakeprocess:5:7507', + processDefinitionKey: 'fakeprocess', + processDefinitionName: 'Fake Process Name', + description: null, category: null, + started: '2015-11-09T12:36:14.184+0000', + startedBy: { + id: 3, firstName: 'tenant2', lastName: 'tenantLastname', email: 'tenant2@tenant' + } + }), + new ProcessInstance({ + id: 2, + name: 'Process 382927392', + processDefinitionId: 'fakeprocess:5:7507', + processDefinitionKey: 'fakeprocess', + processDefinitionName: 'Fake Process Name', + description: null, + category: null, + started: '2017-11-09T12:37:25.184+0000', + startedBy: { + id: 3, firstName: 'tenant2', lastName: 'tenantLastname', email: 'tenant2@tenant' + } + }) +]; + +export var fakeProcessInstancesWithNoName = [ + new ProcessInstance({ + id: 1, + name: null, + processDefinitionId: 'fakeprocess:5:7507', + processDefinitionKey: 'fakeprocess', + processDefinitionName: 'Fake Process Name', + description: null, category: null, + started: '2017-11-09T12:36:14.184+0000', + startedBy: { + id: 3, firstName: 'tenant2', lastName: 'tenantLastname', email: 'tenant2@tenant' + } + }), + new ProcessInstance({ + id: 2, + name: '', + processDefinitionId: 'fakeprocess:5:7507', + processDefinitionKey: 'fakeprocess', + processDefinitionName: 'Fake Process Name', + description: null, + category: null, + started: '2017-11-09T12:37:25.184+0000', + startedBy: { + id: 3, firstName: 'tenant2', lastName: 'tenantLastname', email: 'tenant2@tenant' + } + }) +]; diff --git a/ng2-components/ng2-activiti-processlist/src/assets/activiti-process.model.mock.ts b/ng2-components/ng2-activiti-processlist/src/assets/activiti-process.model.mock.ts index 202b62cf694..bbcf650f155 100644 --- a/ng2-components/ng2-activiti-processlist/src/assets/activiti-process.model.mock.ts +++ b/ng2-components/ng2-activiti-processlist/src/assets/activiti-process.model.mock.ts @@ -50,3 +50,16 @@ export var exampleProcess = new ProcessInstance({ email: 'bob@app.activiti.com' } }); + +export var exampleProcessNoName = new ProcessInstance({ + id: '123', + name: null, + started: '2016-11-10T03:37:30.010+0000', + startedBy: { + id: 1001, + firstName: 'Bob', + lastName: 'Jones', + email: 'bob@app.activiti.com' + }, + processDefinitionName: 'My Process' +}); diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.spec.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.spec.ts index 69bfee68baa..3530eb6779b 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.spec.ts +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.spec.ts @@ -16,15 +16,17 @@ */ import { SimpleChange } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; +import { LogServiceMock } from 'ng2-alfresco-core'; import { ActivitiProcessFilters } from './activiti-filters.component'; import { ActivitiProcessService } from '../services/activiti-process.service'; -import { Observable } from 'rxjs/Rx'; import { FilterRepresentationModel } from 'ng2-activiti-tasklist'; describe('ActivitiFilters', () => { let filterList: ActivitiProcessFilters; let activitiService: ActivitiProcessService; + let logService: LogServiceMock; let fakeGlobalFilter = []; fakeGlobalFilter.push(new FilterRepresentationModel({name: 'FakeInvolvedTasks', filter: { state: 'open', assignment: 'fake-involved'}})); @@ -43,8 +45,9 @@ describe('ActivitiFilters', () => { }); beforeEach(() => { - activitiService = new ActivitiProcessService(null, null); - filterList = new ActivitiProcessFilters(null, activitiService); + logService = new LogServiceMock(); + activitiService = new ActivitiProcessService(null); + filterList = new ActivitiProcessFilters(null, activitiService, logService); }); it('should return the filter task list', (done) => { diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.ts index a6a800cdb15..d26c12f8d2e 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.ts +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.ts @@ -16,10 +16,10 @@ */ import { Component, Output, EventEmitter, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core'; -import { AlfrescoTranslationService } from 'ng2-alfresco-core'; -import { ActivitiProcessService } from './../services/activiti-process.service'; -import { FilterRepresentationModel } from 'ng2-activiti-tasklist'; import { Observable, Observer } from 'rxjs/Rx'; +import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core'; +import { FilterProcessRepresentationModel } from './../models/filter-process.model'; +import { ActivitiProcessService } from './../services/activiti-process.service'; declare let componentHandler: any; @@ -32,10 +32,10 @@ declare let componentHandler: any; export class ActivitiProcessFilters implements OnInit, OnChanges { @Output() - filterClick: EventEmitter = new EventEmitter(); + filterClick: EventEmitter = new EventEmitter(); @Output() - onSuccess: EventEmitter = new EventEmitter(); + onSuccess: EventEmitter = new EventEmitter(); @Output() onError: EventEmitter = new EventEmitter(); @@ -46,16 +46,17 @@ export class ActivitiProcessFilters implements OnInit, OnChanges { @Input() appName: string; - private filterObserver: Observer; - filter$: Observable; + private filterObserver: Observer; + filter$: Observable; - currentFilter: FilterRepresentationModel; + currentFilter: FilterProcessRepresentationModel; - filters: FilterRepresentationModel [] = []; + filters: FilterProcessRepresentationModel [] = []; constructor(private translate: AlfrescoTranslationService, - private activiti: ActivitiProcessService) { - this.filter$ = new Observable(observer => this.filterObserver = observer).share(); + private activiti: ActivitiProcessService, + private logService: LogService) { + this.filter$ = new Observable(observer => this.filterObserver = observer).share(); if (translate) { translate.addTranslationFolder('ng2-activiti-processlist', 'node_modules/ng2-activiti-processlist/src'); @@ -63,7 +64,7 @@ export class ActivitiProcessFilters implements OnInit, OnChanges { } ngOnInit() { - this.filter$.subscribe((filter: FilterRepresentationModel) => { + this.filter$.subscribe((filter: FilterProcessRepresentationModel) => { this.filters.push(filter); }); @@ -102,7 +103,7 @@ export class ActivitiProcessFilters implements OnInit, OnChanges { */ getFiltersByAppId(appId?: number) { this.activiti.getProcessFilters(appId).subscribe( - (res: FilterRepresentationModel[]) => { + (res: FilterProcessRepresentationModel[]) => { this.resetFilter(); res.forEach((filter) => { this.filterObserver.next(filter); @@ -110,8 +111,8 @@ export class ActivitiProcessFilters implements OnInit, OnChanges { this.selectFirstFilter(); this.onSuccess.emit(res); }, - (err) => { - console.log(err); + (err: any) => { + this.logService.error(err); this.onError.emit(err); } ); @@ -128,7 +129,7 @@ export class ActivitiProcessFilters implements OnInit, OnChanges { this.selectFirstFilter(); }, (err) => { - console.log(err); + this.logService.error(err); this.onError.emit(err); }); } @@ -137,7 +138,7 @@ export class ActivitiProcessFilters implements OnInit, OnChanges { * Pass the selected filter as next * @param filter */ - public selectFilter(filter: FilterRepresentationModel) { + public selectFilter(filter: FilterProcessRepresentationModel) { this.currentFilter = filter; this.filterClick.emit(filter); } @@ -157,7 +158,7 @@ export class ActivitiProcessFilters implements OnInit, OnChanges { * Return the current task * @returns {FilterRepresentationModel} */ - getCurrentFilter(): FilterRepresentationModel { + getCurrentFilter(): FilterProcessRepresentationModel { return this.currentFilter; } diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.css b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.css index 65ef475088a..e852011d55d 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.css +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.css @@ -20,3 +20,16 @@ .material-icons { cursor: pointer; } + +.list-wrap { + word-wrap: break-word; + word-break: break-all; + -moz-hyphens:auto; + -webkit-hyphens:auto; + -o-hyphens:auto; + hyphens:auto; +} + +.hide-long-names { + overflow: auto; +} \ No newline at end of file diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.html b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.html index f1760200c3b..17e5ae66819 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.html +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.html @@ -7,8 +7,8 @@