diff options
author | Skip Wonnell <skip@att.com> | 2018-03-01 08:30:15 -0600 |
---|---|---|
committer | Skip Wonnell <skip@att.com> | 2018-03-01 08:33:56 -0600 |
commit | 2c977e2b66ced314a4f51121801f62fe5c3c05e4 (patch) | |
tree | d93b360d7a6502a6aff1f30ba7f96c3e14f8911c /src | |
parent | 912f105d12fe6f8dc3a2d409938c87016204debe (diff) |
Initial seed code contribution for CDT
Issue-ID: APPC-682
Change-Id: I0331ffce2a430195c29d0d1b2295966f9eb28699
Signed-off-by: Skip Wonnell <skip@att.com>
Diffstat (limited to 'src')
147 files changed, 31457 insertions, 0 deletions
diff --git a/src/app/about-us/aboutus.component.css b/src/app/about-us/aboutus.component.css new file mode 100644 index 0000000..93ac11c --- /dev/null +++ b/src/app/about-us/aboutus.component.css @@ -0,0 +1,27 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +.textarea { + width: 800px; + height: 200px +}
\ No newline at end of file diff --git a/src/app/about-us/aboutus.component.html b/src/app/about-us/aboutus.component.html new file mode 100644 index 0000000..bfc6f9a --- /dev/null +++ b/src/app/about-us/aboutus.component.html @@ -0,0 +1,103 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<div class="text-center"> + <div class="card"> + <div class="mdl-dialog__content"> + <div class="card"> + <div class="card-header" style="font-size: 20px">CONTACT DETAILS</div> + <div class="mdl-card__title"> + <div class="text-center"> + Contact us @: <a href="mailto:DL-APPCDEVELOPMENTTEAM@att.com?Subject=1710CDTContactus">APPC + DEVELOPMENT TEAM </a> + </div> + </div> + </div>     + <div class="card"> + <div class="card-header" style="font-size: 20px">VERSION DETAILS</div> + <div class="mdl-card__title"> + <table> + <thead></thead> + <tbody> + <tr> + <td> + <div class="android-title mdl-layout-title">Current Release :</div> + </td> + <td> + <div class="android-title mdl-layout-title">{{releaseName}}</div> + </td> + </tr> + <tr> + <td> + <div class="android-title mdl-layout-title">Current Version :</div> + </td> + <td> + <div class="android-title mdl-layout-title">{{versionNo}}</div> + </td> + </tr> + </tbody> + </table> + </div> + <div class="text-right"> + <div class="mdl-dialog__content"> + <a class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" + (click)="open(content)" (click)="versionLogFile()">VIEW CHANGE LOG</a> + </div> + </div> + + </div> + + </div> + </div> +</div> + +<ng-template #content let-c="close" let-d="dismiss"> + <div class="modal-content" style="width:800px;vertical-align:auto;"> + <div class="modal-header"> + <h4 class="modal-title" style="text-align:center">VERSION CHANGE LOG</h4> + <button type="button" class="close" aria-label="Close" (click)="d('Cross click')"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <div class="form-group row"> + <html> + + <body> + <textarea class="textarea">{{this.data}}</textarea> + </body> + + </html> + </div> + </div> + <div class="modal-footer"> + <button type="button" (click)="downloadLogFile()" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent + " (click)="c('yes')">Download + </button> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary + + " (click)="c('yes')">Cancel + </button> + </div> + </div> +</ng-template>
\ No newline at end of file diff --git a/src/app/about-us/aboutus.component.spec.ts b/src/app/about-us/aboutus.component.spec.ts new file mode 100644 index 0000000..e5541eb --- /dev/null +++ b/src/app/about-us/aboutus.component.spec.ts @@ -0,0 +1,49 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {AboutUsComponent} from './aboutus.component'; + +describe('ContacUsComponent', () => { + let component: AboutUsComponent; + let fixture: ComponentFixture<AboutUsComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [AboutUsComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AboutUsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/about-us/aboutus.component.ts b/src/app/about-us/aboutus.component.ts new file mode 100644 index 0000000..360855e --- /dev/null +++ b/src/app/about-us/aboutus.component.ts @@ -0,0 +1,83 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Component, OnInit} from '@angular/core'; +import {Http} from '@angular/http'; +import {saveAs} from 'file-saver'; +import {ModalDismissReasons, NgbModal} from '@ng-bootstrap/ng-bootstrap'; + +@Component({ + selector: 'app-help', + templateUrl: './aboutus.component.html', + styleUrls: ['./aboutus.component.css'] +}) +export class AboutUsComponent implements OnInit { + + public releaseName: any; + public versionNo: any; + + public data: any; + closeResult: string; + + constructor(private http: Http, private modalService: NgbModal) { + } + + ngOnInit() { + this.versionNo = require('./appVersion.json').versionNo; + this.releaseName = require('./appVersion.json').releaseName; + } + + versionLogFile() { + this.http.get('app/shared/components/about-us/versionLog.txt') + .subscribe(res => this.data = res.text()); + console.log('json data ', this.data); + + } + + open(content) { + this.modalService.open(content).result.then((result) => { + this.closeResult = `Closed with: ${result}`; + }, (reason) => { + this.closeResult = `Dismissed ${this.getDismissReason(reason)}`; + }); + } + + downloadLogFile() { + var blob = new Blob([this.data], { + type: 'text/plain;charset=utf-8' + }); + saveAs(blob, 'versionLog.txt'); + } + + private getDismissReason(reason: any): string { + if (reason === ModalDismissReasons.ESC) { + return 'by pressing ESC'; + } else if (reason === ModalDismissReasons.BACKDROP_CLICK) { + return 'by clicking on a backdrop'; + } else { + return `with: ${reason}`; + } + } + +} diff --git a/src/app/about-us/appVersion.json b/src/app/about-us/appVersion.json new file mode 100644 index 0000000..d4fc816 --- /dev/null +++ b/src/app/about-us/appVersion.json @@ -0,0 +1,4 @@ +{ + "versionNo": "2.0.6", + "releaseName": "1806" +}
\ No newline at end of file diff --git a/src/app/about-us/versionLog.txt b/src/app/about-us/versionLog.txt new file mode 100644 index 0000000..fea7248 --- /dev/null +++ b/src/app/about-us/versionLog.txt @@ -0,0 +1,101 @@ +Version 2.0.6 +=========================================================== +1. Fixed issues raised by ST in test screen. (sj108s) +2. Added test spec file (sj108s) + +Version 2.0.5 +=========================================================== +1. Changed the location of Assign new Template Identifier.(Author-ug0221) +2. Fixed an issue with retaining the selected value in the dropdown for Template Id's.(Author-ug0221) +3. Added Artifact Name to the Filter box.(Author-ug0221) +4. Added empty value validations on create new VNF pop up box.(Author-ug0221) + +Version 2.0.4 +=========================================================== +1. Added test cases to golden configuration spec file(sj108s) +2. Fixed defect in test screen regarding request id while polling using getTestResponse() method (sj108s) +3. Added validation to template configuration tab for accepting only xml and json files (sj108s) +4. Added validation to param values tab to accept only json files (sj108s) + +Version 2.0.3 +=========================================================== +1. Fixed E2E defect 430809 in 1802 : Space is not getting ignored in param configure artifact + generated by CDT tool if VNF name / vnfc - type has spaces (sj108s) + +Version 2.0.2 +=========================================================== +1. Added Licence Info to Reference Data Screen.(ug0221) +2. Added Config ScaleOut Action and Template Identifiers to the Reference screen.(ug0221) +3. resolved a defect where the configscale out file uploaded doesnt populate the template is dropdown.(ug0221) + +Version 2.0.1 +=========================================================== +1. Added Licence Info to golden config/ My VNF and other modules for ONAP- Only Reference Page remaining.(sj108s) +2. Added Test screen to the main menu.(sj108s) +3. Created HTML for Test Screen and integrated ts code.(sj108s) + +Version 2.0.0 +=========================================================== +1. 18/06 Major release.(ak583p) + +Version 1.1.1 +=========================================================== +1. Defect 416768 Block Name should not be merged. Do not allow a merge with a value that double quotes around it, possibly a space and a colon at the end.(Author-ma926a) +2. Populating PD using name/value pairs when Uploading key file.(Author-ma926a) + +Version 1.1.0 +=========================================================== +1. Added functionality for entering names in template through modal.(Author-sj108s) +2. Enabled test screen and added basic test functionality.(Author-sj108s) + +Version 1.0.9 +=========================================================== +1. Allow user to upload of Key Data Files multiple times.(Author-ma926a) +2. Removing INSTAR and its properties using key file. + +Version 1.0.8 +=========================================================== +1. Changed the color code for merge successful/ unsuccessful messages.(Author sj108s) + +Version 1.0.7 +=========================================================== +1. Fixed defect in reference screen where previous vm actions where not getting replaced on uploading the new ones.(Author sj108s) + +Version 1.0.6 +=========================================================== +1. Fixed defect 396019- Added functionality for syncing template from parameters.(Author sj108s) + +Version 1.0.5 +=========================================================== +1. Fixed protocol field while uploading reference artifact file for OpenStack Actions.(Author sj108s) + +Version 1.0.4 +=========================================================== +1. Fixed defect: Changed artifact-list to [] and vnfc-type to null in case of reference artifact generated for OpenStack Actions.(Author sj108s) + +Version 1.0.3 +=========================================================== +1. Fix for Defect#399542 Merge from Params should not Merge the commented section of the base template ( CDT Version : 1.2.1). (Author-ma926a) +2. Fix for Defect#402786 While changing back to Manual from other sources, other fields is not return to previous. (Author-ma926a) +3. With some minor ST issues on PD source, ruletype manipulation. (Author-ma926a) + +Version 1.0.2 +=========================================================== +1. Added functionality for hiding template and PD tabs on selection of OpenStack Actions in reference screen(Author sj108s) +2. Fixed ST defect raised by Ed, wherein the user autoretrieves refrence data with multiple actions from myvnfs, + comes to reference screen, and navigates to template and pd pages and comes back to reference page, the data for the + multiple actions are saving and retrieving correctly now.(Author sj108s) + +Version 1.0.1 +=========================================================== +Story#330094 - Fixed the defects and left over tasks from this story.(Author-ma926a) + 1. Source Manual/INSTAR/A&AI selection handled properly. + 2. Disabling INSTAR to avoid manual selection of INSTAR. + 3. "" empty quates in PD file when we select empty value in dropdowns. + 4. Retrieval of A&AI, ruletype, filter columns. + + +Version 1.0.0(18/02 Release) +========================================================== +First released version. + diff --git a/src/app/app.component.css b/src/app/app.component.css new file mode 100644 index 0000000..57eb0ce --- /dev/null +++ b/src/app/app.component.css @@ -0,0 +1,26 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +.view-page { + padding: 0 100px 0 100px; +}
\ No newline at end of file diff --git a/src/app/app.component.html b/src/app/app.component.html new file mode 100644 index 0000000..6447c28 --- /dev/null +++ b/src/app/app.component.html @@ -0,0 +1,29 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<app-header></app-header> +<div class="view-page"> + <app-navigation [id]="'userLogin'"></app-navigation> + <!--<app-tag-page></app-tag-page>--> + <router-outlet></router-outlet> +</div>
\ No newline at end of file diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts new file mode 100644 index 0000000..a4922f5 --- /dev/null +++ b/src/app/app.component.spec.ts @@ -0,0 +1,61 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ + +import {async, TestBed} from '@angular/core/testing'; +import {AppComponent} from './app.component'; +import {NO_ERRORS_SCHEMA} from '@angular/core'; +import {RouterTestingModule} from '@angular/router/testing'; + +describe('AppComponent', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + AppComponent + ], + schemas: [NO_ERRORS_SCHEMA] + , imports: [RouterTestingModule] + }); + TestBed.compileComponents(); + }); + + it('should create the app', async(() => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + })); + + it(`should have as title 'app works!'`, async(() => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('app works!'); + })); + + it('should render title in a h1 tag', async(() => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('app works!'); + })); +}); diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 0000000..2d5d602 --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,55 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {Component} from '@angular/core'; +import {MappingEditorService} from './shared/services/mapping-editor.service'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'] +}) +export class AppComponent { + title = 'app works!'; + item: any = {}; + subscription: any; + + constructor(private mappingEditorService: MappingEditorService) { + + } + + ngOnInit() { + this.item = this.mappingEditorService.navItem(); + this.subscription = this.mappingEditorService.navChange$.subscribe( + item => this.selectedNavItem(item)); + } + + selectedNavItem(item: any) { + this.item = item; + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } + +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts new file mode 100644 index 0000000..4824351 --- /dev/null +++ b/src/app/app.module.ts @@ -0,0 +1,51 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {BrowserModule} from '@angular/platform-browser'; +import {NgModule} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {SimpleNotificationsModule} from 'angular2-notifications'; +import {HomeModule} from './home/home.module'; +import {AppComponent} from './app.component'; +import {AppRoutingModule} from './app.routing'; +import {SharedModule} from './shared/shared.module'; +import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; +import {HashLocationStrategy, LocationStrategy} from '@angular/common'; +import {NoopAnimationsModule} from '@angular/platform-browser/animations'; +import {RouterModule} from '@angular/router'; +import {TestComponent} from './test/test.component'; +import {AboutUsComponent} from './about-us/aboutus.component'; +import {NgProgressModule} from 'ngx-progressbar'; + +@NgModule({ + declarations: [AppComponent, TestComponent, AboutUsComponent], + imports: [BrowserModule, FormsModule, HomeModule, SharedModule.forRoot(), + NgbModule.forRoot(), NoopAnimationsModule, AppRoutingModule, SimpleNotificationsModule, NgProgressModule], + exports: [RouterModule], + providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}], + + bootstrap: [AppComponent] +}) + +export class AppModule { +}
\ No newline at end of file diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts new file mode 100644 index 0000000..234487e --- /dev/null +++ b/src/app/app.routing.ts @@ -0,0 +1,64 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {NgModule} from '@angular/core'; +import {RouterModule, Routes} from '@angular/router'; +import {HomeComponent} from './home/home/home.component'; +import {LogoutComponent} from './shared/components/logout/logout.component'; +import {HelpComponent} from './shared/components/help/help/help.component'; +import {AboutUsComponent} from './about-us/aboutus.component'; +import {TestComponent} from './test/test.component'; + +const routes: Routes = [ + { + path: 'home', + component: HomeComponent + }, { + path: 'vnfs', + loadChildren: './vnfs/vnfs.module#VnfsModule' + }, { + path: 'test', + component: TestComponent + }, + { + path: 'help', + component: HelpComponent + }, { + path: 'aboutUs', + component: AboutUsComponent + }, { + path: 'logout', + component: LogoutComponent + }, { + path: '', + redirectTo: '/home', + pathMatch: 'full' + } +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule { +}
\ No newline at end of file diff --git a/src/app/home/home.module.ts b/src/app/home/home.module.ts new file mode 100644 index 0000000..9c2a43a --- /dev/null +++ b/src/app/home/home.module.ts @@ -0,0 +1,28 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {HomeComponent} from './home/home.component'; + +@NgModule({imports: [CommonModule], declarations: [HomeComponent]}) +export class HomeModule { +}
\ No newline at end of file diff --git a/src/app/home/home/home.component.css b/src/app/home/home/home.component.css new file mode 100644 index 0000000..9d63aa1 --- /dev/null +++ b/src/app/home/home/home.component.css @@ -0,0 +1,21 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */
\ No newline at end of file diff --git a/src/app/home/home/home.component.html b/src/app/home/home/home.component.html new file mode 100644 index 0000000..728f2ab --- /dev/null +++ b/src/app/home/home/home.component.html @@ -0,0 +1,37 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ --> +<div class="android-more-section"> + + <div class="android-section-title mdl-typography--display-1-color-contrast">WELCOME TO APPC SELF SERVICE + CONFIGURATION DESIGN TOOL + </div> + <div class="mdl-card__title"> + <h4 class="mdl-card__title-text">The Application Configuration (AppC) Configuration Design Tool allows + technology owners to create artifacts for Configuration and Life Cycle Management + functions that are required to manage the lifecycle of Virtual Network Functions (VNFs).<br> Select My VNFS + to enter credentials and view existing + designs or create new ones. + </h4> + + </div> + +</div>
\ No newline at end of file diff --git a/src/app/home/home/home.component.spec.ts b/src/app/home/home/home.component.spec.ts new file mode 100644 index 0000000..fdabce7 --- /dev/null +++ b/src/app/home/home/home.component.spec.ts @@ -0,0 +1,48 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {HomeComponent} from './home.component'; + +describe('HomeComponent', () => { + let component: HomeComponent; + let fixture: ComponentFixture<HomeComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [HomeComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create Home component', () => { + expect(component).toBeTruthy(); + }); + +}); diff --git a/src/app/home/home/home.component.ts b/src/app/home/home/home.component.ts new file mode 100644 index 0000000..ca55179 --- /dev/null +++ b/src/app/home/home/home.component.ts @@ -0,0 +1,36 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-home', + templateUrl: './home.component.html', + styleUrls: ['./home.component.css'] +}) +export class HomeComponent implements OnInit { + constructor() { + } + + ngOnInit() { + } +} + diff --git a/src/app/pipes/vm-filtering.pipe.spec.ts b/src/app/pipes/vm-filtering.pipe.spec.ts new file mode 100644 index 0000000..ccd487e --- /dev/null +++ b/src/app/pipes/vm-filtering.pipe.spec.ts @@ -0,0 +1,29 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ +import {VmFilteringPipe} from './vm-filtering.pipe'; + +describe('VmFilteringPipe', () => { + it('create an instance', () => { + const pipe = new VmFilteringPipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/src/app/pipes/vm-filtering.pipe.ts b/src/app/pipes/vm-filtering.pipe.ts new file mode 100644 index 0000000..fdeb272 --- /dev/null +++ b/src/app/pipes/vm-filtering.pipe.ts @@ -0,0 +1,43 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ +import {Pipe, PipeTransform} from '@angular/core'; + +@Pipe({name: 'vmFiltering', pure: false}) +export class VmFilteringPipe implements PipeTransform { + + transform(value: any, action: any, templateId): any { + + if (action == 'ConfigScaleOut') { + let x = value.filter(obj => { + //return value + return obj['template-id'] == templateId; + }); + + console.log(x); + return x; + } else { + return value; + + } + } + +} diff --git a/src/app/shared/components/header/header.component.css b/src/app/shared/components/header/header.component.css new file mode 100644 index 0000000..f9996f3 --- /dev/null +++ b/src/app/shared/components/header/header.component.css @@ -0,0 +1,31 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* .app-header { + background: #0099CC; + padding: 4px; +} + +.color-white { + color: white +} */
\ No newline at end of file diff --git a/src/app/shared/components/header/header.component.html b/src/app/shared/components/header/header.component.html new file mode 100644 index 0000000..79dea91 --- /dev/null +++ b/src/app/shared/components/header/header.component.html @@ -0,0 +1,29 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + + +<!-- <nav class="navbar navbar-default navbar-fixed-top app-header" role="navigation "> + <div class="text-center"> + <div style=" font-size: 23px;" class="color-white">APPLICATION CONTROLLER</div> + </div> +</nav> -->
\ No newline at end of file diff --git a/src/app/shared/components/header/header.component.spec.ts b/src/app/shared/components/header/header.component.spec.ts new file mode 100644 index 0000000..3335101 --- /dev/null +++ b/src/app/shared/components/header/header.component.spec.ts @@ -0,0 +1,49 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {HeaderComponent} from './header.component'; + +describe('HeaderComponent', () => { + let component: HeaderComponent; + let fixture: ComponentFixture<HeaderComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [HeaderComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(HeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/header/header.component.ts b/src/app/shared/components/header/header.component.ts new file mode 100644 index 0000000..c425fd7 --- /dev/null +++ b/src/app/shared/components/header/header.component.ts @@ -0,0 +1,40 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-header', + templateUrl: './header.component.html', + styleUrls: ['./header.component.css'] +}) +export class HeaderComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/shared/components/help/help/help.component.css b/src/app/shared/components/help/help/help.component.css new file mode 100644 index 0000000..be35e44 --- /dev/null +++ b/src/app/shared/components/help/help/help.component.css @@ -0,0 +1,22 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ diff --git a/src/app/shared/components/help/help/help.component.html b/src/app/shared/components/help/help/help.component.html new file mode 100644 index 0000000..ecdd8c1 --- /dev/null +++ b/src/app/shared/components/help/help/help.component.html @@ -0,0 +1,26 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<p> + help works! +</p> diff --git a/src/app/shared/components/help/help/help.component.spec.ts b/src/app/shared/components/help/help/help.component.spec.ts new file mode 100644 index 0000000..9e09053 --- /dev/null +++ b/src/app/shared/components/help/help/help.component.spec.ts @@ -0,0 +1,49 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {HelpComponent} from './help.component'; + +describe('HelpComponent', () => { + let component: HelpComponent; + let fixture: ComponentFixture<HelpComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [HelpComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(HelpComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/help/help/help.component.ts b/src/app/shared/components/help/help/help.component.ts new file mode 100644 index 0000000..1b79419 --- /dev/null +++ b/src/app/shared/components/help/help/help.component.ts @@ -0,0 +1,40 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-help', + templateUrl: './help.component.html', + styleUrls: ['./help.component.css'] +}) +export class HelpComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/shared/components/logout/logout.component.css b/src/app/shared/components/logout/logout.component.css new file mode 100644 index 0000000..be35e44 --- /dev/null +++ b/src/app/shared/components/logout/logout.component.css @@ -0,0 +1,22 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ diff --git a/src/app/shared/components/logout/logout.component.html b/src/app/shared/components/logout/logout.component.html new file mode 100644 index 0000000..340cb38 --- /dev/null +++ b/src/app/shared/components/logout/logout.component.html @@ -0,0 +1,26 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<p> + logout works! +</p> diff --git a/src/app/shared/components/logout/logout.component.spec.ts b/src/app/shared/components/logout/logout.component.spec.ts new file mode 100644 index 0000000..3e2561f --- /dev/null +++ b/src/app/shared/components/logout/logout.component.spec.ts @@ -0,0 +1,49 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {LogoutComponent} from './logout.component'; + +describe('LogoutComponent', () => { + let component: LogoutComponent; + let fixture: ComponentFixture<LogoutComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [LogoutComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LogoutComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/logout/logout.component.ts b/src/app/shared/components/logout/logout.component.ts new file mode 100644 index 0000000..0c0e3ee --- /dev/null +++ b/src/app/shared/components/logout/logout.component.ts @@ -0,0 +1,39 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-logout', + templateUrl: './logout.component.html', + styleUrls: ['./logout.component.css'] +}) +export class LogoutComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/shared/components/navigation/navigation.component.css b/src/app/shared/components/navigation/navigation.component.css new file mode 100644 index 0000000..5b7aee5 --- /dev/null +++ b/src/app/shared/components/navigation/navigation.component.css @@ -0,0 +1,44 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +.active-tab > { + border-bottom: 5px solid #6ab344; +} + +/* .custom-heade-nav { + border-bottom: none !important; +}*/ +* + +/ + +.nav-link { + font-size: 15PX; + color: black; + +} + +.mdl-navigation__link { + font-weight: 600; + font-size: 16px; +}
\ No newline at end of file diff --git a/src/app/shared/components/navigation/navigation.component.html b/src/app/shared/components/navigation/navigation.component.html new file mode 100644 index 0000000..9e60b6e --- /dev/null +++ b/src/app/shared/components/navigation/navigation.component.html @@ -0,0 +1,72 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + + +<!-- <div class="android-section-title mdl-typography--display-1-color-contrast">APPC Self Service Design Tool</div> --> +<div class="mdl-layout__header-row" font-family='Roboto'> + <span class="android-title mdl-layout-title"> + + </span> + <!-- Add spacer, to align navigation to the right in desktop --> + <div class="android-header-spacer mdl-layout-spacer"></div> + <div class="android-navigation-container"> + <nav class="android-navigation mdl-navigation"> + + <a [ngClass]="{'':((router.url.startsWith('/'+item.url)) || router.url.startsWith(item.url) )}" + *ngFor="let item of navigationTabs"> + <a class="mdl-navigation__link mdl-typography--text-uppercase" + [routerLink]="[item.url]">{{item.name}}</a> + </a> + + <!-- <a *ngIf="userLoggedIn"><b> {{userId}}</b></a> --> + + + </nav> + </div> + <button class="android-more-button mdl-button mdl-js-button mdl-button--primary" id="more-button"> + <a *ngIf="userLoggedIn">{{userId}}</a> + </button> + <ul class="mdl-menu mdl-js-menu mdl-menu--bottom-right mdl-js-ripple-effect" for="more-button"> + <!-- <li *ngIf="userLoggedIn" class="mdl-menu__item">My Profile</li> --> + <li *ngIf="userLoggedIn" class="mdl-menu__item" (click)="logout()">Logout</li> + </ul> +</div> + + +<ng-template #content let-c="close" let-d="dismiss"> + <div class="modal-header"> + <h4 class="modal-title">Modal title</h4> + <button type="button" class="android-more-button mdl-button mdl-js-button mdl-button--accent" aria-label="Close" + (click)="d('Cross click')"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <p>One fine body…</p> + </div> + <div class="modal-footer"> + <button type="button" class="android-more-button mdl-button mdl-js-button mdl-button--accent" + (click)="c('Close click')">Close + </button> + </div> +</ng-template> diff --git a/src/app/shared/components/navigation/navigation.component.spec.ts b/src/app/shared/components/navigation/navigation.component.spec.ts new file mode 100644 index 0000000..c5a436b --- /dev/null +++ b/src/app/shared/components/navigation/navigation.component.spec.ts @@ -0,0 +1,50 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {NavigationComponent} from './navigation.component'; + +describe('NavigationComponent', () => { + let component: NavigationComponent; + let fixture: ComponentFixture<NavigationComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [NavigationComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NavigationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/navigation/navigation.component.ts b/src/app/shared/components/navigation/navigation.component.ts new file mode 100644 index 0000000..acddf9e --- /dev/null +++ b/src/app/shared/components/navigation/navigation.component.ts @@ -0,0 +1,110 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Component, Input, OnInit} from '@angular/core'; +import {Router} from '@angular/router'; +import {EmitterService} from '../../services/emitter.service'; + + +@Component({selector: 'app-navigation', templateUrl: './navigation.component.html', styleUrls: ['./navigation.component.css']}) +export class NavigationComponent implements OnInit { + navigationTabs: Array<Object> = []; + //@ViewChild(GoldenConfigurationComponent) goldenConfig: GoldenConfigurationComponent; + @Input() id: string; + userLoggedIn = false; + userId: string = localStorage['userId']; + + constructor(private router: Router) { + }; + + ngOnChanges() { + EmitterService + .get(this.id) + .subscribe((value) => { + if (value != null && value != '' && value != undefined && value != 'undefined') { + this.userId = value; + this.userLoggedIn = true; + localStorage['userId'] = this.userId; + } else { + this.logout(); + } + + }); + } + + ngOnInit() { + this.userId = localStorage['userId']; + if (this.userId != undefined && this.userId != '') { + this.userLoggedIn = true; + } + + this.navigationTabs = [ + + { + name: 'Home', + url: '/home' + }, { + name: 'MY VNFs', + url: 'vnfs' + }, + { + name: 'Test', + url: 'test', + }, + { + name: 'About us', + url: 'aboutUs' + } + + ]; + } + + + gotoDetail(url) { + + if (url == 'vnfs') { + if (localStorage['userId'] != undefined && localStorage['userId'] != '' && localStorage['userId'] != null) { + this.router.navigate(['/vnfs/list']); + } else { + this.router.navigate(url); + } + } else { + this.router.navigate(url); + } + + + } + + logout() { + window.localStorage.clear(); + sessionStorage.clear(); + localStorage.clear(); + this.userLoggedIn = false; + //window.location.replace("/home"); + this.router.navigate(['home']); + + + } + +}
\ No newline at end of file diff --git a/src/app/shared/confirmModal/confirm.component.ts b/src/app/shared/confirmModal/confirm.component.ts new file mode 100644 index 0000000..79678b3 --- /dev/null +++ b/src/app/shared/confirmModal/confirm.component.ts @@ -0,0 +1,64 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ + +import {Component} from '@angular/core'; +import {DialogComponent, DialogService} from 'ng2-bootstrap-modal'; + +export interface ConfirmModel { + title: string; + message: string; +} + +@Component({ + selector: 'confirm', + template: ` + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" (click)="close()">×</button> + <h4 class="modal-title">Confirm</h4> + </div> + <div class="modal-body"> + <p>Change Actions Without Saving?</p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" (click)="confirm()">Yes</button> + <button type="button" class="btn btn-default" (click)="close()">Cancel</button> + </div> + </div> + </div>` +}) +export class ConfirmComponent extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel { + title: string; + message: string; + + constructor(dialogService: DialogService) { + super(dialogService); + } + + confirm() { + // we set dialog result as true on click on confirm button, + // then we can get dialog result from caller code + this.result = true; + this.close(); + } +}
\ No newline at end of file diff --git a/src/app/shared/directives/collapse.component.ts b/src/app/shared/directives/collapse.component.ts new file mode 100644 index 0000000..bf9c306 --- /dev/null +++ b/src/app/shared/directives/collapse.component.ts @@ -0,0 +1,94 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Directive, HostBinding, Input} from '@angular/core'; + + +@Directive({selector: '[collapse]'}) +export class Collapse { + // style + @HostBinding('style.height') + private height: string; + // shown + @HostBinding('class.in') + @HostBinding('attr.aria-expanded') + private isExpanded: boolean = true; + // hidden + @HostBinding('attr.aria-hidden') + private isCollapsed: boolean = false; + // stale state + @HostBinding('class.collapse') + private isCollapse: boolean = true; + // animation state + @HostBinding('class.collapsing') + private isCollapsing: boolean = false; + + constructor() { + } + + private get collapse(): boolean { + return this.isExpanded; + } + + @Input() + private set collapse(value: boolean) { + this.isExpanded = value; + this.toggle(); + } + + toggle() { + if (this.isExpanded) { + this.hide(); + } else { + this.show(); + } + } + + hide() { + this.isCollapse = false; + this.isCollapsing = true; + + this.isExpanded = false; + this.isCollapsed = true; + setTimeout(() => { + this.height = '0'; + this.isCollapse = true; + this.isCollapsing = false; + }, 4); + } + + show() { + this.isCollapse = false; + this.isCollapsing = true; + + this.isExpanded = true; + this.isCollapsed = false; + setTimeout(() => { + this.height = 'auto'; + + this.isCollapse = true; + this.isCollapsing = false; + }, 4); + } +} diff --git a/src/app/shared/directives/drop-down-toggle.directive.spec.ts b/src/app/shared/directives/drop-down-toggle.directive.spec.ts new file mode 100644 index 0000000..b08d334 --- /dev/null +++ b/src/app/shared/directives/drop-down-toggle.directive.spec.ts @@ -0,0 +1,36 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +/* tslint:disable:no-unused-variable */ + +import {DropDownToggleDirective} from './drop-down-toggle.directive'; +import {ElementRef} from '@angular/core'; + + +describe('DropDownToggleDirective', () => { + it('should create an instance', () => { + const directive = new DropDownToggleDirective(new ElementRef('')); + expect(directive).toBeTruthy(); + }); +}); diff --git a/src/app/shared/directives/drop-down-toggle.directive.ts b/src/app/shared/directives/drop-down-toggle.directive.ts new file mode 100644 index 0000000..7bf9fa8 --- /dev/null +++ b/src/app/shared/directives/drop-down-toggle.directive.ts @@ -0,0 +1,46 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Directive, ElementRef, Input, OnInit} from '@angular/core'; + +@Directive({ + selector: '[appDropDownToggle]' +}) +export class DropDownToggleDirective implements OnInit { + @Input() type: string; + + constructor(private el: ElementRef) { + + + } + + ngOnInit() { + + if (this.type == 'dropdown') + this.el.nativeElement.setAttribute('data-toggle', 'dropdown'); + + + } + +} diff --git a/src/app/shared/directives/dropdown.ts b/src/app/shared/directives/dropdown.ts new file mode 100644 index 0000000..9057302 --- /dev/null +++ b/src/app/shared/directives/dropdown.ts @@ -0,0 +1,92 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {ContentChild, Directive, ElementRef, EventEmitter, Input, Output} from '@angular/core'; +import {DropdownNotClosableZone} from './dropdownnotclosablezone'; + +@Directive({ + selector: '[dropdown]', + exportAs: 'dropdown' +}) +export class Dropdown { + + // ------------------------------------------------------------------------- + // Inputs / Outputs + // ------------------------------------------------------------------------- + + @Input('dropdownToggle') + toggleClick = true; + + @Input('dropdownFocusActivate') + activateOnFocus = false; + + @Output() + onOpen = new EventEmitter(); + + @Output() + onClose = new EventEmitter(); + + // ------------------------------------------------------------------------- + // Properties + // ------------------------------------------------------------------------- + + @ContentChild(DropdownNotClosableZone) + notClosableZone: DropdownNotClosableZone; + + // ------------------------------------------------------------------------- + // Constructor + // ------------------------------------------------------------------------- + + constructor(private elementRef: ElementRef) { + } + + // ------------------------------------------------------------------------- + // Public Methods + // ------------------------------------------------------------------------- + + open() { + const element: HTMLElement = this.elementRef.nativeElement; + element.classList.add('open'); + this.onOpen.emit(undefined); + } + + close() { + const element: HTMLElement = this.elementRef.nativeElement; + element.classList.remove('open'); + this.onClose.emit(undefined); + } + + isOpened() { + const element: HTMLElement = this.elementRef.nativeElement; + return element.classList.contains('open'); + } + + isInClosableZone(element: HTMLElement) { + if (!this.notClosableZone) + return false; + + return this.notClosableZone.contains(element); + } + +}
\ No newline at end of file diff --git a/src/app/shared/directives/dropdownnotclosablezone.ts b/src/app/shared/directives/dropdownnotclosablezone.ts new file mode 100644 index 0000000..9ad351a --- /dev/null +++ b/src/app/shared/directives/dropdownnotclosablezone.ts @@ -0,0 +1,45 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Directive, ElementRef, Input} from '@angular/core'; + +@Directive({ + selector: '[dropdown-not-closable-zone]' +}) +export class DropdownNotClosableZone { + + @Input('dropdown-not-closable-zone') + dropdownNotClosabledZone: boolean; + + constructor(private elementRef: ElementRef) { + } + + contains(element: HTMLElement) { + if (this.dropdownNotClosabledZone === false) + return false; + + const thisElement: HTMLElement = this.elementRef.nativeElement; + return thisElement.contains(element); + } +}
\ No newline at end of file diff --git a/src/app/shared/directives/dropdownopen.ts b/src/app/shared/directives/dropdownopen.ts new file mode 100644 index 0000000..ea2858b --- /dev/null +++ b/src/app/shared/directives/dropdownopen.ts @@ -0,0 +1,147 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Directive, ElementRef, Host, HostListener, OnDestroy} from '@angular/core'; +import {Dropdown} from './dropdown'; + +@Directive({ + selector: '[dropdown-open]', + exportAs: 'dropdownOpen' +}) +export class DropdownOpen implements OnDestroy { + + // ------------------------------------------------------------------------- + // Private Properties + // ------------------------------------------------------------------------- + + /** + * This hack is needed for dropdown not to open and instantly closed + */ + private openedByFocus: boolean = false; + + private closeDropdownOnOutsideClick: (event: Event) => void; + + // ------------------------------------------------------------------------- + // Constructor + // ------------------------------------------------------------------------- + + constructor(@Host() public dropdown: Dropdown, + private elementRef: ElementRef) { + const _this = this; + this.closeDropdownOnOutsideClick = function closeDropdownOnOutsideClick(event: MouseEvent) { + _this.closeIfInClosableZone(event); + }; + } + + // ------------------------------------------------------------------------- + // Public Methods + // ------------------------------------------------------------------------- + + toggle() { + if (this.dropdown.isOpened()) { + this.close(); + } else { + this.open(); + } + } + + open() { + if (this.dropdown.isOpened()) + return; + + this.dropdown.open(); + document.addEventListener('click', this.closeDropdownOnOutsideClick, true); + } + + close() { + if (!this.dropdown.isOpened()) + return; + + this.dropdown.close(); + document.removeEventListener('click', this.closeDropdownOnOutsideClick, true); + } + + @HostListener('click') + openDropdown() { + if (this.dropdown.activateOnFocus && this.openedByFocus) { + this.openedByFocus = false; + return; + } + + if (this.dropdown.isOpened() && this.dropdown.toggleClick) { + this.close(); + } else { + this.open(); + } + } + + @HostListener('keydown', ['$event']) + dropdownKeydown(event: KeyboardEvent) { + if (event.keyCode === 40) { // down + this.openDropdown(); + } + } + + @HostListener('focus') + onFocus() { + if (!this.dropdown.activateOnFocus) return; + this.openedByFocus = true; + this.dropdown.open(); + document.addEventListener('click', this.closeDropdownOnOutsideClick, true); + } + + @HostListener('blur', ['$event']) + onBlur(event: FocusEvent) { + if (!this.dropdown.activateOnFocus) return; + if (event.relatedTarget && + !this.dropdown.isInClosableZone(<HTMLElement> event.relatedTarget) && + event.relatedTarget !== this.elementRef.nativeElement) { + + this.dropdown.close(); + document.removeEventListener('click', this.closeDropdownOnOutsideClick, true); + } + } + + // ------------------------------------------------------------------------- + // Lifecycle Methods + // ------------------------------------------------------------------------- + + ngOnDestroy() { + document.removeEventListener('click', this.closeDropdownOnOutsideClick, true); + } + + // ------------------------------------------------------------------------- + // Private Methods + // ------------------------------------------------------------------------- + + private closeIfInClosableZone(event: Event) { + if (!this.dropdown.isInClosableZone(<HTMLElement> event.target) + && event.target !== this.elementRef.nativeElement + && !this.elementRef.nativeElement.contains(event.target)) { + this.dropdown.close(); + document.removeEventListener('click', this.closeDropdownOnOutsideClick, true); + } + } + +}
\ No newline at end of file diff --git a/src/app/shared/modal/modal.component.css b/src/app/shared/modal/modal.component.css new file mode 100644 index 0000000..f9c2a3c --- /dev/null +++ b/src/app/shared/modal/modal.component.css @@ -0,0 +1,36 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +.titlePopup { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + /* display: none; */ + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; + background: rgba(62, 57, 57, 0.66); +}
\ No newline at end of file diff --git a/src/app/shared/modal/modal.component.html b/src/app/shared/modal/modal.component.html new file mode 100644 index 0000000..e227568 --- /dev/null +++ b/src/app/shared/modal/modal.component.html @@ -0,0 +1,47 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<div id="modalId" class="titlePopup" role="dialog" *ngIf="isShow"> + <div class="modal-dialog"> + + + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="android-more-button mdl-button mdl-js-button mdl-button--accent" + data-dismiss="modal" (click)="isClose()">× + </button> + <h4 class="modal-title">{{title}}</h4> + </div> + <div class="modal-body"> + <p>{{message}}</p> + </div> + <div class="modal-footer"> + <button type="button" + class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" + data-dismiss="modal" (click)="isClose()">Close + </button> + </div> + </div> + + </div> +</div>
\ No newline at end of file diff --git a/src/app/shared/modal/modal.component.ts b/src/app/shared/modal/modal.component.ts new file mode 100644 index 0000000..ec88702 --- /dev/null +++ b/src/app/shared/modal/modal.component.ts @@ -0,0 +1,52 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {Component, Input, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-modal', + templateUrl: './modal.component.html', + styleUrls: ['./modal.component.css'] + + +}) +export class ModalComponent implements OnInit { + + @Input() title: string; + @Input() message: string; + @Input() onDismiss: boolean; + @Input() onConfirm: boolean; + @Input() isShow: boolean; + + constructor() { + + } + + ngOnInit() { + + } + + isClose() { + this.isShow = false; + } +}
\ No newline at end of file diff --git a/src/app/shared/models/ArtifactRequest.ts b/src/app/shared/models/ArtifactRequest.ts new file mode 100644 index 0000000..75438d0 --- /dev/null +++ b/src/app/shared/models/ArtifactRequest.ts @@ -0,0 +1,39 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +export class ArtifactRequest { + public vnfType: string; + public fileName: string; + public version: string; + public action: string; + public templateContent: string; + public pdContent: string; + public referenceContent: string; + public paramsContent: string; + public paramKeysContent: string; + public isTemplatePush: Boolean; + public isPdPush: Boolean; + public isReferenceePush: Boolean; + +}
\ No newline at end of file diff --git a/src/app/shared/models/ConfigMapping.ts b/src/app/shared/models/ConfigMapping.ts new file mode 100644 index 0000000..afe9d13 --- /dev/null +++ b/src/app/shared/models/ConfigMapping.ts @@ -0,0 +1,30 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +export class ConfigMapping { + public selectedRange: any; + public mappingKey: string; + public mappingValue: string; + public duplicateRanges: Array<any> = []; +}
\ No newline at end of file diff --git a/src/app/shared/models/Notification.ts b/src/app/shared/models/Notification.ts new file mode 100644 index 0000000..02f7524 --- /dev/null +++ b/src/app/shared/models/Notification.ts @@ -0,0 +1,29 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +export class Notification { + constructor(public type: string = '', + public message: string = '') { + } +}
\ No newline at end of file diff --git a/src/app/shared/models/index.ts b/src/app/shared/models/index.ts new file mode 100644 index 0000000..5c19bcf --- /dev/null +++ b/src/app/shared/models/index.ts @@ -0,0 +1,31 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +// export * from './TemplateMapping'; +// export * from './TemplateRequest'; +// export * from './TemplateResponse'; +export * from './Notification'; +export * from './ArtifactRequest'; +//export * from './ArtifactResponse'; +export * from './ConfigMapping';
\ No newline at end of file diff --git a/src/app/shared/modules/tidy-table/order-by.pipe.spec.ts b/src/app/shared/modules/tidy-table/order-by.pipe.spec.ts new file mode 100644 index 0000000..82c57a1 --- /dev/null +++ b/src/app/shared/modules/tidy-table/order-by.pipe.spec.ts @@ -0,0 +1,34 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +/* tslint:disable:no-unused-variable */ + +import {OrderBy} from './order-by.pipe'; + +describe('OrderByPipe', () => { + it('create an instance', () => { + const pipe = new OrderBy(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/src/app/shared/modules/tidy-table/order-by.pipe.ts b/src/app/shared/modules/tidy-table/order-by.pipe.ts new file mode 100644 index 0000000..45f44d9 --- /dev/null +++ b/src/app/shared/modules/tidy-table/order-by.pipe.ts @@ -0,0 +1,81 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Pipe, PipeTransform} from '@angular/core'; + +@Pipe({name: 'orderBy'}) +export class OrderBy implements PipeTransform { + + transform(array, orderBy, asc = true) { + + if (!orderBy || orderBy.trim() == '') { + return array; + } + + //ascending + if (asc) { + return Array + .from(array) + .sort((item1: any, item2: any) => { + return this.orderByComparator(item1[orderBy], item2[orderBy]); + }); + } else { + //not asc + return Array + .from(array) + .sort((item1: any, item2: any) => { + return this.orderByComparator(item2[orderBy], item1[orderBy]); + }); + } + + } + + orderByComparator(a: any, b: any): number { + if (a != undefined && b != undefined) { + if ((isNaN(parseFloat(a)) || !isFinite(a)) || (isNaN(parseFloat(b)) || !isFinite(b))) { + // Isn't a number so lowercase the string to properly compare + if (a.toLowerCase() < b.toLowerCase()) + return -1; + if (a.toLowerCase() > b.toLowerCase()) + return 1; + } + else { + //Parse strings as numbers to compare properly + if (parseFloat(a) < parseFloat(b)) + return -1; + if (parseFloat(a) > parseFloat(b)) + return 1; + } + } else { + if (a == undefined) { + return -1; + } else { + return 1; + } + } + + + return 0; //equal each other + } +}
\ No newline at end of file diff --git a/src/app/shared/modules/tidy-table/table-filter.pipe.spec.ts b/src/app/shared/modules/tidy-table/table-filter.pipe.spec.ts new file mode 100644 index 0000000..d8fe6c7 --- /dev/null +++ b/src/app/shared/modules/tidy-table/table-filter.pipe.spec.ts @@ -0,0 +1,34 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +/* tslint:disable:no-unused-variable */ + +import {TableFilterPipe} from './table-filter.pipe'; + +describe('TableFilterPipe', () => { + it('create an instance', () => { + const pipe = new TableFilterPipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/src/app/shared/modules/tidy-table/table-filter.pipe.ts b/src/app/shared/modules/tidy-table/table-filter.pipe.ts new file mode 100644 index 0000000..1eec34b --- /dev/null +++ b/src/app/shared/modules/tidy-table/table-filter.pipe.ts @@ -0,0 +1,53 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Pipe, PipeTransform} from '@angular/core'; +import * as _ from 'underscore'; + +@Pipe({name: 'tableFilter'}) +export class TableFilterPipe implements PipeTransform { + + transform(array: any[], query: string, filetrColumns: Array<String>): any { + if (query) { + return _.filter(array, (row: Object) => this.filterRows(filetrColumns, row, query)); + } + return array; + } + + filterRows(columsn, row, query) { + let temp: Array<boolean> = []; + for (let x = 0; x < columsn.length; x++) { + if ((row[columsn[x]]) != null && query != null) { + temp.push((row[columsn[x]].toLowerCase().indexOf(query.toLowerCase()) > -1)); + } + } + + return _.reduce(temp, function (memoizer, value) { + + return (memoizer || value); + }, false); + + } + +} diff --git a/src/app/shared/modules/tidy-table/tidy-table.module.ts b/src/app/shared/modules/tidy-table/tidy-table.module.ts new file mode 100644 index 0000000..ae5f00a --- /dev/null +++ b/src/app/shared/modules/tidy-table/tidy-table.module.ts @@ -0,0 +1,38 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {OrderBy} from './order-by.pipe'; +import {TableFilterPipe} from './table-filter.pipe'; + +@NgModule({ + imports: [CommonModule], + declarations: [ + TableFilterPipe, OrderBy + ], + exports: [TableFilterPipe, OrderBy] +}) +export class TidyTableModule { +}
\ No newline at end of file diff --git a/src/app/shared/services/emitter.service.spec.ts b/src/app/shared/services/emitter.service.spec.ts new file mode 100644 index 0000000..f12154f --- /dev/null +++ b/src/app/shared/services/emitter.service.spec.ts @@ -0,0 +1,40 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +/* tslint:disable:no-unused-variable */ + +import {inject, TestBed} from '@angular/core/testing'; +import {EmitterService} from './emitter.service'; + +describe('EmitterService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [EmitterService] + }); + }); + + it('should ...', inject([EmitterService], (service: EmitterService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/src/app/shared/services/emitter.service.ts b/src/app/shared/services/emitter.service.ts new file mode 100644 index 0000000..1cedc63 --- /dev/null +++ b/src/app/shared/services/emitter.service.ts @@ -0,0 +1,42 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {EventEmitter, Injectable} from '@angular/core'; + +@Injectable() +export class EmitterService { + private static _emitters: { + [ID: string]: EventEmitter<any> + } = {}; + + constructor() { + } + + static get(ID: string): EventEmitter<any> { + if (!this._emitters[ID]) + this._emitters[ID] = new EventEmitter(); + return this._emitters[ID]; + } + +} diff --git a/src/app/shared/services/httpUtil/http-util.service.spec.ts b/src/app/shared/services/httpUtil/http-util.service.spec.ts new file mode 100644 index 0000000..c6923bb --- /dev/null +++ b/src/app/shared/services/httpUtil/http-util.service.spec.ts @@ -0,0 +1,39 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ + +import {inject, TestBed} from '@angular/core/testing'; +import {HttpUtilService} from './http-util.service'; + +describe('HttpUtilService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [HttpUtilService] + }); + }); + + it('should ...', inject([HttpUtilService], (service: HttpUtilService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/src/app/shared/services/httpUtil/http-util.service.ts b/src/app/shared/services/httpUtil/http-util.service.ts new file mode 100644 index 0000000..35c5047 --- /dev/null +++ b/src/app/shared/services/httpUtil/http-util.service.ts @@ -0,0 +1,57 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ +import { observable } from 'rxjs/symbol/observable'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/toPromise'; +import { Injectable } from '@angular/core'; +import { Http, Response, Headers, RequestOptions } from '@angular/http'; + +@Injectable() +export class HttpUtilService { + headers: Headers; + options: RequestOptions + constructor (private http: Http) { + this.headers = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON + // this.options = new RequestOptions({headers: this.headers}); // + } + + get(req) { + + return this + .http + .get(req.url, this.options) + .map((res: Response) => res.json()) + } + + post(req) { + + this.headers.append('Authorization', 'Basic ' + btoa('m97292@appc.att.com:enc:Ai8KDxN7EANwATsV')); + this.options = new RequestOptions({ headers: this.headers }); + + return this + .http + .post(req.url, req.data, this.options) + .map((res: Response) => res.json()) + } + +}
\ No newline at end of file diff --git a/src/app/shared/services/mapping-editor.service.ts b/src/app/shared/services/mapping-editor.service.ts new file mode 100644 index 0000000..00ef211 --- /dev/null +++ b/src/app/shared/services/mapping-editor.service.ts @@ -0,0 +1,684 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Injectable} from '@angular/core'; +import {ConfigMapping} from '../models/index'; +import {Observable} from 'rxjs/Observable'; +import {Observer} from 'rxjs/Observer'; +import 'rxjs/add/operator/share'; + + +@Injectable() +export class MappingEditorService { + + editor: any; + session: any; + editorContent: string; + configMappings: Array<ConfigMapping> = []; + paramContent: string = '{}'; + + KEY_EXPRESSION: string = '\\${\\(.+?\\)}';//new RegExp('${.+?}'); // \${.+?} + //SYNC_KEY_EXPRESSION: string = '\\${\\)}'; + KEY_START: string = '${('; + KEY_MID: string = ')=('; + KEY_END: string = ')}'; + KEY_START_LENGTH: number = 3; + KEY_MID_LENGTH: number = 3; + KEY_END_LENGTH: number = 2; + SYNC_T_KEY_EXPRESSION: string = '\\${.+?\\}'; + T_KEY_EXPRESSION: string = '\\${.+?}';//new RegExp('${.+?}'); // \${.+?} + T_KEY_START: string = '${'; + T_KEY_END: string = '}'; + T_KEY_START_LENGTH: number = 2; + T_KEY_END_LENGTH: number = 1; + checkSpecialCharsReg: RegExp = /[^\w\s-_]/gi; + public paramData = []; + public referenceNameObjects: any; + prmName: string = ''; + prmValue: string = ''; + navChange$: Observable<any>; + public fromScreen: any = ''; + public storedTemplateData: any; + public storedTemplateMappingData: any; + public fileType: any; + public hasErrorCode: boolean = false; + public appDataObject: any; + public downloadDataObject: any; + public markedarr: any; + public tempAllData: any; + public latestAction: any; + public selectedWord: any; + identifier: any; + private _navItem = {}; + private _observer: Observer<any>; + private referenceList = []; + + constructor() { + this.navChange$ = new Observable(observer => + this._observer = observer).share(); + } + + setSelectedWord(selectedWord: any) { + this.selectedWord = selectedWord; + } + + getSelectedWord() { + return this.selectedWord; + } + + changeNav(object) { + this._navItem = object; + // this._observer.next(object); + this.referenceNameObjects = object; + } + + changeNavAppData(object) { + this._navItem = object; + // this._observer.next(object); + this.appDataObject = object; + } + + changeNavDownloadData(object) { + this._navItem = object; + // this._observer.next(object); + this.downloadDataObject = object; + } + + saveLatestAction(data) { + this.latestAction = data; + } + + saveLatestIdentifier(identifier) { + this.identifier = identifier; + } + + public getParamContent() { + return this.paramContent; + } + + saveTempAllData(data) { + this.tempAllData = data; + } + + navItem() { + return this._navItem; + } + + public setParamContent(paramContent: string): void { + this.paramContent = paramContent; + // localStorage["paramContent"]=paramContent; + } + + public initialise(editor: any, editorContent: string, modal: any): void { + this.editor = editor; + this.editor.session = editor.session; + this.editor.selection.session.$backMarkers = {}; + this.editorContent = editorContent; + this.editor.$blockScrolling = Infinity; + this.editor.$blockSelectEnabled = false; + this.initialiseCommands(modal); + this.editor.setValue(this.editorContent); + this.refreshEditor(); + } + + + public initialiseCommands(modal): void { + /* this.editor.commands.addCommand({ + name: 'annotateCommand', + bindKey: { win: 'ENTER', mac: 'ENTER' }, + exec: (editor: any) => { + this.handleAnnotation(modal); + } + });*/ + + + this.editor.commands.addCommand({ + name: 'keyCompletionCommand', + bindKey: {win: 'Ctrl-s', mac: 'Command-s'}, + exec: (editor: any) => { + this.handlekeyCompletion(); + } + }); + + this.editor.commands.addCommand({ + name: 'autoAnnotateCommand', + bindKey: {win: 'Ctrl-2', mac: 'Command-2'}, + exec: (editor: any) => { + this.autoAnnotateDataForParams(this.fileType); + } + }); + + this.editor.commands.addCommand({ + name: 'autoAnnotateCommand', + bindKey: {win: 'Ctrl-shift-z', mac: 'Command-shift-z'}, + exec: (editor: any) => { + this.removeTheSelectedMarkers(); + } + }); + } + + public getStartBeforeAfterSelection(selection: any, beforeCount: number, afterCount: number) { + let newSelctionRange: any = JSON.parse(JSON.stringify(selection)); + if (selection) { + let newBeforeColumn: number = selection.start.column - beforeCount; + let newAfterColumn: number = selection.end.column + afterCount; + newSelctionRange.start.column = newBeforeColumn; + newSelctionRange.end.column = newAfterColumn; + } + return newSelctionRange; + } + + public checkToDataAdd(value: string): boolean { + let toAdd = false; + if (value && (value.startsWith('"') || value.startsWith('>')) + && (value.endsWith('"') || value.endsWith('<')) + && !value.startsWith('"${') + ) { + toAdd = true; + } + return toAdd; + } + + public autoAnnotateDataForParams(fileType: any): boolean { + this.paramContent = localStorage['paramsContent']; + //console.log("Param content=="+ this.paramContent) + var mergeStatus: boolean = false; + if (this.paramContent) { + var paramJson: JSON = JSON.parse(this.paramContent); + for (var prop in paramJson) { + let value: string = paramJson[prop]; + if (value) { + var occurances = this.editor.findAll(value, {regExp: false}); + var ranges = this.editor.getSelection().getAllRanges(); + if (ranges) { + + for (var r = 0; r < ranges.length; r++) { + let selectedRange: any = ranges[r]; + let selectedWord: string = this.editor.session.getTextRange(selectedRange); + let prefixSuffixselectedWord: string = this.editor.session.getTextRange(this.getStartBeforeAfterSelection(selectedRange, 1, 1)); + if (selectedWord && this.checkComments(selectedRange) && this.checkDelimiters(selectedRange) && this.checkApplied(selectedRange)) { + let replaceWord: any = this.KEY_START + selectedWord + this.KEY_MID + prop + this.KEY_END; + this.editor.session.replace(selectedRange, replaceWord); + mergeStatus = true; + } + } + } + } + } + } + return mergeStatus; + } + + /* syncTemplateNames() { + if (this.paramContent != '{}') { + var paramJson: JSON = JSON.parse(this.paramContent); + for (var prop in paramJson) { + let value: string = paramJson[prop] + if (value) { + var occurances = this.editor.findAll(value, { regExp: false }); + var ranges = this.editor.getSelection().getAllRanges(); + if (ranges) { + for (var r = 0; r < ranges.length; r++) { + let selectedRange: any = ranges[r]; + let selectedWord: string = this.editor.session.getTextRange(selectedRange); + let prefixSuffixselectedWord: string = this.editor.session.getTextRange(this.getStartBeforeAfterSelection(selectedRange, 1, 1)); + if (selectedWord && this.checkApplied(selectedRange)) { + let replaceWord: any = this.KEY_START + selectedWord + this.KEY_MID + prop + this.KEY_END; + this.editor.session.replace(selectedRange, replaceWord); + } + } + } + } + } + for (var prop in paramJson) { + var occurances = this.editor.findAll(prop, { regExp: false }); + var ranges = this.editor.getSelection().getAllRanges(); + if (ranges) { + for (var r = 0; r < ranges.length; r++) { + let selectedRange: any = ranges[r]; + let selectedWord: string = this.editor.session.getTextRange(selectedRange); + if (selectedWord && this.checkApplied(selectedRange)) { + let replaceWord: any = '(' + paramJson[prop] + this.KEY_MID + selectedWord + ')'; + this.editor.session.replace(selectedRange, replaceWord); + } + } + } + else { + this.replaceNamesWithBlankValues(); + } + } + } + else { + this.replaceNamesWithBlankValues() + } + }*/ + + + checkComments(selectedRange: any) { + var tempStartColumn = selectedRange.start.column; + var result = false; + selectedRange.start.column = 0; + if (this.editor.session.getTextRange(selectedRange).trim().startsWith('//')) { + result = false; + } else { + result = true; + } + selectedRange.start.column = tempStartColumn; + return result; + } + + checkApplied(selectedRange: any) { + var tempStartColumn = selectedRange.start.column; + for (var i = selectedRange.start.column; i >= 0; i--) { + selectedRange.start.column = i; + if (this.editor.session.getTextRange(selectedRange).startsWith(this.KEY_START) + || this.editor.session.getTextRange(selectedRange).startsWith(this.T_KEY_START)) { + selectedRange.start.column = tempStartColumn; + return false; + } else if (this.editor.session.getTextRange(selectedRange).startsWith(this.KEY_END) + || this.editor.session.getTextRange(selectedRange).startsWith(this.T_KEY_END)) { + selectedRange.start.column = tempStartColumn; + return true; + } + + } + selectedRange.start.column = tempStartColumn; + return true; + + } + + checkDelimiters(selectedRange: any) { + let result = false; + let actualText = this.editor.session.getTextRange(selectedRange); + var tempStartColumn = selectedRange.start.column; + var tempEndcolumn = selectedRange.end.column; + + selectedRange.start.column = selectedRange.start.column - 1; + selectedRange.end.column = selectedRange.end.column + 1; + if ((this.editor.session.getTextRange(selectedRange).startsWith(' ') + || this.editor.session.getTextRange(selectedRange).startsWith('"') + || this.editor.session.getTextRange(selectedRange).startsWith('>')) + && (this.editor.session.getTextRange(selectedRange).endsWith(' ') + || this.editor.session.getTextRange(selectedRange).endsWith('"') + || this.editor.session.getTextRange(selectedRange).endsWith(',') + || this.editor.session.getTextRange(selectedRange).endsWith(actualText) + || this.editor.session.getTextRange(selectedRange).endsWith('<'))) { + result = true; + } + + //Ignore the JSON key names(which ends with :) + selectedRange.end.column = selectedRange.end.column + 1; + if (this.editor.session.getTextRange(selectedRange).endsWith('":')) { + result = false; + } else { + selectedRange.end.column = selectedRange.end.column + 1; + if (this.editor.session.getTextRange(selectedRange).endsWith('" :')) { + result = false; + } + } + selectedRange.start.column = tempStartColumn; + selectedRange.end.column = tempEndcolumn; + return result; + } + + checkAppliedForNamesOnly(selectedRange: any) { + var tempStartColumn = selectedRange.start.column; + for (var i = selectedRange.start.column; i >= 0; i--) { + selectedRange.start.column = i; + if (this.editor.session.getTextRange(selectedRange).startsWith(this.KEY_START)) { + selectedRange.start.column = tempStartColumn; + return false; + } else if (this.editor.session.getTextRange(selectedRange).startsWith(this.KEY_END)) { + selectedRange.start.column = tempStartColumn; + return true; + } + + } + selectedRange.start.column = tempStartColumn; + return true; + + } + + checkToDataAddForJson(value: string): boolean { + let toAdd = false; + if (value && !value.startsWith('"${') && !value.startsWith('(')) { + toAdd = true; + } + return toAdd; + } + + public autoAnnotateTemplateForParam(): void { + var occurances = this.editor.findAll(this.T_KEY_EXPRESSION, {regExp: true}); + var ranges = this.editor.getSelection().getAllRanges(); + if (ranges) { + for (var r = 0; r < ranges.length; r++) { + let selectedRange: any = ranges[r]; + let selectedWord: string = this.editor.session.getTextRange(selectedRange); + if (selectedWord) { + let key: string = selectedWord.substring(this.T_KEY_START_LENGTH, selectedWord.lastIndexOf(this.T_KEY_END)); + let value: string = this.getValueForKey(key); + let replaceWord: any = this.KEY_START + value + this.KEY_MID + key + this.KEY_END; + this.editor.session.replace(selectedRange, replaceWord); + } + } + } + + } + + /* + * Once you save command is triggered, We need to re populate all the params, which may be defined new + * and auto populate the key if any of the values maps to the keys + */ + public handlekeyCompletion(): void { + this.refreshEditor(); + } + + /* public handleAnnotation(modal): void { + let selectedWord: string = this.editor.session.getTextRange(this.editor.selectionRange); + this.setSelectedWord(selectedWord); + modal.open(); + + /* let selectedWord: string = this.editor.session.getTextRange(this.editor.selectionRange); + if (selectedWord) { + if (selectedWord.startsWith('${(')) { + var replaceWord = selectedWord.substring(3, selectedWord.indexOf(')=(')); + this.editor.session.replace(this.editor.session.selection.getRange(), replaceWord); + } else { + let mappingKey = this.getKeysForValues(selectedWord); + var replaceWord = '${(' + selectedWord + ')=()}'; + this.editor.session.replace(this.editor.session.selection.getRange(), replaceWord); + } + } + this.refreshEditor(); + }*/ + + public checkMethodCall(modal): void { +//this.handleAnnotation(modal) + } + + public refreshEditor(): void { + if (this.editor) { + + // this.replaceNamesWithBlankValues(); + var occurances = this.editor.findAll(this.KEY_EXPRESSION, {regExp: true}); + //console.log("Occurances from save" + occurances) + var ranges = this.editor.getSelection().getAllRanges(); + if (ranges) { + this.refreshParams(ranges); + } + + occurances = this.editor.findAll(this.KEY_EXPRESSION, {regExp: true}); + ranges = this.editor.getSelection().getAllRanges(); + if (ranges) { + this.populateMissingKeys(ranges); + } + this.refreshMarker(); + } + // console.log("Param data from refresh editor=="+this.paramData) + + } + + replaceNamesWithBlankValues() { + var occurances = this.editor.findAll(this.SYNC_T_KEY_EXPRESSION, {regExp: true}); + var ranges = this.editor.getSelection().getAllRanges(); + if (occurances > 0) { + if (ranges) { + for (var r = 0; r < ranges.length; r++) { + let selectedRange: any = ranges[r]; + // console.log("Selected range == " + selectedRange) + let selectedWord: string = this.editor.session.getTextRange(selectedRange); + let specialKeys = (selectedWord.substring(2, selectedWord.length - 1)).match(this.checkSpecialCharsReg); + // console.log("Selected word == " + selectedWord.length) + //if (!selectedWord.startsWith('<') || !selectedWord.startsWith('{')) { + if (selectedWord && this.checkAppliedForNamesOnly(selectedRange) && !specialKeys) { + let replaceWord: any = this.KEY_START + '' + this.KEY_MID + selectedWord.substring(2, selectedWord.length - 1) + this.KEY_END; + this.editor.session.replace(selectedRange, replaceWord); + } + // } + } + } + } + } + + public refreshParams(ranges: any): void { + // console.log("This param content==="+ this.paramContent); + var paramData = []; + if (this.paramContent === undefined) this.paramContent = '{}'; + if (this.editor && ranges) { + var paramJson: JSON = JSON.parse(this.paramContent); + this.hasErrorCode = false; + for (var r = 0; r < ranges.length; r++) { + let keyValue: string = this.editor.session.getTextRange(ranges[r]); + //console.log("keyValues==="+keyValue) + if (keyValue && keyValue.startsWith(this.KEY_START) && keyValue.endsWith(this.KEY_END) && keyValue.includes(this.KEY_MID)) { + let key: string = keyValue.substring(keyValue.indexOf(this.KEY_MID) + this.KEY_MID_LENGTH, keyValue.indexOf(this.KEY_END)); + let value: string = keyValue.substring(this.KEY_START_LENGTH, keyValue.indexOf(this.KEY_MID)); + let specialKeys = key.match(this.checkSpecialCharsReg); + //console.log("Special keys=="+specialKeys) + //console.log("Keys=="+key+",values=="+value); + if (specialKeys && specialKeys.length) { + // this.paramData = []; + // this.hasErrorCode = true; + // break; + } else { + if (this.fromScreen === 'TemplateScreen') { + if (key) { + paramJson[key] = value; + var obj: any = {'paramName': '', 'paramValue': ''}; + obj.paramName = key; + obj.paramValue = value; + paramData.push(obj); + } + + } + else if (this.fromScreen === 'MappingScreen') { + if (key) { + paramJson[key] = value; + var obj: any = {'paramName': '', 'paramValue': ''}; + obj.paramName = key; + obj.paramValue = value; + + paramData.push(obj); + + } + } + } + } + } + // console.log("Param data=="+ JSON.stringify(paramData)) + this.paramData = paramData; + this.paramContent = JSON.stringify(paramJson); + + } + } + + public populateMissingKeys(ranges: any): void { + if (this.editor && ranges) { + // Populate missing keys + for (var r = 0; r < ranges.length; r++) { + let keyValue: string = this.editor.session.getTextRange(ranges[r]); + if (keyValue && keyValue.startsWith(this.KEY_START) && keyValue.endsWith(this.KEY_END) && keyValue.includes(this.KEY_MID)) { + let key: string = keyValue.substring(keyValue.indexOf(this.KEY_MID) + this.KEY_MID_LENGTH, keyValue.indexOf(this.KEY_END)); + let value: string = keyValue.substring(this.KEY_START_LENGTH, keyValue.indexOf(this.KEY_MID)); + if (!key && value) { + let keyFromStore = ''; + if (keyFromStore) { + let replaceWord: string = '${(' + value + ')=(' + keyFromStore + ')}'; + this.editor.session.replace(ranges[r], replaceWord); + } + } + } + } + + } + } + + public refreshMarker(): void { + if (this.editor) { + this.hasErrorCode = false; + var occurances = this.editor.findAll(this.KEY_EXPRESSION, {regExp: true}); + var ranges = this.editor.getSelection().getAllRanges(); + var keysList = []; + // Populate missing keys + for (var r = 0; r < ranges.length; r++) { + let keyValue: string = this.editor.session.getTextRange(ranges[r]); + if (keyValue && keyValue.startsWith(this.KEY_START) && keyValue.endsWith(this.KEY_END) && keyValue.includes(this.KEY_MID)) { + let key: string = keyValue.substring(keyValue.indexOf(this.KEY_MID) + this.KEY_MID_LENGTH, keyValue.indexOf(this.KEY_END)); + let value: string = keyValue.substring(this.KEY_START_LENGTH, keyValue.indexOf(this.KEY_MID)); + let specialKeys = key.match(this.checkSpecialCharsReg); + if (specialKeys && specialKeys.length) { + this.hasErrorCode = true; + break; + } + if (!key && value) { + this.editor.session.addMarker(ranges[r], 'warningMarker', 'text'); + } else { + if (keysList.indexOf(key) > -1) { + this.editor.session.addMarker(ranges[r], 'warningMarker', 'text'); + } else { + this.editor.session.addMarker(ranges[r], 'keyedMarker', 'text'); + } + keysList.push(key); + } + // Refresh Markers + } + } + this.editor.clearSelection(); + this.editor.exitMultiSelectMode(); + } + } + + public getKeysForValues(value: string): string { + var key: string = undefined; + if (this.paramContent && value) { + var paramJson: JSON = JSON.parse(this.paramContent); + for (var prop in paramJson) { + if (value === paramJson[prop]) { + key = prop; + } + } + } + return key; + } + + public getValueForKey(key: string): string { + var value: string = undefined; + if (key) { + var paramJson: JSON = JSON.parse(this.paramContent); + if (paramJson) { + value = paramJson[key]; + } + } + return value; + } + + public generateTemplate(templateEditor: any): void { + if (templateEditor) { + templateEditor.setValue(this.editor.getValue()); + var occurances = templateEditor.findAll(this.KEY_EXPRESSION, {regExp: true}); + var ranges = templateEditor.getSelection().getAllRanges(); + if (ranges) { + for (var r = 0; r < ranges.length; r++) { + let keyValue: string = templateEditor.session.getTextRange(ranges[r]); + if (keyValue && keyValue.startsWith(this.KEY_START) && keyValue.endsWith(this.KEY_END) && keyValue.includes(this.KEY_MID)) { + let key: string = keyValue.substring(keyValue.indexOf(this.KEY_MID) + this.KEY_MID_LENGTH, keyValue.indexOf(this.KEY_END)); + let value: string = keyValue.substring(this.KEY_START_LENGTH, keyValue.indexOf(this.KEY_MID)); + if (key && value) { + let replaceWord: string = '${' + key + '}'; + templateEditor.session.replace(ranges[r], replaceWord); + } + } + } + templateEditor.clearSelection(); + templateEditor.exitMultiSelectMode(); + templateEditor.session.$backMarkers = {}; + + } + } + } + + public generateParams(paramsEditor: any, paramsKeyValueEditor: any): JSON { + if (paramsEditor && paramsKeyValueEditor) { + var occurances = this.editor.findAll(this.KEY_EXPRESSION, {regExp: true}); + var ranges = this.editor.getSelection().getAllRanges(); + if (ranges) { + let paramsJSON: JSON = JSON.parse('{}'); + for (var r = 0; r < ranges.length; r++) { + let keyValue: string = this.editor.session.getTextRange(ranges[r]); + if (keyValue && keyValue.startsWith(this.KEY_START) && keyValue.endsWith(this.KEY_END) && keyValue.includes(this.KEY_MID)) { + let key: string = keyValue.substring(keyValue.indexOf(this.KEY_MID) + this.KEY_MID_LENGTH, keyValue.indexOf(this.KEY_END)); + let value: string = keyValue.substring(this.KEY_START_LENGTH, keyValue.indexOf(this.KEY_MID)); + if (key) { + paramsJSON[key] = value; + } + } + } + + var propertyContent = []; + for (var prop in paramsJSON) { + propertyContent.push(prop + '=' + paramsJSON[prop]); + } + this.editor.clearSelection(); + this.editor.exitMultiSelectMode(); + return paramsJSON; + } + } + } + + setTemplateDataForStore(templateData: any) { + this.storedTemplateData = templateData; + } + + getTemplateDataFromStore() { + return this.storedTemplateData; + } + + removeTheSelectedMarkers() { + var arr: any = []; + arr = this.markedarr; + this.editor.selection.session.$backMarkers = {}; + } + + getsaveMarkers() { + this.markedarr = [...this.editor.selection.session.$selectionMarkers]; + } + + getTemplateMappingDataFromStore() { + return this.storedTemplateMappingData; + } + + setTemplateMappingDataFromStore(templateMappingData: any) { + this.storedTemplateMappingData = templateMappingData; + } + + public setReferenceList(references) { + this.referenceList = references; + } + + public getReferenceList() { + return this.referenceList; + } + + +}
\ No newline at end of file diff --git a/src/app/shared/services/notification.service.ts b/src/app/shared/services/notification.service.ts new file mode 100644 index 0000000..428f9a2 --- /dev/null +++ b/src/app/shared/services/notification.service.ts @@ -0,0 +1,58 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {EventEmitter, Injectable} from '@angular/core'; +import {Notification} from '../models/Notification'; + +@Injectable() +export class NotificationService { + + public notificationsEvent: EventEmitter<Notification>; + + constructor() { + this.notificationsEvent = new EventEmitter<Notification>(); + } + + public add(_notification: Notification) { + this.notificationsEvent.emit(_notification); + } + + public notifySuccessMessage(_message: string) { + this.add(new Notification('success', _message)); + } + + public notifyErrorMessage(_message: string) { + console.error(_message); + this.add(new Notification('error', _message)); + } + + public notifyInfoMessage(_message: string) { + this.add(new Notification('info', _message)); + } + + public notifyAlertMessage(_message: string) { + this.add(new Notification('alert', _message)); + } + +} diff --git a/src/app/shared/services/paramShare.service.ts b/src/app/shared/services/paramShare.service.ts new file mode 100644 index 0000000..559b448 --- /dev/null +++ b/src/app/shared/services/paramShare.service.ts @@ -0,0 +1,85 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Injectable} from '@angular/core'; + +@Injectable() +export class ParamShareService { + + public sharedData: { [index: string]: string; } = {}; + + //Stubbing Name-Value pairs for templateData->will come from Template Generation Component/Editor + public templateData: {}; + public displayData: {}; + public paramData = []; + + + setData(data) { + this.sharedData = data; + } + + getData() { + return this.sharedData; + } + + setTemplateData1() { + /* Stubbing **/ + var paramData = [ + {paramName: 'A-IP', paramValue: '234'}, + {paramName: 'B-IP', paramValue: '10.168.15.15'}, + {paramName: 'C-IP', paramValue: '100.168.150.15'}, + {paramName: 'D-IP', paramValue: '900.168.150.15'}, + {paramName: 'hostIP', paramValue: '200.168.150.15'}, + {paramName: 'hostnameIP', paramValue: '300.168.150.15'}, + {paramName: 'R-IP', paramValue: '400.168.150.15'}, + {paramName: 'someIP', paramValue: '500.168.150.15'} + + ]; + this.templateData = paramData; + } + + setTemplateData(data) { + this.templateData = data; + } + + getTemplateData() { + return (this.templateData); + } + + setDisplayData(data: any[]) { + this.displayData = data.slice(0); + } + + getDisplayData() { + return this.displayData; + } + + setSessionParamData(data) { + this.paramData = data; + } + + getSessionParamData() { + return this.paramData; + } +} diff --git a/src/app/shared/services/utilityService/utility.service.spec.ts b/src/app/shared/services/utilityService/utility.service.spec.ts new file mode 100644 index 0000000..c11927a --- /dev/null +++ b/src/app/shared/services/utilityService/utility.service.spec.ts @@ -0,0 +1,64 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +/* tslint:disable:no-unused-variable */ + +import {inject, TestBed} from '@angular/core/testing'; +import {UtilityService} from './utility.service'; +import {NotificationsService} from 'angular2-notifications'; + +describe('UtilityService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [UtilityService, NotificationsService] + }); + }); + + it('should create a service...', inject([UtilityService], (service: UtilityService) => { + expect(service).toBeTruthy(); + })); + + + it('should apply slashes for a string...', inject([UtilityService], (service: UtilityService) => { + let text = {'vnf-host-ip-address': '135.21.166.36'}; + + expect(service.appendSlashes(JSON.stringify(text))).toEqual('{\\"vnf-host-ip-address\\":\\"135.21.166.36\\"}'); + })); + + + it('should check for status 401', inject([UtilityService], (service: UtilityService) => { + let data = {output: {status: {code: 401}}}; + + expect(service.checkResult(data)).toBeFalsy(); + })); + + + it('should check for status 400', inject([UtilityService], (service: UtilityService) => { + let data = {output: {status: {code: 400}}}; + + expect(service.checkResult(data)).toBeTruthy(); + })); + + +}); diff --git a/src/app/shared/services/utilityService/utility.service.ts b/src/app/shared/services/utilityService/utility.service.ts new file mode 100644 index 0000000..11fa888 --- /dev/null +++ b/src/app/shared/services/utilityService/utility.service.ts @@ -0,0 +1,62 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Injectable} from '@angular/core'; +import {NotificationsService} from 'angular2-notifications'; + +@Injectable() +export class UtilityService { + + private successMessage = 'Retrieved artifact successfully'; + private failureMessage = 'There is no artifact saved in APPC for the selected action!'; + + constructor(private notificationService: NotificationsService) { + } + + randomId() { + let x = (new Date().getUTCMilliseconds()) * Math.random(); + return (x + '').substr(4, 12); + + + } + + appendSlashes(artifactData) { + return artifactData.replace(/"/g, '\\"'); + } + + checkResult(result: any) { + + if (result.output.status.code == '401') { + this.notificationService.info('Information', this.failureMessage); + return false; + } + else if (result.output.status.code == '400') { + this.notificationService.success('Success', this.successMessage); + return true; + } + + } + + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts new file mode 100644 index 0000000..8959587 --- /dev/null +++ b/src/app/shared/shared.module.ts @@ -0,0 +1,73 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {ModuleWithProviders, NgModule} from '@angular/core'; +import {RouterModule} from '@angular/router'; +import {Collapse} from './directives/collapse.component'; +import {CommonModule} from '@angular/common'; +import {DropDownToggleDirective} from './directives/drop-down-toggle.directive'; +import {Dropdown} from './directives/dropdown'; +import {DropdownNotClosableZone} from './directives/dropdownnotclosablezone'; +import {DropdownOpen} from './directives/dropdownopen'; +import {EmitterService} from './services/emitter.service'; +import {HeaderComponent} from './components/header/header.component'; +import {HelpComponent} from './components/help/help/help.component'; +import {HttpModule} from '@angular/http'; +import {HttpUtilService} from './services/httpUtil/http-util.service'; +import {LogoutComponent} from './components/logout/logout.component'; +import {MappingEditorService} from './services/mapping-editor.service'; +import {NavigationComponent} from './components/navigation/navigation.component'; +import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; +import {NotificationService} from './services/notification.service'; +import {ParamShareService} from './services/paramShare.service'; +import {TidyTableModule} from './modules/tidy-table/tidy-table.module'; +import {UtilityService} from './services/utilityService/utility.service'; +import {VmFilteringPipe} from '../pipes/vm-filtering.pipe'; +import {SimpleNotificationsModule} from 'angular2-notifications'; +import { NgProgressModule } from 'ngx-progressbar'; +import {FormsModule} from '@angular/forms'; + +@NgModule({ + imports: [ + FormsModule, + CommonModule, HttpModule, RouterModule, TidyTableModule, NgProgressModule, NgbModule, SimpleNotificationsModule.forRoot()], + + declarations: [VmFilteringPipe, + + HelpComponent, + HeaderComponent, NavigationComponent, LogoutComponent, Collapse, Dropdown, DropdownNotClosableZone, DropdownOpen, DropDownToggleDirective + ], + exports: [VmFilteringPipe, NgProgressModule, NgbModule, HelpComponent, DropDownToggleDirective, HeaderComponent, NavigationComponent, LogoutComponent, TidyTableModule, Collapse, Dropdown, DropdownNotClosableZone, DropdownOpen] +}) +export class SharedModule { + + static forRoot(): ModuleWithProviders { + return { + ngModule: SharedModule, + providers: [HttpUtilService, EmitterService, NotificationService, + UtilityService, + ParamShareService, MappingEditorService] + }; + } +}
\ No newline at end of file diff --git a/src/app/test/test.component.css b/src/app/test/test.component.css new file mode 100644 index 0000000..c1b1169 --- /dev/null +++ b/src/app/test/test.component.css @@ -0,0 +1,35 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +.build-button { + padding: 11px; + font-size: 20px; + color: green; + border: 1PX SOLID GREEN; + MARGIN-BOTTOM: 40PX +} + +table.table th, +table.table td { + padding: 0rem; +}
\ No newline at end of file diff --git a/src/app/test/test.component.html b/src/app/test/test.component.html new file mode 100644 index 0000000..ad6ff7f --- /dev/null +++ b/src/app/test/test.component.html @@ -0,0 +1,205 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> +<simple-notifications [options]="options"></simple-notifications> +<ng-progress [positionUsing]="'marginLeft'" [minimum]="0.15" [maximum]="1" [speed]="200" [showSpinner]="false" [direction]="'leftToRightIncreased'" [color]="'#6ab344'" + [trickleSpeed]="250" [thick]="true" [ease]="'linear'"></ng-progress> + +<div class="card" style=" margin-bottom: 23px;"> + <div class="card-block" style="border-top: 5px solid #6ab344;border-top-right-radius: 7px;border-top-left-radius: 7px;"> + <div class="row"> + <div class="col-lg-3 col-sm-6 col-md-4 col-xs-12"> + <label>Action:</label> + <input class="form-control" type="text" disabled value="{{action}}" /> + </div> + + <!-- <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Vnf Type:</label> + <input class="form-control" type="text" disabled value="{{vnfType}}" /> + + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Vnfc Type:</label> + <input class="form-control" type="text" disabled value="{{vnfcType}}" /> + + </div>--> + <div class="col-lg-3 col-sm-6 col-md-4 col-xs-12"> + <label>Vnf Id:</label> + <input class="form-control" type="text" [(ngModel)]="this.actionIdentifiers['vnf-id']" /> + + </div> + + <div class="col-lg-3 col-sm-6 col-md-4 col-xs-12" *ngIf="this.actionIdentifiers['vserver-id']"> + <label>Vserver-Id(optional):</label> + <input class="form-control" disabled type="text" [(ngModel)]="this.actionIdentifiers['vserver-id']" /> + + </div> + + <!-- <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>VF-Module-Id(optional):</label> + <input class="form-control" disabled type="text" value="{{this.actionIdentifiers['vmodule-id']}}" /> + + </div>--> + + <div class="col-12"> + <div class="input-group"> + <input id="excelInputFile" #myInput1 hidden class="file" type="file" (change)="upload($event)"> + <input [(ngModel)]="uploadFileName" type="text" class="input-lg" disabled placeholder="Upload SpreadSheet" name="uploadFileName" style="width:80%"> + <button (click)="excelBrowseOption($event)" [disabled]="!enableBrowse" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg" + type="button">Upload SpreadSheet + </button> + </div> + </div> + + </div> + </div> +</div> +<br> + +<div class="card"> + + <div class="card-block"> + + <div class="row"> + <div class="col-md-6"> + <span style="margin-left: 5%"><b>REQUEST:</b></span> + </div> + <div class="col-md-6"> + <span style="margin-left: 5%"><b>RESPONSE:</b></span> + </div> + + <div class="col-md-6"> + <div class="col-lg-12 col-sm-12 col-md-12 col-xs-12"> + + <div style="height:200px;width:100%;border:solid 2px grey;overflow:scroll;overflow-x:hidden;overflow-y:scroll;"> + <p style="height:450px;" disabled class="text-center"> + {{apiRequest}} + </p> + </div> + </div> + + </div> + + <div class="col-md-6"> + <div class="col-lg-12 col-sm-12 col-md-12 col-xs-12"> + + <div style="height:200px;width:100%;border:solid 2px grey;overflow:scroll;overflow-x:hidden;overflow-y:scroll;"> + <p style="height:450px;" disabled class="text-center"> + {{apiResponse}} + </p> + </div> + </div> + + </div> + + <div class="col-md-12"> + <div class="row justify-content-center" style="padding-top:0.3cm"> + + <!-- <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" type="button" (click)="clearLog()">Abort Test</button> --> + + <button style="margin-left:6%;" [disabled]="!enableTestButton" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" type="submit" (click)="testVnf()">Execute Test + </button> + <!-- <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" type="button" (click)="abortTest()">Abort Test</button> --> + <!--button class="btn btn-primary" type="submit"> Save Revised Name/Value Pair to APPC</button--> + + </div> + + </div> + + </div> + + </div> + + <div style="padding-left:60%;padding-bottom:0.5cm"> + <!-- <a href="javascript:void(0)" style="color:darkblue; text-decoration: double; font-size: 15px;" (click)="download()">Download Raw Request/Response.</a>--> + <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" type="button" (click)="download()">Download Raw Request/Response + </button> + <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" type="button" [disabled]="!enableAbort" (click)="abortTest()">Abort Test + </button> + + </div> +</div> +<br> +<div class="card"> + <div class="card-block"> + + <div class="mdl-dialog__content" style="border:solid 1px grey;overflow:scroll;overflow-x:hidden;overflow-y:hidden;"> + + <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label" style="margin-left: 25%"> + <input placeholder="Request Id" [(ngModel)]="requestId" class="mdl-textfield__input" id="requestId" required name="requestId"> + </div> + <button type="submit" [disabled]="!enablePollButton" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)=pollTestStatus()>Poll Test Status + </button> + + <div class="col-md-12"> + <span style="margin-left: 18.5%"><b>POLL TEST STATUS RESPONSE</b></span> + </div> + + <div style="margin-left: 18.5%;height:100px;width:60%;border:solid 2px grey;overflow:scroll;overflow-x:hidden;overflow-y:hidden;"> + + <div *ngIf="showStatusResponseDiv"> + <div *ngIf="enableCounterDiv"><b>Poll test no {{pollCounter}}</b></div> + <table> + <thead></thead> + <tbody> + <tr> + <td> + <div class="android-title mdl-layout-title">TimeStamp :</div> + </td> + <td> + <div class="android-title mdl-layout-title">{{outputTimeStamp}}</div> + </td> + </tr> + <tr> + <td> + <div class="android-title mdl-layout-title">Status :</div> + </td> + <td> + <div class="android-title mdl-layout-title">{{status}}</div> + </td> + </tr> + <tr> + <td> + <div class="android-title mdl-layout-title">Status Reason:</div> + </td> + <td> + <div class="android-title mdl-layout-title">{{statusReason}}</div> + </td> + </tr> + </tbody> + </table> + </div> + <div *ngIf="!showStatusResponseDiv"> + <div *ngIf="enableCounterDiv"><b>Poll test no {{pollCounter}}</b></div> + <span>{{statusResponse}}</span> + </div> + + <div *ngIf="errorResponse"> + <p style="height:450px;" disabled class="text-center"> + {{errorResponse}} + </p> + </div> + + </div> + </div> + </div> +</div>
\ No newline at end of file diff --git a/src/app/test/test.component.spec.ts b/src/app/test/test.component.spec.ts new file mode 100644 index 0000000..e869adb --- /dev/null +++ b/src/app/test/test.component.spec.ts @@ -0,0 +1,158 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ + +// Modules +import { async, ComponentFixture, TestBed,inject } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { RouterTestingModule } from '@angular/router/testing'; +import { SimpleNotificationsModule } from 'angular2-notifications'; +import { Http, Response, Headers, RequestOptions, HttpModule } from '@angular/http'; + +// Component +import { TestComponent } from './test.component'; + +// Services +import { NotificationService } from '../shared/services/notification.service'; +import { ParamShareService } from '.././shared/services/paramShare.service'; +import { MappingEditorService } from '../shared/services/mapping-editor.service'; +import { HttpUtilService } from '../shared/services/httpUtil/http-util.service'; +import { UtilityService } from '../shared/services/utilityService/utility.service'; +import { NgProgress } from 'ngx-progressbar'; +import {NgProgressModule} from 'ngx-progressbar'; + +describe( 'TestComponent', () => { + let component: TestComponent; + let fixture: ComponentFixture<TestComponent>; + + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [TestComponent], + imports: [ + FormsModule, + RouterTestingModule, + SimpleNotificationsModule, + HttpModule, + NgProgressModule + ], + providers: [ + NotificationService, + ParamShareService, + MappingEditorService, + HttpUtilService, + UtilityService, + NgProgress + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TestComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it( 'should create', () => { + expect(component).toBeTruthy(); + }); + + // it('test', () => { + // expect(2).toEqual(1) + // }); + + + // it('test preparfilename', inject([MappingEditorService], (mappingEditorService: MappingEditorService) => { + // // fixture = TestBed.createComponent(TestComponent); + // // component = fixture.componentInstance; + // mappingEditorService.latestAction=undefined + + // expect(component.prepareFileName()).toBe(undefined); + // })); + + + it('Should have download method', () => { + expect(component.download).toBeDefined(); + }); + + // Test abortTest Method + it('Should have abortTest method', () => { + expect(component.abortTest).toBeDefined(); + }); + + it('Test abortTest Method', () => { + const temp = component.abortTest(); + expect(component.enableBrowse).toBeTruthy(); + expect(component.enableTestButton).toBeTruthy(); + }); + + it('Should have excelBrowseOption method', () => { + expect(component.excelBrowseOption).toBeDefined(); + }); + + it('Should have upload method', () => { + expect(component.upload).toBeDefined(); + }); + + it('Should have constructTestPayload method', () => { + expect(component.constructTestPayload).toBeDefined(); + }); + + it('Should have constructRequest method', () => { + expect(component.constructRequest).toBeDefined(); + }); + + it('Should have testVnf method', () => { + expect(component.testVnf).toBeDefined(); + }); + + it('Should have pollTestStatus method', () => { + expect(component.pollTestStatus).toBeDefined(); + }); + + + // Test getUrlEndPoint Method + it('Should have getUrlEndPoint method', () => { + expect(component.getUrlEndPoint).toBeDefined(); + }); + + it('getUrlEndPoint Should return value', () => { + expect(component.getUrlEndPoint('configmodify')).toEqual('config-modify'); + expect(component.getUrlEndPoint('configbackup')).toEqual('config-backup'); + expect(component.getUrlEndPoint('configrestore')).toEqual('config-restore'); + expect(component.getUrlEndPoint('healthcheck')).toEqual('health-check'); + expect(component.getUrlEndPoint('quiescetraffic')).toEqual('quiesce-traffic'); + expect(component.getUrlEndPoint('resumetraffic')).toEqual('resume-traffic'); + expect(component.getUrlEndPoint('startapplication')).toEqual('start-application'); + expect(component.getUrlEndPoint('stopapplication')).toEqual('stop-application'); + expect(component.getUrlEndPoint('upgradebackout')).toEqual('upgrade-backout'); + expect(component.getUrlEndPoint('upgradepostcheck')).toEqual('upgrade-post-check'); + expect(component.getUrlEndPoint('upgradeprecheck')).toEqual('upgrade-pre-check'); + expect(component.getUrlEndPoint('upgradesoftware')).toEqual('upgrade-software'); + expect(component.getUrlEndPoint('DeFaultCASE')).toEqual('defaultcase'); + }); +})
\ No newline at end of file diff --git a/src/app/test/test.component.ts b/src/app/test/test.component.ts new file mode 100644 index 0000000..1874904 --- /dev/null +++ b/src/app/test/test.component.ts @@ -0,0 +1,533 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import { Component, OnInit } from '@angular/core'; + +import { saveAs } from 'file-saver'; +import { Location } from '@angular/common'; +import { ActivatedRoute, Router } from '@angular/router'; +import { NotificationService } from '.././shared/services/notification.service'; +import { ParamShareService } from '.././shared/services/paramShare.service'; +import { MappingEditorService } from '.././shared/services/mapping-editor.service'; +import { NotificationsService } from 'angular2-notifications'; +import { HttpUtilService } from '.././shared/services/httpUtil/http-util.service'; +import 'rxjs/add/observable/interval'; +import { Observable } from 'rxjs/Observable'; +import { environment } from '../.././environments/environment'; +import { UtilityService } from '.././shared/services/utilityService/utility.service'; +import 'rxjs/add/operator/map'; +import * as XLSX from 'xlsx'; +import { NgProgress } from 'ngx-progressbar'; + + +let YAML = require('yamljs'); + +type AOA = Array<Array<any>>; +declare var $: any; + +@Component({ selector: 'test', templateUrl: './test.component.html', styleUrls: ['./test.component.css'] }) +export class TestComponent implements OnInit { + public displayParamObjects; + options = { + timeOut: 1000, + showProgressBar: true, + pauseOnHover: true, + clickToClose: true, + maxLength: 200 + }; + public action: any; + public vnfId: any; + public item: any = {}; + + public vnfType: any; + vnfcType: any; + protocol: any; + mode: any = 'NORMAL'; + force: any = 'True'; + ttl: any; + public formattedNameValuePairs = {}; + public requestId = ''; + public enableBrowse: boolean = true; + public enableSpinner: boolean = false; + host: any; + public refNameObj = {}; + + public artifactName; + public type; + public transactions = ''; + public uploadFileName; + + public payload = {}; + public lastvmJson = {}; + public vmPayload = []; + public subPayload = {}; + public vmJson = {}; + public vnfcJson = {}; + public flag = 1; + public oldListName1 = ''; + public actionIdentifiers = {}; + public apiRequest = ''; + public apiResponse = ''; + public statusResponse; + public outputTimeStamp; + public status; + public statusReason; + public errorResponse; + public timer; + public subscribe; + public enableTestButton: boolean = false; + public enableAbort: boolean = false; + public showStatusResponseDiv: boolean = false; + public enablePollButton: boolean = true; + public pollCounter = 0; + public enableCounterDiv: boolean = false; + + constructor(private location: Location, private activeRoutes: ActivatedRoute, private notificationService: NotificationService, private nService: NotificationsService, private router: Router, private paramShareService: ParamShareService, private mappingEditorService: MappingEditorService, private httpUtil: HttpUtilService, + private utiltiy: UtilityService, private ngProgress: NgProgress) { + + } + + ngOnInit() { + + + } + + prepareFileName(): any { + let fileNameObject: any = this.mappingEditorService.latestAction; + return fileNameObject; + } + + /*public download() { + let stringData: any; + stringData = JSON.stringify(this.paramShareService.getSessionParamData()); + let paramsKeyValueFromEditor: JSON; + paramsKeyValueFromEditor = JSON.parse(stringData); + let fileName = 'param_' + this.action + '_' + this.type + '_' + "0.0.1" + 'V'; + this.JSONToCSVConvertor([paramsKeyValueFromEditor], fileName, true); + + }*/ + + public download() { + if (this.apiRequest) { + var fileName = 'test_' + this.action + '_' + this.actionIdentifiers['vnf-id'] + '_request'; + var theJSON = this.apiRequest; + if (fileName != null || fileName != '') { + var blob = new Blob([theJSON], { + type: 'text/json' + }); + saveAs(blob, fileName); + } + } + else { + this.nService.error('Error', 'Please upload spreadsheet to download the request and response'); + } + + if (this.apiResponse) { + var fileName = 'test_' + this.action + '_' + this.actionIdentifiers['vnf-id'] + '_response'; + var theJSON = this.apiResponse; + if (fileName != null || fileName != '') { + var blob = new Blob([theJSON], { + type: 'text/json' + }); + saveAs(blob, fileName); + } + } + + } + + + public abortTest() { + //this.apiResponse = ""; + this.enableBrowse = true; + this.enableTestButton = true; + this.enablePollButton = true; + this.subscribe.unsubscribe(); + + } + + + /*JSONToCSVConvertor(JSONData, fileName, ShowLabel) { + //If JSONData is not an object then JSON.parse will parse the JSON string in an Object + var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData; + + var CSV = ''; + + //This condition will generate the Label/Header + if (ShowLabel) { + var testRow = ""; + for (var index in arrData[0]) { + + CSV += arrData[0][index].name + '\t' + arrData[0][index].value + '\t' + arrData[0][index].source + '\r\n'; + } + } + + if (CSV == '') { + alert("Invalid data"); + return; + } + + //Initialize file format you want csv or xls + var uri = 'data:application/vnd.ms-excel,' + encodeURI(CSV); + + var link = document.createElement("a"); + link.href = uri; + + link.download = fileName + ".xls"; + + //this part will append the anchor tag and remove it after automatic click + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }*/ + + excelBrowseOption() { + $('#excelInputFile').trigger('click'); + } + + + upload(evt: any) { + /* wire up file reader */ + $('#filesparam').trigger('click'); + const target: DataTransfer = <DataTransfer>(evt.target); + + this.uploadFileName = evt.target.files[0].name; + var fileExtension = this.uploadFileName.substr(this.uploadFileName.lastIndexOf('.') + 1); + + if (target.files.length != 1) { + throw new Error('Cannot upload multiple files on the entry'); + } + if (fileExtension.toUpperCase() === 'XLS' || fileExtension.toUpperCase() === 'XLSX') { + const reader = new FileReader(); + reader.onload = (e: any) => { + /* read workbook */ + const bstr = e.target.result; + const wb = XLSX.read(bstr, { type: 'binary' }); + /* grab first sheet */ + const wsname = wb.SheetNames[0]; + const ws = wb.Sheets[wsname]; + + /* save data */ + this.requestId = '' + this.enableTestButton = true; + this.enableAbort = true; + this.enablePollButton = true; + + if (this.subscribe && this.subscribe != undefined) { + this.enableCounterDiv = false; + this.subscribe.unsubscribe(); + } + this.apiRequest = ''; + this.apiResponse = ''; + this.showStatusResponseDiv = false; + this.errorResponse = ''; + this.statusResponse = ''; + + let arrData = (<AOA>(XLSX.utils.sheet_to_json(ws, { blankrows: false }))); + this.nService.success('Success', 'SpreadSheet uploaded successfully'); + + + console.log('Array data ==' + arrData[0]); + this.vmPayload = []; + this.subPayload = {}; + this.vmJson = {}; + this.flag = 1; + this.payload = {}; + this.oldListName1 = ''; + this.actionIdentifiers = {}; + for (var i = 0; i < arrData.length; i++) { + var element = arrData[i]; + if (element['TagName'] === 'action') { + this.action = element['Value']; + } + if (element['List Name'] === 'action-identifiers') { + this.vnfId = element['Value']; + var key = element['TagName']; + var value = element['Value']; + if (key && value) { + this.actionIdentifiers[key] = value; + + } + } + + if (element['List Name'] === 'payload') { + var listName1 = element['List Name_1']; + var listName2 = element['List Name_2']; + var listName3 = element['List Name_3']; + var key = element['TagName']; + var value = element['Value']; + if (listName1) { + if (this.oldListName1 == '' || (listName1 === this.oldListName1)) { + this.constructTestPayload(listName2, listName3, key, value); + this.payload[listName1] = this.subPayload; + } + else { + this.subPayload = {}; + this.constructTestPayload(listName2, listName3, key, value); + this.payload[listName1] = this.subPayload; + } + this.oldListName1 = listName1; + } + else { + this.payload[key] = value; + } + } + } + + //console.log("VM JSON===" + JSON.stringify(this.vmPayload)) + // console.log('VM payload===' + JSON.stringify(this.payload)); + }; + + reader.readAsBinaryString(target.files[0]); + } + else { + this.nService.error('Error', 'Incorrect spreadsheet uploaded'); + this.flag = 1; + this.oldListName1 = ''; + this.vmJson = {}; + this.vnfcJson = {}; + this.subPayload = {}; + this.vmPayload = []; + this.payload = {}; + this.action = ''; + this.actionIdentifiers = {}; + this.apiRequest = ''; + this.apiResponse = ''; + this.enableCounterDiv = false; + } + } + + constructTestPayload(listName2, listName3, key, value) { + if (listName2 == undefined && listName3 == undefined) { + this.subPayload[key] = value; + } + if (listName2) { + + if (!listName3) { + + //vmPayload.push(vmJson) + this.vmJson = {}; + this.vnfcJson = {}; + this.vmJson[key] = value; + this.flag = 0; + } + else { + this.vnfcJson[key] = value; + this.vmJson['vnfc'] = this.vnfcJson; + this.flag = 1; + } + if (this.vmJson) this.lastvmJson = this.vmJson; + if (this.flag == 0) { + this.vmPayload.push(this.lastvmJson); + if (this.vmPayload) this.subPayload['vm'] = this.vmPayload; + } + } + } + + constructRequest() { + console.log('payload==' + JSON.stringify(this.payload)); + let timeStamp = new Date().toISOString(); + console.log('timestamp==' + timeStamp); + let reqId; + this.requestId = reqId = new Date().getTime().toString(); + let data = { + 'input': { + 'common-header': { + 'timestamp': timeStamp, + 'api-ver': '2.00', + 'originator-id': 'CDT', + 'request-id': this.requestId, + 'sub-request-id': this.requestId, + 'flags': { + 'mode': 'NORMAL', + 'force': 'TRUE', + 'ttl': 3600 + } + }, + 'action': this.action, + 'action-identifiers': this.actionIdentifiers, + 'payload': JSON.stringify(this.payload) + } + }; + + return data; + } + + testVnf() { + //let payload = '{"request-parameters":{"vnf-host-ip-address":"' + this.host + '"},"configuration-parameters":"' + JSON.stringify(this.formattedNameValuePairs) + '"}"'; + //let payload = '{"request-parameters":{"host-ip-address:"' + this.host + '",port-number:"'+port+'"}}'; + + this.enableBrowse = false; + this.enableTestButton = false; + this.enablePollButton = false; + this.timer = Observable.interval(10000); + this.subscribe = this.timer.subscribe((t) => this.pollTestStatus()); + //console.log('full payload==' + JSON.stringify(this.apiRequest)); + this.ngProgress.start(); + this.apiRequest = JSON.stringify(this.constructRequest()); + this.httpUtil.post( + { + url: environment.testVnf + this.getUrlEndPoint(this.action.toLowerCase()), data: this.apiRequest + }) + .subscribe(resp => { + this.apiResponse = JSON.stringify(resp); + this.enableBrowse = true; + this.enableTestButton = true; + this.ngProgress.done(); + }, + error => { + this.nService.error('Error', 'Error in connecting to APPC Server'); + this.enableBrowse = true; + this.enableTestButton = true; + this.enablePollButton = true; + this.enableCounterDiv = false; + this.subscribe.unsubscribe(); + + }); + + setTimeout(() => { + this.ngProgress.done(); + }, 3500); + } + + + pollTestStatus() { + if (this.requestId && this.actionIdentifiers['vnf-id']) { + // console.log("payload==" + JSON.stringify(this.payload)) + let timeStamp = new Date().toISOString(); + // console.log("timestamp==" + timeStamp) + let reqId = new Date().getTime().toString(); + let data = { + 'input': { + 'common-header': { + 'timestamp': timeStamp, + 'api-ver': '2.00', + 'originator-id': 'CDT', + 'request-id': reqId, + 'sub-request-id': reqId, + 'flags': { + 'mode': 'NORMAL', + 'force': 'TRUE', + 'ttl': 3600 + } + }, + 'action': 'ActionStatus', + 'action-identifiers': this.actionIdentifiers, + 'payload': '{"request-id":' + this.requestId + '}' + } + }; + //this.ngProgress.start(); + this.httpUtil.post( + { + url: environment.checkTestStatus, data: data + + }) + .subscribe(resp => { + // console.log('Response==' + JSON.stringify(resp)); + this.statusResponse = JSON.stringify(resp); + var status = '' + var statusReason = '' + this.enableCounterDiv = true; + this.pollCounter++; + //this.statusResponse=JSON.parse(this.statusResponse) + if (resp.output) var timeStamp = resp.output['common-header'].timestamp; + if (resp.output.payload) { + var payload = resp.output.payload.replace(/\\/g, "") + try { + payload = JSON.parse(payload) + status = payload['status']; + statusReason = payload['status-reason']; + } + catch (err) { + console.log("error" + err) + } + } + if (timeStamp && status && statusReason) { + this.showStatusResponseDiv = true; + this.outputTimeStamp = timeStamp; + this.status = status; + this.statusReason = statusReason; + if (status.toUpperCase() === 'SUCCESS') { + this.subscribe.unsubscribe(); + this.enablePollButton = true; + } + if (status.toUpperCase() === 'FAILED') { + this.subscribe.unsubscribe(); + this.enablePollButton = true; + } + } + else { + this.showStatusResponseDiv = false; + } + + // this.ngProgress.done(); + }, + error => { + this.statusResponse = null; + this.showStatusResponseDiv = false; + this.errorResponse = 'Error Connecting to APPC server'; + this.enableCounterDiv = false; + this.subscribe.unsubscribe(); + }); + + } + else { + this.nService.error("Error", "Please enter vnf Id & request Id"); + } + // setTimeout(() => { + // this.ngProgress.done(); + // }, 3500); + } + + getUrlEndPoint(action) { + switch (action) { + case 'configmodify': + return 'config-modify'; + case 'configbackup': + return 'config-backup'; + case 'configrestore': + return 'config-restore'; + case 'healthcheck': + return 'health-check'; + case 'quiescetraffic': + return 'quiesce-traffic'; + case 'resumetraffic': + return 'resume-traffic'; + case 'startapplication': + return 'start-application'; + case 'stopapplication': + return 'stop-application'; + case 'upgradebackout': + return 'upgrade-backout'; + case 'upgradepostcheck': + return 'upgrade-post-check'; + case 'upgradeprecheck': + return 'upgrade-pre-check'; + case 'upgradesoftware': + return 'upgrade-software'; + default: + return action.toLowerCase(); + } + + } + +} diff --git a/src/app/vnfs/GCAuthGuard/gcauth-guard.service.ts b/src/app/vnfs/GCAuthGuard/gcauth-guard.service.ts new file mode 100644 index 0000000..c6f0b80 --- /dev/null +++ b/src/app/vnfs/GCAuthGuard/gcauth-guard.service.ts @@ -0,0 +1,59 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {Injectable} from '@angular/core'; +import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router'; +import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; +import {AuthGuardModalComponent} from '../auth-guard-modal/auth-guard-modal'; +import {MappingEditorService} from '../../shared/services/mapping-editor.service'; + +@Injectable() +export class GCAuthGuardService implements CanActivate { + constructor(private ngbModal: NgbModal, private mapService: MappingEditorService, private router: Router) { + } + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> { + return new Promise(resolve => { + + if (this.mapService.referenceNameObjects != null && this.mapService.referenceNameObjects != undefined) { + resolve(true); + } else { + let x = this.ngbModal.open(AuthGuardModalComponent).result; + x.then((result) => { + //.close method + + resolve(true); + }, (reason) => { + //.dismiss method + this.router.navigate([this.router.url]); + + resolve(false); + }); + } + + //return false; + }); + + + } +}
\ No newline at end of file diff --git a/src/app/vnfs/LoginGuardService/Login-guard-service.ts b/src/app/vnfs/LoginGuardService/Login-guard-service.ts new file mode 100644 index 0000000..2c834a8 --- /dev/null +++ b/src/app/vnfs/LoginGuardService/Login-guard-service.ts @@ -0,0 +1,49 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {Injectable} from '@angular/core'; +import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router'; + + +import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; + +import {MappingEditorService} from '../../shared/services/mapping-editor.service'; + +@Injectable() +export class LoginGuardService implements CanActivate { + + constructor(private ngbModal: NgbModal, private mapService: MappingEditorService, private router: Router) { + } + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + + let userId = localStorage['userId']; + if (userId != null && userId != undefined && userId != '') { + this.router.navigate(['/vnfs/list']); + return false; + } else { + return true; + } + + } +}
\ No newline at end of file diff --git a/src/app/vnfs/auth-guard-modal/auth-guard-modal.css b/src/app/vnfs/auth-guard-modal/auth-guard-modal.css new file mode 100644 index 0000000..9d63aa1 --- /dev/null +++ b/src/app/vnfs/auth-guard-modal/auth-guard-modal.css @@ -0,0 +1,21 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */
\ No newline at end of file diff --git a/src/app/vnfs/auth-guard-modal/auth-guard-modal.html b/src/app/vnfs/auth-guard-modal/auth-guard-modal.html new file mode 100644 index 0000000..b4e3fef --- /dev/null +++ b/src/app/vnfs/auth-guard-modal/auth-guard-modal.html @@ -0,0 +1,21 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ -->
\ No newline at end of file diff --git a/src/app/vnfs/auth-guard-modal/auth-guard-modal.ts b/src/app/vnfs/auth-guard-modal/auth-guard-modal.ts new file mode 100644 index 0000000..9fadbde --- /dev/null +++ b/src/app/vnfs/auth-guard-modal/auth-guard-modal.ts @@ -0,0 +1,39 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ + +import {Component, OnInit} from '@angular/core'; +import {NgbActiveModal} from '@ng-bootstrap/ng-bootstrap'; + +@Component({ + selector: 'app-auth-guard-modal', + templateUrl: './auth-guard-modal.html', + styleUrls: ['./auth-guard-modal.css'] +}) +export class AuthGuardModalComponent implements OnInit { + + constructor(public activeModal: NgbActiveModal) { + } + + ngOnInit() { + } + +} diff --git a/src/app/vnfs/build-artifacts/build-artifacts.component.css b/src/app/vnfs/build-artifacts/build-artifacts.component.css new file mode 100644 index 0000000..e7095bd --- /dev/null +++ b/src/app/vnfs/build-artifacts/build-artifacts.component.css @@ -0,0 +1,40 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +.active-tab > a { + border-bottom: 5px solid #6ab344; +} + +.custom-heade-nav { + border-bottom: none !important; +} + +.nav-link { + font-size: 15PX; + color: black +} + +a.disabled { + color: darkolivegreen; + pointer-events: none; +}
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/build-artifacts.component.html b/src/app/vnfs/build-artifacts/build-artifacts.component.html new file mode 100644 index 0000000..e0b2e05 --- /dev/null +++ b/src/app/vnfs/build-artifacts/build-artifacts.component.html @@ -0,0 +1,36 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<div class="container"> + <div class="row"> + <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12"> + <ul class="nav nav-tabs custom-heade-nav" style=" margin-bottom: 12px;"> + <li [ngClass]="{'active-tab':((router.url.indexOf('/'+item.url))>-1 || router.url.indexOf(item.url)>-1 )}" + *ngFor="let item of tabs"> + <a [routerLink]="[item.url]" [type]="item.type" class="nav-link">{{item.name}}</a> + </li> + </ul> + </div> + </div> +</div> +<router-outlet></router-outlet>
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/build-artifacts.component.spec.ts b/src/app/vnfs/build-artifacts/build-artifacts.component.spec.ts new file mode 100644 index 0000000..8545838 --- /dev/null +++ b/src/app/vnfs/build-artifacts/build-artifacts.component.spec.ts @@ -0,0 +1,49 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {BuildDesignComponent} from './build-artifacts.component'; + +describe('BuildDesignComponent', () => { + let component: BuildDesignComponent; + let fixture: ComponentFixture<BuildDesignComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [BuildDesignComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BuildDesignComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/vnfs/build-artifacts/build-artifacts.component.ts b/src/app/vnfs/build-artifacts/build-artifacts.component.ts new file mode 100644 index 0000000..7641aa5 --- /dev/null +++ b/src/app/vnfs/build-artifacts/build-artifacts.component.ts @@ -0,0 +1,82 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import * as _ from 'underscore'; + +@Component({ selector: 'app-build-design', templateUrl: './build-artifacts.component.html', styleUrls: ['./build-artifacts.component.css'] }) +export class BuildDesignComponent implements OnInit { + tabs: Array<Object> = []; + private allowOtherUpdates: boolean = true; + + constructor (private router: Router) { + } + + ngOnInit() { + this.tabs = [ + { + type: 'dropdown', + name: 'Reference Data', + url: 'references', + }, { + name: 'Template', + type: 'dropdown', + url: 'templates/myTemplates', + }, { + name: 'Parameter Definition', + type: 'dropdown', + url: 'parameterDefinitions/create' + } /*, { + name: "Test", + url: 'test', + }*/ + ]; + } + + public setAllowOtherUpdates(allowOtherUpdates: boolean) { + this.allowOtherUpdates = allowOtherUpdates; + } + + // Allow / block access to the update pages of GT and PD if no reference data present + public updateAccessUpdatePages(selectedAction, referenceList) { + // Disable/enable the menu items for update pages of GT and PD. + if (this.isReferenceFound(selectedAction, referenceList)) { + this.setAllowOtherUpdates(true); + } else { + //alert("false") + this.setAllowOtherUpdates(false); + } + } + + public isReferenceFound(selectedAction, referenceList) { + let selectedActioneObject = _.find(referenceList, function (obj) { + return obj['action'] == selectedAction; + }); + if (selectedActioneObject) { + return true; + } else { + return false; + } + } +} diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.spec.ts b/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.spec.ts new file mode 100644 index 0000000..8a9c112 --- /dev/null +++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.spec.ts @@ -0,0 +1,114 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +/* tslint:disable:no-unused-variable */ + +import {inject, TestBed} from '@angular/core/testing'; +import {ParameterDefinitionService} from './parameter-definition.service'; +import {NotificationsService} from 'angular2-notifications'; +import {MappingEditorService} from '../../../shared/services/mapping-editor.service'; +import {HttpUtilService} from '../../../shared/services/httpUtil/http-util.service'; +import {UtilityService} from '../../../shared/services/utilityService/utility.service'; +import {ParamShareService} from '../../../shared/services/paramShare.service'; + + +class MockService { + doStuff() { + return this; + } +} + +describe('ParameterDefinitionService', () => { + beforeEach(() => { + let httpUtilService = new MockService(); + TestBed.configureTestingModule({ + providers: [ParameterDefinitionService, NotificationsService, MappingEditorService, ParamShareService, HttpUtilService, UtilityService, + {provide: HttpUtilService, useValue: httpUtilService}] + }); + }); + + it('should create a service...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => { + expect(service).toBeTruthy(); + })); + + it('should remove unwanted values from PD object...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => { + let obj = { + 'vnf-parameter-list': [{ + 'ruleTypeValues': 'ruleTypeValues', + 'showFilterFields': 'showFilterFields', + 'enableFilterByValue': 'enableFilterByValue' + }] + }; + + expect(service.removeUnwantedvalues(obj)).toEqual({'vnf-parameter-list': [{}]}); + })); + + + it('populateDataUponSource...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => { + let obj = [{'source': 'A&AI', 'ruleType': 'vm-name-list'}]; + + expect(service.populateDataUponSource(obj)); + })); + + it('populateDataUponSource...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => { + let obj = [{'source': 'Manual', 'ruleType': 'vm-name-list'}]; + + expect(service.populateDataUponSource(obj)); + })); + + it('populateDataUponSource...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => { + let obj = [{'source': 'Something', 'ruleType': 'vm-name-list'}]; + + expect(service.populateDataUponSource(obj)); + })); + + + it('populateDataUponSource...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => { + let obj = [{'source': 'Something', 'ruleType': 'vm-name-list'}]; + + expect(service.populatePD(obj)); + })); + + it('processPDfile...', inject([ParameterDefinitionService], (service: ParameterDefinitionService)=> { + let yaml = "---\nkind: Property Definition\nversion: V1\nvnf-parameter-list:\n- name: LICENSE_KEY\n type: null\n description: null\n required: null\n default: null\n source: Manual\n rule-type: null\n request-keys: null\n response-keys: null"; + let expectedPD = [{"name":"LICENSE_KEY","type":null,"description":null,"required":null,"default":null,"source":"Manual","rule-type":null, + "request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null + ,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}]; + + expect(service.processPDfile("testfile.yaml", yaml)).toEqual(expectedPD); + + })); + + // it('processKeyFile...', inject([ParameterDefinitionService, ParamShareService], (service: ParameterDefinitionService, paramShareService: ParamShareService)=> { + // let keyFile = "PARAMVALUE|SOURCE|RULETYPE|KEY1|VALUE1|KEY2|VALUE2|KEY3|VALUE3\nvalue1|INSTAR|interface_ip_address|UniqueKeyName1|addressfqdn123|UniqueKeyValue|m001ssc001p1n001v001|FieldKeyName|ipaddress_v4\nvalue2|INSTAR|interface_ip_address|UniqueKeyName2|addressfqdnAsgar1|UniqueKeyValue|m001ssc001p1n001v002|FieldKeyName|ipaddress_v4"; + // let expectedPD = [{"name":"name1","type":null,"description":null,"required":null,"default":null,"source":"Manual","rule-type":null, + // "request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null + // ,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}]; + // localStorage['paramsContent'] = "{ \"name1\":\"value1\",\"name2\":\"value2\"}"; + // paramShareService.setSessionParamData(expectedPD) + // expect(service.processKeyFile("testfile.txt", keyFile)).toEqual(expectedPD); + + // })); + +}); diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.ts b/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.ts new file mode 100644 index 0000000..89eeec2 --- /dev/null +++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.ts @@ -0,0 +1,509 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +import {Injectable, ViewChild} from '@angular/core'; +import {saveAs} from 'file-saver'; +import {ParamShareService} from '../../../shared/services/paramShare.service'; +import {MappingEditorService} from '../../../shared/services/mapping-editor.service'; +import {ModalComponent} from '../../../shared/modal/modal.component'; +import {HttpUtilService} from '../../../shared/services/httpUtil/http-util.service'; +import {UtilityService} from '../../../shared/services/utilityService/utility.service'; +import {NotificationsService} from 'angular2-notifications'; +import 'rxjs/add/operator/map'; + +let YAML = require('yamljs'); + +declare var $: any; + +@Injectable() +export class ParameterDefinitionService { + + public vnfcTypeData: string = ''; + public selectedUploadType: string; + @ViewChild(ModalComponent) modalComponent: ModalComponent; + public title: string; + public parameterDefinitionMap: { [index: string]: string; } = {}; + public parameterNameValues = {}; + public displayParamObjects; + public modelParamDefinitionObjects; + public vnfType: any; + vnfcType: any; + protocol: any; + public refNameObj = {}; + public action; + public artifactName; + public type; + public appDataObject: any; + public downloadDataObject: any; + public artifact_fileName; + identifier: any; + public myKeyFileName = null; + public myPdFileName = null; + private selectedActionReference: any; + private apiToken = localStorage['apiToken']; + private userId = localStorage['userId']; + + constructor(private mappingEditorService: MappingEditorService, + private paramShareService: ParamShareService, + private nService: NotificationsService, + private httpService: HttpUtilService, + private utilService: UtilityService) { + + } + + public initialize() { + + } + + public setValues(vnfType, vnfcType, protocol, action, artifactName) { + this.vnfType = vnfType; + this.vnfcType = vnfcType; + this.protocol = protocol; + this.action = action; + this.artifact_fileName = artifactName; + } + + public afterInit(artifactName, displayParamObjects) { + + } + + //========================== End of saveChanges() Method============================================ + /* Saves pd to appc */ + public sendPD(yamlString: String) { + let result: any; + let payload = '{"userID": "' + this.userId + '","vnf-type" : "' + this.vnfType + '","action" : "' + this.action + '","artifact-name" : "' + this.artifact_fileName + '","artifact-type" : "APPC-CONFIG","artifact-version" : "0.0.1","artifact-contents" : ' + yamlString + '}'; + let input = { + 'input': { + 'design-request': { + 'request-id': this.apiToken, + 'action': 'uploadArtifact', + 'payload': payload + } + } + }; + this.appDataObject.pd = input; + } + + + //========================== End of filetrByFieldChanged() Method============================================ + removeUnwantedvalues(obj) { + let result = Object.assign({}, obj); + result['vnf-parameter-list'].forEach(obj => { + delete obj['ruleTypeValues']; + delete obj['showFilterFields']; + delete obj['enableFilterByValue']; + }); + return result; + } + + //========================== End of removeUnwantedvalues() Method============================================ + populateDataUponSource(displayParamObjects) { + displayParamObjects.forEach(parameter => { + if (parameter.source == 'A&AI') { + parameter.ruleTypeValues = [null, 'vnf-name', 'vm-name-list', 'vnfc-name-list', 'vnf-oam-ipv4-address', 'vnfc-oam-ipv4-address-list']; + if (parameter['rule-type'] == 'vm-name-list' || parameter['rule-type'] == 'vnfc-name-list' || parameter['rule-type'] == 'vnfc-oam-ipv4-address-list') { + parameter.showFilterFields = true; + parameter.enableFilterByValue = false; + } else { + parameter.showFilterFields = false; + } + + } else if (parameter.source == 'Manual') { + parameter.ruleTypeValues = [null]; + } + else { + parameter.ruleTypeValues = [parameter['rule-type']]; + } + }); + + } + + //========================== End of getPD() Method============================================ + populatePD(result: any) { + let fileContent = JSON.stringify(result); + //Added code to deserialize, serialize and format the response keys for display purposes ??May be unneessary?? To Do: - Check + let fileObj = JSON.parse(fileContent); + this.displayParamObjects = this.formatFileContentForDisplay(fileObj); + this.populateDataUponSource(this.displayParamObjects); + this.formatResponseForKey(this.displayParamObjects); + if (undefined !== this.displayParamObjects) + this.modelParamDefinitionObjects = this.displayParamObjects; + if (this.displayParamObjects !== undefined && this.displayParamObjects.length > 0) { + this.paramShareService.setSessionParamData(this.displayParamObjects); + } + return this.displayParamObjects; + } + + //========================== End of populatePD() Method============================================ + /* Formats each object read from YAML file as per page expectations */ + formatResponseForKey(param: any[]) { + for (var i = 0; i < param.length; i++) { + this.formatKeys(param[i]); + } + } + + //========================== End of formatResponseForKey() Method============================================ + /* Formats for responsekeys of each object */ + formatKeys(parameterDefinitionObject: any) { + if (null == parameterDefinitionObject || undefined === parameterDefinitionObject) + return; + if (null == parameterDefinitionObject['response-keys']) + parameterDefinitionObject['response-keys'] = [{}]; + for (var j = 0; j < 5; j++) { + var keysObj = { + 'key-name': null, + 'key-value': null + }; + if (undefined == parameterDefinitionObject['response-keys'][j] || null == parameterDefinitionObject['response-keys'][j]) { + parameterDefinitionObject['response-keys'].push(keysObj); + } + if (undefined == parameterDefinitionObject['response-keys'][j]['key-name']) { + parameterDefinitionObject['response-keys'][j]['key-name'] = null; + } + if (undefined == parameterDefinitionObject['response-keys'][j]['key-value']) { + parameterDefinitionObject['response-keys'][j]['key-value'] = null; + } + } + if (null == parameterDefinitionObject['request-keys']) + parameterDefinitionObject['request-keys'] = [{}]; + for (var k = 0; k < 3; k++) { + var keysObj = { + 'key-name': null, + 'key-value': null + }; + if (undefined == parameterDefinitionObject['request-keys'][k] || null == parameterDefinitionObject['request-keys'][k]) { + parameterDefinitionObject['request-keys'].push(keysObj); + } + if (undefined == parameterDefinitionObject['request-keys'][k]['key-name']) { + parameterDefinitionObject['request-keys'][k]['key-name'] = null; + } + if (undefined == parameterDefinitionObject['request-keys'][k]['key-value']) { + parameterDefinitionObject['request-keys'][k]['key-value'] = null; + } + } + } + + //========================== End of formatKeys() Method============================================ + //Send null if there are no keys present - Check with key names being absent + formatKeysForFileGeneration() { + for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) { + if (this.modelParamDefinitionObjects[i]['response-keys'][0]['key-name'] == null && this.modelParamDefinitionObjects[i]['response-keys'][1]['key-name'] == null && this.modelParamDefinitionObjects[i]['response-keys'][2]['key-name'] == null) + this.modelParamDefinitionObjects[i]['response-keys'] = null; + if (this.modelParamDefinitionObjects[i]['request-keys'][0]['key-name'] == null && this.modelParamDefinitionObjects[i]['request-keys'][1]['key-name'] == null && this.modelParamDefinitionObjects[i]['request-keys'][2]['key-name'] == null) + this.modelParamDefinitionObjects[i]['request-keys'] = null; + } + } + + //========================== End of formatKeysForFileGeneration() Method============================================ + /* Fn to restore response keys in desired format per backend consumption*/ + processResponseKeys(saveModel: any[]) { + for (var i = 0; i < saveModel.length; i++) { + if (saveModel[i]['response-keys'] != null) { + saveModel[i]['response-keys-new'] = [{}]; + saveModel[i]['response-keys-new'][0] = {};//An array of objects ?? so accessing first element + if (undefined != saveModel[i]['response-keys'][0]['key-name'] && undefined != saveModel[i]['response-keys'][0]['key-value']) { + let keyName1 = saveModel[i]['response-keys'][0]['key-name']; + saveModel[i]['response-keys-new'][0][keyName1] = saveModel[i]['response-keys'][0]['key-value']; + } + if (undefined != saveModel[i]['response-keys'][1]['key-name'] && undefined != saveModel[i]['response-keys'][1]['key-value']) { + let keyName2 = saveModel[i]['response-keys'][1]['key-name']; + saveModel[i]['response-keys-new'][0][keyName2] = saveModel[i]['response-keys'][1]['key-value']; + } + if (undefined != saveModel[i]['response-keys'][2]['key-name'] && undefined != saveModel[i]['response-keys'][2]['key-value']) { + let keyName3 = saveModel[i]['response-keys'][2]['key-name']; + saveModel[i]['response-keys-new'][0][keyName3] = saveModel[i]['response-keys'][2]['key-value']; + } + if (saveModel[i]['response-keys'][3]['key-value'] != undefined && saveModel[i]['response-keys'][3]['key-value'] != null) { + let keyName4 = saveModel[i]['response-keys'][3]['key-name']; + saveModel[i]['response-keys-new'][0]['filter-by-key'] = saveModel[i]['response-keys'][3]['key-value']; + } + if (saveModel[i]['response-keys'][4]['key-value'] != undefined && saveModel[i]['response-keys'][4]['key-value'] != null) { + let keyName4 = saveModel[i]['response-keys'][4]['key-name']; + saveModel[i]['response-keys-new'][0]['filter-by-value'] = saveModel[i]['response-keys'][4]['key-value']; + } + } + else { + saveModel[i]['response-keys-new'] = null; + } + delete saveModel[i]['response-keys']; + saveModel[i]['response-keys'] = saveModel[i]['response-keys-new']; + delete saveModel[i]['response-keys-new']; + } + return saveModel; + } + + //========================== End of processResponseKeys() Method============================================ + /*Fn to format response keys for front end display */ + formatFileContentForDisplay(fileModel: any[]) { + for (var i = 0; i < fileModel.length; i++) { + if (undefined != fileModel[i]['response-keys']) { + let testObj = fileModel[i]['response-keys']; + let keyNum = 0; + fileModel[i]['response-keys-new'] = [{}]; + for (var prop in testObj[0]) { + if (testObj[0].hasOwnProperty(prop)) { + let key = prop; + fileModel[i]['response-keys-new'][keyNum] = {}; + fileModel[i]['response-keys-new'][keyNum]['key-name'] = key; + fileModel[i]['response-keys-new'][keyNum]['key-value'] = testObj[0][key]; + } + keyNum++; + } + delete fileModel[i]['response-keys']; + fileModel[i]['response-keys'] = fileModel[i]['response-keys-new']; + delete fileModel[i]['response-keys=new']; + } + } + return fileModel; + } + + //========================== End of openModal() Method============================================ + getCorrectParameterDefinitionObject(paramName: string) { + var result = { + 'obj': {}, + 'present': false + }; + for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) { + var paramObj = this.modelParamDefinitionObjects[i]; + if (paramObj.name === paramName) { + result.obj = this.modelParamDefinitionObjects[i]; + result.present = true; + return result; + } + } + var parameterDefinitionObject = { + 'name': paramName, + 'type': null, + 'description': null, + 'required': null, + 'default': null, + 'source': null, + 'rule-type': null, + 'response-keys': [{}], + 'request-keys': [{}] + }; + result.obj = parameterDefinitionObject; + result.present = false; + return result; + } + + //========================== End of clearSessionStorageForParam() Method============================================ + isValidateSourceAndResponseKeys(objs: any[]) { + let isValid = true; + if (undefined != objs || null != objs) { + for (var i = 0; i < objs.length; i++) { + if (objs[i].source == 'INSTAR' && (null == objs[i]['response-keys'] || undefined == objs[i]['response-keys'])) { + isValid = false; + return isValid; + } + } + } + return isValid; + } + + + public prepareFileName(): any { + let fileNameObject: any = this.mappingEditorService.latestAction; + this.appDataObject = this.mappingEditorService.appDataObject; + this.downloadDataObject = this.mappingEditorService.downloadDataObject; + return fileNameObject; + } + + public destroy(displayParamObjects) { + this.displayParamObjects = displayParamObjects; + if (this.mappingEditorService.referenceNameObjects) { + this.saveChanges('send'); + this.saveChanges('download'); + this.mappingEditorService.changeNavAppData(this.appDataObject); + this.mappingEditorService.changeNavDownloadData(this.downloadDataObject); + } + } + + //========================== End of fileChangeEvent() Method============================================ + /* Saves pd file in YAML format */ + public saveChanges(downLoadOrSend: String) { + if (undefined != this.displayParamObjects && null != this.displayParamObjects && this.displayParamObjects.length > 0) { + this.paramShareService.setSessionParamData(this.displayParamObjects); + + //Generate File Name per given rules - if not, return without saving + this.modelParamDefinitionObjects = this.displayParamObjects.slice(0); + this.paramShareService.setDisplayData(this.displayParamObjects); + this.formatKeysForFileGeneration(); + //Added code to serialize, deserialize and then make changes needed to save response keys as needed in pd file + let jsonString = JSON.stringify(this.modelParamDefinitionObjects, null, '\t'); + jsonString = jsonString.replace(/"null"/g, 'null'); + let saveModel = JSON.parse(jsonString); + let pdFileObject = this.processResponseKeys(saveModel); + //Validate for Source =INSTAR and responsekeys present + if (this.isValidateSourceAndResponseKeys(pdFileObject)) { + let yamlObject = { + 'kind': 'Property Definition', + 'version': 'V1', + 'vnf-parameter-list': [] + }; + yamlObject['vnf-parameter-list'] = pdFileObject; + yamlObject = this.removeUnwantedvalues(yamlObject); + let yamlStringTemp = YAML.stringify(yamlObject, 6, 1); + var re = /\'/gi; + var newYamlStringTemp = yamlStringTemp.replace(re, '"'); + var re2 = / -\n +/gi; + var newYamlStringTemp2 = newYamlStringTemp.replace(re2, '- '); + let yamlString = '---\n' + newYamlStringTemp2; + if (downLoadOrSend === 'download') { + var blob = new Blob([yamlString], { + type: 'text/plain' + }); + //let fileName = "pd_" + this.action + "_" + this.type + "_0.0.1V.yaml" + this.downloadDataObject.pd.pdData = yamlString; + this.downloadDataObject.pd.pdFileName = this.artifact_fileName; + } + else { + this.sendPD(JSON.stringify(yamlString)); + } + } + else { + for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) { + this.formatKeys(this.modelParamDefinitionObjects[i]); + } + this.nService.error('Error', 'Response Keys cannot be empty if source is INSTAR'); + return; + } + //Restore Keys for display + for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) { + this.formatKeys(this.modelParamDefinitionObjects[i]); + } + } + + } + + + //This method will create parameter definitions as an array of objects from template name-value pairs and associative array for value from external key file if present + createOrUpdateParameterDefinitionData(usecase) { + this.parameterNameValues = JSON.parse(localStorage['paramsContent']); + this.parameterDefinitionMap = this.paramShareService.getData(); + //Return if there are no name-value pairs or send some alert notification + if (undefined != this.modelParamDefinitionObjects && this.modelParamDefinitionObjects.length > 0 && usecase == 'create') { + //Do not recreate if object is already created + return; + } + else { + } + this.parameterDefinitionMap = this.paramShareService.getData(); + //To Do:: Add Check for empty parameterDefinitionmap + var nameValueObj = {}, pName, pValue; + for (var key in this.parameterNameValues) { + if (this.parameterNameValues.hasOwnProperty(key)) { + pName = key; + pValue = this.parameterNameValues[key]; + } + + if (this.parameterDefinitionMap !== undefined) + //Check if parameter exists - if so, just update the keys, else create new object + var result = this.getCorrectParameterDefinitionObject(pName); + var parameterDefinitionObject = result.obj; + if (parameterDefinitionObject['source'] != 'A&AI' && (undefined !== this.parameterDefinitionMap) && (undefined !== this.parameterDefinitionMap[pValue.toUpperCase()])) { + var fields = this.parameterDefinitionMap[pValue.toUpperCase()].split('|'); + //Starts with 2, first vallue is source, second is rule-type + let respInd = 0; + for (var i = 2; i < fields.length; i += 2) { + parameterDefinitionObject['response-keys'][respInd] = {}; + parameterDefinitionObject['response-keys'][respInd]['key-name'] = fields[i]; + if ((i + 1) < fields.length) { + parameterDefinitionObject['response-keys'][respInd]['key-value'] = fields[i + 1]; + } + respInd++; + } + parameterDefinitionObject['source'] = fields[0]; + parameterDefinitionObject['rule-type'] = fields[1]; + } else { + if (parameterDefinitionObject['source'] === 'INSTAR') { + parameterDefinitionObject['source'] = 'Manual'; + parameterDefinitionObject['ruleTypeValues'] = [null]; + parameterDefinitionObject['rule-type'] = null; + parameterDefinitionObject['showFilterFields'] = false; + for (let x = 0; x < 5; x++) { + parameterDefinitionObject['response-keys'][x]['key-name'] = null; + parameterDefinitionObject['response-keys'][x]['key-value'] = null; + } + } + } + this.formatKeys(parameterDefinitionObject); //Ensure there are 3 elements for response-keys, request-keys for display purposes + if (!result.present) { //only push if not present + this.modelParamDefinitionObjects.push(parameterDefinitionObject); + } + } + for (var indx in this.modelParamDefinitionObjects) { + if (this.modelParamDefinitionObjects[indx] != undefined && (this.modelParamDefinitionObjects[indx].source == undefined || this.modelParamDefinitionObjects[indx].source == null || this.modelParamDefinitionObjects[indx].source == '')) { + this.modelParamDefinitionObjects[indx].source = 'Manual'; + } + } + this.displayParamObjects = this.modelParamDefinitionObjects.slice(0); + this.paramShareService.setDisplayData(this.displayParamObjects); + } + + public processKeyFile(fileName, result) { + this.myKeyFileName = fileName; + if (!this.myKeyFileName.endsWith('.txt')) { + this.nService.error('Error', 'Uploaded file is not a TXT file'); + } + this.parameterDefinitionMap = {}; + var rows = result.split(/\r\n|\r|\n/g); + for (var i = 1; i < rows.length; i++) { //Omit headings, so start from 1 + let ind = rows[i].indexOf('|'); + let key = rows[i].slice(0, ind); + let value = rows[i].slice(ind + 1); + this.parameterDefinitionMap[key.toUpperCase()] = value; + } + this.paramShareService.setData(this.parameterDefinitionMap); + //this.notificationService.notifySuccessMessage('External Key file successfully uploaded..'); + let sessionVar = [{}]; + sessionVar = this.paramShareService.getSessionParamData(); + if (sessionVar !== undefined && sessionVar != null && sessionVar.length > 0) { + if (undefined == this.displayParamObjects) + this.displayParamObjects = this.modelParamDefinitionObjects = []; + this.displayParamObjects = sessionVar; + this.modelParamDefinitionObjects = this.displayParamObjects; + if (localStorage['paramsContent'] && (undefined !== this.displayParamObjects) && (this.displayParamObjects.length > 0)) { + this.createOrUpdateParameterDefinitionData('update'); + //update the session variable with the updated data + this.paramShareService.setSessionParamData(this.displayParamObjects); + } + } else { + this.displayParamObjects = this.modelParamDefinitionObjects = []; + } + this.populateDataUponSource(this.displayParamObjects); + return this.displayParamObjects; + } + + public processPDfile(fileName, result) { + this.myPdFileName = fileName; + if (!this.myPdFileName.endsWith('.yaml')) { + this.nService.error('Error', 'Uploaded file is not a YAML file'); + } + var pdObject = YAML.parse(result); + let fileModel = pdObject['vnf-parameter-list']; + this.populatePD(fileModel); + return this.displayParamObjects; + } +}
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.css b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.css new file mode 100644 index 0000000..be35e44 --- /dev/null +++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.css @@ -0,0 +1,22 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.html b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.html new file mode 100644 index 0000000..ed0fbd3 --- /dev/null +++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.html @@ -0,0 +1,219 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ +--> + +<simple-notifications [options]="options"></simple-notifications> +<ng-progress [positionUsing]="'marginLeft'" [minimum]="0.15" [maximum]="1" [speed]="200" [showSpinner]="false" [direction]="'leftToRightIncreased'" [color]="'#6ab344'" + [trickleSpeed]="250" [thick]="true" [ease]="'linear'"></ng-progress> +<div class="card" style=" margin-bottom: 23px;"> + <img class="card-img-top" data-src="holder.js/100%x180/" alt=""> + <div class="card-block" style="border-top: 5px solid #6ab344;border-top-right-radius: 7px;border-top-left-radius: 7px;"> + <div class="row" style="padding: 15px 25px"> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Action</label> + <input class="form-control" type="text" disabled value="{{action}}" /> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Vnf Type</label><input class="form-control" type="text" disabled value="{{vnfType}}" /> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Vnfc Type</label><input class="form-control" type="text" disabled value="{{vnfcType}}" /> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Protocol</label><input class="form-control" type="text" disabled value="{{protocol}}" /> + </div> + <div *ngIf="(action === 'ConfigScaleOut')" class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>templateIdentifier</label><input class="form-control" type="text" disabled value="{{identifier}}" /> + </div> + </div> + </div> +</div> +<div class="row create-wrapper"> + <div class="col-md-12"> + <div class="row" style="padding: 5px 5px"> + <div class="col-12 mb-3"> + <div class="input-group"> + <input id="inputFile1" class="file" hidden #myInput1 type='file' (change)="fileChange(myInput1, 'pdfile')"> + <input [(ngModel)]="myPdFileName" type="text" class="input-lg" disabled placeholder="Upload parameters from PC" style="width:85%;"> + <button [disabled]="(undefined == mappingEditorService.latestAction)" (click)="browsePdFile($event)" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg" + type="button"> UPLOAD PD FILE + </button> + </div> + </div> + <div class="col-12"> + <div class="input-group"> + <input id="inputFile2" class="file" hidden #myInput2 type='file' (change)="fileChange(myInput2, 'keyfile')"> + <input [(ngModel)]="myKeyFileName" type="text" class="input-lg" disabled placeholder="Upload key file from PC. You can upload a key file only if you have some parameters." + style="width:85%;"> + <button [disabled]="(!(undefined !== displayParamObjects && displayParamObjects.length>0))" (click)="browseKeyFile($event)" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg" + type="button">UPLOAD KEY FILE + </button> + </div> + </div> + </div> + </div> + <br> + <hr> + <!--h4>testing{{initialData}}</h4--> + <div *ngIf="((undefined !== displayParamObjects && displayParamObjects.length>0) ) " class="col-md-12 "> + <form *ngIf="undefined !== displayParamObjects" class="form-inline" novalidate #paramForm="ngForm" (ngSubmit)="saveChanges('download', paramForm.valid)"> + + <div style="height: 210px; overflow: auto;"> + <table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp"> + <thead> + <tr> + <th class="mdl-data-table__cell--non-numeric">NAME</th> + <th class="mdl-data-table__cell--non-numeric">DESCRIPTION</th> + <th class="mdl-data-table__cell--non-numeric">TYPE</th> + <th class="mdl-data-table__cell--non-numeric">REQUIRED</th> + <th class="mdl-data-table__cell--non-numeric">DEFAULT</th> + <th class="mdl-data-table__cell--non-numeric">SOURCE</th> + <th class="mdl-data-table__cell--non-numeric">RULETYPE</th> + <th class="mdl-data-table__cell--non-numeric">FILTER BY FIELD</th> + <th class="mdl-data-table__cell--non-numeric">FILTER BY VALUE</th> + <th class="mdl-data-table__cell--non-numeric">RESPKEY NAME</th> + <th class="mdl-data-table__cell--non-numeric">RESPKEY VALUE</th> + <th class="mdl-data-table__cell--non-numeric">RESPKEY NAME</th> + <th class="mdl-data-table__cell--non-numeric">RESPKEY VALUE</th> + <th class="mdl-data-table__cell--non-numeric">RESPKEY NAME</th> + <th class="mdl-data-table__cell--non-numeric">RESPKEY VALUE</th> + <th class="mdl-data-table__cell--non-numeric">REQKEY NAME</th> + <th class="mdl-data-table__cell--non-numeric">REQKEY VALUE</th> + <th class="mdl-data-table__cell--non-numeric">REQKEY NAME</th> + <th class="mdl-data-table__cell--non-numeric">REQKEY VALUE</th> + <th class="mdl-data-table__cell--non-numeric">REQKEY NAME</th> + <th class="mdl-data-table__cell--non-numeric">REQKEY VALUE</th> + </tr> + </thead> + <tbody> + <tr *ngFor="let obj of displayParamObjects; let i = index"> + <td class="mdl-data-table__cell--non-numeric"> + <input required id="id1" [(ngModel)]="obj.name" #objName="ngModel" name="objName{{i}}" style="width:300px"> + <span class="error-message" [hidden]="objName.valid || (objName.pristine && !paramForm.submitted)">Required Field</span> + </td> + <td class="mdl-data-table__cell--non-numeric"><input [(ngModel)]="obj.description" #objDesc="ngModel" name="objDesc{{i}}"> + </td> + <td class="mdl-data-table__cell--non-numeric"> + <select id="id3" [(ngModel)]="obj.type" name="{{'objType'+i}}"> + <option *ngFor="let typ of typeValues" + [value]="typ" + [selected]="obj.type === typ" + > + {{typ}} + </option> + </select> + </td> + <td class="mdl-data-table__cell--non-numeric"> + <select [(ngModel)]="obj.required" #objRequired="ngModel" name="{{'objRequired'+i}}"> + <option *ngFor="let req of requiredValues" + [value]="req" + [selected]="req === obj.required" + > + {{req}} + </option> + </select> + </td> + <td class="mdl-data-table__cell--non-numeric"><input id="id1" [(ngModel)]="obj.default" #objDefault="ngModel" name="objDefault{{i}}"></td> + <td class="mdl-data-table__cell--non-numeric"> + <select class="form-control" required id="id3" [(ngModel)]="obj.source" #objSource="ngModel" (ngModelChange)="sourceChanged($event,obj)" name="{{'objSource'+i}}"> + <option *ngFor="let src of sourceValues" + [value]="src" + [selected]="src === obj.source" + [disabled]="src === 'INSTAR'"> + {{src}} + </option> + + </select> + <span class="error-message" [hidden]="objSource.valid || (objSource.pristine && !paramForm.submitted)">Required Field</span> + </td> + + <td class="mdl-data-table__cell--non-numeric"> + <select (ngModelChange)="ruleTypeChanged($event,obj)" class="form-control" id="id4" [(ngModel)]="obj['rule-type']" #objRuleType="ngModel" name="objRuleType{{i}}" + list="ruleTypes"> + <option *ngFor="let rTyp of obj.ruleTypeValues;" [value]="rTyp" + [selected]="rTyp === obj.rule-type"> + {{rTyp}} + </option> + </select> + </td> + + <td> + <select *ngIf="obj.showFilterFields" (ngModelChange)="filetrByFieldChanged($event,obj)" class="form-control" id="id4" [(ngModel)]="obj['response-keys'][3]['key-value']" + #objfilterByField="ngModel" name="filterByField{{i}}" list="ruleTypes"> + <option *ngFor="let fTyp of filterByFieldvalues;" [value]="fTyp" + [selected]="fTyp === obj['response-keys'][3]['key-value']"> + {{fTyp}} + </option> + </select> + </td> + <td> + <input *ngIf="obj.showFilterFields" [disabled]="!(obj.enableFilterByValue)" type="text" [value]="obj['response-keys'][4]['key-value']" class="form-control" + id="id4" [(ngModel)]="obj['response-keys'][4]['key-value']" #objfilterByValue="ngModel" name="objfilterByValue{{i}}" list="ruleTypes"> + </td> + + <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][0]['key-name']}} + + </td> + <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][0]['key-value']}} + + </td> + <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][1]['key-name']}} + + </td> + <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][1]['key-value']}} + + </td> + <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][2]['key-name']}} + + </td> + <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][2]['key-value']}} + + </td> + + <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][0]['key-name']}} + + </td> + <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][0]['key-value']}} + + </td> + <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][1]['key-name']}} + + </td> + <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][1]['key-value']}} + + </td> + <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][2]['key-name']}} + + </td> + <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][2]['key-value']}} + + </td> + </tr> + </tbody> + </table> + ` + </div> + + </form> + </div> +</div>
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.spec.ts b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.spec.ts new file mode 100644 index 0000000..2668f2b --- /dev/null +++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.spec.ts @@ -0,0 +1,197 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed, inject} from '@angular/core/testing'; +import {NO_ERRORS_SCHEMA} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {NotificationService} from '../../../shared/services/notification.service'; +import {ParamShareService} from '../../../shared/services/paramShare.service'; +import {MappingEditorService} from '../../../shared/services/mapping-editor.service'; +import {ModalComponent} from '../../../shared/modal/modal.component'; +import {DialogService} from 'ng2-bootstrap-modal'; +import {ConfirmComponent} from '../../../shared/confirmModal/confirm.component'; +import {RouterTestingModule} from '@angular/router/testing'; +import {HttpUtilService} from '../../../shared/services/httpUtil/http-util.service'; +import {UtilityService} from '../../../shared/services/utilityService/utility.service'; + +import {BuildDesignComponent} from '../build-artifacts.component'; +import {NotificationsService} from 'angular2-notifications'; +import {HomeComponent} from '../../../home/home/home.component'; +import {LogoutComponent} from '../../../shared/components/logout/logout.component'; +import {HelpComponent} from '../../../shared/components/help/help/help.component'; +import {AboutUsComponent} from '../../../about-us/aboutus.component'; +import {TestComponent} from '../../../test/test.component'; +import {ParameterComponent} from './parameter.component'; +import {HttpModule} from '@angular/http'; +import { NgProgress } from 'ngx-progressbar'; + + + +describe('ParameterComponent', () => { + let component: ParameterComponent; + let fixture: ComponentFixture<ParameterComponent>; + const routes = [ + { + path: 'home', + component: HomeComponent + }, { + path: 'vnfs', + loadChildren: './vnfs/vnfs.module#VnfsModule' + }, { + path: 'test', + component: TestComponent + }, + { + path: 'help', + component: HelpComponent + }, { + path: 'aboutUs', + component: AboutUsComponent + }, { + path: 'logout', + component: LogoutComponent + }, { + path: '', + redirectTo: '/home', + pathMatch: 'full' + } + ]; + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ParameterComponent, HomeComponent, TestComponent, HelpComponent, AboutUsComponent, LogoutComponent], + schemas: [NO_ERRORS_SCHEMA], + imports: [HttpModule, FormsModule, RouterTestingModule.withRoutes(routes)], + providers: [UtilityService, NgProgress, BuildDesignComponent, ParamShareService, DialogService, NotificationService, HttpUtilService, MappingEditorService, NotificationsService] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ParameterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + + it('should retrieve PD from APPC...', () => { + expect(component.getPD()); + }); + + it('should infer some information from reference object...', inject([MappingEditorService], (mappingEditorService: MappingEditorService) => { + mappingEditorService.latestAction = {"action":"Configure","action-level":"vnf","scope":{"vnf-type":"ticktack","vnfc-type":""},"template":"Y","vm":[],"device-protocol":"CHEF","user-name":"","port-number":"","artifact-list":[{"artifact-name":"template_Configure_ticktack_0.0.1V.json","artifact-type":"config_template"},{"artifact-name":"pd_Configure_ticktack_0.0.1V.yaml","artifact-type":"parameter_definitions"}],"scopeType":"vnf-type"}; + expect(component.ngOnInit()); + expect(component.vnfType).toEqual('ticktack'); + expect(component.vnfcType).toEqual(''); + expect(component.protocol).toEqual('CHEF'); + expect(component.action).toEqual('Configure'); + expect(component.artifact_fileName).toEqual('pd_Configure_ticktack_0.0.1V.yaml'); + })); + + + it('should retrieve the PD from cache...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => { + mappingEditorService.latestAction = {"action":"Configure","action-level":"vnf","scope":{"vnf-type":"ticktack","vnfc-type":""},"template":"Y","vm":[],"device-protocol":"CHEF","user-name":"","port-number":"","artifact-list":[{"artifact-name":"template_Configure_ticktack_0.0.1V.json","artifact-type":"config_template"},{"artifact-name":"pd_Configure_ticktack_0.0.1V.yaml","artifact-type":"parameter_definitions"}],"scopeType":"vnf-type"}; + paramShareService.setSessionParamData("TEST PD INFORMATION") + expect(component.ngAfterViewInit()).toEqual("TEST PD INFORMATION"); + })); + +/* + it('should read file key file content...', () => { + let input = {"__zone_symbol__changefalse":[{"type":"eventTask","state":"running","source":"HTMLInputElement.addEventListener:change","zone":"angular","runCount":2}]}; + expect(component.fileChange(input, 'keyfile')); + }); + +let content = new Blob(["PARAMVALUE|SOURCE|RULETYPE|KEY1|VALUE1|KEY2|VALUE2|KEY3|VALUE3\nvalue1|INSTAR|interface_ip_address|UniqueKeyName1|addressfqdn123|UniqueKeyValue|m001ssc001p1n001v001|FieldKeyName|ipaddress_v4\nvalue2|INSTAR|interface_ip_address|UniqueKeyName2|addressfqdnAsgar1|UniqueKeyValue|m001ssc001p1n001v002|FieldKeyName|ipaddress_v4"] +{includes:()}); +let file = new File(content, "test.txt"); + it('should read file PD file content...', () => { + let input = {"__zone_symbol__changefalse":[{"type":"eventTask","state":"running","source":"HTMLInputElement.addEventListener:change","zone":"angular","runCount":2}]}; + + expect(component.fileChange(input, 'pdfile')); + }); + */ + + it('should set the ruletypes for source A&AI...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => { + let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]} + let data = "A&AI"; + expect(component.sourceChanged(data, obj)); + expect(obj.ruleTypeValues).toEqual([null, 'vnf-name', 'vm-name-list', 'vnfc-name-list', 'vnf-oam-ipv4-address', 'vnfc-oam-ipv4-address-list']); + })); + + it('should set the ruletypes for source Manual...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => { + let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]} + let data = "Manual"; + expect(component.sourceChanged(data, obj)); + expect(obj.ruleTypeValues).toEqual([null]); + expect(obj['rule-type']).toBeNull(); + })); + + it('should set the ruletypes for source INSTAR...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => { + let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]} + let data = "INSTAR"; + expect(component.sourceChanged(data, obj)); + expect(obj.ruleTypeValues).toEqual([null]); + })); + + it('should set the ruletypes for ruletype null...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => { + let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]} + let data = null + expect(component.ruleTypeChanged(data, obj)); + expect(obj['showFilterFields']).toBeFalsy(); + expect(obj['rule-type']).toBeNull(); + })); + + it('should set the ruletypes for ruletype vm-name-list...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => { + let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]} + let data = 'vm-name-list'; + let sourceObject = component.ruleTypeConfiguaration[data]; + + expect(component.ruleTypeChanged(data, obj)); + expect(obj['showFilterFields']).toBeTruthy(); + expect(obj['rule-type']).toBeNull(); + + for (let x = 0; x < sourceObject.length; x++) { + expect(obj['response-keys'][x]['key-name']).toEqual(sourceObject[x]['key-name']); + expect(obj['response-keys'][x]['key-value']).toEqual(sourceObject[x]['key-value']); + } + })); + + + it('should set the ruletypes for ruletype vnf-name...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => { + let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]} + let data = "vnf-name"; + expect(component.ruleTypeChanged(data, obj)); + expect(obj['showFilterFields']).toBeFalsy(); + expect(obj['response-keys'][3]['key-name']).toBeNull; + expect(obj['response-keys'][3]['key-value']).toBeNull; + expect(obj['response-keys'][4]['key-name']).toBeNull; + expect(obj['response-keys'][4]['key-value']).toBeNull; + })); + + + +}); diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.ts b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.ts new file mode 100644 index 0000000..2732473 --- /dev/null +++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.ts @@ -0,0 +1,430 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import { Component, OnInit, ViewChild } from '@angular/core'; +import { saveAs } from 'file-saver'; +import { ParamShareService } from '../../../shared/services/paramShare.service'; +import { MappingEditorService } from '../../../shared/services/mapping-editor.service'; +import { ModalComponent } from '../../../shared/modal/modal.component'; +import { HttpUtilService } from '../../../shared/services/httpUtil/http-util.service'; +import { UtilityService } from '../../../shared/services/utilityService/utility.service'; +import { environment } from '../../../../environments/environment'; +import { NotificationsService } from 'angular2-notifications'; +import { ParameterDefinitionService } from './parameter-definition.service'; +import 'rxjs/add/operator/map'; +import { NgProgress } from 'ngx-progressbar'; + + +let YAML = require('yamljs'); + +declare var $: any; + +@Component({ + selector: 'parameter-form', + templateUrl: './parameter.component.html', + styleUrls: ['../reference-dataform/reference-dataform.component.css'], + providers: [ParameterDefinitionService] +}) +export class ParameterComponent implements OnInit { + public paramForm: any; + public actionType: any; + public showFilterFields: boolean; + public filterByFieldvalues = [null, 'vm-number', 'vnfc-function-code']; + public ruleTypeConfiguaration = { + 'vnf-name': [ + { + 'key-name': 'unique-key-name', + 'key-value': 'parent-name' + }, + { + 'key-name': 'unique-key-value', + 'key-value': 'vnf' + }, + { + 'key-name': 'field-key-name', + 'key-value': 'vnf-name' + } + ], + 'vm-name-list': [ + { + 'key-name': 'unique-key-name', + 'key-value': 'parent-name' + }, + { + 'key-name': 'unique-key-value', + 'key-value': 'vserver' + }, + { + 'key-name': 'field-key-name', + 'key-value': 'vserver-name' + } + ], + 'vnfc-name-list': [ + { + 'key-name': 'unique-key-name', + 'key-value': 'parent-name' + }, + { + 'key-name': 'unique-key-value', + 'key-value': 'vnfc' + }, + { + 'key-name': 'field-key-name', + 'key-value': 'vnfc-name' + } + ], + 'vnf-oam-ipv4-address': [ + { + 'key-name': 'unique-key-name', + 'key-value': 'parent-name' + }, + { + 'key-name': 'unique-key-value', + 'key-value': 'vnf' + }, + { + 'key-name': 'field-key-name', + 'key-value': 'ipv4-oam-ipaddress' + } + ], + 'vnfc-oam-ipv4-address-list': [ + { + 'key-name': 'unique-key-name', + 'key-value': 'parent-name' + }, + { + 'key-name': 'unique-key-value', + 'key-value': 'vnfc' + }, + { + 'key-name': 'field-key-name', + 'key-value': 'ipaddress-v4-oam-vip' + } + ] + }; + public requiredValues: boolean[] = [null, true, false]; + public sourceValues = ['Manual', 'INSTAR', 'A&AI']; + public ruleTypeValues = [null, 'vnf-name', 'vm-name-list', 'vnfc-name-list', 'vnf-oam-ipv4-address', 'vnfc-oam-ipv4-address-list']; + public typeValues = [null, 'ipv4-address', 'ipv6-address', 'ipv4-prefix', 'ipv6-prefix']; + public responseKeyNameValues = ['', 'unique-key-name', 'unique-key-value', 'field-key-name']; + public responseKeyValues = ['(none)', 'addressfqdn', 'ipaddress-v4', 'ipaddress-v6']; + public requestKeyNameValues = ['']; + public requestKeyValues = ['', '(none)']; + public myKeyFileName = null; + public myPdFileName = null; + public disposable: any; + public confirmation: boolean; + public showConfirmation: boolean; + public test: boolean; + apiToken = localStorage['apiToken']; + userId = localStorage['userId']; + public initialData: any; + public intialData: any; + public initialAction: any; + public item: any = {}; + public subscription: any; + public Actions = [ + { action: 'ConfigBackup', value: 'ConfigBackup' }, + { action: 'ConfigModify', value: 'ConfigModify' }, + { action: 'ConfigRestore', value: 'ConfigRestore' }, + { action: 'Configure', value: 'Configure' }, + { action: 'GetRunningConfig', value: 'GetRunningConfig' }, + { action: 'HealthCheck', value: 'HealthCheck' }, + { action: 'StartApplication', value: 'StartApplication' }, + { action: 'StopApplication', value: 'StopApplication' } + ]; + public uploadTypes = [{ + value: 'External Key File', + display: 'KeyFile' + }, + { + value: 'Pd File', + display: 'Pd File' + } + ]; + + options = { + timeOut: 1000, + showProgressBar: true, + pauseOnHover: true, + clickToClose: true, + maxLength: 200 + }; + public vnfcTypeData: string = ''; + public selectedUploadType: string; + @ViewChild(ModalComponent) modalComponent: ModalComponent; + public title: string; + public parameterDefinitionMap: { [index: string]: string; } = {}; + public parameterNameValues = {}; + public displayParamObjects; + public modelParamDefinitionObjects; + public vnfType: any; + vnfcType: any; + protocol: any; + public refNameObj = {}; + public action; + public artifactName; + public appDataObject: any; + public downloadDataObject: any; + public artifact_fileName; + identifier: any; + private selectedActionReference: any; + + //this.mappingeditorservice.referenceNameObjects = object;PLEASE USE THIS OBJECT TO GET TEMPALLDATA + + constructor (private httpService: HttpUtilService, + private parameterDefinitionService: ParameterDefinitionService, + private paramShareService: ParamShareService, + private mappingEditorService: MappingEditorService, + private httpUtil: HttpUtilService, + private utilService: UtilityService, + private nService: NotificationsService, + private ngProgress: NgProgress) { + } + + ngOnInit() { + this.selectedActionReference = this.parameterDefinitionService.prepareFileName(); + if (this.selectedActionReference && this.selectedActionReference != undefined) { + + this.vnfType = this.selectedActionReference.scope['vnf-type']; + this.vnfcType = this.selectedActionReference.scope['vnfc-type']; + this.protocol = this.selectedActionReference['device-protocol']; + this.action = this.selectedActionReference.action; + + for (let i = 0; i < this.selectedActionReference['artifact-list'].length; i++) { + let artifactList = this.selectedActionReference['artifact-list']; + if (artifactList[i]['artifact-type'] === 'parameter_definitions') { + this.artifact_fileName = artifactList[i]['artifact-name']; + } + } + this.parameterDefinitionService.setValues(this.vnfType, this.vnfcType, this.protocol, this.action, this.artifact_fileName); + } + else { + this.selectedActionReference = { + 'action': '', + 'scope': { 'vnf-type': '', 'vnfc-type': '' }, + 'vm': [], + 'protocol': '', + 'download-dg-reference': '', + 'user-name': '', + 'port-number': '', + 'artifact-list': [], + 'deviceTemplate': '', + 'scopeType': '' + }; + } + + //let path = this.location.path + /* this.activeRoutes.url.subscribe(UrlSegment => { + this.actionType = UrlSegment[0].path + }) + */ + this.identifier = this.mappingEditorService.identifier; + } + + ngAfterViewInit() { + if (this.mappingEditorService.latestAction) { + this.displayParamObjects = []; + this.modelParamDefinitionObjects = []; + if (this.paramShareService.getSessionParamData() != undefined && this.paramShareService.getSessionParamData().length > 0) { + this.displayParamObjects = this.paramShareService.getSessionParamData(); + } else { + this.getPD(); + } + } else { + this.nService.error('Error', 'Please enter Action and VNF type in Reference Data screen'); + } + return this.displayParamObjects; + } + + + public getPD() { + let result: any; + let input = { + 'input': { + 'design-request': { + 'request-id': this.apiToken, + 'action': 'getArtifact', + 'payload': '{"userID": "' + this.userId + '", "vnf-type" : "' + this.vnfType + '", "artifact-type":"APPC-CONFIG", "artifact-name":"' + this.artifact_fileName + '"}' + } + } + }; + let artifactContent: any; + this.ngProgress.start(); + return this.httpService.post({ + url: environment.getDesigns, + data: input + }).subscribe(data => { + if (this.utilService.checkResult(data)) { + let result: any = JSON.parse(data.output.data.block).artifactInfo[0]; + var pdObject = YAML.parse(result['artifact-content']); + let fileModel = pdObject['vnf-parameter-list']; + this.displayParamObjects = this.parameterDefinitionService.populatePD(fileModel); + } + else { + + } + this.ngProgress.done(); + }, + + error => this.nService.error('Error', 'Error in connecting APPC Server')); + + } + + //========================== End of NGInit() Method============================================ + selectedNavItem(item: any) { + this.item = item; + } + + //========================== End of selectedNavItem() Method============================================ + browsePdFile() { + $('#inputFile1').trigger('click'); + } + + //========================== End of browsePdFile() Method============================================ + browseKeyFile() { + $('#inputFile2').trigger('click'); + + } + + //========================== End of browseKeyFile() Method============================================ + + + //========================== End of appendSlashes() Method============================================ + + + //========================== End of prepareFileName() Method============================================ + ngOnDestroy() { + this.parameterDefinitionService.destroy(this.displayParamObjects); + } + + //========================== End of ngOnDestroy() Method============================================ + + //========================== End of createOrUpdateParameterDefinitionData() Method============================================ + public showUpload() { + this.selectedUploadType = this.uploadTypes[0].value; + }; + + //========================== End of showUpload() Method============================================ + //This is called when the user selects new files from the upload button + public fileChange(input, uploadType) { + if (input.files && input.files[0]) { + // Create the file reader + let reader = new FileReader(); + this.readFile(input.files[0], reader, (result) => { + if ('keyfile' === uploadType) { + this.myKeyFileName = input.files[0].name; + this.displayParamObjects = this.parameterDefinitionService.processKeyFile(this.myKeyFileName, result); + } + if ('pdfile' === uploadType) { + this.myPdFileName = input.files[0].name; + this.displayParamObjects = this.parameterDefinitionService.processPDfile(this.myPdFileName, result); + } + }); + } else { + //this.notificationService.notifyErrorMessage('Failed to read file!Please try again.'); + } + } + + //========================== End of fileChange() Method============================================ + public readFile(file, reader, callback) { + // Set a callback funtion to fire after the file is fully loaded + reader.onload = () => { + // callback with the results + callback(reader.result); + }; + //this.notificationService.notifySuccessMessage('Uploading File ' + file.name + ':' + file.type + ':' + file.size); + // Read the file + reader.readAsText(file, 'UTF-8'); + } + + //========================== End of readFile() Method============================================ + fileChangeEvent(fileInput: any) { + let obj: any = fileInput.target.files; + } + + + sourceChanged(data, obj) { + if (data == 'A&AI') { + obj.ruleTypeValues = [null, 'vnf-name', 'vm-name-list', 'vnfc-name-list', 'vnf-oam-ipv4-address', 'vnfc-oam-ipv4-address-list']; + for (let x = 0; x < 5; x++) { + obj['response-keys'][x]['key-name'] = null; + obj['response-keys'][x]['key-value'] = null; + } + } else if (data == 'Manual') { + obj.ruleTypeValues = [null]; + obj['rule-type'] = null; + obj.showFilterFields = false; + for (let x = 0; x < 5; x++) { + obj['response-keys'][x]['key-name'] = null; + obj['response-keys'][x]['key-value'] = null; + } + } + else { + obj.ruleTypeValues = [null]; + } + } + + //========================== End of sourceChanged() Method============================================ + ruleTypeChanged(data, obj) { + if (data == null || data == undefined || data == 'null') { + obj.showFilterFields = false; + obj['rule-type'] = null; + for (let x = 0; x < 5; x++) { + obj['response-keys'][x]['key-name'] = null; + obj['response-keys'][x]['key-value'] = null; + } + } else { + let sourceObject = this.ruleTypeConfiguaration[data]; + if (data == 'vm-name-list' || data == 'vnfc-name-list' || data == 'vnfc-oam-ipv4-address-list') { + this.showFilterFields = false; + obj.showFilterFields = true; + this.filetrByFieldChanged(obj['response-keys'][3]['key-value'], obj); + } else { + obj.showFilterFields = false; + obj['response-keys'][3]['key-name'] = null; + obj['response-keys'][3]['key-value'] = null; + obj['response-keys'][4]['key-name'] = null; + obj['response-keys'][4]['key-value'] = null; + } + for (let x = 0; x < sourceObject.length; x++) { + obj['response-keys'][x]['key-name'] = sourceObject[x]['key-name']; + obj['response-keys'][x]['key-value'] = sourceObject[x]['key-value']; + } + } + + } + + //========================== End of ruleTypeChanged() Method============================================ + filetrByFieldChanged(data, obj) { + if (data == null || data == undefined || data == 'null') { + obj.enableFilterByValue = false; + obj['response-keys'][4]['key-value'] = null; + } else { + obj.enableFilterByValue = true; + } + + } + + +}
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.css b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.css new file mode 100644 index 0000000..7c075eb --- /dev/null +++ b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.css @@ -0,0 +1,22 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.html b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.html new file mode 100644 index 0000000..6668ed1 --- /dev/null +++ b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.html @@ -0,0 +1,24 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<router-outlet></router-outlet>
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.spec.ts b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.spec.ts new file mode 100644 index 0000000..2ab9fd8 --- /dev/null +++ b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.spec.ts @@ -0,0 +1,49 @@ +/** + ============LICENSE_START========================================== + =================================================================== + Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + =================================================================== + + Unless otherwise specified, all software contained herein is licensed + under the Apache License, Version 2.0 (the License); + you may not use this software 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. + + ECOMP is a trademark and service mark of AT&T Intellectual Property. + ============LICENSE_END============================================ + */ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {ParameterHolderComponent} from './parameter-holder.component'; + +describe('ParameterHolderComponent', () => { + let component: ParameterHolderComponent; + let fixture: ComponentFixture<ParameterHolderComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ParameterHolderComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ParameterHolderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.ts b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.ts new file mode 100644 index 0000000..73c9aa1 --- /dev/null +++ b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.ts @@ -0,0 +1,39 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-parameter-holder', + templateUrl: './parameter-holder.component.html', + styleUrls: ['./parameter-holder.component.css'] +}) +export class ParameterHolderComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.css b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.css new file mode 100644 index 0000000..9d63aa1 --- /dev/null +++ b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.css @@ -0,0 +1,21 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.html b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.html new file mode 100644 index 0000000..2dc338f --- /dev/null +++ b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.html @@ -0,0 +1,22 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ --> +<router-outlet></router-outlet>
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.spec.ts b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.spec.ts new file mode 100644 index 0000000..ffada5d --- /dev/null +++ b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.spec.ts @@ -0,0 +1,48 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {ReferenceDataHolderComponent} from './reference-data-holder.component'; + +describe('ReferenceDataHolderComponent', () => { + let component: ReferenceDataHolderComponent; + let fixture: ComponentFixture<ReferenceDataHolderComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ReferenceDataHolderComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ReferenceDataHolderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.ts b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.ts new file mode 100644 index 0000000..878b4dd --- /dev/null +++ b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.ts @@ -0,0 +1,37 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-reference-data-holder', + templateUrl: './reference-data-holder.component.html', + styleUrls: ['./reference-data-holder.component.css'] +}) +export class ReferenceDataHolderComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.css b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.css new file mode 100644 index 0000000..1b4c470 --- /dev/null +++ b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.css @@ -0,0 +1,137 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +.form-group { + padding: 5px +} + +.panel { + margin-top: 20px; +} + +.form-control { + width: 100%; +} + +.panel-header { + padding: 20px 0px; +} + +.container { + border-radius: 0.375rem; + transition: all 0.3s ease; + padding: 40px; +} + +.container2 { + box-shadow: -4px 14px 20px 0px rgba(46, 61, 73, 0.15); + border-radius: 0.375rem; + transition: all 0.3s ease; + padding: 10px; + margin-top: 57px; +} + +.error-message { + color: red; +} + +.create-wrapper { + text-align: left; +} + +.removevnfcClass { + text-align: right; +} + +.form-custom-group { + margin-bottom: 0; + vertical-align: middle; +} + +.side-by-side { + position: relative; +} + +.sidebtn { + position: absolute; + left: 26.5em; + top: 0em; +} + +.clear-control { + margin: 40px 20px; + display: inherit; +} + +.short-column { + width: 100px; +} + +.long-column { + width: 200px; +} + +th, +td { + min-width: 150px; +} + +.headlinesInBold { + font-weight: bold; +} + +.titleCustom { + padding-left: 25px; + overflow: visible; +} + +.anchorHover { + cursor: pointer; +} + +.custom-btn { + margin-top: 20px; + margin-bottom: 10px; +} + +.clear-btn { + margin-top: 23px; +} + +.col-md-button { + margin: auto; + margin-right: 20px; + text-align: center; + margin-bottom: 15px; +} + +.selectedAction { + /* change here */ + font-weight: bold; + color: #1A86E4 +} + +.file { + visibility: hidden; + position: absolute; +}
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.html b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.html new file mode 100644 index 0000000..d38620a --- /dev/null +++ b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.html @@ -0,0 +1,354 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<simple-notifications [options]="options"></simple-notifications> +<ng-progress [positionUsing]="'marginLeft'" [minimum]="0.15" [maximum]="1" [speed]="200" [showSpinner]="false" [direction]="'leftToRightIncreased'" [color]="'#6ab344'" + [trickleSpeed]="250" [thick]="true" [ease]="'linear'"></ng-progress> +<form class="" novalidate #userForm="ngForm" (ngSubmit)="save(userForm.value,userForm.valid)"> + <div class="card"> + + <div class="card-block" style=" border-top: 5px solid #6ab344; border-top-right-radius: 7px;border-top-left-radius: 7px;"> + <div class="row" style="padding: 15px 25px"> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Action*</label> + <select class="form-control" required id="cmbAction" [(ngModel)]="referenceDataObject.action" (ngModelChange)="updateSessionValues($event,'action');actionChange($event,content,userForm);" + #action="ngModel" name="action"> + <option [value]="actionType" + [ngClass]="{'selectedAction':selectedActions.indexOf(actionType)>-1}" + [selected]="referenceDataObject.action===actionType" + *ngFor="let actionType of actions ">{{actionType}} + </option> + </select> + + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>VNF Type* </label> + <input type="text" [readonly]="updateParams !='undefined' || vnfParams?.vnfType " class="form-control" id="txtVnfType" required [(ngModel)]="referenceDataObject['scope']['vnf-type']" + (ngModelChange)="updateSessionValues($event,'vnfType')" #vnftype="ngModel" name="vnftype"> + <span class="error-message" [hidden]="vnfParams?.vnfType || vnftype.valid || (vnftype.pristine && !userForm.submitted)">Required Field</span> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>VNFC Type</label> + <input type="text" class="form-control" [disabled]="nonConfigureAction || updateParams !='undefined' || vnfParams?.vnfType" id="txtVnfcType" [(ngModel)]="referenceDataObject.scope['vnfc-type']" + (blur)="setVnfcType($event.target.value)" (ngModelChange)="updateSessionValues($event,'vnfcType')" #vnfcType="ngModel" name="vnfcType" + disabled="disabled"> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Device Protocol*</label> + <select class="form-control" required id="txtDeviceProtocol" [(ngModel)]="referenceDataObject['device-protocol']" #deviceProtocol="ngModel" name="deviceProtocol"> + <option [value]="device" [selected]="referenceDataObject.deviceProtocol===device" + *ngFor="let device of deviceProtocols">{{device}} + </option> + </select> + + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12" *ngIf="referenceDataObject['action']== 'ConfigScaleOut'"> + <label>Template Identifier</label> + <select class="form-control" required id="tempIdentifier" (ngModelChange)="dataModified()" [(ngModel)]="templateIdentifier" #deviceProtocol="ngModel" name="templateIdentifier"> + <option [value]="val" *ngFor="let val of referenceDataObject['template-id-list']">{{val}} + </option> + </select> + <span class="error-message" [hidden]="deviceProtocol.valid || (deviceProtocol.pristine && !userForm.submitted)">Required Field</span> + </div> + + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12" *ngIf="referenceDataObject['action']== 'ConfigScaleOut'" style="margin-top: 30px"> + <span *ngIf="referenceDataObject.action === 'ConfigScaleOut'"> <a style=" color: blue;" + href="javascript:void(0)" + (click)="showIdentifier()">Assign New Template Identifier</a></span> + + </div> + </div> + <div class="col-12" *ngIf="!(referenceDataObject.action === 'OpenStack Actions')"> + <div class="input-group"> + <input id="inputFile" class="file" #myInput type='file' (change)="fileChange($event)"> + <input [(ngModel)]="fileName" type="text" class="input-lg" disabled placeholder="Upload Reference File from PC" name="browse" style="width:80%"> + <button (click)="browseOption($event)" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg" type="button">Upload Reference File + </button> + </div> + </div> + <div class="col-12" *ngIf="referenceDataObject.action === 'OpenStack Actions'"> + <div class="input-group"> + <input id="excelInputFile" #myInput1 class="file" type="file" (change)="upload($event)"> + <input [(ngModel)]="uploadFileName" type="text" class="input-lg" disabled placeholder="Upload VM Capabilities File" name="uploadFileName" style="width:80%"> + <button (click)="excelBrowseOption($event)" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg" + type="button">Upload VM Capabilities File + </button> + </div> + </div> + </div> + <div class="card-block" style="padding: 10px"> + <div> + <div class="create-wrapper" style="padding: 0px 25px"> + <div class="row" style="margin-bottom: 30px"> + <div class=" col-6"> + + </div> + <div class="text-right col-6"> + <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" type="submit">Download All To PC + </button>   + <button id="saveToAppc" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" type="button" (click)="saveToAppc(userForm.valid, userForm)">Save All to APPC + </button>   + </div> + </div> + <div class="row"> + <div class="col-12"> + <div class="row" *ngIf="!(referenceDataObject.action === 'OpenStack Actions')"> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label>Template</label> + <select class="form-control" id="txtDeviceProtocol" [(ngModel)]="referenceDataObject['template']" #template="ngModel" name="template"> + <option [value]="template" *ngFor="let template of deviceTemplates"> + {{template}} + </option> + </select> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label>User Name</label> + <input type="text" class="form-control" id="txtIpaddress" [(ngModel)]="referenceDataObject['user-name']" name="loginUserName"> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label>Port Number</label> + <input type="text" class="form-control" id="txtIpaddress" [(ngModel)]="referenceDataObject['port-number']" name="portNumber"> + </div> + <div *ngIf="actionHealthCheck && referenceDataObject['device-protocol'] =='REST' " class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Context Url</label> + <input type="text" class="form-control" id="txtIpaddress" [(ngModel)]="referenceDataObject['context-url']" name="portNumber"> + </div> + </div> + <div class="card-block" *ngIf="(referenceDataObject.action =='ConfigScaleOut' || referenceDataObject.action =='Configure'|| referenceDataObject.action =='' || referenceDataObject.action ==undefined)" + style="border-top: 5px solid #6ab344;border-top-right-radius: 7px;border-top-left-radius: 7px;"> + <div class="col-12"> + <h5 style="margin-top: 0.5rem;font-family: Roboto"> VNFC Information + <span class="pull-right"> + <i (click)="isCollapsedContent = !isCollapsedContent" + [ngClass]="{'fa-minus-circle':isCollapsedContent,'fa-plus-circle':!isCollapsedContent}" + class="fa" aria-hidden="true"></i> + </span> + </h5> + </div> + </div> + <div class="row" *ngIf="(( referenceDataObject.action =='ConfigScaleOut' ||referenceDataObject.action =='Configure'|| referenceDataObject.action =='' || referenceDataObject.action ==undefined ) && isCollapsedContent) "> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px;">VNFC Type*</label> + <input type="text" class="form-control" id="txtVnfcTypeInColl" [(ngModel)]="Sample['vnfc-type']" #vnfcType="ngModel" name="samplevnfcType"> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px">VNFC Function Code*</label> + <input type="text" class="form-control" id="txtVnfcFunctionCode" [(ngModel)]="Sample['vnfc-function-code']" #vnfcFunctionCode="ngModel" name="samplevnfcFunctionCode"> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px;">IPAddress V4 OAM VIP</label> + <select class="form-control" id="cmbIpAddedBoo" [(ngModel)]="Sample['ipaddress-v4-oam-vip']" name="sampleIpaddress"> + <option [value]="hasIp" *ngFor="let hasIp of ipAddressBoolean">{{hasIp}} + </option> + </select> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px;">Group Notation Type</label> + <select class="form-control" id="cmbGroupType" [(ngModel)]="Sample['group-notation-type']" name="sampleGroupNotation"> + <option [value]="type" *ngFor="let type of groupAnotationType">{{type}}</option> + </select> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px;">Group Notation Value</label> + <input type="text" class="form-control" id="txtGroupValue" [(ngModel)]="Sample['group-notation-value']" name="sampleGroupValue"> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent clear-btn" (click)="clearVnfcData()">Clear VNFC Info + </button> + </div> + </div> + <hr> + <div *ngIf="(referenceDataObject.action =='ConfigScaleOut' || referenceDataObject.action =='Configure'|| referenceDataObject.action =='' )" class="row"> + <div class="col-lg-2 col-md-2 hdden-sm-down"> + <label style="margin-top: 17px;" class="headlinesInBold"> Number Of VM(s): </label> + </div> + <div class="col-lg-5 col-md-5 col-sm-6 col-xs-6"> + <div class="form-group"> + <input type="text" placeholder="Number of VM(s)" class="form-control" id="txtVmnumber22" [(ngModel)]="refernceScopeObj.from" (ngModelChange)="numberValidation($event)" + name="txtNumber23"> + </div> + </div> + <div class="col-lg-5 col-md-5 col-sm-6 col-xs-6 text-right"> + <div class="form-group"> + <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" type="button" [disabled]="!refernceScopeObj.from || !numberOfVmTest" + (click)="addVms()">Add VM Information + </button> + </div> + </div> + </div> + <div *ngIf="referenceDataObject.vm?.length>0"> + <div class="row" *ngFor="let noOfvm of referenceDataObject.vm | vmFiltering:referenceDataObject?.action:templateIdentifier; let j=index"> + <div *ngIf="((referenceDataObject.action =='ConfigScaleOut' || referenceDataObject.action =='Configure'|| referenceDataObject.action =='' || referenceDataObject.action ==undefined ))" + class="col-12"> + <div class="row" *ngFor="let item of noOfvm.vnfc; let i=index"> + <div class="col-md-12" *ngIf="i==0"> + <h5 class="headlinesInBold">VM Number: {{j+1}}</h5> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px;">VNFC Instance No.</label> + <input type="text" class="form-control" id="txtVmnumber" disabled='true' [(ngModel)]="item['vnfc-instance']" name="vmNumber{{j}}"> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px;">VNFC Type*</label> + <input type="text" class="form-control" id="txtVnfcTypeInColl" required [(ngModel)]="item['vnfc-type']" #vnfcType="ngModel" name="vnfcType{{j}}"> + <span class="error-message" [hidden]="vnfcType.valid || (vnfcType.pristine && !userForm.submitted)">Required Field</span> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px;">VNFC Function Code*</label> + <input type="text" class="form-control" id="txtVnfcFunctionCode" required [(ngModel)]="item['vnfc-function-code']" #vnfcFunctionCode="ngModel" name="vnfcFunctionCode{{j}}"> + <span class="error-message" [hidden]="vnfcFunctionCode.valid || (vnfcFunctionCode.pristine && !userForm.submitted)">Required Field</span> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px;">IPAddress V4 OAM VIP</label> + <select class="form-control" id="cmbIpAddress" [(ngModel)]="item['ipaddress-v4-oam-vip']" name="ipaddress{{j}}"> + <option [value]="hasIP" [selected]="item.ipAddressBoolean===hasIP" + *ngFor="let hasIP of ipAddressBoolean">{{hasIP}} + </option> + </select> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px;">Group Notation Type</label> + <select class="form-control" id="cmbGroupType" [(ngModel)]="item['group-notation-type']" name="selectedGroupType{{j}}"> + <option [value]="type" [selected]="item.groupNotationType===type" + *ngFor="let type of groupAnotationType">{{type}} + </option> + </select> + </div> + <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12"> + <label style="font-size:12px;">Group Notation Value</label> + <input type="text" class="form-control" id="txtGroupValue" [(ngModel)]="item['group-notation-value']" name="selectedGroupValue{{j}}"> + </div> + <div class="col-lg-12 col-sm-12 col-md-12 col-xs-12"> + <div class="removevnfcClass" *ngIf="refernceScopeObj.sourceType !='vnfcType'"> + <a role="button" style="color: white" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" (click)="removeFeature(j,i)">Remove Vm</a> + </div> + <div> + <a *ngIf="(referenceDataObject.vm[j].vnfc.length-1) == i " [hidden]="true" role="button" (click)="addVnfcData(j)">Add VNFC + Information</a> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + <div class="row" *ngIf="(referenceDataObject.action === 'OpenStack Actions')"> + <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12"> + <div class="table-responsive" style="height:auto; overflow: auto;"> + <table> + <thead> + <tr> + <td *ngFor="let item of firstArrayElement"> + <div> + <h1 style="font-size: 110%"> {{item}} </h1> + </div> + </td> + </tr> + </thead> + <tbody> + <tr *ngFor="let item of remUploadedDataArray; let i=index"> + <td *ngFor="let subItem of item; let j=index"> + {{subItem}} + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div> + </div> + </div> + </div> + </div> +</form> +<!-- Modal --> +<div id="messageModal" class="modal fade" role="dialog"> + <div class="modal-dialog"> + <!-- Modal content--> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="android-more-button mdl-button mdl-js-button mdl-button--accent" data-dismiss="modal">× + </button> + <h4 class="modal-title">Warning</h4> + </div> + <div class="modal-body"> + <div *ngIf="allowAction==false" class="alert alert-danger"> + <b> Configure </b> action not yet saved + </div> + <div *ngIf="actionExist" class="alert alert-danger"> + <b> {{referenceDataObject.action}}</b> already exists. Please continue... + </div> + </div> + <div class="modal-footer"> + <button type="close" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" data-dismiss="modal">Close + </button> + </div> + </div> + </div> +</div> +<div id="identifierModal" class="modal fade" role="dialog"> + <div class="modal-dialog"> + <!-- Modal content--> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="android-more-button mdl-button mdl-js-button mdl-button--accent" data-dismiss="modal">× + </button> + <h4 class="modal-title">Enter New Template Identifier</h4> + </div> + <div class="modal-body"> + <div> + <div> + <input name="test" type="text" class="" [(ngModel)]="templateId" placeholder="identifier"> + </div> + <div> + <button style="padding: 10px" class="btn btn-primary" data-dismiss="modal" (click)="addToIdentDrp()">submit + </button> + <button style="padding: 10px" class="btn btn-primary" (click)="templateId=''" data-dismiss="modal">cancel + </button> + </div> + </div> + </div> + <div class="modal-footer"> + + </div> + </div> + </div> +</div> +<ng-template #content let-c="close" let-d="dismiss"> + <div class="modal-header"> + <h6 class="modal-title">Save all changes for current action to APPC database.</h6> + <button type="button" class="close" aria-label="Close" (click)="d('Cross click')"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <p>Do you want to save the changes?</p> + </div> + <div class="modal-footer"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" (click)="c('no')">No + </button> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="c('yes')">Yes + </button> + </div> +</ng-template>
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.spec.ts b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.spec.ts new file mode 100644 index 0000000..67ba8f5 --- /dev/null +++ b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.spec.ts @@ -0,0 +1,67 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; +import {NO_ERRORS_SCHEMA} from '@angular/core'; +import {ReferenceDataformComponent} from './reference-dataform.component'; +import {FormsModule} from '@angular/forms'; +import { NotificationService } from '../../../shared/services/notification.service'; +import { ParamShareService } from '../../..//shared/services/paramShare.service'; +import { MappingEditorService } from '../../..//shared/services/mapping-editor.service'; +import {DialogService} from 'ng2-bootstrap-modal'; +import {RouterTestingModule} from '@angular/router/testing'; +import { HttpUtilService } from '../../../shared/services/httpUtil/http-util.service'; +import { NgModule } from '@angular/core'; +import { NgProgress } from 'ngx-progressbar'; +import { HttpModule } from '@angular/http'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { SharedModule } from '../../../shared/shared.module'; + + +describe('ReferenceDataformComponent', () => { + let component: ReferenceDataformComponent; + let fixture: ComponentFixture<ReferenceDataformComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ReferenceDataformComponent], + schemas: [NO_ERRORS_SCHEMA], + imports: [FormsModule, RouterTestingModule,HttpModule,NgbModule.forRoot()], + providers: [NgProgress, ParamShareService, DialogService, NotificationService, HttpUtilService, MappingEditorService] + + }) + .compileComponents(); + })); + + beforeEach(() => { + + fixture = TestBed.createComponent(ReferenceDataformComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create reference component', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.ts b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.ts new file mode 100644 index 0000000..c66a003 --- /dev/null +++ b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.ts @@ -0,0 +1,1242 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ +import * as XLSX from 'xlsx'; +import * as _ from 'underscore'; +import { ActivatedRoute, Router } from '@angular/router'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { BuildDesignComponent } from '../build-artifacts.component'; +import { HttpUtilService } from '../../../shared/services/httpUtil/http-util.service'; +import { Location } from '@angular/common'; +import { MappingEditorService } from '../../..//shared/services/mapping-editor.service'; +import { ModalComponent } from '../../../shared/modal/modal.component'; +import { NotificationService } from '../../../shared/services/notification.service'; +import { NotificationsService } from 'angular2-notifications'; +import { ParamShareService } from '../../..//shared/services/paramShare.service'; +import { environment } from '../../../../environments/environment'; +import { saveAs } from 'file-saver'; +import { NgProgress } from 'ngx-progressbar'; + + +declare var $: any; +type AOA = Array<Array<any>>; + +@Component({ + selector: 'reference-dataform', + templateUrl: './reference-dataform.component.html', + styleUrls: ['./reference-dataform.component.css'] +}) +export class ReferenceDataformComponent implements OnInit { + @ViewChild(ModalComponent) modalComponent: ModalComponent; + public showUploadStatus: boolean = false; + public fileUploaded: boolean = false; + public uploadedData: any; + public statusMsg: string; + public uploadStatus: boolean = false; + public isCollapsedContent: boolean = true; + public vnfcCollLength: number = 0; + public vfncCollection = []; + public userForm: any; + public actionType: any; + numberTest: RegExp = /^[^.a-z]+$/; + public numberOfVmTest: boolean = true; + public tempAllData = []; + public noRefData = false; + public disableRetrieve = false; + public getRefStatus = false; + public uploadStatusError: boolean; + public showUploadErrorStatus: boolean; + public noData: string; + selectedActions = []; + public appData = { reference: {}, template: { templateData: {}, nameValueData: {} }, pd: {} }; + public downloadData = { + reference: {}, + template: { templateData: {}, nameValueData: {}, templateFileName: '', nameValueFileName: '' }, + pd: { pdData: '', pdFileName: '' } + }; + fileName: any; + public uploadFileName: any; + public addVmClickedFlag: boolean = false; + public getExcelUploadStatus: boolean = false; + public uploadedDataArray: any; + public actionFlag = false; + currentAction: any; + oldAction: any; + nonConfigureAction: any; + templateId; + templateIdentifier; + public actionLevels = [ + 'vnfc', 'vnf' + ]; + + identifierDrp: any; + identifierDrpValues: any = []; + //settings for the notifications. + options = { + timeOut: 1000, + showProgressBar: true, + pauseOnHover: true, + clickToClose: true, + maxLength: 200 + }; + //initializing this object to contain all the parameters to be captured + public referenceDataObject = { + action: '', + 'action-level': 'vnf', + scope: { 'vnf-type': '', 'vnfc-type': '' }, + 'template': 'Y', + vm: [], + 'device-protocol': '', + 'user-name': '', + 'port-number': '', + 'artifact-list': [] + }; + public refernceScopeObj = { sourceType: '', from: '', to: '' }; + public actions = ['', 'Configure', 'ConfigModify', 'ConfigBackup', 'ConfigRestore', 'GetRunningConfig', 'HealthCheck', 'StartApplication', 'StopApplication', 'QuiesceTraffic', 'ResumeTraffic', 'UpgradeBackout', 'UpgradeBackup', 'UpgradePostCheck', 'UpgradePreCheck', 'UpgradeSoftware', 'OpenStack Actions', 'ConfigScaleOut']; + public groupAnotationValue = ['', 'Pair']; + public groupAnotationType = ['', 'first-vnfc-name', 'fixed-value', 'relative-value']; + public deviceProtocols = ['', 'ANSIBLE', 'CHEF', 'NETCONF-XML', 'REST', 'CLI', 'RESTCONF']; + public deviceTemplates = ['', 'Y', 'N']; + public sourceTypeColl = ['', 'vnfType', 'vnfcType']; + public ipAddressBoolean = ['', 'Y', 'N']; + public Sample: any = { + 'vnfc-instance': '1', + 'vnfc-function-code': '', + 'ipaddress-v4-oam-vip': '', + 'group-notation-type': '', + 'group-notation-value': '' + }; + hideModal: boolean = false; + public self: any; + public uploadTypes = [{ + value: 'Reference Data', + display: 'Sample Json Param File' + }, + { + value: 'Mapping Data', + display: 'Sample Json Param File' + } + ]; + public selectedUploadType: string = this.uploadTypes[0].value; + public vnfcTypeData: string = ''; + public title: string; + public allowAction: boolean = true; + public actionExist: boolean = false; + public disableVnftype: boolean = false; + public otherActions: boolean = false; + public actionHealthCheck: boolean = false; + public actionChanged: boolean = false; + public initialAction: string = ''; + public noCacheData: boolean; + public updateParams: any; + public vnfParams: any; + public firstArrayElement = []; + public remUploadedDataArray = []; + + constructor (private buildDesignComponent: BuildDesignComponent, private httpUtils: HttpUtilService, private route: Router, private location: Location, private activeRoutes: ActivatedRoute, private notificationService: NotificationService, + private paramShareService: ParamShareService, private mappingEditorService: MappingEditorService, private modalService: NgbModal, private nService: NotificationsService, private ngProgress: NgProgress) { + } + + ngOnInit() { + this.self = this; + let path = this.location.path; + this.title = 'Reference Data'; + this.referenceDataObject = { + action: '', + 'action-level': 'vnf', + scope: { 'vnf-type': '', 'vnfc-type': '' }, + 'template': 'Y', + vm: [], + 'device-protocol': '', + 'user-name': '', + 'port-number': '', + 'artifact-list': [] + }; + this.updateParams = sessionStorage.getItem('updateParams'); + let cacheData = this.mappingEditorService.referenceNameObjects; + if (cacheData != undefined && cacheData != null && cacheData.length > 0) { + this.tempAllData = cacheData; + if (this.mappingEditorService.latestAction != undefined) { + this.referenceDataObject = this.mappingEditorService.latestAction; + //this.referenceDataObject['template-id-list'] = this.mappingEditorService.identifier + //use these commented objects to be used in template and pd pages + //this.templateIdentifier = this.mappingEditorService.identifier + this.refernceScopeObj.sourceType = this.referenceDataObject['scopeType']; + this.oldAction = this.referenceDataObject.action; + this.populateExistinAction(this.referenceDataObject.action); + } + } else if (this.updateParams != 'undefined') { + this.getArtifact(); + } + var appData = this.mappingEditorService.appDataObject; + if (appData != null || appData != undefined) this.appData = appData; + var downloadData = this.mappingEditorService.downloadDataObject; + if (downloadData != null || downloadData != undefined) this.downloadData = downloadData; + this.vnfParams = JSON.parse(sessionStorage.getItem('vnfParams')); + if (this.vnfParams && this.vnfParams.vnfType) { + this.referenceDataObject['scope']['vnf-type'] = this.vnfParams.vnfType; + } + if (this.vnfParams && this.vnfParams.vnfcType) { + this.referenceDataObject['scope']['vnfc-type'] = this.vnfParams.vnfcType; + } + this.uploadedDataArray = []; + this.remUploadedDataArray = []; + this.firstArrayElement = []; + this.uploadFileName = ''; + this.templateIdentifier = this.mappingEditorService.identifier + //this.tempAllData = []; + } + + //to retrive the data from appc and assign it to the vaiables, if no data display the message reterived from the API + getArtifact() { + try { + let payload = JSON.parse(sessionStorage.getItem('updateParams')); + payload['userID'] = localStorage['userId']; + payload = JSON.stringify(payload); + let data = { + 'input': { + 'design-request': { + 'request-id': localStorage['apiToken'], + 'action': 'getArtifact', + 'payload': payload + } + } + }; + this.ngProgress.start(); + this.httpUtils.post({ + url: environment.getDesigns, + data: data + }).subscribe(resp => { + if (resp.output.data.block != undefined) { + this.nService.success('Status', 'data fetched '); + let artifactInfo = JSON.parse(resp.output.data.block).artifactInfo[0]; + let reference_data = JSON.parse(artifactInfo['artifact-content'])['reference_data'][0]; + this.referenceDataObject = reference_data; + console.log('reference data obj==' + JSON.stringify(this.referenceDataObject)); + this.refernceScopeObj.sourceType = this.referenceDataObject['scopeType']; + this.mappingEditorService.getReferenceList().push(JSON.parse(artifactInfo['artifact-content'])); + this.tempAllData = JSON.parse(artifactInfo['artifact-content'])['reference_data']; + this.oldAction = this.referenceDataObject.action; + if (this.referenceDataObject.action === 'OpenStack Actions') { + this.deviceProtocols = ['', 'OpenStack']; + this.buildDesignComponent.tabs = [ + { + + name: 'Reference Data', + url: 'references', + }]; + } + else { + this.buildDesignComponent.tabs = [ + { + name: 'Reference Data', + url: 'references', + }, { + name: 'Template', + url: 'templates/myTemplates', + }, { + name: 'Parameter Definition', + url: 'parameterDefinitions/create' + }/*, { + name: "Test", + url: 'test', + }*/ + ]; + } + console.log('tempalldata===' + JSON.stringify(this.tempAllData)); + } else { + this.nService.success('Status', 'Sorry !!! I dont have any artifact Named : ' + (JSON.parse(payload))['artifact-name']); + } + this.ngProgress.done(); + }); + } + catch (e) { + this.nService.warn('status', 'error while reteriving artifact'); + } + setTimeout(() => { + this.ngProgress.done(); + }, 3500); + } + + //reinitializing the required values + ngOnDestroy() { + let referenceObject = this.prepareReferenceObject(); + this.mappingEditorService.changeNavAppData(this.appData); + this.mappingEditorService.changeNavDownloadData(this.downloadData); + this.uploadedDataArray = []; + this.remUploadedDataArray = []; + this.firstArrayElement = []; + this.uploadFileName = ''; + // this.tempAllData = []; + console.log('temp all data===' + JSON.stringify(this.tempAllData)); + } + + numberValidation(event: any) { + // console.log(this.numberTest.test(event)); + if (this.numberTest.test(event) && event != 0) { + this.numberOfVmTest = true; + } + else { + this.numberOfVmTest = false; + } + } + + updateSessionValues(event: any, type: string) { + if (type === 'action') { + sessionStorage.setItem('action', event); + } + if (type === 'vnfType') { + sessionStorage.setItem('vnfType', event); + } + } + + checkConfigure(data) { + if (data == null) { + return; + } + if (this.fileUploaded && this.actionType == 'update') { + let refObject = this.uploadedData.find(obj => { + return obj.action == data; + }); + this.referenceDataObject = JSON.parse(JSON.stringify(refObject)); + if (data == 'HealthCheck') { + //show additional fileds user name port number and others + this.actionHealthCheck = true; + } else { + this.actionHealthCheck = false; + if (data == 'StartApplication' || data == 'StopApplication') { + this.disableVnftype = true; + } else { + + this.otherActions = true; + } + } + return; + } + this.buildDesignComponent.updateAccessUpdatePages(data, this.mappingEditorService.getReferenceList()); + let configureObject = _.find(this.tempAllData, function (obj) { + return obj['action'] == 'Configure'; + }); + if (data != 'Configure') { + if (!configureObject) { + this.allowAction = false; + $('#messageModal').modal(); + } else { + this.allowAction = true; + } + if (this.referenceDataObject.action == 'Configure') { + this.allowAction = true; + } + } + //dont allow any action second time + let y = _.find(this.tempAllData, function (obj) { + return obj['action'] == data; + }); + if (y) { + this.actionExist = true; + $('#messageModal').modal(); + } else { + this.actionExist = false; + } + //populate configure values for other actions + if (data != 'Configure' && configureObject != undefined) { + if (data == 'HealthCheck') { + //show additional fileds user name port number and others + this.actionHealthCheck = true; + } else { + this.actionHealthCheck = false; + if (data == 'StartApplication' || data == 'StopApplication') { + this.disableVnftype = true; + } else { + this.otherActions = true; + } + } + this.referenceDataObject.scope['vnf-type'] = configureObject['scope']['vnf-type']; + this.referenceDataObject.scope['vnfc-type'] = configureObject['scope']['vnfc-type']; + this.referenceDataObject['device-protocol'] = configureObject['device-protocol']; + this.refernceScopeObj['sourceType'] = configureObject['scopeType']; + } else { + this.actionHealthCheck = false; + this.otherActions = false; + this.disableVnftype = false; + } + //set default values for further actions + } + + addVnfcData(vmNumber: number) { + var newObj = { + 'vnfc-instance': this.referenceDataObject.vm[vmNumber].vnfc.length + 1, + 'vnfc-type': this.vnfcTypeData, + 'vnfc-function-code': '', + 'ipaddress-v4-oam-vip': '', + 'group-notation-type': '', + 'group-notation-value': '' + }; + this.referenceDataObject.vm[vmNumber].vnfc.push(newObj); + } + + //to remove the VM's created by the user + removeFeature(vmNumber: any, index: any) { + this.referenceDataObject.vm.splice(vmNumber, 1); + } + + //add new VM's to the configure + addVms() { + let arr = []; + var vnfcObj = JSON.parse(JSON.stringify(this.Sample)); + let mberOFVm = Number(this.refernceScopeObj.from); + let arrlength = this.referenceDataObject.vm.length; + mberOFVm = arrlength + mberOFVm; + for (var i = (arrlength); i < mberOFVm; i++) { + if (this.referenceDataObject.action == 'ConfigScaleOut') { + arr.push({ 'template-id': this.templateIdentifier, 'vm-instance': (i + 1), vnfc: [Object.assign({}, this.Sample)] }); + } else { + arr.push({ 'vm-instance': (i + 1), vnfc: [Object.assign({}, this.Sample)] }); + } + + } + //this.referenceDataObject.vm.splice(arrlength, 0, ...arr); + this.referenceDataObject.vm = this.referenceDataObject.vm.concat(arr); //splice(arrlength, 0, ...arr); + } + + //Reference object to create reference data + prepareReferenceObject() { + // console.log("this temp all data before=="+ JSON.stringify(this.tempAllData)) + + this.referenceDataObject['artifact-list'] = []; + let scopeName = ''; + //if only vnf is there + if (this.referenceDataObject.scope['vnfc-type'] == '' || this.referenceDataObject.scope['vnfc-type'] == null || this.referenceDataObject.scope['vnfc-type'] == 'null') { + scopeName = this.referenceDataObject.scope['vnf-type']; + this.referenceDataObject.scope['vnfc-type'] = ''; + this.referenceDataObject['action-level'] = 'vnf'; + this.referenceDataObject['scopeType'] = 'vnf-type'; + } + //if VNFC is entered set action level & Scope type to VNFC for configure and configure modify, and default the values to vnf and vnf type for all other actions + else { + scopeName = this.referenceDataObject.scope['vnfc-type']; + if (this.referenceDataObject.action == 'Configure' || this.referenceDataObject.action == 'ConfigModify') { + this.referenceDataObject['action-level'] = 'vnfc'; + this.referenceDataObject['scopeType'] = 'vnfc-type'; + } else { + this.referenceDataObject['action-level'] = 'vnf'; + this.referenceDataObject['scopeType'] = 'vnf-type'; + } + } + //replacing / with _ and removing spaces in the scopeName + if (scopeName) { + scopeName = scopeName.replace(/ /g, '').replace(new RegExp('/', 'g'), '_').replace(/ /g, ''); + } + //marking the extension based on the device-protocol selected by the user + let extension = 'json'; + if (this.referenceDataObject['device-protocol'] == 'ANSIBLE' || this.referenceDataObject['device-protocol'] == 'CHEF' || this.referenceDataObject['device-protocol'] == 'CLI') { + extension = 'json'; + } else if (this.referenceDataObject['device-protocol'] == 'NETCONF-XML' || this.referenceDataObject['device-protocol'] == 'REST') { + extension = 'xml'; + } + //preparing the artifact list array file names along with extension + let config_template_fileName = this.referenceDataObject.action + '_' + scopeName + '_' + '0.0.1V.' + extension; + let pd_fileName = this.referenceDataObject.action + '_' + scopeName + '_' + '0.0.1V.yaml'; + let reference_fileName = this.referenceDataObject.action + '_' + scopeName + '_' + '0.0.1V.json'; + + let configTemplate = { + 'artifact-name': 'template_' + config_template_fileName, + 'artifact-type': 'config_template' + }; + + let pdTemplate = { + 'artifact-name': 'pd_' + pd_fileName, + 'artifact-type': 'parameter_definitions' + }; + if (this.referenceDataObject.action != 'ConfigScaleOut') { + + this.referenceDataObject['artifact-list'].push(configTemplate, + pdTemplate + ); + + } else { + let identifiers = this.referenceDataObject['template-id-list']; + if (identifiers) { + + + for (var x = 0; x < identifiers.length; x++) { + pd_fileName = this.referenceDataObject.action + '_' + scopeName + '_' + '0.0.1V_' + identifiers[x] + '.yaml'; + config_template_fileName = this.referenceDataObject.action + '_' + scopeName + '_' + '0.0.1V_' + identifiers[x] + '.' + extension; + + configTemplate = { + 'artifact-name': 'template_' + config_template_fileName, + 'artifact-type': 'config_template' + }; + pdTemplate = { + 'artifact-name': 'pd_' + pd_fileName, + 'artifact-type': 'parameter_definitions' + }; + this.referenceDataObject['artifact-list'].push(configTemplate, + pdTemplate + ); + } + } + + } + + if (this.referenceDataObject.scope['vnfc-type'] === '') { + this.referenceDataObject.scope['vnfc-type'] = ''; + } + if (this.referenceDataObject.action === 'OpenStack Actions') { + this.referenceDataObject['template'] = 'N'; + this.referenceDataObject['artifact-list'] = []; + } + let newObj = $.extend(true, {}, this.referenceDataObject); + let action = this.referenceDataObject.action; + let configureObject = (newObj.action == 'Configure'); + let ConfigScaleOut = (newObj.action == 'ConfigScaleOut'); + //delete VM's if selected action is configure. + if (!ConfigScaleOut && !configureObject && this.tempAllData.length != 0) { + // delete newObj.vm + newObj.vm = []; + //this.tempAllData.push(newObj); + } else { + if (ConfigScaleOut) { + + + // //add template identifier + // for(let x=0;x<newObj.vm.length;x++){ + // let vmObj= newObj.vm[x] + // vmObj['template-id'] = this.templateIdentifier + // } + } else { + delete newObj['template-id-list']; + } + } + //remove artifact list if template is N + if (this.referenceDataObject.template == 'N') { + } + let actionObjIndex = this.tempAllData.findIndex(obj => { + return obj['action'] == action; + }); + if (newObj.action != 'HealthCheck') { + delete newObj['context-url']; + } + if (actionObjIndex > -1) { + this.tempAllData[actionObjIndex] = newObj; + this.mappingEditorService.saveLatestAction(this.tempAllData[actionObjIndex]); + this.mappingEditorService.saveLatestIdentifier(this.templateIdentifier); + } else { + if (newObj.action != '') { + this.tempAllData.push(newObj); + this.mappingEditorService.saveLatestAction(newObj); + this.mappingEditorService.saveLatestIdentifier(this.templateIdentifier); + } + } + //Creating all action block to allow mulitple actions at once + let allAction = { + action: 'AllAction', + 'action-level': 'vnf', + scope: newObj.scope, + 'artifact-list': [{ + 'artifact-name': 'reference_AllAction' + '_' + scopeName + '_' + '0.0.1V.json', + 'artifact-type': 'reference_template' + }] + }; + let allActionIndex = this.tempAllData.findIndex(obj => { + return obj['action'] == 'AllAction'; + }); + if (allActionIndex > -1) { + this.tempAllData[allActionIndex] = allAction; + } else { + this.tempAllData.push(allAction); + } + console.log('This uploaded array===' + JSON.stringify(this.uploadedDataArray)); + if (this.uploadedDataArray && this.uploadedDataArray != undefined && this.uploadedDataArray.length != 0) { + /*for (var i = 0; i < this.uploadedDataArray.length; i++) { + var actionData = this.uploadedDataArray[i][0]; + // console.log("Action data=="+ actionData); + for (var j = 0; j < this.tempAllData.length; j++) { + //console.log("Actions from temp all data=="+ this.tempAllData[j].action) + //console.log("Matched=="+ (actionData === this.tempAllData[j].action)) + if (actionData === this.tempAllData[j].action) { + this.tempAllData.splice(j,1); + + } + } + }*/ + if (this.tempAllData && this.tempAllData != undefined) { + for (var i = 0; i < this.tempAllData.length; i++) { + // alert(this.checkIfelementExistsInArray(this.tempAllData[i].action,this.actions)) + var result = false; + + if (this.tempAllData[i].action === 'AllAction') { + result = true; + } + else { + result = this.checkIfelementExistsInArray(this.tempAllData[i].action, this.actions); + } + if (!result) { + console.log('Removing VM action==' + this.tempAllData[i].action); + this.tempAllData.splice(i, 1); + i = i - 1; + } + + } + } + this.addVmCapabilitiesData(); + } + // console.log("this temp all data after=="+ JSON.stringify(this.tempAllData)) + //console.log("temp all data from save to appc=="+JSON.stringify(this.tempAllData)) + this.mappingEditorService.getReferenceList().push(JSON.parse(JSON.stringify(this.referenceDataObject))); + this.buildDesignComponent.updateAccessUpdatePages(this.referenceDataObject.action, this.mappingEditorService.getReferenceList()); + this.mappingEditorService.changeNav(this.tempAllData); + return { totlaRefDtaa: this.tempAllData, scopeName: scopeName }; + } + + public checkIfelementExistsInArray(element, array) { + //console.log("Element==" + element) + var result: boolean = false; + + array.forEach(function (item) { + // console.log("Item==" + item) + if (element === item) { + console.log('Element==' + element + 'Item==' + item); + result = true; + } + } + ); + return result; + } + + upload(evt: any) { + /* console.log("This uploaded array==" + JSON.stringify(this.uploadedDataArray)) + // console.log("This template data before==" + JSON.stringify(this.tempAllData)) + if (this.uploadedDataArray && this.uploadedDataArray != undefined && this.uploadedDataArray.length!=0) { + /* for (var i = 0; i < this.uploadedDataArray.length; i++) { + var action = this.uploadedDataArray[i][0]; + for (var j = 0; j < this.tempAllData.length; j++) { + if (action === this.tempAllData[j].action) { + this.tempAllData.splice(j); + console.log("This template data===" + this.tempAllData[j]); + } + } + } + if (this.tempAllData && this.tempAllData != undefined) { + for (var i = 0; i < this.tempAllData.length; i++) { + // alert(this.checkIfelementExistsInArray(this.tempAllData[i].action,this.actions)) + var result = this.checkIfelementExistsInArray(this.tempAllData[i].action, this.actions); + if (this.tempAllData[i].action === "AllAction") result = true; + if (!result) { + console.log("Removing VM action==" + this.tempAllData[i].action) + this.tempAllData.splice(i, 1); + } + + } + } + } + // console.log("This template data after==" + JSON.stringify(this.tempAllData)) + /* wire up file reader */ + const target: DataTransfer = <DataTransfer>(evt.target); + + //console.log("filename========" + evt.target.files[0].name) + this.uploadFileName = evt.target.files[0].name; + var fileExtension = this.uploadFileName.substr(this.uploadFileName.lastIndexOf('.') + 1); + if (target.files.length != 1) { + throw new Error('Cannot upload multiple files on the entry'); + } + if (fileExtension.toUpperCase() === 'XLS' || fileExtension.toUpperCase() === 'XLSX') { + const reader = new FileReader(); + reader.onload = (e: any) => { + /* read workbook */ + const bstr = e.target.result; + // console.log("print 1---" + bstr); + const wb = XLSX.read(bstr, { type: 'binary' }); + // console.log("print 2---" + JSON.stringify(wb)); + /* grab first sheet */ + const wsname = wb.SheetNames[0]; + // console.log("Name:---" + wsname); + const ws = wb.Sheets[wsname]; + + /* save data */ + + let arrData = (<AOA>(XLSX.utils.sheet_to_json(ws, { header: 1 }))); + //console.log("row======" + (XLSX.utils.sheet_to_json(ws, { header: 1 })).toString()) + // console.log("Array data---" + JSON.stringify(arrData)); + this.uploadedDataArray = arrData; + this.firstArrayElement = arrData[0]; + var remUploadedDataArray = arrData; + remUploadedDataArray.shift(); + this.remUploadedDataArray = remUploadedDataArray; + if (arrData != null) { + this.getExcelUploadStatus = true; + this.nService.success('Success', 'Vm capabilities data uploaded successfully'); + + } + else { + this.nService.success('Error', 'Empty Vm capabilities file uploaded'); + } + }; + reader.readAsBinaryString(target.files[0]); + console.log('TARGET files---' + JSON.stringify(evt.target)); + } + else { + this.nService.error('Error', 'Incorrect VM capabilities file uploaded'); + } + + } + + addVmCapabilitiesData() { + for (var i = 0; i < this.uploadedDataArray.length; i++) { + var vnfcFuncCodeArray = []; + var data = this.uploadedDataArray[i]; + // console.log("Data is "+ JSON.stringify(data)) + //console.log("Data length: "+ data.length) + for (var j = 1; j < data.length; j++) { + // console.log("Data " +j +" is "+ JSON.stringify(data[j])) + if (data[j] != undefined) { + if (data[j].toUpperCase() === 'Y') { + vnfcFuncCodeArray.push(this.firstArrayElement[j]); + //vnfcFuncCodeArray.push({name:this.firstArrayElement[j]}); + } + } + } + var action = this.uploadedDataArray[i][0]; + if (action && action != undefined) { + var json = { + 'action': action, + 'action-level': 'vm', + 'scope': { + 'vnf-type': this.referenceDataObject['scope']['vnf-type'], //need to confirm what should be this value + 'vnfc-type': null + }, + 'vnfc-function-code-list': vnfcFuncCodeArray, + 'template': 'N', + 'device-protocol': 'OS' + }; + + this.tempAllData.push(json); + } + + } + } + + //download template + save(form: any, isValid: boolean) { + if (this.referenceDataObject.action === '') { + this.nService.error('Error', 'Select a valid Action'); + return; + } + if (this.referenceDataObject['device-protocol'] === '') { + this.nService.error('Error', 'Select a valid Device protocol'); + return; + } + + if (isValid) { + let referenceObject = this.prepareReferenceObject(); + let theJSON = JSON.stringify({ 'reference_data': this.tempAllData }, null, '\t'); + let uri = 'data:application/json;charset=UTF-8,' + encodeURIComponent(theJSON); + this.downloadData.reference = theJSON; + this.validateTempAllData(); + var blob = new Blob([theJSON], { + type: 'text/plain' + }); + let fileName = 'reference_AllAction_' + referenceObject.scopeName + '_' + '0.0.1V.json'; + saveAs(blob, fileName); + var templateData = JSON.stringify(this.downloadData.template.templateData); + var nameValueData = JSON.stringify(this.downloadData.template.nameValueData); + var pdData = this.downloadData.pd.pdData; + if (templateData != '{}' && templateData != null && templateData != undefined) this.downloadTemplate(); + if (nameValueData != '{}' && nameValueData != null && nameValueData != undefined) this.downloadNameValue(); + if (pdData != '' && pdData != null && pdData != undefined) this.downloadPd(); + } + } + + downloadTemplate() { + var fileName = this.downloadData.template.templateFileName; + var theJSON = this.downloadData.template.templateData; + if (fileName != null || fileName != '') { + var fileExtensionArr = fileName.split('.'); + var blob = new Blob([theJSON], { + type: 'text/' + fileExtensionArr[1] + }); + saveAs(blob, fileName); + } + } + + downloadNameValue() { + var fileName = this.downloadData.template.nameValueFileName; + var theJSON = this.downloadData.template.nameValueData; + var blob = new Blob([theJSON], { + type: 'text/json' + }); + + saveAs(blob, fileName); + } + + downloadPd() { + let fileName = this.downloadData.pd.pdFileName; + let theJSON = this.downloadData.pd.pdData; + var blob = new Blob([theJSON], { + type: 'text/plain' + }); + + saveAs(blob, fileName); + } + + saveToAppc(valid, form) { + if (this.referenceDataObject.action === '') { + this.nService.error('Error', 'Select a valid Action'); + return; + } + if (this.referenceDataObject['device-protocol'] === '') { + this.nService.error('Error', 'Select a valid Device protocol'); + return; + } + + try { + form._submitted = true; + if (valid) { + + let referenceObject = this.prepareReferenceObject(); + console.log('##########'); + + console.log(referenceObject); + this.validateTempAllData(); + let theJSON = JSON.stringify(this.tempAllData, null, '\t'); + let fileName = 'reference_AllAction_' + referenceObject.scopeName + '_' + '0.0.1V.json'; + this.uploadArtifact(JSON.stringify({ reference_data: this.tempAllData }), this.tempAllData[this.tempAllData.length - 1], fileName); + var templateData = JSON.stringify(this.appData.template.templateData); + var nameValueData = JSON.stringify(this.appData.template.nameValueData); + var pdData = JSON.stringify(this.appData.pd); + if (templateData != '{}' && templateData != null && templateData != undefined) this.saveTemp(); + if (nameValueData != '{}' && nameValueData != null && nameValueData != undefined) this.saveNameValue(); + if (pdData != '{}' && pdData != null && pdData != undefined) this.savePd(); + if (this.actionChanged) { + this.referenceDataObject.action = this.currentAction; + this.populateExistinAction(this.referenceDataObject.action); + this.actionChanged = false; + } + } + } + catch (e) { + this.nService.warn('status', 'unable to save the artifact'); + } + } + + validateTempAllData() { + if (this.tempAllData) { + var updatedData = []; + this.tempAllData.forEach(data => { + if (data.action) { + updatedData.push(data); + } + }); + this.tempAllData = updatedData; + } + } + + appendSlashes(artifactData) { + return artifactData.replace(/"/g, '\\"'); + } + + uploadArtifact(artifactData, dataJson, fileName) { + let data = []; + let slashedPayload = this.appendSlashes(artifactData); + let newPyaload = '{"userID": "' + localStorage['userId'] + '","vnf-type" : "' + dataJson['scope']['vnf-type'] + '","action" : "AllAction","artifact-name" : "' + fileName + '","artifact-type" : "APPC-CONFIG","artifact-version" : "0.1","artifact-contents" :" ' + slashedPayload + '"}'; + let payload = { + 'input': { + 'design-request': { + 'request-id': localStorage['apiToken'], + 'action': 'uploadArtifact', + 'payload': newPyaload, + } + } + }; + this.ngProgress.start(); + this.httpUtils.post({ + url: environment.getDesigns, + data: payload + }).subscribe((resp) => { + if (resp != null && resp.output.status.code == '400') { + window.scrollTo(0, 0); + this.nService.success('Status', 'successfully uploaded the Reference Data'); + } else { + this.nService.warn('Status', 'Error while saving Reference Data'); + } + this.uploadStatusError = false; + this.getRefStatus = false; + this.ngProgress.done(); + }, (err) => { + this.nService.error('Status', 'Error Connecting to the APPC Network'); + window.scrollTo(0, 0); + }); + this.appData.reference = payload; + setTimeout(() => { + this.ngProgress.done(); + }, 3500); + } + + retriveFromAppc() { + if (sessionStorage.getItem('updateParams') != 'undefined') { + this.getArtifact(); + this.noCacheData = false; + } else { + this.noCacheData = true; + } + } + + cloneMessage(servermessage) { + var clone = {}; + for (var key in servermessage) { + if (servermessage.hasOwnProperty(key)) //ensure not adding inherited props + clone[key] = servermessage[key]; + } + return clone; + } + + public showUpload() { + this.selectedUploadType = this.uploadTypes[0].value; + }; + + public fileChange(input) { + this.fileName = input.target.files[0].name.replace(/C:\\fakepath\\/i, ''); + this.fileUploaded = true; + this.disableRetrieve = true; + if (input.target.files && input.target.files[0]) { + // Create the file reader + let reader = new FileReader(); + this.readFile(input.target.files[0], reader, (result) => { + // After the callback fires do: + if ('Reference Data' === this.selectedUploadType) { + try { + let obj: any; + let jsonObject = (JSON.parse(result))['reference_data']; + this.uploadedData = JSON.parse(JSON.stringify(jsonObject)); + this.tempAllData = JSON.parse(JSON.stringify(jsonObject)); + this.notificationService.notifySuccessMessage('Reference Data file successfully uploaded..'); + if (jsonObject instanceof Array) { + this.referenceDataObject = jsonObject[0]; + jsonObject.forEach(obj => { + this.selectedActions.push(obj.action); + }); + } else { + this.referenceDataObject = jsonObject; + this.selectedActions.push(jsonObject.action); + } + if (this.referenceDataObject.action === 'OpenStack Actions') { + this.deviceProtocols = ['', 'OpenStack']; + this.buildDesignComponent.tabs = [ + { + type: 'dropdown', + name: 'Reference Data', + url: 'references', + }]; + } + else { + this.buildDesignComponent.tabs = [ + { + name: 'Reference Data', + url: 'references', + }, { + name: 'Template', + url: 'templates/myTemplates', + }, { + name: 'Parameter Definition', + url: 'parameterDefinitions/create' + } /*, { + name: "Test", + url: 'test', + }*/ + ]; + } + if (this.referenceDataObject.template == null) { + this.referenceDataObject.template = 'Y'; + } + if (this.referenceDataObject['action-level'] == null) { + this.referenceDataObject['action-level'] = 'VNF'; + } + } catch (e) { + this.nService.error('Error', 'Incorrect file format'); + } + } + this.hideModal = true; + }); + } else { + this.notificationService.notifyErrorMessage('Failed to read file..'); + } + + } + + public readFile(file, reader, callback) { + // Set a callback funtion to fire after the file is fully loaded + reader.onload = () => { + // callback with the results + callback(reader.result); + }; + this.notificationService.notifySuccessMessage('Uploading File ' + file.name + ':' + file.type + ':' + file.size); + // Read the file + reader.readAsText(file, 'UTF-8'); + } + + fileChangeEvent(fileInput: any) { + let obj: any = fileInput.target.files; + } + + clearVnfcData() { + this.Sample = { + 'vnfc-instance': '1', + 'vnfc-function-code': '', + 'ipaddress-v4-oam-vip': '', + 'group-notation-type': '', + 'group-notation-value': '' + }; + } + + setVmInstance(index) { + this.referenceDataObject.vm[index]['vm-instance'] = index + 1; + } + + setVnfcType(str: String) { + this.Sample['vnfc-type'] = str; + } + + getChange(value: String) { + if (value === 'vnfType') { + this.referenceDataObject.scope['vnfc-type'] = ''; + } + } + + resetForm() { + this.referenceDataObject['action-level'] = 'vnf'; + this.referenceDataObject.template = 'Y'; + this.referenceDataObject['device-protocol'] = ''; + this.referenceDataObject['user-name'] = ''; + this.referenceDataObject['port-number'] = ''; + this.refernceScopeObj.sourceType = ''; + this.Sample['vnfc-type'] = ''; + } + + populateExistinAction(data) { + let existAction = this.tempAllData.findIndex(obj => { + return obj.action == data; + }); + if (existAction > -1) { + let obj = $.extend(true, {}, this.tempAllData[existAction]); + this.referenceDataObject = obj; + this.referenceDataObject.scope['vnf-type'] = obj['scope']['vnf-type']; + this.referenceDataObject.scope['vnfc-type'] = obj['scope']['vnfc-type']; + this.referenceDataObject['device-protocol'] = obj['device-protocol']; + this.refernceScopeObj['sourceType'] = obj['scopeType']; + } else { + this.resetForm(); + this.referenceDataObject.action = data; + } + //# iof healthCeck change deviceprotocol drp vaues + if (data == 'HealthCheck') { + this.deviceProtocols = ['', 'ANSIBLE', 'CHEF', 'REST']; + this.actionHealthCheck = true; + } else if (data == 'UpgradeBackout' || data == 'ResumeTraffic' || data == 'QuiesceTraffic' || data == 'UpgradeBackup' || data == 'UpgradePostCheck' || data == 'UpgradePreCheck' || data == 'UpgradeSoftware' || data == 'ConfigBackup' || data == 'ConfigRestore' || data == 'StartApplication' || data == 'StopApplication') { + this.deviceProtocols = ['', 'CHEF', 'ANSIBLE']; + } else if (data == 'OpenStack Actions') { + this.deviceProtocols = ['', 'OpenStack']; + } else if (data == 'ConfigScaleOut' || data == 'Configure' || data == 'ConfigModify') { + this.deviceProtocols = ['', 'CHEF', 'ANSIBLE', 'NETCONF']; + } else if (data == 'GetRunningConfig') { + this.deviceProtocols = ['', 'NETCONF']; + } else { + this.deviceProtocols = ['', 'ANSIBLE', 'CHEF', 'NETCONF-XML', 'REST', 'RESTCONF', 'CLI']; + this.actionHealthCheck = false; + } + } + + //Modal pop up for action change with values entered. + actionChange(data, content, userForm) { + // this.actionChanged = true; + if (data == null) { + return; + } + if ((userForm.valid) && this.oldAction != '' && this.oldAction != undefined) { + this.actionChanged = true; + this.modalService.open(content).result.then(res => { + if (res == 'yes') { + this.currentAction = this.referenceDataObject.action; + this.referenceDataObject.action = this.oldAction; + $('#saveToAppc').click();//make sure the save all is done before the tempall obj is saved form the API + this.oldAction = this.referenceDataObject.action + ''; + if (this.oldAction === 'OpenStack Actions') { + + this.uploadedDataArray = []; + this.remUploadedDataArray = []; + this.firstArrayElement = []; + this.uploadFileName = ''; + //this.tempAllData = []; + } + this.clearCache(); + } else { + this.populateExistinAction(data); + this.oldAction = this.referenceDataObject.action + ''; + this.clearCache(); + } + }); + } else { + this.oldAction = this.referenceDataObject.action + ''; + this.populateExistinAction(data); + } + + + if (data == 'OpenStack Actions') { + this.buildDesignComponent.tabs = [ + { + type: 'dropdown', + name: 'Reference Data', + url: 'references', + }]; + } + else { + this.buildDesignComponent.tabs = [ + { + name: 'Reference Data', + url: 'references', + }, { + name: 'Template', + url: 'templates/myTemplates', + }, { + name: 'Parameter Definition', + url: 'parameterDefinitions/create' + }/*, { + name: "Test", + url: 'test', + }*/ + ]; + } + if (data == 'Configure' || data == 'ConfigModify') { + this.nonConfigureAction = false; + } else { + this.nonConfigureAction = true; + } + } + + clearCache() { + // get the value and save the userid and persist it. + this.mappingEditorService.setTemplateMappingDataFromStore(undefined); + localStorage['paramsContent'] = '{}'; + this.mappingEditorService.setParamContent(undefined); + this.paramShareService.setSessionParamData(undefined); + this.appData = { reference: {}, template: { templateData: {}, nameValueData: {} }, pd: {} }; + this.downloadData = { + reference: {}, + template: { templateData: {}, nameValueData: {}, templateFileName: '', nameValueFileName: '' }, + pd: { pdData: '', pdFileName: '' } + }; + } + + saveTemp() { + this + .httpUtils + .post( + { url: environment.getDesigns, data: this.appData.template.templateData }) + .subscribe(resp => { + if (resp.output.status.code === '400' && resp.output.status.message === 'success') { + this.nService.success('Status', 'Successfully uploaded the Template Data'); + } + if (resp.output.status.code === '401') { + this.nService.warn('Status', 'Error in saving the Template to Appc'); + + } + }, + (err) => this.nService.error('Status', 'Error Connecting to the APPC Network')); + } + + saveNameValue() { + this + .httpUtils + .post( + { + url: environment.getDesigns, data: this.appData.template.nameValueData + }) + .subscribe(resp => { + if (resp.output.status.code === '400' && resp.output.status.message === 'success') { + this.nService.success('Status', 'Successfully uploaded the Name Value Pairs'); + } + if (resp.output.status.code === '401') { + this.nService.warn('Status', 'Error in saving the Name value pairs to Appc'); + } + }, + error => { + this.nService.error('Status', 'Error Connecting to the APPC Network'); + return false; + }); + } + + savePd() { + this + .httpUtils + .post( + { + url: environment.getDesigns, data: this.appData.pd + }) + .subscribe(resp => { + if (resp.output.status.code === '400' && resp.output.status.message === 'success') { + this.nService.success('Status', 'Successfully uploaded PD file'); + } + if (resp.output.status.code === '401') { + this.nService.warn('Status', 'Error in saving the PD to Appc'); + } + }, + error => { + this.nService.error('Status', 'Error Connecting to the APPC Network'); + return false; + }); + } + + openModel(toShow: any, message: any, title: any) { + this.modalComponent.isShow = toShow; + this.modalComponent.message = message; + this.modalComponent.title = title; + } + + browseOption() { + $('#inputFile').trigger('click'); + } + + excelBrowseOption() { + $('#excelInputFile').trigger('click'); + } + + showIdentifier() { + $('#identifierModal').modal(); + } + + addToIdentDrp() { + if (!(this.referenceDataObject['template-id-list'])) { + this.referenceDataObject['template-id-list'] = []; + } + this.referenceDataObject['template-id-list'].push(this.templateId); + // this.referenceDataObject['template-id-list'] = this.identifierDrpValues + //this.identifierDrp = "" + } + + resetVms() { + this.referenceDataObject.vm = []; + } + + dataModified() { + this.referenceDataObject.vm = this.referenceDataObject.vm; + } +}
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.css b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.css new file mode 100644 index 0000000..94ef767 --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.css @@ -0,0 +1,35 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +.file { + visibility: hidden; + position: absolute; +} + +.mt-30 { + margin-top: 30px; +} + +.active-tab > a { + border-bottom: 5px solid #4B515D; +}
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.html b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.html new file mode 100644 index 0000000..150d5ad --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.html @@ -0,0 +1,119 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<simple-notifications [options]="options"></simple-notifications> +<ng-progress [positionUsing]="'marginLeft'" [minimum]="0.15" [maximum]="1" [speed]="200" [showSpinner]="false" [direction]="'leftToRightIncreased'" [color]="'#6ab344'" + [trickleSpeed]="250" [thick]="true" [ease]="'linear'"></ng-progress> + +<tabs> + <tab [tabTitle]="'Template Configuration'"> + <div> + <app-golden-configuration [(configMappingEditorContent)]="configMappingEditorContent" [isMappingComp]="true" #mappingComponent> + </app-golden-configuration> + </div> + </tab> + <tab [tabTitle]="'Param Values'"> + <div class="form-group"> + <div [hidden]="true"> + <button type="button" id="modalButton" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="modal.open()">Open me! + </button> + </div> + <div> + <modal #modal> + <modal-header [show-close]="true"> + <h4 class="modal-title">{{title}}</h4> + </modal-header> + <modal-body> + {{message}} + </modal-body> + <modal-footer> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" data-dismiss="modal">Close + </button> + </modal-footer> + </modal> + </div> + <div class="card" style=" margin-bottom: 23px;"> + <img class="card-img-top" data-src="holder.js/100%x180/" alt=""> + <div class="card-block" style="border-top: 5px solid #6ab344;border-top-right-radius: 7px;border-top-left-radius: 7px;"> + <div class="row" style="padding: 15px 25px"> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Action</label> + <input class="form-control" type="text" disabled value="{{action}}" /> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Vnf Type</label><input class="form-control" type="text" disabled value="{{vnfType}}" /> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Vnfc Type</label><input class="form-control" type="text" disabled value="{{vnfcType}}" /> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Protocol</label><input class="form-control" type="text" disabled value="{{protocol}}" /> + </div> + </div> + </div> + </div> + + <div class="col-12"> + <div class="input-group"> + <input id="inputFile2" class="file" #myInput type='file' (change)='fileChange(myInput)'> + <input type="text" class="input-lg" [(ngModel)]="myfileName" disabled placeholder="Upload Param file from PC" style="width:80%"> + <button (click)="browseOption($event)" [disabled]="!enableMappingBrowse" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg"> + Upload Param file + </button> + </div> + </div> + + <input type="file" id="filesparam" style="visibility:hidden;" class="form-control-file" (change)="fileParamChange(myInputParam)" #myInputParam placeholder="Upload file..." + /> + <div class="row" style="margin-bottom: 20px;"> + <div class="col-md-12 text-right"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="retrieveNameValueFromAppc()">Retrieve Name/Value from APPC + </button> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="syncParam()">Synchronize with name values + </button> + </div> + </div> + </div> + <hr> + <!--Commenting out 1712 changes here--> + <!--<div class="col-md-12" [hidden]="!showMappingDownloadDiv"><label>Download Name/Value pair as : </label> + <select class="form-control col-md-3" [(ngModel)]="mapppingDownloadType" (ngModelChange)="onDownloadParameter()"> + <option value="">Select</option> + <option value="Json">JSON</option> + <option value="Xls">XLS</option> + </select> +</div>--> + + <div class="col-md-12"></div> + <div><label for="textAreaGeneratedTemplate"> + <div class="mdl-card__title-text">Param Name Value List</div> + <div><font size="1">(Please click anywhere on the editor to see the synced name value pairs)</font></div> + </label> + <!-- <ace-editor [(text)]="this.artifactRequest.paramsContent" [theme]="'chrome'" [mode]="'velocity'" (textChanged)="onParamChanges($event)" [options]="{maxLines: 'Infinity', fontSize: '13pt'}" + style="min-height: 500px; width: fit-content;"></ace-editor> --> + <ace-editor [(text)]="this.artifactRequest.paramsContent" #templateeditor [theme]="'chrome'" [mode]="'velocity'" (textChanged)="onParamChanges($event)" + [options]="{maxLines: 'Infinity', fontSize: '13pt' }" style="min-height: 500px; width: 100%"></ace-editor> + </div> + + </tab> +</tabs>
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.ts b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.ts new file mode 100644 index 0000000..9ea95ec --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.ts @@ -0,0 +1,711 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import { Component, ContentChildren, OnInit, QueryList, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MappingEditorService } from '../../../../shared/services/mapping-editor.service'; +import { HttpUtilService } from '../../../../shared/services/httpUtil/http-util.service'; +import { GoldenConfigurationComponent } from '../template-configuration/template-configuration.component'; +import { ArtifactRequest } from '../../../../shared/models/index'; +import { NotificationService } from '../../../../shared/services/notification.service'; +import { ModalComponent } from '../../../../shared/modal/modal.component'; +import { saveAs } from 'file-saver'; +import { DialogService } from 'ng2-bootstrap-modal'; +import { ConfirmComponent } from '../../../../shared/confirmModal/confirm.component'; +import { BuildDesignComponent } from '../../build-artifacts.component'; +import { ParamShareService } from '../../../../shared/services/paramShare.service'; +import { NotificationsService } from 'angular2-notifications'; +import { Tab } from './tab'; +import { environment } from '../../../../../environments/environment'; +import { NgProgress } from 'ngx-progressbar'; +import * as XLSX from 'xlsx'; + +type AOA = Array<Array<any>>; + +function s2ab(s: string): ArrayBuffer { + const buf = new ArrayBuffer(s.length); + const view = new Uint8Array(buf); + for (let i = 0; i !== s.length; ++i) { + view[i] = s.charCodeAt(i) & 0xFF; + } + return buf; +} + +declare var $: any; + +@Component({ + selector: 'app-golden-configuration-mapping', + templateUrl: './param-name-value.component.html', + styleUrls: ['./param-name-value.component.css'] +}) +export class GoldenConfigurationMappingComponent implements OnInit { + enableMappingSave: boolean = false; + aceText: string = ''; + fileName: string = ''; + actionType: any; + modal: any; + configMappingEditorContent: any; + fileType: any = ''; + myfileName: any; + initialData: any; + scopeName: any; + downloadedFileName: any; + enableSaveToAppc: boolean = false; + versionNo: any = '0.0.1'; + showVersionDiv: boolean = false; + initialAction: any; + title: any; + message: any; + enableMappingBrowse: boolean = true; + enableDownload: boolean = false; + showMappingDownloadDiv: boolean = false; + mapppingDownloadType: any; + action: any; + artifactName: any; + enableMerge: boolean = false; + apiToken = localStorage['apiToken']; + userId = localStorage['userId']; + public uploadTypes = [ + { + value: 'Mapping Data', + display: 'Sample Json Param File' + } + ]; + selectedUploadType: string = this.uploadTypes[0].value; + options = { + timeOut: 1000, + showProgressBar: true, + pauseOnHover: true, + clickToClose: true, + maxLength: 200 + }; + artifactRequest: ArtifactRequest = new ArtifactRequest(); + @ViewChild(GoldenConfigurationComponent) mappingComponent: GoldenConfigurationComponent; + @ViewChild('templateeditor') templateeditor; + @ViewChild('myInputParam') myInputParam: any; + @ViewChild(ModalComponent) modalComponent: ModalComponent; + @ContentChildren(Tab) tabs: QueryList<Tab>; + public subscription: any; + public item: any = {}; + + public Actions = [ + { action: 'ConfigBackup', value: 'ConfigBackup' }, + { action: 'ConfigModify', value: 'ConfigModify' }, + { action: 'ConfigRestore', value: 'ConfigRestore' }, + { action: 'Configure', value: 'Configure' }, + { action: 'GetRunningConfig', value: 'GetRunningConfig' }, + { action: 'HealthCheck', value: 'HealthCheck' }, + { action: 'StartApplication', value: 'StartApplication' }, + { action: 'StopApplication', value: 'StopApplication' } + ]; + vnfType: any; + vnfcType: any; + protocol: any; + refObj: any; + public paramsContent = localStorage['paramsContent']; + + constructor (private buildDesignComponent: BuildDesignComponent, private paramShareService: ParamShareService, private router: Router, private httpUtil: HttpUtilService, private dialogService: DialogService, private activeRoutes: ActivatedRoute, private mappingEditorService: MappingEditorService, private notificationService: NotificationService, private nService: NotificationsService, private ngProgress: NgProgress) { + this.artifactRequest.action = ''; + this.artifactRequest.version = ''; + this.artifactRequest.paramKeysContent = ''; + } + + ngOnInit() { + var refObj = this.refObj = this.prepareFileName(); + if (refObj && refObj != undefined) { + if (this.paramsContent && this.paramsContent != undefined && this.paramsContent !== '{}') { + this.artifactRequest.paramsContent = this.formatNameValuePairs(this.paramsContent); + // this.artifactRequest.paramsContent = this.paramsContent; + + } + else { + this.artifactRequest.paramsContent = '{}'; + } + + // refObj = refObj[refObj.length - 1]; + this.item = refObj; + this.vnfType = this.item.scope['vnf-type']; + this.vnfcType = this.item.scope['vnfc-type']; + this.protocol = this.item['device-protocol']; + this.action = this.item.action; + var artifactList = this.item['artifact-list']; + for (var i = 0; i < artifactList.length; i++) { + var artifactName = artifactList[i]['artifact-name']; + var array = artifactName.split('_'); + if (array[0].toUpperCase() === 'TEMPLATE') { + this.artifactName = artifactName; + } + } + } + else { + this.item = { + 'action': '', + 'scope': { 'vnf-type': '', 'vnfc-type': '' }, + 'vm': [], + 'protocol': '', + 'download-dg-reference': '', + 'user-name': '', + 'port-number': '', + 'artifact-list': [], + 'deviceTemplate': '', + 'scopeType': '' + }; + } + this.initialAction = this.item.action; + this.activeRoutes.url.subscribe(UrlSegment => { + this.actionType = UrlSegment[0].path; + }); + if (this.actionType === 'configureTemplate') { + this.mappingEditorService.fromScreen = 'TemplateScreen'; + } + if (this.actionType === 'myTemplates') { + this.mappingEditorService.fromScreen = 'MappingScreen'; + } + this.mappingEditorService.paramData = []; + + + } + + //========================== End of ngOnInit() Method============================================ + browseOption() { + $('#filesparam').trigger('click'); + } + + //========================== End of browseOption() Method============================================ + selectedNavItem(item: any) { + this.item = item; + } + + //========================== End of selectedNavItem() Method============================================ + ngOnDestroy() { + this.prepareFileName(); + } + + //========================== End of ngOnDestroy() Method============================================ + ngAfterViewInit() { + if (this.mappingEditorService.fromScreen === 'MappingScreen') { + this.configMappingEditorContent = this.mappingEditorService.getTemplateMappingDataFromStore(); + this.fileType = sessionStorage.getItem('fileType'); + if (this.configMappingEditorContent) + this.mappingEditorService.initialise(this.mappingComponent.templateeditor.getEditor(), this.configMappingEditorContent, this.modal); + } + if (this.refObj) { + + this.artifactRequest.action = this.item.action; + this.artifactRequest.vnfType = this.vnfType; + if (this.vnfcType && this.vnfcType.length != 0) { + this.scopeName = this.vnfcType; + } + else { + this.scopeName = this.vnfType; + } + } + else { + this.Actions = []; + this.enableMappingBrowse = false; + } + } + + //========================== End of ngAfterViewInit() Method============================================ + upload(evt: any) { + /* wire up file reader */ + if (evt.target.files[0]) { + const target: DataTransfer = <DataTransfer>(evt.target); + this.myfileName = evt.target.files[0].name; + var fileExtension = this.myfileName.substr(this.myfileName.lastIndexOf('.') + 1); + if (fileExtension.toUpperCase() === 'xls'.toUpperCase()) { + if (target.files.length != 1) { + throw new Error('Cannot upload multiple files on the entry'); + } + const reader = new FileReader(); + reader.onload = (e: any) => { + /* read workbook */ + const bstr = e.target.result; + const wb = XLSX.read(bstr, { type: 'binary' }); + /* grab first sheet */ + const wsname = wb.SheetNames[0]; + const ws = wb.Sheets[wsname]; + /* save data */ + let arrData = (<AOA>(XLSX.utils.sheet_to_json(ws, { header: 1 }))); + var jsonStr = arrData.toString(); + var JsonArr = jsonStr.split(','); + var finalStr = '{\r\n'; + for (var i = 0; i < JsonArr.length; i = i + 2) { + var key = JsonArr[i]; + var value = JsonArr[i + 1]; + finalStr = finalStr + key + ':' + value + ',\r\n'; + } + finalStr = finalStr.substring(0, finalStr.length - 3) + '\r\n}'; + this.artifactRequest.paramsContent = finalStr; + this.initialData = finalStr; + this.enableMappingSave = true; + }; + reader.readAsBinaryString(target.files[0]); + if ('Mapping Data' === this.selectedUploadType) { + this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..'); + this.mappingEditorService.setParamContent(this.artifactRequest.paramsContent); + } + } + else { + let reader = new FileReader(); + this.readFile(evt.target.files[0], reader, (result) => { + if ('Mapping Data' === this.selectedUploadType) { + var jsonObject = JSON.parse(result); + this.artifactRequest.paramsContent = JSON.stringify(jsonObject, null, 1); + this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..'); + this.mappingEditorService.setParamContent(this.artifactRequest.paramsContent); + } + this.initialData = result; + this.enableMappingSave = true; + }); + } + } + else { + this.notificationService.notifyErrorMessage('Failed to reading file..'); + } + this.myInputParam.nativeElement.value = ''; + } + + //========================== End of upload() Method============================================ + //uncommenting for 1710 + public fileParamChange(input) { + if (input.files && input.files[0]) { + this.enableMappingSave = true; + this.myfileName = input.files[0].name; + var fileExtension = this.myfileName.substr(this.myfileName.lastIndexOf('.') + 1); + if (this.validateUploadedFile(fileExtension)) { + // Create the file reader + let reader = new FileReader(); + this.readFile(input.files[0], reader, (result) => { + if ('Mapping Data' === this.selectedUploadType) { + var jsonObject = JSON.parse(result); + this.artifactRequest.paramsContent = JSON.stringify(jsonObject, null, 1); + this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..'); + this.mappingEditorService.setParamContent(this.artifactRequest.paramsContent); + localStorage['paramsContent'] = this.artifactRequest.paramsContent; + } + this.enableMerge = true; + this.initialData = result; + }); + } + else { + this.nService.error("Error", "Incorrect File Format") + this.artifactRequest.paramsContent = '' + } + } + else { + this.nService.error("Error", "Failed to read file"); + } + this.myInputParam.nativeElement.value = ''; + } + + //========================== End of fileParamChange() Method============================================ + validateUploadedFile(fileExtension) { + + if (fileExtension.toUpperCase() === 'json'.toUpperCase()) { + return true; + } + else { + return false; + } + + } + //========================== End of validateUploadedFile() Method============================================ + public readFile(file, reader, callback) { + // Set a callback funtion to fire after the file is fully loaded + reader.onload = () => { + // callback with the results + callback(reader.result); + }; + this.notificationService.notifySuccessMessage('Uploading File ' + file.name + ':' + file.type + ':' + file.size); + // Read the file + reader.readAsText(file, 'UTF-8'); + } + + //========================== End of readFile() Method============================================ + public onParamChanges(data) { + this.artifactRequest.paramsContent = data; + localStorage['paramsContent'] = this.artifactRequest.paramsContent; + } + + //========================== End of onParamChanges() Method============================================ + onDownloadParameter() { + let refObj = this.refObj; + if (refObj) { + // refObj = refObj[refObj.length - 1]; + let paramsKeyValueFromEditor: JSON; + this.initialData = this.artifactRequest.paramsContent; + paramsKeyValueFromEditor = JSON.parse(this.artifactRequest.paramsContent); + let theJSON = JSON.stringify(paramsKeyValueFromEditor, null, '\t'); + var blob = new Blob([theJSON], { + type: 'text/json' + }); + this.showVersionDiv = true; + let fileName: any; + fileName = this.updateFileName(refObj.action, this.scopeName, this.versionNo); + saveAs(blob, fileName); + } + else { + this.nService.error('Error', 'Please enter Action and VNF type in Reference Data screen'); + + } + } + + //========================== End of onDownloadParameter() Method============================================ + JSONToCSVConvertor(JSONData, fileName, ShowLabel) { + //If JSONData is not an object then JSON.parse will parse the JSON string in an Object + var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData; + var CSV = ''; + //This condition will generate the Label/Header + if (ShowLabel) { + var testRow = ''; + for (var index in arrData[0]) { + CSV += index + '\t' + arrData[0][index] + '\r\n'; + } + } + if (CSV == '') { + return; + } + //Initialize file format you want csv or xls + var uri = 'data:application/vnd.ms-excel,' + encodeURI(CSV); + var link = document.createElement('a'); + link.href = uri; + link.download = fileName + '.xls'; + //this part will append the anchor tag and remove it after automatic click + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + + //========================== End of JSONToCSVConvertor() Method============================================ + updateFileNameForXls(action: any, scopeName: any, versionNo: any) { + let fileName = 'param_' + action + '_' + scopeName + '_' + versionNo + 'V'; + return fileName; + } + + //========================== End of updateFileNameForXls() Method============================================ + appendSlashes(artifactData) { + let x = artifactData.replace(new RegExp(',"', 'g'), ',\"'); + let y = x.replace(new RegExp('":', 'g'), '\":'); + let z = y.replace(new RegExp('{"', 'g'), '{\"'); + let t = z.replace(new RegExp(':"', 'g'), ':\"'); + let m = t.replace(new RegExp('",', 'g'), '\",'); + let n = y.replace(new RegExp('"}', 'g'), '\"}'); + let nw = n.replace(new RegExp('{"', 'g'), '{\"'); + let nw1 = nw.replace(new RegExp(':"', 'g'), ':\"'); + let nw2 = nw1.replace(new RegExp('",', 'g'), '\",'); + return nw2; + } + + //========================== End of appendSlashes() Method============================================ + updateFileName(action: any, scopeName: any, versionNo: any) { + let fileName = 'param_' + action + '_' + scopeName + '_' + versionNo + 'V.json'; + this.downloadedFileName = fileName; + return fileName; + } + + //========================== End of updateFileName() Method============================================ + prepareFileName(): any { + let fileNameObject: any = this.mappingEditorService.latestAction; + return fileNameObject; + } + + //========================== End of prepareFileName() Method============================================ + openModel(toShow: any, message: any, title: any) { + this.message = message; + this.title = title; + $('#modalButton').trigger('click'); + } + + //========================== End of openModel() Method============================================ + checkSave(selectedAction): void { + if (this.actionType === 'updateTemplate') { + if (!this.buildDesignComponent.isReferenceFound(selectedAction, this.mappingEditorService.getReferenceList())) { + this.nService.error('Error', 'Reference Data not found. Please add Reference Data for Action:' + selectedAction); + } + } + if (this.initialData != this.artifactRequest.paramsContent) { + this.showConfirm(this.initialData); + } + else { + this.initialAction = this.item.action; + } + } + + //========================== End of checkSave() Method============================================ + showConfirm(initialData) { + let disposable = this.dialogService.addDialog(ConfirmComponent, { + title: 'Confirm title', + message: 'Confirm message' + }) + .subscribe((isConfirmed) => { + //We get dialog result + if (isConfirmed) { + this.artifactRequest.paramsContent = initialData; + this.initialAction = this.item.action; + } + else { + this.item.action = this.initialAction; + } + }); + } + + //========================== End of showConfirm() Method============================================ + retrieveNameValueFromAppc() { + let refObj = this.refObj; + if (refObj && refObj != undefined) { + // console.log("REF OBJECT IN RETRIVE"+JSON.stringify(refObj)); + this.enableMerge = true; + var scopeName = this.scopeName.replace(/ /g, '').replace(new RegExp('/', "g"), '_').replace(/ /g, ''); + let fileName = this.updateFileName(this.item.action, scopeName, this.versionNo); + let payload = '{"userID": "' + this.userId + '", "action": "' + this.item.action + '", "vnf-type" : "' + this.vnfType + '", "artifact-type":"APPC-CONFIG", "artifact-name":"' + fileName + '"}'; + // console.log("payload OBJECT IN RETRIVE"+JSON.stringify(payload)); + let input = { + 'input': { + 'design-request': { + 'request-id': this.apiToken, + 'action': 'getArtifact', + 'payload': payload + } + } + }; + + console.log('Retrieve name value from appc payload===>>' + payload); + let artifactContent: any; + this.ngProgress.start(); + this.httpUtil.post({ + url: environment.getDesigns, + data: input + }).subscribe(resp => { + if (resp.output.status.code === '400' && resp.output.status.message === 'success') { + this.nService.success('Success', 'Name/value pairs retrieved successfully from APPC'); + this.enableMerge = true; + let result = JSON.parse(resp.output.data.block).artifactInfo[0]; + result = result['artifact-content']; + var string = result.substring(2, result.length - 2); + var stringArr = string.split(','); + var newStringArr = []; + var resultStr = '{\r\n'; + for (var index in stringArr) { + newStringArr[index] = stringArr[index] + ',\r\n'; + } + for (var index in newStringArr) { + resultStr = resultStr + newStringArr[index]; + } + resultStr = resultStr.substring(0, resultStr.length - 3) + '\r\n}'; + this.artifactRequest.paramsContent = resultStr; + this.mappingEditorService.setParamContent(resultStr); + localStorage['paramsContent'] = resultStr; + this.enableMappingSave = true; + } + else { + this.nService.info('Information', 'There are no name value pairs saved in APPC for the selected action!'); + } + this.ngProgress.done(); + }, + error => this.nService.error('Error', 'Error in connecting to APPC Server')); + } + setTimeout(() => { + this.ngProgress.done(); + }, 3500); + } + + //========================== End of retrieveNameValueFromAppc() Method============================================ + saveNameValueToAppc() { + let refObj = this.refObj; + if (refObj && refObj != undefined) { + // refObj = refObj[refObj.length - 1]; + let paramsKeyValueFromEditor = JSON.parse(this.artifactRequest.paramsContent); + let action = this.item.action; + let fileName = this.updateFileName(refObj.action, this.scopeName, this.versionNo); + let vnfType = this.vnfType; + let Json = [paramsKeyValueFromEditor]; + let slashedPayload = this.appendSlashes(JSON.stringify(Json)); + let newPayload = + { + 'userID': this.userId, + 'vnf-type': this.vnfType, + 'action': action, + 'artifact-name': fileName, + 'artifact-type': 'APPC-CONFIG', + 'artifact-version': this.versionNo, + 'artifact-contents': slashedPayload + }; + let data = + { + 'input': { + 'design-request': { + 'request-id': this.apiToken, + 'action': 'uploadArtifact', + 'payload': JSON.stringify(newPayload) + } + } + }; + this + .httpUtil + .post( + { url: environment.getDesigns, data: data }) + .subscribe(resp => { + if (resp.output.status.code === '400' && resp.output.status.message === 'success') { + this.nService.success('Success', 'Name/value pairs saved successfully to APPC'); + } + if (resp.output.status.code === '401') { + this.nService.error('Error', resp.output.status.message); + } + }, + error => this.nService.error('Error', 'Could not save name value pairs. Error in connecting APPC Server')); + } + setTimeout(() => { + this.ngProgress.done(); + }, 3500); + } + + //========================== End of saveNameValueToAppc() Method============================================ + formatNameValuePairs(namevaluePairs: string) { + //var string = namevaluePairs.substring(2, namevaluePairs.length - 2); + /* var stringArr = string.split(","); + var newStringArr = []; + var resultStr = "{\r\n\""; + for (var index in stringArr) { + newStringArr[index] = stringArr[index] + ",\r\n"; + } + for (var index in newStringArr) { + resultStr = resultStr + newStringArr[index]; + } + resultStr = resultStr.substring(0, resultStr.length - 3) + "\"\r\n}" + return resultStr;*/ + + var string = namevaluePairs.substring(1, namevaluePairs.length - 1); + var stringArr = string.split(','); + var newStringArr = []; + var resultStr = '{\r\n'; + for (var index in stringArr) { + newStringArr[index] = stringArr[index] + ',\r\n'; + } + for (var index in newStringArr) { + resultStr = resultStr + newStringArr[index]; + } + resultStr = resultStr.substring(0, resultStr.length - 3) + '\r\n}'; + return resultStr; + } + + //========================== End of formatNameValuePairs() Method============================================ + + public syncParam() { + var paramNameValuesStr = localStorage['paramsContent']; + var pdData = this.paramShareService.getSessionParamData(); + var paramNameValues = []; + var pdDataArrayForParamShare = []; + var pdDataArrayForSession = []; + try { + paramNameValues = JSON.parse(paramNameValuesStr); + console.log('Param Name values array==' + JSON.stringify(paramNameValues)); + if (paramNameValues && paramNameValues != undefined) { + for (var index in paramNameValues) { + var json = { + 'paramName': index, + 'paramValue': paramNameValues[index] + }; + pdDataArrayForParamShare.push(json); + + pdDataArrayForSession.push({ + 'name': index, + 'type': null, + 'description': null, + 'required': null, + 'default': null, + 'source': 'Manual', + 'rule-type': null, + 'request-keys': [{ + 'key-name': null, + 'key-value': null + }, { + 'key-name': null, + 'key-value': null + }, { + 'key-name': null, + 'key-value': null + }], + 'response-keys': [{ + 'key-name': null, + 'key-value': null + }, { + 'key-name': null, + 'key-value': null + }, { + 'key-name': null, + 'key-value': null + }, { + 'key-name': null, + 'key-value': null + }, { + 'key-name': null, + 'key-value': null + }], + 'ruleTypeValues': [null] + + }); + + } + this.paramShareService.setTemplateData(pdDataArrayForParamShare); + + if (pdData && pdData != undefined) { + for (var i = 0; i < pdDataArrayForSession.length; i++) { + + pdData.forEach(function (arr2item) { + if (pdDataArrayForSession[i].name === arr2item.name) { + + var json = { + 'name': arr2item.name, + 'type': arr2item.type, + 'description': arr2item.description, + 'required': arr2item.required, + 'default': arr2item.default, + 'source': arr2item.source, + 'rule-type': arr2item['rule-type'], + 'request-keys': arr2item['request-keys'], + 'response-keys': arr2item['response-keys'], + 'ruleTypeValues': arr2item.ruleTypeValues + }; + pdDataArrayForSession.splice(i, 1, json); + // console.log("Result array index ==" + JSON.stringify(resultArr[i])) + } + + }); + + } + } + + this.paramShareService.setSessionParamData(pdDataArrayForSession); + + this.router.navigate(['../../../vnfs/design/parameterDefinitions/create']); + + } + } + catch (error) { + console.log('Error occured in syncing param names' + JSON.stringify(error)); + this.nService.error('Error', 'Error synchronising with name values. Please check the format of json uploaded/ retrieved'); + } + } + +}
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/template-holder/param-name-value/tab.ts b/src/app/vnfs/build-artifacts/template-holder/param-name-value/tab.ts new file mode 100644 index 0000000..5e4fa6c --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/param-name-value/tab.ts @@ -0,0 +1,43 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {Component, Input} from '@angular/core'; + +@Component({ + selector: 'tab', + styles: [` + .pane { + padding: 1em; + } + `], + template: ` + <div [hidden]="!isactive" class="pane"> + <ng-content></ng-content> + </div> + ` +}) +export class Tab { + @Input('tabTitle') title: string; + @Input() isactive = false; + @Input() isParamTab = false; +}
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/template-holder/param-name-value/tabs.ts b/src/app/vnfs/build-artifacts/template-holder/param-name-value/tabs.ts new file mode 100644 index 0000000..92f489e --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/param-name-value/tabs.ts @@ -0,0 +1,63 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {AfterContentInit, Component, ContentChildren, QueryList} from '@angular/core'; +import {Tab} from './tab'; + +@Component({ + selector: 'tabs', + template: ` + <ul class="nav nav-tabs"> + <li [ngClass]="{'active-tab':(tab.isactive==true)}" class="nav-item" *ngFor="let tab of tabs" (click)="selectTab(tab)" + [class.active]="tab.isactive"> + <a class="nav-link" ng-href=''>{{tab.title}}</a> + </li> + </ul> + <ng-content></ng-content> + `, styleUrls: ['./param-name-value.component.css'] +}) +export class Tabs implements AfterContentInit { + + @ContentChildren(Tab) tabs: QueryList<Tab>; + + + // contentChildren are set + ngAfterContentInit() { + // get all active tabs + let activeTabs = this.tabs.filter((tab) => tab.isactive); + + // if there is no active tab set, activate the first + if (activeTabs.length === 0) { + this.selectTab(this.tabs.first); + } + } + + public selectTab(tab: Tab) { + // deactivate all tabs + this.tabs.toArray().forEach(tab => tab.isactive = false); + + // activate the tab the user has clicked on. + tab.isactive = true; + } + +} diff --git a/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.css b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.css new file mode 100644 index 0000000..c8100e3 --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.css @@ -0,0 +1,35 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +.file { + visibility: hidden; + position: absolute; +} + +.mt-30 { + margin-top: 30px; +} + +.options-menu { + padding: 3px 20px; +}
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.html b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.html new file mode 100644 index 0000000..c1fb030 --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.html @@ -0,0 +1,100 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> +<simple-notifications [options]="options"></simple-notifications> +<ng-progress [positionUsing]="'marginLeft'" [minimum]="0.15" [maximum]="1" [speed]="200" [showSpinner]="false" [direction]="'leftToRightIncreased'" [color]="'#6ab344'" + [trickleSpeed]="250" [thick]="true" [ease]="'linear'"></ng-progress> +<div> + <div> + <div class="card" style="margin-bottom: 23px;"> + <img class="card-img-top" data-src="holder.js/100%x180/" alt=""> + <div class="card-block" style="border-top: 5px solid #6ab344;border-top-right-radius: 7px;border-top-left-radius: 7px;"> + <div class="row" style="padding: 15px 25px"> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Action</label> + <input class="form-control" type="text" disabled value="{{action}}" /> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Vnf Type</label><input class="form-control" type="text" disabled value="{{vnfType}}" /> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Vnfc Type</label><input class="form-control" type="text" disabled value="{{vnfcType}}" /> + </div> + <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>Protocol</label><input class="form-control" type="text" disabled value="{{protocol}}" /> + </div> + <div *ngIf="(action === 'ConfigScaleOut')" class="col-lg-3 col-sm-6 col-md-3 col-xs-12"> + <label>templateIdentifier</label><input class="form-control" type="text" disabled value="{{identifier}}" /> + </div> + </div> + </div> + </div> + + <div class="col-12"> + <div class="input-group"> + <input id="inputFile" class="file" #myInput type='file' (change)='fileChange(myInput)'> + <input [(ngModel)]="fileName" type="text" class="input-lg" disabled placeholder="Upload template from PC" style="width:80%"> + <button (click)="browseOption($event)" [disabled]="!enableBrowse" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg" + type="button">Upload Template File + </button> + </div> + </div> + + <br> + <div class="row" style="margin-bottom: 20px;"> + <div class="col-md-12 text-right"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="syncTemplate()">Synchronize Template Parameters + </button> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="mergeParams()"> Merge from Param + </button> + </div> + </div> + </div> + <hr> + <div><label for="textAreaGeneratedTemplate"> + <div class="mdl-card__title-text">File Editor</div> + </label> + <!-- <ace-editor [(text)]="configMappingEditorContent" #templateeditor [theme]="'chrome'" [mode]="'velocity'" [options]="{maxLines: 'Infinity', fontSize: '13pt'}" + style="min-height: 500px; width: fit-content;scroll-snap-coordinate: 3%"></ace-editor> --> + <ace-editor [(text)]="configMappingEditorContent" #templateeditor [theme]="'chrome'" [mode]="'velocity'" [options]="{maxLines: 'Infinity', fontSize: '13pt' }" + style="min-height: 500px; width: 100%"></ace-editor> + </div> + <app-modal [title]="'Confirmation'" [isShow]="false" [message]="'Template is saved and ready for creating parameter definition'" #modalComponent> + </app-modal> + <modal #myModal> + <modal-header [show-close]="true"> + <h4 class="modal-title">Enter Name for {{selectedWord}}</h4> + </modal-header> + <modal-body> + <div class="form-group row"> + <label for="example-text-input" class="col-12 col-form-label">Name</label> + <div class="col-12"> + <input class="form-control" [(ngModel)]="tempName" name="templateName" type="text" id="tempName"> + <span class="error-message" [hidden]="checkNameEntered" style="color: red;">Required Field</span> + </div> + </div> + </modal-body> + <modal-footer [show-default-buttons]="false"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" (click)="submitNameValues()">Submit + </button> + </modal-footer> + </modal>
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.spec.ts b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.spec.ts new file mode 100644 index 0000000..f26e5fd --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.spec.ts @@ -0,0 +1,199 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing'; +import { By, BrowserModule } from '@angular/platform-browser'; +import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; +import { Component, OnInit, ViewChild, Input } from '@angular/core'; +//import { ModalComponent } from '../../modal/modal.component'; +import { HttpUtilService } from '../../../../shared/services/httpUtil/http-util.service'; +import { MappingEditorService } from '../../../../shared/services/mapping-editor.service'; +import { ArtifactRequest } from '../../../../shared/models/index'; +import { ActivatedRoute, Router } from "@angular/router"; +import { saveAs } from "file-saver"; +import { NotificationService } from '../../../../shared/services/notification.service'; +import { NotificationsService } from "angular2-notifications" +import { ParamShareService } from '../../../../shared/services/paramShare.service'; +import { DialogService } from "ng2-bootstrap-modal"; +import {ConfirmComponent} from '../../../../shared/confirmModal/confirm.component'; +import {BuildDesignComponent} from '../../build-artifacts.component'; +import { environment } from '../../../../../environments/environment'; +import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal' +import { FormsModule } from '@angular/forms'; +import { RouterTestingModule } from '@angular/router/testing'; +import { HomeComponent } from '../../../../home/home/home.component'; +import { LogoutComponent } from '../../../../shared/components/logout/logout.component'; +import { HelpComponent } from '../../../../shared/components/help/help/help.component'; +import { AboutUsComponent } from '../../../../about-us/aboutus.component'; +import { TestComponent } from '../../../../test/test.component'; +import { HttpModule } from '@angular/http'; +import { AceEditorComponent } from 'ng2-ace-editor'; +import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal'; +import { SimpleNotificationsModule } from 'angular2-notifications'; +import { GoldenConfigurationComponent } from './template-configuration.component'; +import { NgProgress } from 'ngx-progressbar'; + +describe('GoldenConfigurationComponent', () => { + let component: GoldenConfigurationComponent; + let fixture: ComponentFixture<GoldenConfigurationComponent>; + let buildDesignComponent: BuildDesignComponent; + let paramShareService: ParamShareService; + let dialogService: DialogService; + let notificationService: NotificationService; + let httpUtil: HttpUtilService; + let mappingEditorService: MappingEditorService; + let activeRoutes: ActivatedRoute; + let router: Router; + let nService: NotificationsService + const routes = [ + { + path: 'home', + component: HomeComponent + }, { + path: 'vnfs', + loadChildren: '../../../../vnfs/vnfs.module#VnfsModule' + }, { + path: 'test', + component: TestComponent + }, + { + path: 'help', + component: HelpComponent + }, { + path: 'aboutUs', + component: AboutUsComponent + }, { + path: 'logout', + component: LogoutComponent + }, { + path: '', + redirectTo: '/home', + pathMatch: 'full' + } + ]; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [FormsModule, BrowserModule, RouterTestingModule.withRoutes(routes), HttpModule, Ng2Bs3ModalModule, SimpleNotificationsModule.forRoot()], + declarations: [GoldenConfigurationComponent, HomeComponent, TestComponent, HelpComponent, AboutUsComponent, LogoutComponent, AceEditorComponent], + providers: [BuildDesignComponent, NgProgress, ParamShareService, DialogService, NotificationService, HttpUtilService, MappingEditorService, NotificationsService], + schemas: [NO_ERRORS_SCHEMA], + }) + + }); + + beforeEach(async(() => { + TestBed.compileComponents() + + })); + + + it('validate if uploaded file should be xml or json', () => { + fixture = TestBed.createComponent(GoldenConfigurationComponent); + component = fixture.componentInstance; + expect(component.validateUploadedFile('xls')).toBe(false); + expect(component.validateUploadedFile('json')).toBe(true); + expect(component.validateUploadedFile('xml')).toBe(true); + }); + + + it('validate initialisation of variables in ngOnit() function', inject([MappingEditorService], (mappingEditorService: MappingEditorService) => { + fixture = TestBed.createComponent(GoldenConfigurationComponent); + component = fixture.componentInstance; + mappingEditorService.latestAction = { "action": "Configure", "action-level": "vnf", "scope": { "vnf-type": "testVnf", "vnfc-type": "" }, "template": "Y", "vm": [], "device-protocol": "CHEF", "user-name": "", "port-number": "", "artifact-list": [{ "artifact-name": "template_Configure_test_0.0.1V.json", "artifact-type": "config_template" }, { "artifact-name": "pd_Configure_test_0.0.1V.yaml", "artifact-type": "parameter_definitions" }], "scopeType": "vnf-type" } + + expect(component.ngOnInit()); + expect(component.ngAfterViewInit()); + expect(component.action).toEqual('Configure'); + expect(component.vnfType).toEqual('testVnf'); + expect(component.vnfcType).toEqual(''); + expect(component.protocol).toEqual('CHEF'); + + expect(component.artifactName).toEqual('template_Configure_test_0.0.1V.json'); + + mappingEditorService.latestAction = { "action": "Configure", "action-level": "vnf", "scope": { "vnf-type": "testVnf", "vnfc-type": "testVnfc" }, "template": "Y", "vm": [], "device-protocol": "CHEF", "user-name": "", "port-number": "", "artifact-list": [{ "artifact-name": "template_Configure_test_0.0.1V.json", "artifact-type": "config_template" }, { "artifact-name": "pd_Configure_test_0.0.1V.yaml", "artifact-type": "parameter_definitions" }], "scopeType": "vnf-type" } + expect(component.ngOnInit()); + expect(component.vnfcType).toEqual('testVnfc'); + + + })); + + it('check if variables are empty when reference data object is empty', inject([MappingEditorService], (mappingEditorService: MappingEditorService) => { + fixture = TestBed.createComponent(GoldenConfigurationComponent); + component = fixture.componentInstance; + mappingEditorService.latestAction = { "action": "", "scope": { "vnf-type": "", "vnfc-type": "" }, "vm": [], "protocol": "", "download-dg-reference": "", "user-name": "", "port-number": "", "artifact-list": [], "deviceTemplate": "", "scopeType": "" }; + + expect(component.ngAfterViewInit()); + expect(component.action).toEqual(''); + expect(component.vnfType).toEqual(''); + expect(component.vnfcType).toEqual(''); + expect(component.protocol).toEqual(''); + expect(component.artifactName).toEqual(''); + + })); + + it('check if correct notification is fired while initialising if reference data object is undefined',()=>{ + fixture = TestBed.createComponent(GoldenConfigurationComponent); + component = fixture.componentInstance; + expect(component.ngAfterViewInit()); + expect(component.Actions.length).toBe(0) + expect(component.enableBrowse).toBe(false) + }); + + it('test sync template when template data, param data and pd data are available', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => { + fixture = TestBed.createComponent(GoldenConfigurationComponent); + component = fixture.componentInstance; + mappingEditorService.fromScreen === 'MappingScreen' + component.configMappingEditorContent="<configuration xmlns=\"http://xml.juniper.net/xnm/1.1/xnm\" \n xmlns:a=\"http://xml.juniper.net/junos/15.1X49/junos\" >\n <version>15.1X49-D50.3</version>\n <groups>\n <name>node0</name>\n <system>\n <tacplus-server>\n <name>${sync_auto-pop_name1}</name>\n <source-address>${sync_auto-pop_address1}</source-address>\n </tacplus-server>\n <tacplus-server>\n <name>${node0_tacplus_server_name2}</name>\n <source-address>${sync_auto-pop_address1}</source-address>\n </tacplus-server>\n </system> \n </groups>\n </configuration>" + mappingEditorService.initialise(component.templateeditor.getEditor(), component.configMappingEditorContent, component.modal); + + var pdData=[{"name":"sync_auto-pop_name1","type":null,"description":null,"required":null,"default":null,"source":"A&AI","rule-type":"vnfc-oam-ipv4-address-list","request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":"unique-key-name","key-value":"parent-name"},{"key-name":"unique-key-value","key-value":"vnfc"},{"key-name":"field-key-name","key-value":"ipaddress-v4-oam-vip"},{"key-name":null,"key-value":"vm-number"},{"key-name":null,"key-value":"test"}],"ruleTypeValues":[null,"vnf-name","vm-name-list","vnfc-name-list","vnf-oam-ipv4-address","vnfc-oam-ipv4-address-list"],"showFilterFields":true,"enableFilterByValue":true},{"name":"sync_auto-pop_address1","type":null,"description":null,"required":null,"default":null,"source":"A&AI","rule-type":"vm-name-list","request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":"unique-key-name","key-value":"parent-name"},{"key-name":"unique-key-value","key-value":"vserver"},{"key-name":"field-key-name","key-value":"vserver-name"},{"key-name":null,"key-value":"vnfc-function-code"},{"key-name":null,"key-value":null}],"ruleTypeValues":[null,"vnf-name","vm-name-list","vnfc-name-list","vnf-oam-ipv4-address","vnfc-oam-ipv4-address-list"],"showFilterFields":true,"enableFilterByValue":true},{"name":"node0_tacplus_server_name2","type":null,"description":null,"required":null,"default":null,"source":"Manual","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}]; + paramShareService.setSessionParamData([pdData]); + localStorage["paramsContent"]={ + "sync_auto-pop_name1":"10.0.1.34", + "sync_auto-pop_address1":"", + "node0_tacplus_server_name2":"192.34.45.5" + }; + expect(component.syncTemplate()); + + + })); + + it('test sync template when template data, param data and pd data are not available', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => { + fixture = TestBed.createComponent(GoldenConfigurationComponent); + component = fixture.componentInstance; + mappingEditorService.fromScreen === 'MappingScreen' + component.configMappingEditorContent="<configuration xmlns=\"http://xml.juniper.net/xnm/1.1/xnm\" \n xmlns:a=\"http://xml.juniper.net/junos/15.1X49/junos\" >\n <version>15.1X49-D50.3</version>\n <groups>\n <name>node0</name>\n <system>\n <tacplus-server>\n <name>${sync_auto-pop_name1}</name>\n <source-address>${sync_auto-pop_address1}</source-address>\n </tacplus-server>\n <tacplus-server>\n <name>${node0_tacplus_server_name2}</name>\n <source-address>${sync_auto-pop_address1}</source-address>\n </tacplus-server>\n </system> \n </groups>\n </configuration>" + mappingEditorService.initialise(component.templateeditor.getEditor(), component.configMappingEditorContent, component.modal); + + var pdData=[]; + paramShareService.setSessionParamData([pdData]); + localStorage["paramsContent"]={}; + expect(component.syncTemplate()); + + + })); + + +}); diff --git a/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.ts b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.ts new file mode 100644 index 0000000..8514e24 --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.ts @@ -0,0 +1,977 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import { Component, Input, OnInit, ViewChild } from '@angular/core'; +//import { ModalComponent } from '../../modal/modal.component'; +import { HttpUtilService } from '../../../../shared/services/httpUtil/http-util.service'; +import { MappingEditorService } from '../../../../shared/services/mapping-editor.service'; +import { ArtifactRequest } from '../../../../shared/models/index'; +import { ActivatedRoute, Router } from '@angular/router'; +import { saveAs } from 'file-saver'; +import { NotificationService } from '../../../../shared/services/notification.service'; +import { NotificationsService } from 'angular2-notifications'; +import { ParamShareService } from '../../../../shared/services/paramShare.service'; +import { DialogService } from 'ng2-bootstrap-modal'; +import { ConfirmComponent } from '../../../../shared/confirmModal/confirm.component'; +import { BuildDesignComponent } from '../../build-artifacts.component'; +import { environment } from '../../../../../environments/environment'; +import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal'; +import { NgProgress } from 'ngx-progressbar'; +declare var $: any + +@Component({ selector: 'app-golden-configuration', templateUrl: './template-configuration.component.html', styleUrls: ['./template-configuration.component.css'] }) +export class GoldenConfigurationComponent implements OnInit { + @ViewChild('templateeditor') templateeditor; + @Input() configMappingEditorContent: string; + @Input() isMappingComp: boolean; + @ViewChild('myInput') myInputVariable: any; + // @ViewChild(ModalComponent) modalComponent: ModalComponent; + @ViewChild('myModal') modal: ModalComponent; + aceText: string = "" + fileName: string = "" + showTemplateVersionDiv: any; + downloadedTemplateFileName: any; + downloadedParamFileName: any; + templateVersionNo: any = '0.0.1'; + saveToGuiCacheFlag = 'false'; + initialAction: any; + public referenceData: Array<Object> = []; + public scopeName: any; + public subscription: any; + public item: any = {}; + public goldenActions: Array<string> = []; + public refNameObj = {}; + public action = ''; + public artifactName = ''; + public type; + public showError: boolean = false; + public tempretrieveFlag: boolean = false; + public fileNameForTempSave; + initialData: any; + showDownloadDiv: boolean = false; + downloadType: any; + enableBrowse: boolean = true; + enableMerge: boolean = false; + uploadValidationSuccess: boolean = false; + fileExtension: any = "xml"; + apiToken = localStorage['apiToken']; + public appDataObject: any; + public downloadDataObject: any; + public checkNameEntered: boolean = true; + public selectedWord: any = this.mappingEditorService.getSelectedWord(); + public Actions = [ + { action: "ConfigBackup", value: "ConfigBackup" }, + { action: "ConfigModify", value: "ConfigModify" }, + { action: "ConfigRestore", value: "ConfigRestore" }, + { action: "Configure", value: "Configure" }, + { action: "GetRunningConfig", value: "GetRunningConfig" }, + { action: "HealthCheck", value: "HealthCheck" }, + { action: "StartApplication", value: "StartApplication" }, + { action: "StopApplication", value: "StopApplication" } + ]; + options = { + timeOut: 1000, + showProgressBar: true, + pauseOnHover: true, + clickToClose: true, + maxLength: 200 + } + public enableDownloadButtons: boolean = false; + constructor(private buildDesignComponent: BuildDesignComponent, private paramShareService: ParamShareService, private dialogService: DialogService, private notificationService: NotificationService, private httpUtil: HttpUtilService, private mappingEditorService: MappingEditorService, private activeRoutes: ActivatedRoute, private router: Router, private nService: NotificationsService, private ngProgress: NgProgress) { + this.artifactRequest.action = ''; + this.artifactRequest.version = ''; + this.artifactRequest.paramsContent = '{}'; + this.artifactRequest.paramKeysContent = ''; + } + public templateEditor: any; + public fileType: any = ''; + public actionType: any; + public myfileName: any; + userId = localStorage['userId']; + public artifactRequest: ArtifactRequest = new ArtifactRequest(); + public showUploadStatus: boolean = false; + public uploadStatus: boolean = false; + public uploadTypes = [ + { + value: 'Generated Template', + display: 'Sample Json Param File' + }, + { + value: 'Mapping Data', + display: 'Sample Json Param File' + } + ]; + vnfType: any = ''; + vnfcType: any = ''; + protocol: any = ''; + refObj: any; + editor: any; + editorContent: any; + tempName: any; + enableValidateTemplate: boolean = false;; + public selectedUploadType: string = this.uploadTypes[0].value; + identifier: any; + //this.mappingeditorservice.referenceNameObjects = object;PLEASE USE THIS OBJECT TO GET TEMPALLDATA + //==================================================== + ngOnInit() { + var refObj = this.refObj = this.prepareFileName(); + // console.log("Ref object: " + JSON.stringify(refObj)) + if (refObj && refObj != undefined) { + // refObj = refObj[refObj.length - 1]; + this.item = refObj; + + this.vnfType = this.item.scope["vnf-type"]; + this.vnfcType = this.item.scope["vnfc-type"]; + this.protocol = this.item['device-protocol']; + this.action = this.item.action; + this.artifactRequest.action = this.item.action; + this.artifactRequest.vnfType = this.vnfType; + if (this.vnfcType != undefined && this.vnfcType.length != 0) { + this.scopeName = this.vnfcType; + } + else { + this.scopeName = this.vnfType; + } + } + else { + this.item = { "action": "", "scope": { "vnf-type": "", "vnfc-type": "" }, "vm": [], "protocol": "", "download-dg-reference": "", "user-name": "", "port-number": "", "artifact-list": [], "deviceTemplate": "", "scopeType": "" }; + } + this.initialAction = this.item.action; + this.activeRoutes.url.subscribe(UrlSegment => { + this.actionType = UrlSegment[0].path + }) + /*if (this.actionType === 'createTemplate') { + this.mappingEditorService.fromScreen = 'TemplateScreen'; + } + if (this.actionType === 'updateTemplate') {*/ + this.mappingEditorService.fromScreen = 'MappingScreen'; + // } + this.identifier = this.mappingEditorService.identifier; + } + //========================== End of ngOnInit() Method============================================ + ngOnDestroy() { + //console.log("Reference object =="+ JSON.stringify(this.refObj)); + if (this.refObj && this.refObj != undefined) { + if (this.configMappingEditorContent && this.configMappingEditorContent != undefined) { + this.saveTemplate(); + this.prepareAppData(); + this.prepareDownloadData(); + this.mappingEditorService.changeNavAppData(this.appDataObject); + this.mappingEditorService.changeNavDownloadData(this.downloadDataObject); + } + } + } + //========================== End of ngOnDestroy() Method============================================ + ngAfterViewInit() { + if (this.mappingEditorService.latestAction) { + this.refNameObj = this.mappingEditorService.latestAction; + if (this.vnfcType !== 'null') { + this.type = this.vnfcType; + } + else { + this.type = this.vnfType; + } + for (let i = 0; i < this.refNameObj['artifact-list'].length; i++) { + let artifactList = this.refNameObj['artifact-list']; + if (artifactList[i]['artifact-type'] === 'config_template') { + this.artifactName = artifactList[i]['artifact-name']; + } + } + } + let self = this; + this.templateEditor = self.templateeditor.getEditor(); + /* this.templateeditor.getEditor().commands.addCommand({ + name: 'annotateCommand', + bindKey: { win: 'Ctrl-4', mac: 'Command-4' }, + exec: function (editor) { + self.mappingEditorService.checkMethodCall(this.modal); + } + });*/ + this.templateeditor.getEditor().commands.addCommand({ + name: 'annotateCommand', + bindKey: { win: 'ENTER', mac: 'ENTER' }, + exec: (editor: any) => { + this.handleAnnotation(this.modal); + } + }); + if (this.mappingEditorService.fromScreen === 'MappingScreen') { + this.configMappingEditorContent = this.mappingEditorService.getTemplateMappingDataFromStore(); + this.fileType = sessionStorage.getItem('fileType'); + } + /* else if (this.mappingEditorService.fromScreen === 'TemplateScreen') { + this.configMappingEditorContent = this.mappingEditorService.getTemplateDataFromStore(); + this.fileType = sessionStorage.getItem('fileType'); + }*/ + if (this.configMappingEditorContent) { + this.artifactRequest.templateContent = this.configMappingEditorContent; + this.mappingEditorService.initialise(this.templateeditor.getEditor(), this.artifactRequest.templateContent, this.modal); + } + if (this.refObj) { + if (this.mappingEditorService.getTemplateMappingDataFromStore() && this.mappingEditorService.getTemplateMappingDataFromStore() != undefined) { + this.configMappingEditorContent = this.mappingEditorService.getTemplateMappingDataFromStore(); + } + else { + if (this.artifactName) this.retrieveTemplateFromAppc(); + } + } + else { + this.Actions = []; + this.enableBrowse = false; + this.nService.error("Error", "Please enter Action and VNF type in Reference Data screen"); + } + } + + //========================== End of ngAfterViewInit() Method============================================ + browseOption() { + $("#inputFile").trigger('click'); + } + //========================== End of browseOption() Method============================================ + /* openFile(event) { + let input = event.target; + this.fileName = event.currentTarget.value.replace(/C:\\fakepath\\/i, ''); + for (let index = 0; index < input.files.length; index++) { + let reader = new FileReader(); + reader.onload = () => { + this.configMappingEditorContent = reader.result; + } + reader.readAsText(input.files[index]); + }; + } + //========================== End of openFile() Method============================================*/ + //save to GUI + public saveTemplate() { + this.saveToGuiCacheFlag = 'true'; + this.mappingEditorService.paramData = []; + if (this.configMappingEditorContent) { + this.initialData = this.configMappingEditorContent; + this.mappingEditorService.refreshEditor(); + let paramArr: any = [] + if (this.mappingEditorService.paramData && this.mappingEditorService.paramData != undefined) { + if (this.mappingEditorService.paramData.length === 0 && this.mappingEditorService.hasErrorCode === true) { + this.nService.error("Error", 'Special characters error', 'Error') + return; + } + else { + this.showError = false; + } + } + this.showTemplateVersionDiv = true; + + if (this.mappingEditorService.fromScreen === 'MappingScreen') { + this.mappingEditorService.setTemplateMappingDataFromStore(this.configMappingEditorContent); + } + if (this.fileType === 'text/xml') { + sessionStorage.setItem('fileType', 'text/xml'); + } + if (this.fileType === '') { + sessionStorage.setItem('fileType', ''); + } + // paramArr = this.mappingEditorService.paramData; + // this.paramShareService.setTemplateData(paramArr) + } + } + //========================== End of saveTemplate() Method============================================ + /* clearHighlight() { + this.mappingEditorService.removeTheSelectedMarkers(); + } + //========================== End of clearHighlight() Method============================================*/ + /*validateTemplate() { + var fileExtensionArr = this.fileType.split("/"); + let data = { + "input": { + "design-request": { + "request-id": this.apiToken, + "action": "validateTemplate", + "data-type": fileExtensionArr[1].toUpperCase(), + "payload": this.configMappingEditorContent + } + } + }; + let url = environment.validateTemplate; + this + .httpUtil + .post( + { url: url, data: data }) + .subscribe(resp => { + if (resp.output.status.code === '400' && resp.output.status.message === "success") { + this.uploadValidationSuccess = true; + this.nService.success("Success", "Template Validated succesfully"); + return true; + } + else if (resp.output.status.code === '401') { + this.nService.error("Error", resp.output.status.message); + return false; + } + }, + error => this.nService.error("Error", "Unable to validate the uploaded template. Error in connecting APPC Server")); + } + //========================== End of validateTemplate() Method============================================*/ + retrieveTemplateFromAppc() { + let refObj = this.refObj; + if (refObj && refObj != undefined) { + + let fileName = this.artifactName; + let payload = '{"userID": "' + this.userId + '","action": "' + this.item.action + '", "vnf-type" : "' + this.vnfType + '", "artifact-type":"APPC-CONFIG", "artifact-name":"' + fileName + '"}'; + let input = { + "input": { + "design-request": { + "request-id": this.apiToken, + "action": "getArtifact", + "payload": payload + } + } + }; + // console.log("Retrieve artifact payload=="+ payload); + let artifactContent: any; + this.ngProgress.start(); + this.httpUtil.post({ + url: environment.getDesigns, + data: input + }).subscribe(resp => { + if (resp.output.status.code === '400' && resp.output.status.message === "success") { + this.nService.success("Success", "Template retrieved successfully from APPC"); + let result = JSON.parse(resp.output.data.block).artifactInfo[0]; + result = result['artifact-content']; + if ('Generated Template' === this.selectedUploadType) { + this.configMappingEditorContent = result + this.artifactRequest.templateContent = this.configMappingEditorContent; + this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..'); + if (this.artifactRequest.templateContent) { + this.mappingEditorService.initialise(this.templateeditor.getEditor(), this.artifactRequest.templateContent, this.modal); + } + } + this.tempretrieveFlag = true; + this.fileNameForTempSave = fileName; + this.enableDownloadButtons = true; + this.initialData = result; + this.saveTemplate(); + } + else { + this.nService.info("Information", "There is no template saved in APPC for the selected action!"); + } + this.ngProgress.done(); + }, + /* (error) => { + // this.showUploadErrorStatus = true; + // this.nService.error('Status','Error Connecting to the APPC Network') + //this.notificationService.notifyErrorMessage('Configuration Template file successfully uploaded..') + //this.uploadStatusError = true; + //window.scrollTo(0, 0) + // this. nService.error('Status','Error Connecting to the APPC Network') + this.openModel(true, "Could not retrieve latest template for given action""Error in connecting to APPC database") + });*/ + error => this.nService.error("Error", "Error in connecting to APPC Server")); + setTimeout(() => { + this.ngProgress.done(); + }, 3500); + } + } + //========================== End of retrieveTemplateFromAppc() Method============================================ + prepareAppData() { + let refObj = this.refObj; + //console.log("Reference object =="+ JSON.stringify(refObj)); + if (refObj && refObj != undefined) { + // refObj = refObj[refObj.length - 1]; + let paramsKeyValueFromEditor: JSON; + /* if (this.fileExtension.toUpperCase() === "XML") + paramsKeyValueFromEditor = this.mappingEditorService.generateParams(this.templateeditor.getEditor(), this.artifactRequest.templateContent); + else*/ + // paramsKeyValueFromEditor = this.mappingEditorService.generateParams(this.templateeditor.getEditor(), this.artifactRequest.templateContent); + try { + paramsKeyValueFromEditor = JSON.parse(localStorage["paramsContent"]); + } + catch (error) { + console.log("Could not parse name value pairs==" + error); + } + if (paramsKeyValueFromEditor) { + this.showTemplateVersionDiv = true; + let action = this.item.action; + var scopeName = this.scopeName.replace(/ /g, '').replace(new RegExp('/', "g"), '_').replace(/ /g, ''); + let fileName = this.updateParamFileName(refObj.action, scopeName, this.templateVersionNo); + let vnfType = this.vnfType; + let Json = [paramsKeyValueFromEditor]; + let slashedPayload = this.appendSlashes(JSON.stringify(Json)); + let newPayload = + { + "userID": this.userId, + "vnf-type": this.vnfType, + "action": action, + "artifact-name": fileName, + "artifact-type": "APPC-CONFIG", + "artifact-version": this.templateVersionNo, + "artifact-contents": slashedPayload + } + let data = + { + "input": { + "design-request": { + "request-id": this.apiToken, + "action": "uploadArtifact", + "payload": JSON.stringify(newPayload) + + } + } + } + this.appDataObject.template.nameValueData = data; + } + if (this.configMappingEditorContent) { + let actualContent = this.configMappingEditorContent; + this.mappingEditorService.generateTemplate(this.templateEditor); + this.showTemplateVersionDiv = true; + let action = this.item.action; + let versionandFileType: any; + if (this.fileType === "text/xml") { + + versionandFileType = this.templateVersionNo + 'V.xml' + } else { + + versionandFileType = this.templateVersionNo + 'V.json' + } + let fileName: any; + if (this.tempretrieveFlag) { + fileName = this.fileNameForTempSave; + } + else { + // fileName = this.updateDownloadTemplateFileName(refObj.action, this.scopeName, versionandFileType); + fileName = this.artifactName; + } + let vnfType = this.vnfType; + let newPayload = + { + "userID": this.userId, + "vnf-type": this.vnfType, + "action": action, + "artifact-name": fileName, + "artifact-type": "APPC-CONFIG", + "artifact-version": this.templateVersionNo, + //"artifact-contents": this.configMappingEditorContent + "artifact-contents": this.configMappingEditorContent.replace(/\(([^()]|(R))*\)=\(/g, '').replace(/\)}/g, '}') + + } + let data = + { + "input": { + "design-request": { + "request-id": this.apiToken, + "action": "uploadArtifact", + "payload": JSON.stringify(newPayload) + + } + } + } + this.appDataObject.template.templateData = data; + this.mappingEditorService.initialise(this.templateeditor.getEditor(), actualContent, this.modal); + } + } + } + //========================== End of prepareAppData() Method============================================ + /*retrieveNameValueFromAppc() { + let refObj: any = this.prepareFileName(); + if (refObj && refObj != undefined) { + let fileName = this.updateParamFileName(this.item.action, this.scopeName, this.templateVersionNo); + let payload = '{"userID": "' + this.userId + '","action": "' + this.item.action + '", "vnf-type" : "' + this.vnfType + '", "artifact-type":"APPC-CONFIG", "artifact-name":"' + fileName + '"}'; + let input = { + "input": { + "design-request": { + "request-id": this.apiToken, + "action": "getArtifact", + "payload": payload + } + } + }; + + let artifactContent: any; + this.httpUtil.post({ + // url:"https://mtanjv9apdb51.aic.cip.att.com:8443/restconf/operations/design-services:dbservice", + url: environment.getDesigns, + data: input + }).subscribe(resp => { + if (resp.output.status.code === '400' && resp.output.status.message === "success") { + this.openModel(true, 'Name/value pairs retrieved successfully from APPC', 'Success'); + let result = JSON.parse(resp.output.data.block).artifactInfo[0]; + result = JSON.parse(result['artifact-content']); + var jsonString = JSON.stringify(result[0]); + var string = jsonString.substring(1, jsonString.length - 1); + var stringArr = string.split(","); + var newStringArr = []; + var resultStr = "{\r\n" + for (var index in stringArr) { + newStringArr[index] = stringArr[index] + ",\r\n"; + } + for (var index in newStringArr) { + resultStr = resultStr + newStringArr[index]; + } + resultStr = resultStr.substring(0, resultStr.length - 3) + "\r\n}" + this.configMappingEditorContent = resultStr; + + } + }, + error => this.openModel(true, "Could not retrieve the name value pairs. Error in connecting to APPC Server", "ERROR")); + } + }*/ + //========================== End of retrieveNameValueFromAppc() Method============================================ + prepareFileName(): any { + let fileNameObject: any = this.mappingEditorService.latestAction; + this.appDataObject = this.mappingEditorService.appDataObject; + this.downloadDataObject = this.mappingEditorService.downloadDataObject; + this.referenceData = fileNameObject; + return fileNameObject; + } + //========================== End of prepareFileName() Method============================================ + onDownloadParameter() { + let refObj = this.refObj; + if (refObj) { + // refObj = refObj[refObj.length - 1]; + let paramsKeyValueFromEditor: JSON; + if (this.fileExtension.toUpperCase() === "XML") + paramsKeyValueFromEditor = this.mappingEditorService.generateParams(this.templateeditor.getEditor(), this.artifactRequest.templateContent); + else + paramsKeyValueFromEditor = this.mappingEditorService.generateParams(this.templateeditor.getEditor(), this.artifactRequest.templateContent); + + try { + paramsKeyValueFromEditor = JSON.parse(localStorage["paramsContent"]); + } + catch (error) { + console.log("Could not parse name value pairs==" + error); + } + let theJSON = JSON.stringify(paramsKeyValueFromEditor, null, "\t") + var blob = new Blob([theJSON], { + type: "text/json" + }); + this.showTemplateVersionDiv = true; + let fileName: any; + var scopeName = this.scopeName.replace(/ /g, '').replace(new RegExp('/', "g"), '_').replace(/ /g, ''); + fileName = this.updateParamFileName(refObj.action, scopeName, this.templateVersionNo); + this.downloadDataObject.template.nameValueData = theJSON; + this.downloadDataObject.template.nameValueFileName = fileName; + } + else { + this.nService.error("Error", "Please enter Action and VNF type in Reference Data screen"); + } + + } + //========================== End of onDownloadParameter() Method============================================ + /* JSONToCSVConvertor(JSONData, fileName, ShowLabel) { + //If JSONData is not an object then JSON.parse will parse the JSON string in an Object + var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData; + var CSV = ''; + //This condition will generate the Label/Header + if (ShowLabel) { + var testRow = ""; + for (var index in arrData[0]) { + CSV += index + '\t' + arrData[0][index] + '\r\n'; + } + } + if (CSV == '') { + return; + } + //Initialize file format you want csv or xls + var uri = 'data:application/vnd.ms-excel,' + encodeURI(CSV); + var link = document.createElement("a"); + link.href = uri; + link.download = fileName + ".xls"; + //this part will append the anchor tag and remove it after automatic click + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + //========================== End of JSONToCSVConvertor() Method============================================ + updateParamFileNameForXls(action: any, scopeName: any, versionNo: any) { + let fileName = 'param_' + action + '_' + scopeName + '_' + versionNo + 'V'; + this.downloadedParamFileName = fileName; + return fileName; + } + //========================== End of updateParamFileNameForXls() Method============================================*/ + updateParamFileName(action: any, scopeName: any, versionNo: any) { + let fileName = 'param_' + action + '_' + scopeName + '_' + versionNo + 'V.json'; + this.downloadedParamFileName = fileName; + return fileName; + } + //========================== End of updateParamFileName() Method============================================ + public onDownloadTemplate(artifact: string) { + let actualContent = this.configMappingEditorContent; + var textToSaveAsBlob: any; + var config_template_fileName: any + let refObj = this.refObj; + let versionandFileType: string; + this.mappingEditorService.generateTemplate(this.templateEditor); + if (artifact == 'Template' && this.artifactRequest && this.configMappingEditorContent && refObj) { + // refObj = refObj[refObj.length - 1]; + this.showTemplateVersionDiv = true; + if (this.fileType === "text/xml") { + textToSaveAsBlob = new Blob([this.configMappingEditorContent], { + type: "text/xml" + }); + versionandFileType = this.templateVersionNo + 'V.xml' + } + if (this.fileType === "text/plain") { + textToSaveAsBlob = new Blob([this.configMappingEditorContent], { + type: "text/plain" + }); + versionandFileType = this.templateVersionNo + 'V.txt' + } + if (this.fileType === "text/json") { + textToSaveAsBlob = new Blob([this.configMappingEditorContent], { + type: "text/json" + }); + versionandFileType = this.templateVersionNo + 'V.json' + } + if (this.tempretrieveFlag) { + config_template_fileName = this.fileNameForTempSave; + var filextension = config_template_fileName.substring(config_template_fileName.indexOf("V") + 2, config_template_fileName.length); + + textToSaveAsBlob = new Blob([this.configMappingEditorContent], { + type: "text/" + filextension + }); + } + else { + // config_template_fileName = this.updateDownloadTemplateFileName(refObj.action, this.scopeName, versionandFileType); + config_template_fileName = this.artifactName; + } + // saveAs(textToSaveAsBlob, config_template_fileName); + this.mappingEditorService.initialise(this.templateeditor.getEditor(), actualContent, this.modal); + //this.downloadDataObject.template.templateData = this.configMappingEditorContent; + this.downloadDataObject.template.templateData = this.configMappingEditorContent.replace(/\(([^()]|(R))*\)=\(/g, '').replace(/\)}/g, '}'); + this.downloadDataObject.template.templateFileName = config_template_fileName; + } + + } + //========================== End of onDownloadTemplate() Method============================================ + updateDownloadTemplateFileName(action: any, scopeName: any, versionandFileType: any) { + let fileName = 'template_' + action + '_' + scopeName + '_' + versionandFileType; + this.downloadedTemplateFileName = fileName; + return fileName; + } + //========================== End of updateDownloadTemplateFileName() Method============================================ + /* openModel(toShow: any, message: any, title: any) { + //this.modalComponent.isShow = toShow; + //this.modalComponent.message = message; + //this.modalComponent.title = title; + } + //========================== End of openModel() Method============================================*/ + fileChange(input) { + + let self = this; + let refObj = this.refObj; + this.enableValidateTemplate = true; + + if (refObj && refObj != undefined) { + // refObj = refObj[refObj.length - 1]; + if (input.files && input.files[0]) { + console.log("input files0" + JSON.stringify(input.files[0])) + this.myfileName = input.files[0].name; + this.fileName = input.files[0].name; + this.fileType = input.files[0].type; + // var fileExtension = this.myfileName.substr(this.myfileName.lastIndexOf('.') + 1); + + let reader = new FileReader(); + // if(this.validateUploadedFile(fileExtension)) + //{ + this.readFile(input.files[0], reader, (result) => { + if (this.fileType === 'text/xml') { + sessionStorage.setItem('fileType', 'text/xml'); + } + if (this.fileName.endsWith(".json")) { + this.fileType = "text/json"; + sessionStorage.setItem('fileType', 'text/json'); + } + if (this.fileType === '') { + sessionStorage.setItem('fileType', ''); + } + + + if ('Generated Template' === this.selectedUploadType) { + this.configMappingEditorContent = result + this.artifactRequest.templateContent = this.configMappingEditorContent; + console.log("editor content==" + JSON.stringify(this.configMappingEditorContent)) + this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..'); + if (this.artifactRequest.templateContent) { + this.mappingEditorService.initialise(this.templateeditor.getEditor(), this.artifactRequest.templateContent, this.modal); + } + } + this.enableDownloadButtons = true; + this.initialData = result; + this.saveTemplate(); + + }); + // } + // else{ + // this.nService.error("Error", "Incorrect File Format") + //this.configMappingEditorContent='' + //} + } + else { + this.nService.error("Error", "Failed to read file"); + } + this.myInputVariable.nativeElement.value = ""; + } + else { + this.nService.error("Error", "Please enter Action and VNF type in Reference Data screen"); + return false; + } + } + //========================== End of fileChange() Method============================================ + public readFile(file, reader, callback) { + // Set a callback funtion to fire after the file is fully loaded + reader.onload = () => { + // callback with the results + callback(reader.result); + } + this.notificationService.notifySuccessMessage('Uploading File ' + file.name + ':' + file.type + ':' + file.size); + // Read the file + reader.readAsText(file, "UTF-8"); + } + //========================== End of readFile() Method============================================ + validateUploadedFile(fileExtension) { + + if (fileExtension.toUpperCase() === 'json'.toUpperCase() || fileExtension.toUpperCase() === 'xml'.toUpperCase()) { + return true; + } + else { + return false; + } + + } + //========================== End of validateUploadedFile() Method============================================ + appendSlashes(artifactData) { + let x = artifactData.replace(new RegExp(',"', "g"), ',\"'); + let y = x.replace(new RegExp('":', 'g'), '\":'); + let z = y.replace(new RegExp('{"', 'g'), '{\"') + let t = z.replace(new RegExp(':"', 'g'), ':\"') + let m = t.replace(new RegExp('",', 'g'), '\",'); + let n = y.replace(new RegExp('"}', 'g'), '\"}') + let nw = n.replace(new RegExp('{"', 'g'), '{\"'); + let nw1 = nw.replace(new RegExp(':"', 'g'), ':\"'); + let nw2 = nw1.replace(new RegExp('",', 'g'), '\",'); + return nw2; + } + //========================== End of appendSlashes() Method============================================ + prepareDownloadData() { + this.onDownloadParameter(); + this.onDownloadTemplate('Template'); + } + //========================== End of prepareDownloadData() Method============================================ + syncTemplate() { + this.mappingEditorService.replaceNamesWithBlankValues(); + this.saveTemplate(); + + var templateData = this.mappingEditorService.paramData; //template data array + // this.paramShareService.setTemplateData(templateData); + + //console.log("Template Name value pairs ===" + JSON.stringify(templateData)) + var pdData = this.paramShareService.getSessionParamData(); //PD data array + console.log("PD name value pairs===" + JSON.stringify(pdData)) + + + var paramsContent = localStorage["paramsContent"]; + console.log("Param content before==" + paramsContent); + + if (paramsContent && paramsContent != undefined) { + try { + var paramTabData = JSON.parse(paramsContent); + //console.log("Param content after==" + paramsContent); + //console.log("Param tab data after==" + JSON.stringify(paramTabData)) + } + catch (error) { + console.log("error is : " + error) + } + } + var resultArr = []; + var json = {}; + var resultParamObj = {}; + let checkNamesOnlyCondition: boolean = true; + + if (templateData && templateData != undefined) { + templateData.forEach(function (item) { + if (item.paramValue !== "" && item.paramValue != undefined && item.paramValue != null) { + checkNamesOnlyCondition = false; + } + + }); + + templateData.forEach(function (item) { + resultParamObj[item.paramName] = item.paramValue; + }); + // console.log("pARAM Result array before is " + JSON.stringify(resultParamObj)) + if (paramTabData && paramTabData != undefined) { + templateData.forEach(function (item) { + for (var index in paramTabData) { + if (item.paramName === index) { + if (checkNamesOnlyCondition) { + resultParamObj[index] = paramTabData[index]; + } + else { + if (item.paramValue === "") { + resultParamObj[index] = paramTabData[index]; + } + else { + resultParamObj[index] = item.paramValue; + } + } + } + + } + + }); + + } + localStorage["paramsContent"] = JSON.stringify(resultParamObj); + //console.log("param content after==" +JSON.stringify(resultParamObj)); + + //removing duplicate elements from the array + templateData = Array.from(new Set(templateData.map((itemInArray) => itemInArray.paramName))) + + //reformatting arr1 to match with PD + templateData.forEach(function (item) { + + resultArr.push({ + "name": item, + "type": null, + "description": null, + "required": null, + "default": null, + "source": "Manual", + "rule-type": null, + "request-keys": [{ + "key-name": null, + "key-value": null + }, { + "key-name": null, + "key-value": null + }, { + "key-name": null, + "key-value": null + }], + "response-keys": [{ + "key-name": null, + "key-value": null + }, { + "key-name": null, + "key-value": null + }, { + "key-name": null, + "key-value": null + }, { + "key-name": null, + "key-value": null + }, { + "key-name": null, + "key-value": null + }], + "ruleTypeValues": [null] + + }) + }); + } + //console.log("Result array before is " + JSON.stringify(resultArr)) + // console.log("Length before is: " + resultArr.length) + + if (pdData && pdData != undefined) { + for (var i = 0; i < resultArr.length; i++) { + + pdData.forEach(function (arr2item) { + if (resultArr[i].name === arr2item.name) { + + var json = { + "name": arr2item.name, + "type": arr2item.type, + "description": arr2item.description, + "required": arr2item.required, + "default": arr2item.default, + "source": arr2item.source, + "rule-type": arr2item["rule-type"], + "request-keys": arr2item["request-keys"], + "response-keys": arr2item["response-keys"], + "ruleTypeValues": arr2item.ruleTypeValues + }; + resultArr.splice(i, 1, json) + // console.log("Result array index ==" + JSON.stringify(resultArr[i])) + } + + }); + + }; + + } + this.paramShareService.setSessionParamData(resultArr); + //console.log("Result array after is " + JSON.stringify(resultArr)) + //console.log("Length after is: " + resultArr.length) + this.mappingEditorService.paramData = []; + //navigate to PD page after sync + this + .router + .navigate(['../../../vnfs/design/parameterDefinitions/create']); + } + + //========================== End of syncTemplate() Method============================================ + mergeParams() { + var mergeStatus: boolean = this.mappingEditorService.autoAnnotateDataForParams(this.fileType); + if (mergeStatus) { + this.nService.success("Success", "Merge Successful"); + } + else { + this.nService.error("Error", "Merge Unsuccessful"); + } + this.saveTemplate(); + } + //========================== End of mergeParams() Method============================================ + public handleAnnotation(modal) { + + let selectedWord: string = this.templateeditor.getEditor().session.getTextRange(this.templateeditor.getEditor().selectionRange); + this.selectedWord = selectedWord; + modal.open(); + } + //========================== End of handleAnnotations() Method============================================ + public submitNameValues() { + /*var editor = this.templateeditor.getEditor() + this.editor = editor; + this.editor.session = editor.session; + this.editor.selection.session.$backMarkers = {}; + this.editorContent = this.artifactRequest.templateContent; + this.editor.$blockScrolling = Infinity; + this.editor.$blockSelectEnabled = false;*/ + if (this.tempName) { + this.checkNameEntered = true; + + if (this.selectedWord) { + if (this.selectedWord.startsWith('${(')) { + var replaceWord: any = this.selectedWord.substring(3, this.selectedWord.indexOf(')=(')) + this.tempName; + this.templateeditor.getEditor().session.replace(this.templateeditor.getEditor().session.selection.getRange(), replaceWord); + } else { + let mappingKey = this.mappingEditorService.getKeysForValues(this.selectedWord); + var replaceWord: any = '${(' + this.selectedWord + ')=(' + this.tempName + ')}'; + this.templateeditor.getEditor().session.replace(this.templateeditor.getEditor().session.selection.getRange(), replaceWord); + } + } + this.mappingEditorService.refreshEditor(); + this.tempName = ''; + this.modal.close(); + + } + else { + this.checkNameEntered = false; + } + + } + //========================== End of submitNameValues() Method============================================ +} diff --git a/src/app/vnfs/build-artifacts/template-holder/template-holder.component.css b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.css new file mode 100644 index 0000000..7c075eb --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.css @@ -0,0 +1,22 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/template-holder/template-holder.component.html b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.html new file mode 100644 index 0000000..6668ed1 --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.html @@ -0,0 +1,24 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<router-outlet></router-outlet>
\ No newline at end of file diff --git a/src/app/vnfs/build-artifacts/template-holder/template-holder.component.spec.ts b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.spec.ts new file mode 100644 index 0000000..22c71d1 --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.spec.ts @@ -0,0 +1,49 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {GoldenConfigurationHolderComponent} from './template-holder.component'; + +describe('GoldenConfigurationHolderComponent', () => { + let component: GoldenConfigurationHolderComponent; + let fixture: ComponentFixture<GoldenConfigurationHolderComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [GoldenConfigurationHolderComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(GoldenConfigurationHolderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/vnfs/build-artifacts/template-holder/template-holder.component.ts b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.ts new file mode 100644 index 0000000..33bed31 --- /dev/null +++ b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.ts @@ -0,0 +1,39 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-golden-configuration-holder', + templateUrl: './template-holder.component.html', + styleUrls: ['./template-holder.component.css'] +}) +export class GoldenConfigurationHolderComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/vnfs/myvnfs/myvnfs.component.css b/src/app/vnfs/myvnfs/myvnfs.component.css new file mode 100644 index 0000000..c1b1169 --- /dev/null +++ b/src/app/vnfs/myvnfs/myvnfs.component.css @@ -0,0 +1,35 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +.build-button { + padding: 11px; + font-size: 20px; + color: green; + border: 1PX SOLID GREEN; + MARGIN-BOTTOM: 40PX +} + +table.table th, +table.table td { + padding: 0rem; +}
\ No newline at end of file diff --git a/src/app/vnfs/myvnfs/myvnfs.component.html b/src/app/vnfs/myvnfs/myvnfs.component.html new file mode 100644 index 0000000..c214a2c --- /dev/null +++ b/src/app/vnfs/myvnfs/myvnfs.component.html @@ -0,0 +1,132 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> +<ng-progress [positionUsing]="'marginLeft'" [minimum]="0.15" [maximum]="1" [speed]="200" [showSpinner]="false" [direction]="'leftToRightIncreased'" [color]="'#6ab344'" [trickleSpeed]="250" [thick]="true" [ease]="'linear'"></ng-progress> +<div class="container"> + <div *ngIf="noData != true"> + <div class="row"> + <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12"> + + </div> + <div class="col-xs-12 col-sm-12 col-md-3 col-lg-3"> + <input placeholder="filter table" class="form-control" type="text" [(ngModel)]="filterQuery" /> + </div> + </div> + <div class="row"> + <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12"> + <div class="table-responsive" style="height:auto; overflow: auto;"> + <table class="table"> + <thead> + <tr> + <th>VNF TYPE <i class="fa fa-sort" (click)="sortOrder= !sortOrder; sortBy='vnf-type'" aria-hidden="true"></i></th> + <th>VNFC TYPE<i class="fa fa-sort" (click)="sortOrder= !sortOrder; sortBy='vnfc-type'" aria-hidden="true"></i></th> + <!-- <th>INCART<i class="fa fa-sort" (click)="sortOrder= !sortOrder; sortBy='subscriber'" aria-hidden="true"></i></th> --> + <!-- <th>PROTOCOL<i class="fa fa-sort" (click)="sortOrder= !sortOrder; sortBy='protocol'" aria-hidden="true"></i></th> + <th>ACTION<i class="fa fa-sort" (click)="sortOrder= !sortOrder; sortBy='action'" aria-hidden="true"></i></th> --> + <th>ARTIFACT NAME<i class="fa fa-sort" (click)="sortOrder= !sortOrder; sortBy='artifact-name'" aria-hidden="true"></i></th> + <!-- <th>ARTIFACT TYPE<i class="fa fa-sort" (click)="sortOrder= !sortOrder; sortBy='artifact-type'" + aria-hidden="true"></i></th> --> + <th></th> + </tr> + </thead> + + <tbody style="padding: 15px 25px"> + <tr *ngFor="let item of vnfData | orderBy:sortBy:sortOrder | tableFilter:filterQuery:filter"> + <td>{{item['vnf-type']}}</td> + <td>{{item['vnfc-type']}}</td> + <!-- <td>{{item.incart}}</td> --> + <!-- <td>{{item.protocol}}</td> + <td>{{item.action}}</td> --> + <td>{{item['artifact-name']}}</td> + <!-- <td>{{item['artifact-type']}}</td> --> + <td> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="navigateToReference(item)"><i class="fa fa-edit" + aria-hidden="true"></i> View/Edit + </button> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div> + </div> + <div *ngIf="noData == true" class="text-center"> + <div class="card"> + <div class="mdl-dialog__content"> + <div class="mdl-card__title"> + <h2 class="mdl-card__title-text">You don't have any Artifacts</h2> + </div> + <div class="mdl-card__supporting-text"> + {{noDataMsg}} + </div> + </div> + </div> + </div> + <div class="col-lg-12-ln2"> + <button type="button" (click)="buildNewDesign(content)" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary">Create New + VNF Type or VNFC Type + </button> + </div> +</div> + +<ng-template #content let-c="close" let-d="dismiss"> + <form ngNativeValidate (ngSubmit)="c('yes')"> + <div class="modal-header"> + <h4 class="modal-title">Enter VNF type and VNFC to proceed</h4> + <button type="button" class="close" aria-label="Close" (click)="d('Cross click')"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + + <div class="form-group row"> + <label for="example-text-input" class="col-12 col-form-label">Enter Vnf Type</label> + <div class="col-12"> + <input required name="vnfType" class="form-control" [(ngModel)]="vnfType" type="text" id="vnfType"> + </div> + </div> + <div class="form-check"> + <label class="form-check-label"> + <input name="vnfcRequired" class="form-check-input" [(ngModel)]="vnfcRequired" type="checkbox" + id="vnfcRequired"> + Enter vnfc info + </label> + </div> + <div class="form-group row" *ngIf="vnfcRequired"> + <label for="example-search-input" class="col-12 col-form-label">Enter Vnfc Type</label> + <div class="col-12"> + <input required name="vnfcType" class="form-control" [(ngModel)]="vnfcType" type="text" id="vnfcType"> + </div> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent + + " (click)="c('yes')">Proceed anyway + </button> + <button type="submit" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary">Next + </button> + + </div> + </form> +</ng-template>
\ No newline at end of file diff --git a/src/app/vnfs/myvnfs/myvnfs.component.spec.ts b/src/app/vnfs/myvnfs/myvnfs.component.spec.ts new file mode 100644 index 0000000..5e0c51f --- /dev/null +++ b/src/app/vnfs/myvnfs/myvnfs.component.spec.ts @@ -0,0 +1,168 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing'; +import { NO_ERRORS_SCHEMA, Output } from '@angular/core'; +import { MyvnfsComponent } from './myvnfs.component'; +import { FormsModule } from '@angular/forms'; +import { NotificationService } from './../../shared/services/notification.service'; +import { ParamShareService } from './../../shared/services/paramShare.service'; +import { MappingEditorService } from './../../shared/services/mapping-editor.service'; +import { DialogService } from 'ng2-bootstrap-modal'; +import { RouterTestingModule } from '@angular/router/testing'; +import { HttpUtilService } from '.././../shared/services/httpUtil/http-util.service'; +import { UtilityService } from '.././../shared/services/utilityService/utility.service'; +// import{TableFilterPipe} from '.././../shared/modules/tidy-table/table-filter.pipe'; +import { TidyTableModule } from '../../shared/modules/tidy-table/tidy-table.module'; +import { NgModule } from '@angular/core'; +import { NgProgress } from 'ngx-progressbar'; + +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { + HttpModule, + Http, + Response, + ResponseOptions, + XHRBackend +} from '@angular/http'; + +import { MockBackend } from '@angular/http/testing'; +describe('MyvnfsComponent', () => { + let component: MyvnfsComponent; + let fixture: ComponentFixture<MyvnfsComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [MyvnfsComponent], + schemas: [NO_ERRORS_SCHEMA], + imports: [FormsModule, RouterTestingModule, TidyTableModule, HttpModule, NgbModule.forRoot()], + providers: [ + + { provide: XHRBackend, useClass: MockBackend }, + NgProgress, UtilityService, ParamShareService, DialogService, NotificationService, HttpUtilService, MappingEditorService] + + }) + .compileComponents(); + })); + + beforeEach(() => { + + fixture = TestBed.createComponent(MyvnfsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create myvnfscomponent', () => { + expect(component).toBeTruthy(); + }); + it('Post call to get artifact', inject([HttpUtilService, XHRBackend], (httpUtilService, mockBackend) => { + + const mockResponse = { + "output": { + "data": { + "block": "{\"userID\":\"ug0221\",\"designInfo\":[{\"vnf-type\":\"demo123\",\"vnfc-type\":\"null\",\"protocol\":\"\",\"incart\":\"N\",\"action\":\"AllAction\",\"artifact-name\":\"reference_AllAction_demo123_0.0.1V.json\",\"artifact-type\":\"APPC-CONFIG\"}],\"statusInfo\":null,\"artifactInfo\":null}", + "status":{ + "code": "400", + "message": "success" + } + } + } + } + + //"{'userID':'ug0221','designInfo':[{'vnf-type':'demo123','vnfc-type':'null','protocol':'','incart':'N','action':'AllAction','artifact-name':'reference_AllAction_demo123_0.0.1V.json','artifact-type':'APPC-CONFIG'}]}" + const data = { + 'input': { + 'design-request': { + 'request-id': "apiToken", + 'action': 'getDesigns', + 'payload': '{"userID": "","filter":"reference"}' + } + } + }; + + + mockBackend.connections.subscribe((connection) => { + connection.mockRespond(new Response(new ResponseOptions({ + body: JSON.stringify(mockResponse) + }))); + }); + component.getArtifacts(data) + httpUtilService.post({ + url: "test url", + data: data + }).subscribe((resp) => { + console.log("resp") + console.log(resp) + let block = JSON.parse(resp.output.data.block) + expect(block.userID).toBe("ug0221"); + + + + + }); + + + })) + it('Checking for the successfull post call', inject([HttpUtilService, XHRBackend], (httpUtilService, mockBackend) => { + + const mockResponse = { + "output": { + "data": { + "block": "{\"userID\":\"ug0221\",\"designInfo\":[{\"vnf-type\":\"demo123\",\"vnfc-type\":\"null\",\"protocol\":\"\",\"incart\":\"N\",\"action\":\"AllAction\",\"artifact-name\":\"reference_AllAction_demo123_0.0.1V.json\",\"artifact-type\":\"APPC-CONFIG\"}],\"statusInfo\":null,\"artifactInfo\":null}", + "status":{ + "code": "400", + "message": "success" + } + } + } + } + const data = { + 'input': { + 'design-request': { + 'request-id': "apiToken", + 'action': 'getDesigns', + 'payload': '{"userID": "","filter":"reference"}' + } + } + }; + + + mockBackend.connections.subscribe((connection) => { + connection.mockRespond(new Response(new ResponseOptions({ + body: JSON.stringify(mockResponse) + }))); + }); + component.getArtifacts(data) + httpUtilService.post({ + url: "test url", + data: data + }).subscribe((resp) => { + console.log("resp") + console.log(resp) + let block = JSON.parse(resp.output.data.status.code) + console.log("code",block) + expect(block).toBe(400); + }); + })) +}); diff --git a/src/app/vnfs/myvnfs/myvnfs.component.ts b/src/app/vnfs/myvnfs/myvnfs.component.ts new file mode 100644 index 0000000..37ebe96 --- /dev/null +++ b/src/app/vnfs/myvnfs/myvnfs.component.ts @@ -0,0 +1,163 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { HttpUtilService } from '../../shared/services/httpUtil/http-util.service'; +import { MappingEditorService } from '../../shared/services/mapping-editor.service'; +import { ParamShareService } from '../../shared/services/paramShare.service'; +import { environment } from '../../../environments/environment'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { NgProgress } from 'ngx-progressbar'; + + +@Component({ selector: 'app-myvnfs', templateUrl: './myvnfs.component.html', styleUrls: ['./myvnfs.component.css'] }) +export class MyvnfsComponent implements OnInit { + vnfData: Array<Object> = []; + sortOrder = false; + noData = true; + sortBy: string; + filter: Object = {}; + noDataMsg: string; + vnfType: any; + vnfcType: any; + + constructor (private paramShareService: ParamShareService, private ngProgress: NgProgress, private httpUtil: HttpUtilService, private router: Router, private activeROute: ActivatedRoute, + private mappingEditorService: MappingEditorService, private modalService: NgbModal) { + } + + ngOnInit() { + + sessionStorage.setItem('updateParams', undefined); + this.mappingEditorService.latestAction = undefined; + const apiToken = localStorage['apiToken']; + + const data = { + 'input': { + 'design-request': { + 'request-id': apiToken, + 'action': 'getDesigns', + 'payload': '{"userID": "","filter":"reference"}' + } + } + }; + const x = JSON.parse(data.input['design-request']['payload']); + x.userID = localStorage['userId']; + data.input['design-request']['payload'] = JSON.stringify(x); + // console.log("input to payload====", JSON.stringify(data)); + this.getArtifacts(data); + this.clearCache(); + } + + getArtifacts(data) { + this.ngProgress.start(); + this.httpUtil.post({ + url: environment.getDesigns, + data: data + }) + .subscribe(resp => { + console.log("resp:",resp); + const tempObj = JSON.parse(resp.output.data.block); + this.vnfData = tempObj.designInfo; + if (this.vnfData == undefined || this.vnfData == null || this.vnfData.length == 0) { + this.noData = true; + + this.noDataMsg = resp.output.data.status.message; + } else { + this.noData = false; + } + console.log(this.noData); + this.ngProgress.done(); + }); + + this.filter = ['vnf-type', 'vnfc-type', 'artifact-name']; + setTimeout(() => { + this.ngProgress.done(); + }, 3500); + } + + + + getData() { + } + + buildNewDesign(content) { + + this.modalService.open(content).result.then(res => { + this.mappingEditorService.referenceNameObjects = undefined; + sessionStorage.setItem('vnfParams', JSON.stringify({ vnfType: this.vnfType, vnfcType: this.vnfcType })); + this + .router + .navigate([ + 'vnfs', 'design', 'references' + ]); + }); + + + } + + navigateToReference(item) { + sessionStorage.setItem('updateParams', JSON.stringify(item)); + this.mappingEditorService.referenceNameObjects = undefined; + + this + .router + .navigate(['../design/references'], { + relativeTo: this.activeROute, + queryParams: { + id: item.id + } + }); + } + + navigateToRefrenceUpdate() { + + this + .router + .navigate(['../design/references/update'], { + relativeTo: this.activeROute, + queryParams: { + id: '10' + } + }); + } + + clearCache() { + // get the value and save the userid and persist it. + + this.mappingEditorService.setTemplateMappingDataFromStore(undefined); + localStorage['paramsContent'] = '{}'; + this.mappingEditorService.setParamContent(undefined); + this.paramShareService.setSessionParamData(undefined); + const appData = { reference: {}, template: { templateData: {}, nameValueData: {} }, pd: {} }; + const downloadData = { + reference: {}, + template: { templateData: {}, nameValueData: {}, templateFileName: '', nameValueFileName: '' }, + pd: { pdData: '', pdFileName: '' } + }; + this.mappingEditorService.changeNavAppData(appData); + this.mappingEditorService.changeNavDownloadData(downloadData); + } + + +}
\ No newline at end of file diff --git a/src/app/vnfs/userlogin-form/userlogin-form.component.css b/src/app/vnfs/userlogin-form/userlogin-form.component.css new file mode 100644 index 0000000..4df88b5 --- /dev/null +++ b/src/app/vnfs/userlogin-form/userlogin-form.component.css @@ -0,0 +1,27 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* .error-msg{ + + color: red +} */
\ No newline at end of file diff --git a/src/app/vnfs/userlogin-form/userlogin-form.component.html b/src/app/vnfs/userlogin-form/userlogin-form.component.html new file mode 100644 index 0000000..af58842 --- /dev/null +++ b/src/app/vnfs/userlogin-form/userlogin-form.component.html @@ -0,0 +1,45 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<div class="container"> + <div class="row"> + <div class="col-lg-4 col-md-4 hidden-sm-down"> + </div> + <div class="card"> + <div class="mdl-dialog__content"> + <form #userForm="ngForm" (ngSubmit)="getData()"> + <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> + <input placeholder="Enter user Id" class="mdl-textfield__input" id="userId" required + [(ngModel)]="userId" name="userId" value="" #user="ngModel"> + </div> + <div class="form-group text-right"> + <button type="submit" [disabled]="!userForm.form.valid" + class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary"> + Submit + </button> + </div> + </form> + </div> + </div> + </div> +</div>
\ No newline at end of file diff --git a/src/app/vnfs/userlogin-form/userlogin-form.component.spec.ts b/src/app/vnfs/userlogin-form/userlogin-form.component.spec.ts new file mode 100644 index 0000000..d253cb7 --- /dev/null +++ b/src/app/vnfs/userlogin-form/userlogin-form.component.spec.ts @@ -0,0 +1,96 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { userloginFormComponent } from './userlogin-form.component'; +import { FormsModule } from '@angular/forms'; +import { NotificationService } from './../../shared/services/notification.service'; +import { ParamShareService } from './../../shared/services/paramShare.service'; +import { MappingEditorService } from './../../shared/services/mapping-editor.service'; +import { DialogService } from 'ng2-bootstrap-modal'; +import { RouterTestingModule } from '@angular/router/testing'; +import { HttpUtilService } from '.././../shared/services/httpUtil/http-util.service'; +import { UtilityService } from '.././../shared/services/utilityService/utility.service'; +import { Router } from '@angular/router'; +import {NotificationsService} from 'angular2-notifications'; + +describe('userloginFormComponent', () => { + let component: userloginFormComponent; + let fixture: ComponentFixture<userloginFormComponent>; + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [userloginFormComponent], + schemas: [NO_ERRORS_SCHEMA], + imports: [FormsModule, RouterTestingModule,], + providers: [UtilityService, ParamShareService, DialogService, NotificationService,NotificationsService, HttpUtilService, MappingEditorService, { + provide: Router, + useClass: MockRouter + }, { provide: Router, useClass: MockRouter }] + }) + .compileComponents(); + })); + beforeEach(() => { + fixture = TestBed.createComponent(userloginFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + // localStorage['userId'] = "testUser" + component.userId = 'test Usr'; + }); + + class MockRouter { + navigateByUrl(url: string) { + return url; + } + + navigate(url: string) { + return url; + } + } + class MockUtility { + randomId() { + return 123; + } + } + it('should create', () => { + expect(component).toBeTruthy(); + }); + it('get the user Id', () => { + component.getData(); + expect(localStorage.userId).toEqual('test Usr'); + }); + + it('should route to myvnfform', inject([Router], (router: Router) => { + const spy = spyOn(router, 'navigate'); + component.getData(); + const url = spy.calls.first().args[0]; + + + expect(url.length).toBe(2); + expect(url[0]).toEqual('vnfs'); + + expect(url[1]).toEqual('list'); + })); + +}); diff --git a/src/app/vnfs/userlogin-form/userlogin-form.component.ts b/src/app/vnfs/userlogin-form/userlogin-form.component.ts new file mode 100644 index 0000000..dfb665e --- /dev/null +++ b/src/app/vnfs/userlogin-form/userlogin-form.component.ts @@ -0,0 +1,51 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {Component, OnInit} from '@angular/core'; +import {Router} from '@angular/router'; +import {EmitterService} from '../../shared/services/emitter.service'; +import {UtilityService} from '../../shared/services/utilityService/utility.service'; + +@Component({selector: 'app-mvnfs-form', templateUrl: './userlogin-form.component.html', styleUrls: ['./userlogin-form.component.css']}) +export class userloginFormComponent implements OnInit { + + userId: string = ''; + + constructor(private router: Router, private utiltiy: UtilityService) { + } + + ngOnInit() { + } + + getData() { + localStorage['userId'] = this.userId; + localStorage['apiToken'] = this.utiltiy.randomId(); + EmitterService + .get('userLogin') + .emit(this.userId); + this + .router + .navigate(['vnfs', 'list']); + } + +} diff --git a/src/app/vnfs/vnf.routing.ts b/src/app/vnfs/vnf.routing.ts new file mode 100644 index 0000000..b12530d --- /dev/null +++ b/src/app/vnfs/vnf.routing.ts @@ -0,0 +1,132 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import { GoldenConfigurationHolderComponent, } from './build-artifacts/template-holder/template-holder.component'; +import { MyvnfsComponent } from './myvnfs/myvnfs.component'; +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { ReferenceDataformComponent } from './build-artifacts/reference-dataform/reference-dataform.component'; +import { GoldenConfigurationComponent } from './build-artifacts/template-holder/template-configuration/template-configuration.component'; +import { GoldenConfigurationMappingComponent } from './build-artifacts/template-holder/param-name-value/param-name-value.component'; +import { ParameterComponent } from './build-artifacts/parameter-definitions/parameter.component'; +import { ParameterHolderComponent } from './build-artifacts/parameter-holder/parameter-holder.component'; +import { VnfsComponent } from './vnfs/vnfs.component'; +import { BuildDesignComponent } from './build-artifacts/build-artifacts.component'; +import { userloginFormComponent } from './userlogin-form/userlogin-form.component'; +import { LoginGuardService } from './LoginGuardService/Login-guard-service'; +import { ReferenceDataHolderComponent } from './build-artifacts/reference-data-holder/reference-data-holder.component'; + + +const routes: Routes = [ + { + path: '', + component: VnfsComponent, + children: [ + { + path: '', + component: userloginFormComponent, + canActivate: [LoginGuardService], + + }, { + path: 'list', + component: MyvnfsComponent + + }, + + { + path: 'design', + component: BuildDesignComponent, + children: [ + { + path: 'references', + component: ReferenceDataHolderComponent, + children: [ + { + path: '', + component: ReferenceDataformComponent + } + ] + }, { + path: 'templates', + component: GoldenConfigurationHolderComponent, + // canActivate:[GCAuthGuardService], + children: [ + { + path: 'configureTemplate', + component: GoldenConfigurationComponent + }, + { + path: 'myTemplates', + component: GoldenConfigurationMappingComponent + } + , { + path: '', + redirectTo: 'myTemplates', + pathMatch: 'full' + } + ] + }, { + path: 'parameterDefinitions', + component: ParameterHolderComponent, + children: [ + { + path: 'create', + component: ParameterComponent + }, + { + path: 'update', + component: ParameterComponent + }, + { + path: 'session', + component: ParameterComponent + }, + { + path: 'key', + component: ParameterComponent + }, + { + path: 'clearparams', + component: ParameterComponent + }, + { + path: '', + redirectTo: 'create', + pathMatch: 'full' + } + + + ] + }, + ] + } + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class VnfRoutingModule { +}
\ No newline at end of file diff --git a/src/app/vnfs/vnfs.module.ts b/src/app/vnfs/vnfs.module.ts new file mode 100644 index 0000000..c63d24a --- /dev/null +++ b/src/app/vnfs/vnfs.module.ts @@ -0,0 +1,93 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {NgModule} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {CommonModule} from '@angular/common'; +// modules +import {VnfRoutingModule} from './vnf.routing'; +import {SharedModule} from '../shared/shared.module'; + +import {AceEditorComponent} from 'ng2-ace-editor'; +// components +import {MyvnfsComponent} from './myvnfs/myvnfs.component'; +import {ReferenceDataformComponent} from './build-artifacts/reference-dataform/reference-dataform.component'; +import {GoldenConfigurationComponent} from './build-artifacts/template-holder/template-configuration/template-configuration.component'; +import {ParameterComponent} from './build-artifacts/parameter-definitions/parameter.component'; +import {ParameterHolderComponent} from './build-artifacts/parameter-holder/parameter-holder.component'; +import {BootstrapModalModule} from 'ng2-bootstrap-modal'; +import {BuildDesignComponent} from './build-artifacts/build-artifacts.component'; +import {userloginFormComponent} from './userlogin-form/userlogin-form.component'; +import {ReferenceDataHolderComponent} from './build-artifacts/reference-data-holder/reference-data-holder.component'; +import {ModalComponent} from '../shared/modal/modal.component'; +import {VnfsComponent} from './vnfs/vnfs.component'; +import {ConfirmComponent} from '../shared/confirmModal/confirm.component'; +import {GoldenConfigurationHolderComponent} from './build-artifacts/template-holder/template-holder.component'; +import {GoldenConfigurationMappingComponent} from './build-artifacts/template-holder/param-name-value/param-name-value.component'; +import {Tab} from './build-artifacts/template-holder/param-name-value/tab'; +import {Tabs} from './build-artifacts/template-holder/param-name-value/tabs'; +import {Ng2Bs3ModalModule} from 'ng2-bs3-modal/ng2-bs3-modal'; +import {AuthGuardModalComponent} from './auth-guard-modal/auth-guard-modal'; +import {GCAuthGuardService} from './GCAuthGuard/gcauth-guard.service'; +import {LoginGuardService} from './LoginGuardService/Login-guard-service'; +import {SimpleNotificationsModule} from 'angular2-notifications'; + + +export const components = [ + BuildDesignComponent, + GoldenConfigurationComponent, + GoldenConfigurationMappingComponent, + ParameterComponent, + ParameterHolderComponent, + MyvnfsComponent, + userloginFormComponent, + VnfsComponent, + ReferenceDataformComponent, + ReferenceDataHolderComponent, + ModalComponent, + GoldenConfigurationHolderComponent, + AceEditorComponent, + Tab, + Tabs, + ConfirmComponent, + AuthGuardModalComponent, + + +]; + +export const modules = [ + CommonModule, VnfRoutingModule, SharedModule.forRoot(), + FormsModule, BootstrapModalModule, Ng2Bs3ModalModule, SimpleNotificationsModule.forRoot() + +]; + +@NgModule({ + imports: [...modules], + declarations: [...components], + providers: [GCAuthGuardService, LoginGuardService], + + + entryComponents: [ConfirmComponent, AuthGuardModalComponent] +}) +export class VnfsModule { +}
\ No newline at end of file diff --git a/src/app/vnfs/vnfs/vnfs.component.css b/src/app/vnfs/vnfs/vnfs.component.css new file mode 100644 index 0000000..7c075eb --- /dev/null +++ b/src/app/vnfs/vnfs/vnfs.component.css @@ -0,0 +1,22 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/
\ No newline at end of file diff --git a/src/app/vnfs/vnfs/vnfs.component.html b/src/app/vnfs/vnfs/vnfs.component.html new file mode 100644 index 0000000..6668ed1 --- /dev/null +++ b/src/app/vnfs/vnfs/vnfs.component.html @@ -0,0 +1,24 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<router-outlet></router-outlet>
\ No newline at end of file diff --git a/src/app/vnfs/vnfs/vnfs.component.spec.ts b/src/app/vnfs/vnfs/vnfs.component.spec.ts new file mode 100644 index 0000000..bb19213 --- /dev/null +++ b/src/app/vnfs/vnfs/vnfs.component.spec.ts @@ -0,0 +1,49 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/* tslint:disable:no-unused-variable */ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {VnfsComponent} from './vnfs.component'; + +describe('VnfsComponent', () => { + let component: VnfsComponent; + let fixture: ComponentFixture<VnfsComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [VnfsComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(VnfsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/vnfs/vnfs/vnfs.component.ts b/src/app/vnfs/vnfs/vnfs.component.ts new file mode 100644 index 0000000..0add612 --- /dev/null +++ b/src/app/vnfs/vnfs/vnfs.component.ts @@ -0,0 +1,39 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-vnfs', + templateUrl: './vnfs.component.html', + styleUrls: ['./vnfs.component.css'] +}) +export class VnfsComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/assets/.gitkeep b/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/assets/.gitkeep diff --git a/src/assets/images/ic_play.png b/src/assets/images/ic_play.png Binary files differnew file mode 100644 index 0000000..54b628d --- /dev/null +++ b/src/assets/images/ic_play.png diff --git a/src/assets/images/ic_play1.png b/src/assets/images/ic_play1.png Binary files differnew file mode 100644 index 0000000..8609e0d --- /dev/null +++ b/src/assets/images/ic_play1.png diff --git a/src/assets/images/menu_icon.png b/src/assets/images/menu_icon.png Binary files differnew file mode 100644 index 0000000..b7ffb92 --- /dev/null +++ b/src/assets/images/menu_icon.png diff --git a/src/assets/images/menuicon.png b/src/assets/images/menuicon.png Binary files differnew file mode 100644 index 0000000..b7ffb92 --- /dev/null +++ b/src/assets/images/menuicon.png diff --git a/src/environments/environment.dev3.ts b/src/environments/environment.dev3.ts new file mode 100644 index 0000000..38deafd --- /dev/null +++ b/src/environments/environment.dev3.ts @@ -0,0 +1,37 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. +export const environment = { + production: false, + getDesigns: 'https://' + window.location.hostname + ':8443/restconf/operations/design-services:dbservice', + //getDesigns: "http://localhost:9090/" + "https://mtanjv9apbc51.aic.cip.att.com:8443/restconf/operations/design-services:dbservice", + + //getDesigns:"http://localhost:8443/restconf/operations/design-services:dbservice", + // validateTemplate:"https://"+window.location.hostname+":8443/restconf/operations/design-services:validator" + validateTemplate: 'https://' + window.location.hostname + ':8443/restconf/operations/design-services:validator', + testConfigure: 'https://' + window.location.hostname + ':8443/restconf/operations/appc-provider-lcm:configure' +}; diff --git a/src/environments/environment.dev4.ts b/src/environments/environment.dev4.ts new file mode 100644 index 0000000..38deafd --- /dev/null +++ b/src/environments/environment.dev4.ts @@ -0,0 +1,37 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. +export const environment = { + production: false, + getDesigns: 'https://' + window.location.hostname + ':8443/restconf/operations/design-services:dbservice', + //getDesigns: "http://localhost:9090/" + "https://mtanjv9apbc51.aic.cip.att.com:8443/restconf/operations/design-services:dbservice", + + //getDesigns:"http://localhost:8443/restconf/operations/design-services:dbservice", + // validateTemplate:"https://"+window.location.hostname+":8443/restconf/operations/design-services:validator" + validateTemplate: 'https://' + window.location.hostname + ':8443/restconf/operations/design-services:validator', + testConfigure: 'https://' + window.location.hostname + ':8443/restconf/operations/appc-provider-lcm:configure' +}; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts new file mode 100644 index 0000000..d0c6462 --- /dev/null +++ b/src/environments/environment.prod.ts @@ -0,0 +1,37 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. +export const environment = { + production: true, + getDesigns: 'https://' + window.location.hostname + ':8443/restconf/operations/design-services:dbservice', + //getDesigns: "http://localhost:9090/" + "https://mtanjv9apbc51.aic.cip.att.com:8443/restconf/operations/design-services:dbservice", + + //getDesigns:"http://localhost:8443/restconf/operations/design-services:dbservice", + // validateTemplate:"https://"+window.location.hostname+":8443/restconf/operations/design-services:validator" + validateTemplate: 'https://' + window.location.hostname + ':8443/restconf/operations/design-services:validator', + testConfigure: 'https://' + window.location.hostname + ':8443/restconf/operations/appc-provider-lcm:configure' +}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts new file mode 100644 index 0000000..37d7598 --- /dev/null +++ b/src/environments/environment.ts @@ -0,0 +1,60 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + + +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. +export const environment = { + production: false, + //Environment for PROD + + // getDesigns: 'https://' + window.location.hostname + ':8443/restconf/operations/design-services:dbservice', + // validateTemplate: 'https://' + window.location.hostname + ':8443/restconf/operations/design-services:validator', + // testVnf: 'https://' + window.location.hostname + ':8443/restconf/operations/appc-provider-lcm:', + // checkTestStatus: 'https://' + window.location.hostname + ':8443/restconf/operations/appc-provider-lcm:action-status' + + // Evn for Dev3 should always be commented + // + // getDesigns: "https://mtanjv9apbc53.aic.cip.att.com:8443/restconf/operations/design-services:dbservice", + // validateTemplate: "https://mtanjv9apbc53.aic.cip.att.com:8443/restconf/operations/design-services:validator", + // testVnf: "https://mtanjv9apbc53.aic.cip.att.com:8443/restconf/operations/appc-provider-lcm:", + // checkTestStatus: "https://mtanjv9apbc53.aic.cip.att.com:8443/restconf/operations/appc-provider-lcm:action-status" + + + // Evn for Dev1 should always be commented + + getDesigns: "https://mtanjv9apbc51.aic.cip.att.com:8443/restconf/operations/design-services:dbservice", + validateTemplate: "https://mtanjv9apbc51.aic.cip.att.com:8443/restconf/operations/design-services:validator", + testVnf: "https://mtanjv9apbc51.aic.cip.att.com:8443/restconf/operations/appc-provider-lcm:", + checkTestStatus: "https://mtanjv9apbc51.aic.cip.att.com:8443/restconf/operations/appc-provider-lcm:action-status" + + // Evn for Dev6 should always be commented + + // getDesigns: "https://mtanjv9apdb53.aic.cip.att.com:8443/restconf/operations/design-services:dbservice", + // validateTemplate: "https://mtanjv9apdb53.aic.cip.att.com:8443/restconf/operations/design-services:validator", + // testVnf: "https://mtanjv9apdb53.aic.cip.att.com:8443/restconf/operations/appc-provider-lcm:", + // checkTestStatus: "https://mtanjv9apdb53.aic.cip.att.com:8443/restconf/operations/appc-provider-lcm:action-status" + +}; diff --git a/src/favicon.ico b/src/favicon.ico Binary files differnew file mode 100644 index 0000000..68bee8a --- /dev/null +++ b/src/favicon.ico diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..0bdd78c --- /dev/null +++ b/src/index.html @@ -0,0 +1,39 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> + +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>APPC Self Service Design Tool</title> + <base href="./index.html"> + + + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="icon" type="image/x-icon" href="favicon.ico"> + +</head> +<body> +<app-root></app-root> +</body> +</html> diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..76bd61f --- /dev/null +++ b/src/main.ts @@ -0,0 +1,35 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import {enableProdMode} from '@angular/core'; +import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; + +import {AppModule} from './app/app.module'; +import {environment} from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/src/main/assembly/assembly.xml b/src/main/assembly/assembly.xml new file mode 100644 index 0000000..9fc9018 --- /dev/null +++ b/src/main/assembly/assembly.xml @@ -0,0 +1,38 @@ +<!-- +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +--> +<assembly + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <id>zip</id> + <formats> + <format>zip</format> + </formats> + <includeBaseDirectory>false</includeBaseDirectory> + <fileSets> + <fileSet> + <directory>dist/</directory> + <outputDirectory>config-design-tool/</outputDirectory> + </fileSet> + </fileSets> +</assembly>
\ No newline at end of file diff --git a/src/material.css b/src/material.css new file mode 100644 index 0000000..7891482 --- /dev/null +++ b/src/material.css @@ -0,0 +1,13487 @@ +/** + * material-design-lite - Material Design Components in CSS, JS and HTML + * @version v1.3.0 + * @license Apache-2.0 + * @copyright 2015 Google, Inc. + * @link https://github.com/google/material-design-lite + */ +@charset "UTF-8"; +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Material Design Lite */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/* + * What follows is the result of much research on cross-browser styling. + * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal, + * Kroc Camen, and the H5BP dev community and team. + */ +/* ========================================================================== + Base styles: opinionated defaults + ========================================================================== */ +html { + color: rgba(0, 0, 0, 0.87); + font-size: 1em; + line-height: 1.4; +} + +/* + * Remove text-shadow in selection highlight: + * https://twitter.com/miketaylr/status/12228805301 + * + * These selection rule sets have to be separate. + * Customize the background color to match your design. + */ +::-moz-selection { + background: #b3d4fc; + text-shadow: none; +} + +::selection { + background: #b3d4fc; + text-shadow: none; +} + +/* + * A better looking default horizontal rule + */ +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #ccc; + margin: 1em 0; + padding: 0; +} + +/* + * Remove the gap between audio, canvas, iframes, + * images, videos and the bottom of their containers: + * https://github.com/h5bp/html5-boilerplate/issues/440 + */ +audio, +canvas, +iframe, +img, +svg, +video { + vertical-align: middle; +} + +/* + * Remove default fieldset styles. + */ +fieldset { + border: 0; + margin: 0; + padding: 0; +} + +/* + * Allow only vertical resizing of textareas. + */ +textarea { + resize: vertical; +} + +/* ========================================================================== + Browser Upgrade Prompt + ========================================================================== */ +.browserupgrade { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0; +} + +/* ========================================================================== + Author's custom styles + ========================================================================== */ +/* ========================================================================== + Helper classes + ========================================================================== */ +/* + * Hide visually and from screen readers: + */ +.hidden { + display: none !important; +} + +/* + * Hide only visually, but have it available for screen readers: + * http://snook.ca/archives/html_and_css/hiding-content-for-accessibility + */ +.visuallyhidden { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +/* + * Extends the .visuallyhidden class to allow the element + * to be focusable when navigated to via the keyboard: + * https://www.drupal.org/node/897638 + */ +.visuallyhidden.focusable:active, +.visuallyhidden.focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; +} + +/* + * Hide visually and from screen readers, but maintain layout + */ +.invisible { + visibility: hidden; +} + +/* + * Clearfix: contain floats + * + * For modern browsers + * 1. The space content is one way to avoid an Opera bug when the + * `contenteditable` attribute is included anywhere else in the document. + * Otherwise it causes space to appear at the top and bottom of elements + * that receive the `clearfix` class. + * 2. The use of `table` rather than `block` is only necessary if using + * `:before` to contain the top-margins of child elements. + */ +.clearfix:before, +.clearfix:after { + content: " "; + /* 1 */ + display: table; + /* 2 */ +} + +.clearfix:after { + clear: both; +} + +/* ========================================================================== + EXAMPLE Media Queries for Responsive Design. + These examples override the primary ('mobile first') styles. + Modify as content requires. + ========================================================================== */ +@media only screen and (min-width: 35em) { + /* Style adjustments for viewports that meet the condition */ +} + +@media print, (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 1.25dppx), (min-resolution: 120dpi) { + /* Style adjustments for high resolution devices */ +} + +/* ========================================================================== + Print styles. + Inlined to avoid the additional HTTP request: + http://www.phpied.com/delay-loading-your-print-css/ + ========================================================================== */ +@media print { + *, + *:before, + *:after, + *:first-letter { + background: transparent !important; + color: #000 !important; + /* Black prints faster: http://www.sanbeiji.com/archives/953 */ + box-shadow: none !important; + } + + a, + a:visited { + text-decoration: underline; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + /* + * Don't show links that are fragment identifiers, + * or use the `javascript:` pseudo protocol + */ + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + /* + * Printing Tables: + * http://css-discuss.incutio.com/wiki/Printing_Tables + */ + 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; + } +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Remove the unwanted box around FAB buttons */ +/* More info: http://goo.gl/IPwKi */ +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); +} + +/* + * Make html take up the entire screen + * Then set touch-action to avoid touch delay on mobile IE + */ +html { + width: 100%; + height: 100%; + -ms-touch-action: manipulation; + touch-action: manipulation; +} + +/* +* Make body take up the entire screen +* Remove body margin so layout containers don't cause extra overflow. +*/ +body { + width: 100%; + min-height: 100%; + margin: 0; +} + +/* + * Main display reset for IE support. + * Source: http://weblog.west-wind.com/posts/2015/Jan/12/main-HTML5-Tag-not-working-in-Internet-Explorer-91011 + */ +main { + display: block; +} + +/* +* Apply no display to elements with the hidden attribute. +* IE 9 and 10 support. +*/ +*[hidden] { + display: none !important; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +html, body { + font-family: "Roboto"; + font-size: 14px; + font-weight: 400; + line-height: 20px; +} + +h1, h2, h3, h4, h5, h6, p { + margin: 0; + padding: 0; +} + +/** + * Styles for HTML elements + */ +h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + font-family: "Roboto"; + font-size: 56px; + font-weight: 400; + line-height: 1.35; + letter-spacing: -0.02em; + opacity: 0.54; + font-size: 0.6em; +} + +h1 { + font-family: "Roboto"; + font-size: 56px; + font-weight: 400; + line-height: 1.35; + letter-spacing: -0.02em; + margin-top: 24px; + margin-bottom: 24px; +} + +h2 { + font-family: "Roboto"; + font-size: 45px; + font-weight: 400; + line-height: 48px; + margin-top: 24px; + margin-bottom: 24px; +} + +h3 { + font-family: "Roboto"; + font-size: 34px; + font-weight: 400; + line-height: 40px; + margin-top: 24px; + margin-bottom: 24px; +} + +h4 { + font-family: "Roboto"; + font-size: 24px; + font-weight: 400; + line-height: 32px; + -moz-osx-font-smoothing: grayscale; + margin-top: 24px; + margin-bottom: 16px; +} + +h5 { + font-family: "Roboto"; + font-size: 20px; + font-weight: 500; + line-height: 1; + letter-spacing: 0.02em; + margin-top: 24px; + margin-bottom: 16px; +} + +h6 { + font-family: "Roboto"; + font-size: 16px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0.04em; + margin-top: 24px; + margin-bottom: 16px; +} + +p { + font-size: 14px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + margin-bottom: 16px; +} + +a { + color: rgb(255, 64, 129); + font-weight: 500; +} + +blockquote { + font-family: "Roboto"; + position: relative; + font-size: 24px; + font-weight: 300; + font-style: italic; + line-height: 1.35; + letter-spacing: 0.08em; +} + +blockquote:before { + position: absolute; + left: -0.5em; + content: '“'; +} + +blockquote:after { + content: '”'; + margin-left: -0.05em; +} + +mark { + background-color: #f4ff81; +} + +dt { + font-weight: 700; +} + +address { + font-size: 12px; + font-weight: 400; + line-height: 1; + letter-spacing: 0; + font-style: normal; +} + +ul, ol { + font-size: 14px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; +} + +/** + * Class Name Styles + */ +.mdl-typography--display-4 { + font-family: "Roboto"; + font-size: 112px; + font-weight: 300; + line-height: 1; + letter-spacing: -0.04em; +} + +.mdl-typography--display-4-color-contrast { + font-family: "Roboto"; + font-size: 112px; + font-weight: 300; + line-height: 1; + letter-spacing: -0.04em; + opacity: 0.54; +} + +.mdl-typography--display-3 { + font-family: "Roboto"; + font-size: 56px; + font-weight: 400; + line-height: 1.35; + letter-spacing: -0.02em; +} + +.mdl-typography--display-3-color-contrast { + font-family: "Roboto"; + font-size: 56px; + font-weight: 400; + line-height: 1.35; + letter-spacing: -0.02em; + opacity: 0.54; +} + +.mdl-typography--display-2 { + font-family: "Roboto"; + font-size: 45px; + font-weight: 400; + line-height: 48px; +} + +.mdl-typography--display-2-color-contrast { + font-family: "Roboto"; + font-size: 45px; + font-weight: 400; + line-height: 48px; + opacity: 0.54; +} + +.mdl-typography--display-1 { + font-family: "Roboto"; + font-size: 34px; + font-weight: 400; + line-height: 40px; +} + +.mdl-typography--display-1-color-contrast { + font-family: "Roboto"; + font-size: 34px; + font-weight: 400; + line-height: 40px; + opacity: 0.54; +} + +.mdl-typography--headline { + font-family: "Roboto"; + font-size: 24px; + font-weight: 400; + line-height: 32px; + -moz-osx-font-smoothing: grayscale; +} + +.mdl-typography--headline-color-contrast { + font-family: "Roboto"; + font-size: 24px; + font-weight: 400; + line-height: 32px; + -moz-osx-font-smoothing: grayscale; + opacity: 0.87; +} + +.mdl-typography--title { + font-family: "Roboto"; + font-size: 20px; + font-weight: 500; + line-height: 1; + letter-spacing: 0.02em; +} + +.mdl-typography--title-color-contrast { + font-family: "Roboto"; + font-size: 20px; + font-weight: 500; + line-height: 1; + letter-spacing: 0.02em; + opacity: 0.87; +} + +.mdl-typography--subhead { + font-family: "Roboto"; + font-size: 16px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0.04em; +} + +.mdl-typography--subhead-color-contrast { + font-family: "Roboto"; + font-size: 16px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0.04em; + opacity: 0.87; +} + +.mdl-typography--body-2 { + font-size: 14px; + font-weight: bold; + line-height: 24px; + letter-spacing: 0; +} + +.mdl-typography--body-2-color-contrast { + font-size: 14px; + font-weight: bold; + line-height: 24px; + letter-spacing: 0; + opacity: 0.87; +} + +.mdl-typography--body-1 { + font-size: 14px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; +} + +.mdl-typography--body-1-color-contrast { + font-size: 14px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + opacity: 0.87; +} + +.mdl-typography--body-2-force-preferred-font { + font-family: "Roboto"; + font-size: 14px; + font-weight: 500; + line-height: 24px; + letter-spacing: 0; +} + +.mdl-typography--body-2-force-preferred-font-color-contrast { + font-family: "Roboto"; + font-size: 14px; + font-weight: 500; + line-height: 24px; + letter-spacing: 0; + opacity: 0.87; +} + +.mdl-typography--body-1-force-preferred-font { + font-family: "Roboto"; + font-size: 14px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; +} + +.mdl-typography--body-1-force-preferred-font-color-contrast { + font-family: "Roboto"; + font-size: 14px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + opacity: 0.87; +} + +.mdl-typography--caption { + font-size: 12px; + font-weight: 400; + line-height: 1; + letter-spacing: 0; +} + +.mdl-typography--caption-force-preferred-font { + font-family: "Roboto"; + font-size: 12px; + font-weight: 400; + line-height: 1; + letter-spacing: 0; +} + +.mdl-typography--caption-color-contrast { + font-size: 12px; + font-weight: 400; + line-height: 1; + letter-spacing: 0; + opacity: 0.54; +} + +.mdl-typography--caption-force-preferred-font-color-contrast { + font-family: "Roboto"; + font-size: 12px; + font-weight: 400; + line-height: 1; + letter-spacing: 0; + opacity: 0.54; +} + +.mdl-typography--menu { + font-family: "Roboto"; + font-size: 14px; + font-weight: 500; + line-height: 1; + letter-spacing: 0; +} + +.mdl-typography--menu-color-contrast { + font-family: "Roboto"; + font-size: 14px; + font-weight: 500; + line-height: 1; + letter-spacing: 0; + opacity: 0.87; +} + +.mdl-typography--button { + font-family: "Roboto"; + font-size: 14px; + font-weight: 500; + text-transform: uppercase; + line-height: 1; + letter-spacing: 0; +} + +.mdl-typography--button-color-contrast { + font-family: "Roboto"; + font-size: 14px; + font-weight: 500; + text-transform: uppercase; + line-height: 1; + letter-spacing: 0; + opacity: 0.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: normal; + 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; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.mdl-color-text--red { + color: rgb(244, 67, 54) !important; +} + +.mdl-color--red { + background-color: rgb(244, 67, 54) !important; +} + +.mdl-color-text--red-50 { + color: rgb(255, 235, 238) !important; +} + +.mdl-color--red-50 { + background-color: rgb(255, 235, 238) !important; +} + +.mdl-color-text--red-100 { + color: rgb(255, 205, 210) !important; +} + +.mdl-color--red-100 { + background-color: rgb(255, 205, 210) !important; +} + +.mdl-color-text--red-200 { + color: rgb(239, 154, 154) !important; +} + +.mdl-color--red-200 { + background-color: rgb(239, 154, 154) !important; +} + +.mdl-color-text--red-300 { + color: rgb(229, 115, 115) !important; +} + +.mdl-color--red-300 { + background-color: rgb(229, 115, 115) !important; +} + +.mdl-color-text--red-400 { + color: rgb(239, 83, 80) !important; +} + +.mdl-color--red-400 { + background-color: rgb(239, 83, 80) !important; +} + +.mdl-color-text--red-500 { + color: rgb(244, 67, 54) !important; +} + +.mdl-color--red-500 { + background-color: rgb(244, 67, 54) !important; +} + +.mdl-color-text--red-600 { + color: rgb(229, 57, 53) !important; +} + +.mdl-color--red-600 { + background-color: rgb(229, 57, 53) !important; +} + +.mdl-color-text--red-700 { + color: rgb(211, 47, 47) !important; +} + +.mdl-color--red-700 { + background-color: rgb(211, 47, 47) !important; +} + +.mdl-color-text--red-800 { + color: rgb(198, 40, 40) !important; +} + +.mdl-color--red-800 { + background-color: rgb(198, 40, 40) !important; +} + +.mdl-color-text--red-900 { + color: rgb(183, 28, 28) !important; +} + +.mdl-color--red-900 { + background-color: rgb(183, 28, 28) !important; +} + +.mdl-color-text--red-A100 { + color: rgb(255, 138, 128) !important; +} + +.mdl-color--red-A100 { + background-color: rgb(255, 138, 128) !important; +} + +.mdl-color-text--red-A200 { + color: rgb(255, 82, 82) !important; +} + +.mdl-color--red-A200 { + background-color: rgb(255, 82, 82) !important; +} + +.mdl-color-text--red-A400 { + color: rgb(255, 23, 68) !important; +} + +.mdl-color--red-A400 { + background-color: rgb(255, 23, 68) !important; +} + +.mdl-color-text--red-A700 { + color: rgb(213, 0, 0) !important; +} + +.mdl-color--red-A700 { + background-color: rgb(213, 0, 0) !important; +} + +.mdl-color-text--pink { + color: rgb(233, 30, 99) !important; +} + +.mdl-color--pink { + background-color: rgb(233, 30, 99) !important; +} + +.mdl-color-text--pink-50 { + color: rgb(252, 228, 236) !important; +} + +.mdl-color--pink-50 { + background-color: rgb(252, 228, 236) !important; +} + +.mdl-color-text--pink-100 { + color: rgb(248, 187, 208) !important; +} + +.mdl-color--pink-100 { + background-color: rgb(248, 187, 208) !important; +} + +.mdl-color-text--pink-200 { + color: rgb(244, 143, 177) !important; +} + +.mdl-color--pink-200 { + background-color: rgb(244, 143, 177) !important; +} + +.mdl-color-text--pink-300 { + color: rgb(240, 98, 146) !important; +} + +.mdl-color--pink-300 { + background-color: rgb(240, 98, 146) !important; +} + +.mdl-color-text--pink-400 { + color: rgb(236, 64, 122) !important; +} + +.mdl-color--pink-400 { + background-color: rgb(236, 64, 122) !important; +} + +.mdl-color-text--pink-500 { + color: rgb(233, 30, 99) !important; +} + +.mdl-color--pink-500 { + background-color: rgb(233, 30, 99) !important; +} + +.mdl-color-text--pink-600 { + color: rgb(216, 27, 96) !important; +} + +.mdl-color--pink-600 { + background-color: rgb(216, 27, 96) !important; +} + +.mdl-color-text--pink-700 { + color: rgb(194, 24, 91) !important; +} + +.mdl-color--pink-700 { + background-color: rgb(194, 24, 91) !important; +} + +.mdl-color-text--pink-800 { + color: rgb(173, 20, 87) !important; +} + +.mdl-color--pink-800 { + background-color: rgb(173, 20, 87) !important; +} + +.mdl-color-text--pink-900 { + color: rgb(136, 14, 79) !important; +} + +.mdl-color--pink-900 { + background-color: rgb(136, 14, 79) !important; +} + +.mdl-color-text--pink-A100 { + color: rgb(255, 128, 171) !important; +} + +.mdl-color--pink-A100 { + background-color: rgb(255, 128, 171) !important; +} + +.mdl-color-text--pink-A200 { + color: rgb(255, 64, 129) !important; +} + +.mdl-color--pink-A200 { + background-color: rgb(255, 64, 129) !important; +} + +.mdl-color-text--pink-A400 { + color: rgb(245, 0, 87) !important; +} + +.mdl-color--pink-A400 { + background-color: rgb(245, 0, 87) !important; +} + +.mdl-color-text--pink-A700 { + color: rgb(197, 17, 98) !important; +} + +.mdl-color--pink-A700 { + background-color: rgb(197, 17, 98) !important; +} + +.mdl-color-text--purple { + color: rgb(156, 39, 176) !important; +} + +.mdl-color--purple { + background-color: rgb(156, 39, 176) !important; +} + +.mdl-color-text--purple-50 { + color: rgb(243, 229, 245) !important; +} + +.mdl-color--purple-50 { + background-color: rgb(243, 229, 245) !important; +} + +.mdl-color-text--purple-100 { + color: rgb(225, 190, 231) !important; +} + +.mdl-color--purple-100 { + background-color: rgb(225, 190, 231) !important; +} + +.mdl-color-text--purple-200 { + color: rgb(206, 147, 216) !important; +} + +.mdl-color--purple-200 { + background-color: rgb(206, 147, 216) !important; +} + +.mdl-color-text--purple-300 { + color: rgb(186, 104, 200) !important; +} + +.mdl-color--purple-300 { + background-color: rgb(186, 104, 200) !important; +} + +.mdl-color-text--purple-400 { + color: rgb(171, 71, 188) !important; +} + +.mdl-color--purple-400 { + background-color: rgb(171, 71, 188) !important; +} + +.mdl-color-text--purple-500 { + color: rgb(156, 39, 176) !important; +} + +.mdl-color--purple-500 { + background-color: rgb(156, 39, 176) !important; +} + +.mdl-color-text--purple-600 { + color: rgb(142, 36, 170) !important; +} + +.mdl-color--purple-600 { + background-color: rgb(142, 36, 170) !important; +} + +.mdl-color-text--purple-700 { + color: rgb(123, 31, 162) !important; +} + +.mdl-color--purple-700 { + background-color: rgb(123, 31, 162) !important; +} + +.mdl-color-text--purple-800 { + color: rgb(106, 27, 154) !important; +} + +.mdl-color--purple-800 { + background-color: rgb(106, 27, 154) !important; +} + +.mdl-color-text--purple-900 { + color: rgb(74, 20, 140) !important; +} + +.mdl-color--purple-900 { + background-color: rgb(74, 20, 140) !important; +} + +.mdl-color-text--purple-A100 { + color: rgb(234, 128, 252) !important; +} + +.mdl-color--purple-A100 { + background-color: rgb(234, 128, 252) !important; +} + +.mdl-color-text--purple-A200 { + color: rgb(224, 64, 251) !important; +} + +.mdl-color--purple-A200 { + background-color: rgb(224, 64, 251) !important; +} + +.mdl-color-text--purple-A400 { + color: rgb(213, 0, 249) !important; +} + +.mdl-color--purple-A400 { + background-color: rgb(213, 0, 249) !important; +} + +.mdl-color-text--purple-A700 { + color: rgb(170, 0, 255) !important; +} + +.mdl-color--purple-A700 { + background-color: rgb(170, 0, 255) !important; +} + +.mdl-color-text--deep-purple { + color: rgb(103, 58, 183) !important; +} + +.mdl-color--deep-purple { + background-color: rgb(103, 58, 183) !important; +} + +.mdl-color-text--deep-purple-50 { + color: rgb(237, 231, 246) !important; +} + +.mdl-color--deep-purple-50 { + background-color: rgb(237, 231, 246) !important; +} + +.mdl-color-text--deep-purple-100 { + color: rgb(209, 196, 233) !important; +} + +.mdl-color--deep-purple-100 { + background-color: rgb(209, 196, 233) !important; +} + +.mdl-color-text--deep-purple-200 { + color: rgb(179, 157, 219) !important; +} + +.mdl-color--deep-purple-200 { + background-color: rgb(179, 157, 219) !important; +} + +.mdl-color-text--deep-purple-300 { + color: rgb(149, 117, 205) !important; +} + +.mdl-color--deep-purple-300 { + background-color: rgb(149, 117, 205) !important; +} + +.mdl-color-text--deep-purple-400 { + color: rgb(126, 87, 194) !important; +} + +.mdl-color--deep-purple-400 { + background-color: rgb(126, 87, 194) !important; +} + +.mdl-color-text--deep-purple-500 { + color: rgb(103, 58, 183) !important; +} + +.mdl-color--deep-purple-500 { + background-color: rgb(103, 58, 183) !important; +} + +.mdl-color-text--deep-purple-600 { + color: rgb(94, 53, 177) !important; +} + +.mdl-color--deep-purple-600 { + background-color: rgb(94, 53, 177) !important; +} + +.mdl-color-text--deep-purple-700 { + color: rgb(81, 45, 168) !important; +} + +.mdl-color--deep-purple-700 { + background-color: rgb(81, 45, 168) !important; +} + +.mdl-color-text--deep-purple-800 { + color: rgb(69, 39, 160) !important; +} + +.mdl-color--deep-purple-800 { + background-color: rgb(69, 39, 160) !important; +} + +.mdl-color-text--deep-purple-900 { + color: rgb(49, 27, 146) !important; +} + +.mdl-color--deep-purple-900 { + background-color: rgb(49, 27, 146) !important; +} + +.mdl-color-text--deep-purple-A100 { + color: rgb(179, 136, 255) !important; +} + +.mdl-color--deep-purple-A100 { + background-color: rgb(179, 136, 255) !important; +} + +.mdl-color-text--deep-purple-A200 { + color: rgb(124, 77, 255) !important; +} + +.mdl-color--deep-purple-A200 { + background-color: rgb(124, 77, 255) !important; +} + +.mdl-color-text--deep-purple-A400 { + color: rgb(101, 31, 255) !important; +} + +.mdl-color--deep-purple-A400 { + background-color: rgb(101, 31, 255) !important; +} + +.mdl-color-text--deep-purple-A700 { + color: rgb(98, 0, 234) !important; +} + +.mdl-color--deep-purple-A700 { + background-color: rgb(98, 0, 234) !important; +} + +.mdl-color-text--indigo { + color: rgb(63, 81, 181) !important; +} + +.mdl-color--indigo { + background-color: rgb(63, 81, 181) !important; +} + +.mdl-color-text--indigo-50 { + color: rgb(232, 234, 246) !important; +} + +.mdl-color--indigo-50 { + background-color: rgb(232, 234, 246) !important; +} + +.mdl-color-text--indigo-100 { + color: rgb(197, 202, 233) !important; +} + +.mdl-color--indigo-100 { + background-color: rgb(197, 202, 233) !important; +} + +.mdl-color-text--indigo-200 { + color: rgb(159, 168, 218) !important; +} + +.mdl-color--indigo-200 { + background-color: rgb(159, 168, 218) !important; +} + +.mdl-color-text--indigo-300 { + color: rgb(121, 134, 203) !important; +} + +.mdl-color--indigo-300 { + background-color: rgb(121, 134, 203) !important; +} + +.mdl-color-text--indigo-400 { + color: rgb(92, 107, 192) !important; +} + +.mdl-color--indigo-400 { + background-color: rgb(92, 107, 192) !important; +} + +.mdl-color-text--indigo-500 { + color: rgb(63, 81, 181) !important; +} + +.mdl-color--indigo-500 { + background-color: rgb(63, 81, 181) !important; +} + +.mdl-color-text--indigo-600 { + color: rgb(57, 73, 171) !important; +} + +.mdl-color--indigo-600 { + background-color: rgb(57, 73, 171) !important; +} + +.mdl-color-text--indigo-700 { + color: rgb(48, 63, 159) !important; +} + +.mdl-color--indigo-700 { + background-color: rgb(48, 63, 159) !important; +} + +.mdl-color-text--indigo-800 { + color: rgb(40, 53, 147) !important; +} + +.mdl-color--indigo-800 { + background-color: rgb(40, 53, 147) !important; +} + +.mdl-color-text--indigo-900 { + color: rgb(26, 35, 126) !important; +} + +.mdl-color--indigo-900 { + background-color: rgb(26, 35, 126) !important; +} + +.mdl-color-text--indigo-A100 { + color: rgb(140, 158, 255) !important; +} + +.mdl-color--indigo-A100 { + background-color: rgb(140, 158, 255) !important; +} + +.mdl-color-text--indigo-A200 { + color: rgb(83, 109, 254) !important; +} + +.mdl-color--indigo-A200 { + background-color: rgb(83, 109, 254) !important; +} + +.mdl-color-text--indigo-A400 { + color: rgb(61, 90, 254) !important; +} + +.mdl-color--indigo-A400 { + background-color: rgb(61, 90, 254) !important; +} + +.mdl-color-text--indigo-A700 { + color: rgb(48, 79, 254) !important; +} + +.mdl-color--indigo-A700 { + background-color: rgb(48, 79, 254) !important; +} + +.mdl-color-text--blue { + color: rgb(33, 150, 243) !important; +} + +.mdl-color--blue { + background-color: rgb(33, 150, 243) !important; +} + +.mdl-color-text--blue-50 { + color: rgb(227, 242, 253) !important; +} + +.mdl-color--blue-50 { + background-color: rgb(227, 242, 253) !important; +} + +.mdl-color-text--blue-100 { + color: rgb(187, 222, 251) !important; +} + +.mdl-color--blue-100 { + background-color: rgb(187, 222, 251) !important; +} + +.mdl-color-text--blue-200 { + color: rgb(144, 202, 249) !important; +} + +.mdl-color--blue-200 { + background-color: rgb(144, 202, 249) !important; +} + +.mdl-color-text--blue-300 { + color: rgb(100, 181, 246) !important; +} + +.mdl-color--blue-300 { + background-color: rgb(100, 181, 246) !important; +} + +.mdl-color-text--blue-400 { + color: rgb(66, 165, 245) !important; +} + +.mdl-color--blue-400 { + background-color: rgb(66, 165, 245) !important; +} + +.mdl-color-text--blue-500 { + color: rgb(33, 150, 243) !important; +} + +.mdl-color--blue-500 { + background-color: rgb(33, 150, 243) !important; +} + +.mdl-color-text--blue-600 { + color: rgb(30, 136, 229) !important; +} + +.mdl-color--blue-600 { + background-color: rgb(30, 136, 229) !important; +} + +.mdl-color-text--blue-700 { + color: rgb(25, 118, 210) !important; +} + +.mdl-color--blue-700 { + background-color: rgb(25, 118, 210) !important; +} + +.mdl-color-text--blue-800 { + color: rgb(21, 101, 192) !important; +} + +.mdl-color--blue-800 { + background-color: rgb(21, 101, 192) !important; +} + +.mdl-color-text--blue-900 { + color: rgb(13, 71, 161) !important; +} + +.mdl-color--blue-900 { + background-color: rgb(13, 71, 161) !important; +} + +.mdl-color-text--blue-A100 { + color: rgb(130, 177, 255) !important; +} + +.mdl-color--blue-A100 { + background-color: rgb(130, 177, 255) !important; +} + +.mdl-color-text--blue-A200 { + color: rgb(68, 138, 255) !important; +} + +.mdl-color--blue-A200 { + background-color: rgb(68, 138, 255) !important; +} + +.mdl-color-text--blue-A400 { + color: rgb(41, 121, 255) !important; +} + +.mdl-color--blue-A400 { + background-color: rgb(41, 121, 255) !important; +} + +.mdl-color-text--blue-A700 { + color: rgb(41, 98, 255) !important; +} + +.mdl-color--blue-A700 { + background-color: rgb(41, 98, 255) !important; +} + +.mdl-color-text--light-blue { + color: rgb(3, 169, 244) !important; +} + +.mdl-color--light-blue { + background-color: rgb(3, 169, 244) !important; +} + +.mdl-color-text--light-blue-50 { + color: rgb(225, 245, 254) !important; +} + +.mdl-color--light-blue-50 { + background-color: rgb(225, 245, 254) !important; +} + +.mdl-color-text--light-blue-100 { + color: rgb(179, 229, 252) !important; +} + +.mdl-color--light-blue-100 { + background-color: rgb(179, 229, 252) !important; +} + +.mdl-color-text--light-blue-200 { + color: rgb(129, 212, 250) !important; +} + +.mdl-color--light-blue-200 { + background-color: rgb(129, 212, 250) !important; +} + +.mdl-color-text--light-blue-300 { + color: rgb(79, 195, 247) !important; +} + +.mdl-color--light-blue-300 { + background-color: rgb(79, 195, 247) !important; +} + +.mdl-color-text--light-blue-400 { + color: rgb(41, 182, 246) !important; +} + +.mdl-color--light-blue-400 { + background-color: rgb(41, 182, 246) !important; +} + +.mdl-color-text--light-blue-500 { + color: rgb(3, 169, 244) !important; +} + +.mdl-color--light-blue-500 { + background-color: rgb(3, 169, 244) !important; +} + +.mdl-color-text--light-blue-600 { + color: rgb(3, 155, 229) !important; +} + +.mdl-color--light-blue-600 { + background-color: rgb(3, 155, 229) !important; +} + +.mdl-color-text--light-blue-700 { + color: rgb(2, 136, 209) !important; +} + +.mdl-color--light-blue-700 { + background-color: rgb(2, 136, 209) !important; +} + +.mdl-color-text--light-blue-800 { + color: rgb(2, 119, 189) !important; +} + +.mdl-color--light-blue-800 { + background-color: rgb(2, 119, 189) !important; +} + +.mdl-color-text--light-blue-900 { + color: rgb(1, 87, 155) !important; +} + +.mdl-color--light-blue-900 { + background-color: rgb(1, 87, 155) !important; +} + +.mdl-color-text--light-blue-A100 { + color: rgb(128, 216, 255) !important; +} + +.mdl-color--light-blue-A100 { + background-color: rgb(128, 216, 255) !important; +} + +.mdl-color-text--light-blue-A200 { + color: rgb(64, 196, 255) !important; +} + +.mdl-color--light-blue-A200 { + background-color: rgb(64, 196, 255) !important; +} + +.mdl-color-text--light-blue-A400 { + color: rgb(0, 176, 255) !important; +} + +.mdl-color--light-blue-A400 { + background-color: rgb(0, 176, 255) !important; +} + +.mdl-color-text--light-blue-A700 { + color: rgb(0, 145, 234) !important; +} + +.mdl-color--light-blue-A700 { + background-color: rgb(0, 145, 234) !important; +} + +.mdl-color-text--cyan { + color: rgb(0, 188, 212) !important; +} + +.mdl-color--cyan { + background-color: rgb(0, 188, 212) !important; +} + +.mdl-color-text--cyan-50 { + color: rgb(224, 247, 250) !important; +} + +.mdl-color--cyan-50 { + background-color: rgb(224, 247, 250) !important; +} + +.mdl-color-text--cyan-100 { + color: rgb(178, 235, 242) !important; +} + +.mdl-color--cyan-100 { + background-color: rgb(178, 235, 242) !important; +} + +.mdl-color-text--cyan-200 { + color: rgb(128, 222, 234) !important; +} + +.mdl-color--cyan-200 { + background-color: rgb(128, 222, 234) !important; +} + +.mdl-color-text--cyan-300 { + color: rgb(77, 208, 225) !important; +} + +.mdl-color--cyan-300 { + background-color: rgb(77, 208, 225) !important; +} + +.mdl-color-text--cyan-400 { + color: rgb(38, 198, 218) !important; +} + +.mdl-color--cyan-400 { + background-color: rgb(38, 198, 218) !important; +} + +.mdl-color-text--cyan-500 { + color: rgb(0, 188, 212) !important; +} + +.mdl-color--cyan-500 { + background-color: rgb(0, 188, 212) !important; +} + +.mdl-color-text--cyan-600 { + color: rgb(0, 172, 193) !important; +} + +.mdl-color--cyan-600 { + background-color: rgb(0, 172, 193) !important; +} + +.mdl-color-text--cyan-700 { + color: rgb(0, 151, 167) !important; +} + +.mdl-color--cyan-700 { + background-color: rgb(0, 151, 167) !important; +} + +.mdl-color-text--cyan-800 { + color: rgb(0, 131, 143) !important; +} + +.mdl-color--cyan-800 { + background-color: rgb(0, 131, 143) !important; +} + +.mdl-color-text--cyan-900 { + color: rgb(0, 96, 100) !important; +} + +.mdl-color--cyan-900 { + background-color: rgb(0, 96, 100) !important; +} + +.mdl-color-text--cyan-A100 { + color: rgb(132, 255, 255) !important; +} + +.mdl-color--cyan-A100 { + background-color: rgb(132, 255, 255) !important; +} + +.mdl-color-text--cyan-A200 { + color: rgb(24, 255, 255) !important; +} + +.mdl-color--cyan-A200 { + background-color: rgb(24, 255, 255) !important; +} + +.mdl-color-text--cyan-A400 { + color: rgb(0, 229, 255) !important; +} + +.mdl-color--cyan-A400 { + background-color: rgb(0, 229, 255) !important; +} + +.mdl-color-text--cyan-A700 { + color: rgb(0, 184, 212) !important; +} + +.mdl-color--cyan-A700 { + background-color: rgb(0, 184, 212) !important; +} + +.mdl-color-text--teal { + color: rgb(0, 150, 136) !important; +} + +.mdl-color--teal { + background-color: rgb(0, 150, 136) !important; +} + +.mdl-color-text--teal-50 { + color: rgb(224, 242, 241) !important; +} + +.mdl-color--teal-50 { + background-color: rgb(224, 242, 241) !important; +} + +.mdl-color-text--teal-100 { + color: rgb(178, 223, 219) !important; +} + +.mdl-color--teal-100 { + background-color: rgb(178, 223, 219) !important; +} + +.mdl-color-text--teal-200 { + color: rgb(128, 203, 196) !important; +} + +.mdl-color--teal-200 { + background-color: rgb(128, 203, 196) !important; +} + +.mdl-color-text--teal-300 { + color: rgb(77, 182, 172) !important; +} + +.mdl-color--teal-300 { + background-color: rgb(77, 182, 172) !important; +} + +.mdl-color-text--teal-400 { + color: rgb(38, 166, 154) !important; +} + +.mdl-color--teal-400 { + background-color: rgb(38, 166, 154) !important; +} + +.mdl-color-text--teal-500 { + color: rgb(0, 150, 136) !important; +} + +.mdl-color--teal-500 { + background-color: rgb(0, 150, 136) !important; +} + +.mdl-color-text--teal-600 { + color: rgb(0, 137, 123) !important; +} + +.mdl-color--teal-600 { + background-color: rgb(0, 137, 123) !important; +} + +.mdl-color-text--teal-700 { + color: rgb(0, 121, 107) !important; +} + +.mdl-color--teal-700 { + background-color: rgb(0, 121, 107) !important; +} + +.mdl-color-text--teal-800 { + color: rgb(0, 105, 92) !important; +} + +.mdl-color--teal-800 { + background-color: rgb(0, 105, 92) !important; +} + +.mdl-color-text--teal-900 { + color: rgb(0, 77, 64) !important; +} + +.mdl-color--teal-900 { + background-color: rgb(0, 77, 64) !important; +} + +.mdl-color-text--teal-A100 { + color: rgb(167, 255, 235) !important; +} + +.mdl-color--teal-A100 { + background-color: rgb(167, 255, 235) !important; +} + +.mdl-color-text--teal-A200 { + color: rgb(100, 255, 218) !important; +} + +.mdl-color--teal-A200 { + background-color: rgb(100, 255, 218) !important; +} + +.mdl-color-text--teal-A400 { + color: rgb(29, 233, 182) !important; +} + +.mdl-color--teal-A400 { + background-color: rgb(29, 233, 182) !important; +} + +.mdl-color-text--teal-A700 { + color: rgb(0, 191, 165) !important; +} + +.mdl-color--teal-A700 { + background-color: rgb(0, 191, 165) !important; +} + +.mdl-color-text--green { + color: rgb(76, 175, 80) !important; +} + +.mdl-color--green { + background-color: rgb(76, 175, 80) !important; +} + +.mdl-color-text--green-50 { + color: rgb(232, 245, 233) !important; +} + +.mdl-color--green-50 { + background-color: rgb(232, 245, 233) !important; +} + +.mdl-color-text--green-100 { + color: rgb(200, 230, 201) !important; +} + +.mdl-color--green-100 { + background-color: rgb(200, 230, 201) !important; +} + +.mdl-color-text--green-200 { + color: rgb(165, 214, 167) !important; +} + +.mdl-color--green-200 { + background-color: rgb(165, 214, 167) !important; +} + +.mdl-color-text--green-300 { + color: rgb(129, 199, 132) !important; +} + +.mdl-color--green-300 { + background-color: rgb(129, 199, 132) !important; +} + +.mdl-color-text--green-400 { + color: rgb(102, 187, 106) !important; +} + +.mdl-color--green-400 { + background-color: rgb(102, 187, 106) !important; +} + +.mdl-color-text--green-500 { + color: rgb(76, 175, 80) !important; +} + +.mdl-color--green-500 { + background-color: rgb(76, 175, 80) !important; +} + +.mdl-color-text--green-600 { + color: rgb(67, 160, 71) !important; +} + +.mdl-color--green-600 { + background-color: rgb(67, 160, 71) !important; +} + +.mdl-color-text--green-700 { + color: rgb(56, 142, 60) !important; +} + +.mdl-color--green-700 { + background-color: rgb(56, 142, 60) !important; +} + +.mdl-color-text--green-800 { + color: rgb(46, 125, 50) !important; +} + +.mdl-color--green-800 { + background-color: rgb(46, 125, 50) !important; +} + +.mdl-color-text--green-900 { + color: rgb(27, 94, 32) !important; +} + +.mdl-color--green-900 { + background-color: rgb(27, 94, 32) !important; +} + +.mdl-color-text--green-A100 { + color: rgb(185, 246, 202) !important; +} + +.mdl-color--green-A100 { + background-color: rgb(185, 246, 202) !important; +} + +.mdl-color-text--green-A200 { + color: rgb(105, 240, 174) !important; +} + +.mdl-color--green-A200 { + background-color: rgb(105, 240, 174) !important; +} + +.mdl-color-text--green-A400 { + color: rgb(0, 230, 118) !important; +} + +.mdl-color--green-A400 { + background-color: rgb(0, 230, 118) !important; +} + +.mdl-color-text--green-A700 { + color: rgb(0, 200, 83) !important; +} + +.mdl-color--green-A700 { + background-color: rgb(0, 200, 83) !important; +} + +.mdl-color-text--light-green { + color: rgb(139, 195, 74) !important; +} + +.mdl-color--light-green { + background-color: rgb(139, 195, 74) !important; +} + +.mdl-color-text--light-green-50 { + color: rgb(241, 248, 233) !important; +} + +.mdl-color--light-green-50 { + background-color: rgb(241, 248, 233) !important; +} + +.mdl-color-text--light-green-100 { + color: rgb(220, 237, 200) !important; +} + +.mdl-color--light-green-100 { + background-color: rgb(220, 237, 200) !important; +} + +.mdl-color-text--light-green-200 { + color: rgb(197, 225, 165) !important; +} + +.mdl-color--light-green-200 { + background-color: rgb(197, 225, 165) !important; +} + +.mdl-color-text--light-green-300 { + color: rgb(174, 213, 129) !important; +} + +.mdl-color--light-green-300 { + background-color: rgb(174, 213, 129) !important; +} + +.mdl-color-text--light-green-400 { + color: rgb(156, 204, 101) !important; +} + +.mdl-color--light-green-400 { + background-color: rgb(156, 204, 101) !important; +} + +.mdl-color-text--light-green-500 { + color: rgb(139, 195, 74) !important; +} + +.mdl-color--light-green-500 { + background-color: rgb(139, 195, 74) !important; +} + +.mdl-color-text--light-green-600 { + color: rgb(124, 179, 66) !important; +} + +.mdl-color--light-green-600 { + background-color: rgb(124, 179, 66) !important; +} + +.mdl-color-text--light-green-700 { + color: rgb(104, 159, 56) !important; +} + +.mdl-color--light-green-700 { + background-color: rgb(104, 159, 56) !important; +} + +.mdl-color-text--light-green-800 { + color: rgb(85, 139, 47) !important; +} + +.mdl-color--light-green-800 { + background-color: rgb(85, 139, 47) !important; +} + +.mdl-color-text--light-green-900 { + color: rgb(51, 105, 30) !important; +} + +.mdl-color--light-green-900 { + background-color: rgb(51, 105, 30) !important; +} + +.mdl-color-text--light-green-A100 { + color: rgb(204, 255, 144) !important; +} + +.mdl-color--light-green-A100 { + background-color: rgb(204, 255, 144) !important; +} + +.mdl-color-text--light-green-A200 { + color: rgb(178, 255, 89) !important; +} + +.mdl-color--light-green-A200 { + background-color: rgb(178, 255, 89) !important; +} + +.mdl-color-text--light-green-A400 { + color: rgb(118, 255, 3) !important; +} + +.mdl-color--light-green-A400 { + background-color: rgb(118, 255, 3) !important; +} + +.mdl-color-text--light-green-A700 { + color: rgb(100, 221, 23) !important; +} + +.mdl-color--light-green-A700 { + background-color: rgb(100, 221, 23) !important; +} + +.mdl-color-text--lime { + color: rgb(205, 220, 57) !important; +} + +.mdl-color--lime { + background-color: rgb(205, 220, 57) !important; +} + +.mdl-color-text--lime-50 { + color: rgb(249, 251, 231) !important; +} + +.mdl-color--lime-50 { + background-color: rgb(249, 251, 231) !important; +} + +.mdl-color-text--lime-100 { + color: rgb(240, 244, 195) !important; +} + +.mdl-color--lime-100 { + background-color: rgb(240, 244, 195) !important; +} + +.mdl-color-text--lime-200 { + color: rgb(230, 238, 156) !important; +} + +.mdl-color--lime-200 { + background-color: rgb(230, 238, 156) !important; +} + +.mdl-color-text--lime-300 { + color: rgb(220, 231, 117) !important; +} + +.mdl-color--lime-300 { + background-color: rgb(220, 231, 117) !important; +} + +.mdl-color-text--lime-400 { + color: rgb(212, 225, 87) !important; +} + +.mdl-color--lime-400 { + background-color: rgb(212, 225, 87) !important; +} + +.mdl-color-text--lime-500 { + color: rgb(205, 220, 57) !important; +} + +.mdl-color--lime-500 { + background-color: rgb(205, 220, 57) !important; +} + +.mdl-color-text--lime-600 { + color: rgb(192, 202, 51) !important; +} + +.mdl-color--lime-600 { + background-color: rgb(192, 202, 51) !important; +} + +.mdl-color-text--lime-700 { + color: rgb(175, 180, 43) !important; +} + +.mdl-color--lime-700 { + background-color: rgb(175, 180, 43) !important; +} + +.mdl-color-text--lime-800 { + color: rgb(158, 157, 36) !important; +} + +.mdl-color--lime-800 { + background-color: rgb(158, 157, 36) !important; +} + +.mdl-color-text--lime-900 { + color: rgb(130, 119, 23) !important; +} + +.mdl-color--lime-900 { + background-color: rgb(130, 119, 23) !important; +} + +.mdl-color-text--lime-A100 { + color: rgb(244, 255, 129) !important; +} + +.mdl-color--lime-A100 { + background-color: rgb(244, 255, 129) !important; +} + +.mdl-color-text--lime-A200 { + color: rgb(238, 255, 65) !important; +} + +.mdl-color--lime-A200 { + background-color: rgb(238, 255, 65) !important; +} + +.mdl-color-text--lime-A400 { + color: rgb(198, 255, 0) !important; +} + +.mdl-color--lime-A400 { + background-color: rgb(198, 255, 0) !important; +} + +.mdl-color-text--lime-A700 { + color: rgb(174, 234, 0) !important; +} + +.mdl-color--lime-A700 { + background-color: rgb(174, 234, 0) !important; +} + +.mdl-color-text--yellow { + color: rgb(255, 235, 59) !important; +} + +.mdl-color--yellow { + background-color: rgb(255, 235, 59) !important; +} + +.mdl-color-text--yellow-50 { + color: rgb(255, 253, 231) !important; +} + +.mdl-color--yellow-50 { + background-color: rgb(255, 253, 231) !important; +} + +.mdl-color-text--yellow-100 { + color: rgb(255, 249, 196) !important; +} + +.mdl-color--yellow-100 { + background-color: rgb(255, 249, 196) !important; +} + +.mdl-color-text--yellow-200 { + color: rgb(255, 245, 157) !important; +} + +.mdl-color--yellow-200 { + background-color: rgb(255, 245, 157) !important; +} + +.mdl-color-text--yellow-300 { + color: rgb(255, 241, 118) !important; +} + +.mdl-color--yellow-300 { + background-color: rgb(255, 241, 118) !important; +} + +.mdl-color-text--yellow-400 { + color: rgb(255, 238, 88) !important; +} + +.mdl-color--yellow-400 { + background-color: rgb(255, 238, 88) !important; +} + +.mdl-color-text--yellow-500 { + color: rgb(255, 235, 59) !important; +} + +.mdl-color--yellow-500 { + background-color: rgb(255, 235, 59) !important; +} + +.mdl-color-text--yellow-600 { + color: rgb(253, 216, 53) !important; +} + +.mdl-color--yellow-600 { + background-color: rgb(253, 216, 53) !important; +} + +.mdl-color-text--yellow-700 { + color: rgb(251, 192, 45) !important; +} + +.mdl-color--yellow-700 { + background-color: rgb(251, 192, 45) !important; +} + +.mdl-color-text--yellow-800 { + color: rgb(249, 168, 37) !important; +} + +.mdl-color--yellow-800 { + background-color: rgb(249, 168, 37) !important; +} + +.mdl-color-text--yellow-900 { + color: rgb(245, 127, 23) !important; +} + +.mdl-color--yellow-900 { + background-color: rgb(245, 127, 23) !important; +} + +.mdl-color-text--yellow-A100 { + color: rgb(255, 255, 141) !important; +} + +.mdl-color--yellow-A100 { + background-color: rgb(255, 255, 141) !important; +} + +.mdl-color-text--yellow-A200 { + color: rgb(255, 255, 0) !important; +} + +.mdl-color--yellow-A200 { + background-color: rgb(255, 255, 0) !important; +} + +.mdl-color-text--yellow-A400 { + color: rgb(255, 234, 0) !important; +} + +.mdl-color--yellow-A400 { + background-color: rgb(255, 234, 0) !important; +} + +.mdl-color-text--yellow-A700 { + color: rgb(255, 214, 0) !important; +} + +.mdl-color--yellow-A700 { + background-color: rgb(255, 214, 0) !important; +} + +.mdl-color-text--amber { + color: rgb(255, 193, 7) !important; +} + +.mdl-color--amber { + background-color: rgb(255, 193, 7) !important; +} + +.mdl-color-text--amber-50 { + color: rgb(255, 248, 225) !important; +} + +.mdl-color--amber-50 { + background-color: rgb(255, 248, 225) !important; +} + +.mdl-color-text--amber-100 { + color: rgb(255, 236, 179) !important; +} + +.mdl-color--amber-100 { + background-color: rgb(255, 236, 179) !important; +} + +.mdl-color-text--amber-200 { + color: rgb(255, 224, 130) !important; +} + +.mdl-color--amber-200 { + background-color: rgb(255, 224, 130) !important; +} + +.mdl-color-text--amber-300 { + color: rgb(255, 213, 79) !important; +} + +.mdl-color--amber-300 { + background-color: rgb(255, 213, 79) !important; +} + +.mdl-color-text--amber-400 { + color: rgb(255, 202, 40) !important; +} + +.mdl-color--amber-400 { + background-color: rgb(255, 202, 40) !important; +} + +.mdl-color-text--amber-500 { + color: rgb(255, 193, 7) !important; +} + +.mdl-color--amber-500 { + background-color: rgb(255, 193, 7) !important; +} + +.mdl-color-text--amber-600 { + color: rgb(255, 179, 0) !important; +} + +.mdl-color--amber-600 { + background-color: rgb(255, 179, 0) !important; +} + +.mdl-color-text--amber-700 { + color: rgb(255, 160, 0) !important; +} + +.mdl-color--amber-700 { + background-color: rgb(255, 160, 0) !important; +} + +.mdl-color-text--amber-800 { + color: rgb(255, 143, 0) !important; +} + +.mdl-color--amber-800 { + background-color: rgb(255, 143, 0) !important; +} + +.mdl-color-text--amber-900 { + color: rgb(255, 111, 0) !important; +} + +.mdl-color--amber-900 { + background-color: rgb(255, 111, 0) !important; +} + +.mdl-color-text--amber-A100 { + color: rgb(255, 229, 127) !important; +} + +.mdl-color--amber-A100 { + background-color: rgb(255, 229, 127) !important; +} + +.mdl-color-text--amber-A200 { + color: rgb(255, 215, 64) !important; +} + +.mdl-color--amber-A200 { + background-color: rgb(255, 215, 64) !important; +} + +.mdl-color-text--amber-A400 { + color: rgb(255, 196, 0) !important; +} + +.mdl-color--amber-A400 { + background-color: rgb(255, 196, 0) !important; +} + +.mdl-color-text--amber-A700 { + color: rgb(255, 171, 0) !important; +} + +.mdl-color--amber-A700 { + background-color: rgb(255, 171, 0) !important; +} + +.mdl-color-text--orange { + color: rgb(255, 152, 0) !important; +} + +.mdl-color--orange { + background-color: rgb(255, 152, 0) !important; +} + +.mdl-color-text--orange-50 { + color: rgb(255, 243, 224) !important; +} + +.mdl-color--orange-50 { + background-color: rgb(255, 243, 224) !important; +} + +.mdl-color-text--orange-100 { + color: rgb(255, 224, 178) !important; +} + +.mdl-color--orange-100 { + background-color: rgb(255, 224, 178) !important; +} + +.mdl-color-text--orange-200 { + color: rgb(255, 204, 128) !important; +} + +.mdl-color--orange-200 { + background-color: rgb(255, 204, 128) !important; +} + +.mdl-color-text--orange-300 { + color: rgb(255, 183, 77) !important; +} + +.mdl-color--orange-300 { + background-color: rgb(255, 183, 77) !important; +} + +.mdl-color-text--orange-400 { + color: rgb(255, 167, 38) !important; +} + +.mdl-color--orange-400 { + background-color: rgb(255, 167, 38) !important; +} + +.mdl-color-text--orange-500 { + color: rgb(255, 152, 0) !important; +} + +.mdl-color--orange-500 { + background-color: rgb(255, 152, 0) !important; +} + +.mdl-color-text--orange-600 { + color: rgb(251, 140, 0) !important; +} + +.mdl-color--orange-600 { + background-color: rgb(251, 140, 0) !important; +} + +.mdl-color-text--orange-700 { + color: rgb(245, 124, 0) !important; +} + +.mdl-color--orange-700 { + background-color: rgb(245, 124, 0) !important; +} + +.mdl-color-text--orange-800 { + color: rgb(239, 108, 0) !important; +} + +.mdl-color--orange-800 { + background-color: rgb(239, 108, 0) !important; +} + +.mdl-color-text--orange-900 { + color: rgb(230, 81, 0) !important; +} + +.mdl-color--orange-900 { + background-color: rgb(230, 81, 0) !important; +} + +.mdl-color-text--orange-A100 { + color: rgb(255, 209, 128) !important; +} + +.mdl-color--orange-A100 { + background-color: rgb(255, 209, 128) !important; +} + +.mdl-color-text--orange-A200 { + color: rgb(255, 171, 64) !important; +} + +.mdl-color--orange-A200 { + background-color: rgb(255, 171, 64) !important; +} + +.mdl-color-text--orange-A400 { + color: rgb(255, 145, 0) !important; +} + +.mdl-color--orange-A400 { + background-color: rgb(255, 145, 0) !important; +} + +.mdl-color-text--orange-A700 { + color: rgb(255, 109, 0) !important; +} + +.mdl-color--orange-A700 { + background-color: rgb(255, 109, 0) !important; +} + +.mdl-color-text--deep-orange { + color: rgb(255, 87, 34) !important; +} + +.mdl-color--deep-orange { + background-color: rgb(255, 87, 34) !important; +} + +.mdl-color-text--deep-orange-50 { + color: rgb(251, 233, 231) !important; +} + +.mdl-color--deep-orange-50 { + background-color: rgb(251, 233, 231) !important; +} + +.mdl-color-text--deep-orange-100 { + color: rgb(255, 204, 188) !important; +} + +.mdl-color--deep-orange-100 { + background-color: rgb(255, 204, 188) !important; +} + +.mdl-color-text--deep-orange-200 { + color: rgb(255, 171, 145) !important; +} + +.mdl-color--deep-orange-200 { + background-color: rgb(255, 171, 145) !important; +} + +.mdl-color-text--deep-orange-300 { + color: rgb(255, 138, 101) !important; +} + +.mdl-color--deep-orange-300 { + background-color: rgb(255, 138, 101) !important; +} + +.mdl-color-text--deep-orange-400 { + color: rgb(255, 112, 67) !important; +} + +.mdl-color--deep-orange-400 { + background-color: rgb(255, 112, 67) !important; +} + +.mdl-color-text--deep-orange-500 { + color: rgb(255, 87, 34) !important; +} + +.mdl-color--deep-orange-500 { + background-color: rgb(255, 87, 34) !important; +} + +.mdl-color-text--deep-orange-600 { + color: rgb(244, 81, 30) !important; +} + +.mdl-color--deep-orange-600 { + background-color: rgb(244, 81, 30) !important; +} + +.mdl-color-text--deep-orange-700 { + color: rgb(230, 74, 25) !important; +} + +.mdl-color--deep-orange-700 { + background-color: rgb(230, 74, 25) !important; +} + +.mdl-color-text--deep-orange-800 { + color: rgb(216, 67, 21) !important; +} + +.mdl-color--deep-orange-800 { + background-color: rgb(216, 67, 21) !important; +} + +.mdl-color-text--deep-orange-900 { + color: rgb(191, 54, 12) !important; +} + +.mdl-color--deep-orange-900 { + background-color: rgb(191, 54, 12) !important; +} + +.mdl-color-text--deep-orange-A100 { + color: rgb(255, 158, 128) !important; +} + +.mdl-color--deep-orange-A100 { + background-color: rgb(255, 158, 128) !important; +} + +.mdl-color-text--deep-orange-A200 { + color: rgb(255, 110, 64) !important; +} + +.mdl-color--deep-orange-A200 { + background-color: rgb(255, 110, 64) !important; +} + +.mdl-color-text--deep-orange-A400 { + color: rgb(255, 61, 0) !important; +} + +.mdl-color--deep-orange-A400 { + background-color: rgb(255, 61, 0) !important; +} + +.mdl-color-text--deep-orange-A700 { + color: rgb(221, 44, 0) !important; +} + +.mdl-color--deep-orange-A700 { + background-color: rgb(221, 44, 0) !important; +} + +.mdl-color-text--brown { + color: rgb(121, 85, 72) !important; +} + +.mdl-color--brown { + background-color: rgb(121, 85, 72) !important; +} + +.mdl-color-text--brown-50 { + color: rgb(239, 235, 233) !important; +} + +.mdl-color--brown-50 { + background-color: rgb(239, 235, 233) !important; +} + +.mdl-color-text--brown-100 { + color: rgb(215, 204, 200) !important; +} + +.mdl-color--brown-100 { + background-color: rgb(215, 204, 200) !important; +} + +.mdl-color-text--brown-200 { + color: rgb(188, 170, 164) !important; +} + +.mdl-color--brown-200 { + background-color: rgb(188, 170, 164) !important; +} + +.mdl-color-text--brown-300 { + color: rgb(161, 136, 127) !important; +} + +.mdl-color--brown-300 { + background-color: rgb(161, 136, 127) !important; +} + +.mdl-color-text--brown-400 { + color: rgb(141, 110, 99) !important; +} + +.mdl-color--brown-400 { + background-color: rgb(141, 110, 99) !important; +} + +.mdl-color-text--brown-500 { + color: rgb(121, 85, 72) !important; +} + +.mdl-color--brown-500 { + background-color: rgb(121, 85, 72) !important; +} + +.mdl-color-text--brown-600 { + color: rgb(109, 76, 65) !important; +} + +.mdl-color--brown-600 { + background-color: rgb(109, 76, 65) !important; +} + +.mdl-color-text--brown-700 { + color: rgb(93, 64, 55) !important; +} + +.mdl-color--brown-700 { + background-color: rgb(93, 64, 55) !important; +} + +.mdl-color-text--brown-800 { + color: rgb(78, 52, 46) !important; +} + +.mdl-color--brown-800 { + background-color: rgb(78, 52, 46) !important; +} + +.mdl-color-text--brown-900 { + color: rgb(62, 39, 35) !important; +} + +.mdl-color--brown-900 { + background-color: rgb(62, 39, 35) !important; +} + +.mdl-color-text--grey { + color: rgb(158, 158, 158) !important; +} + +.mdl-color--grey { + background-color: rgb(158, 158, 158) !important; +} + +.mdl-color-text--grey-50 { + color: rgb(250, 250, 250) !important; +} + +.mdl-color--grey-50 { + background-color: rgb(250, 250, 250) !important; +} + +.mdl-color-text--grey-100 { + color: rgb(245, 245, 245) !important; +} + +.mdl-color--grey-100 { + background-color: rgb(245, 245, 245) !important; +} + +.mdl-color-text--grey-200 { + color: rgb(238, 238, 238) !important; +} + +.mdl-color--grey-200 { + background-color: rgb(238, 238, 238) !important; +} + +.mdl-color-text--grey-300 { + color: rgb(224, 224, 224) !important; +} + +.mdl-color--grey-300 { + background-color: rgb(224, 224, 224) !important; +} + +.mdl-color-text--grey-400 { + color: rgb(189, 189, 189) !important; +} + +.mdl-color--grey-400 { + background-color: rgb(189, 189, 189) !important; +} + +.mdl-color-text--grey-500 { + color: rgb(158, 158, 158) !important; +} + +.mdl-color--grey-500 { + background-color: rgb(158, 158, 158) !important; +} + +.mdl-color-text--grey-600 { + color: rgb(117, 117, 117) !important; +} + +.mdl-color--grey-600 { + background-color: rgb(117, 117, 117) !important; +} + +.mdl-color-text--grey-700 { + color: rgb(97, 97, 97) !important; +} + +.mdl-color--grey-700 { + background-color: rgb(97, 97, 97) !important; +} + +.mdl-color-text--grey-800 { + color: rgb(66, 66, 66) !important; +} + +.mdl-color--grey-800 { + background-color: rgb(66, 66, 66) !important; +} + +.mdl-color-text--grey-900 { + color: rgb(33, 33, 33) !important; +} + +.mdl-color--grey-900 { + background-color: rgb(33, 33, 33) !important; +} + +.mdl-color-text--blue-grey { + color: rgb(96, 125, 139) !important; +} + +.mdl-color--blue-grey { + background-color: rgb(96, 125, 139) !important; +} + +.mdl-color-text--blue-grey-50 { + color: rgb(236, 239, 241) !important; +} + +.mdl-color--blue-grey-50 { + background-color: rgb(236, 239, 241) !important; +} + +.mdl-color-text--blue-grey-100 { + color: rgb(207, 216, 220) !important; +} + +.mdl-color--blue-grey-100 { + background-color: rgb(207, 216, 220) !important; +} + +.mdl-color-text--blue-grey-200 { + color: rgb(176, 190, 197) !important; +} + +.mdl-color--blue-grey-200 { + background-color: rgb(176, 190, 197) !important; +} + +.mdl-color-text--blue-grey-300 { + color: rgb(144, 164, 174) !important; +} + +.mdl-color--blue-grey-300 { + background-color: rgb(144, 164, 174) !important; +} + +.mdl-color-text--blue-grey-400 { + color: rgb(120, 144, 156) !important; +} + +.mdl-color--blue-grey-400 { + background-color: rgb(120, 144, 156) !important; +} + +.mdl-color-text--blue-grey-500 { + color: rgb(96, 125, 139) !important; +} + +.mdl-color--blue-grey-500 { + background-color: rgb(96, 125, 139) !important; +} + +.mdl-color-text--blue-grey-600 { + color: rgb(84, 110, 122) !important; +} + +.mdl-color--blue-grey-600 { + background-color: rgb(84, 110, 122) !important; +} + +.mdl-color-text--blue-grey-700 { + color: rgb(69, 90, 100) !important; +} + +.mdl-color--blue-grey-700 { + background-color: rgb(69, 90, 100) !important; +} + +.mdl-color-text--blue-grey-800 { + color: rgb(55, 71, 79) !important; +} + +.mdl-color--blue-grey-800 { + background-color: rgb(55, 71, 79) !important; +} + +.mdl-color-text--blue-grey-900 { + color: rgb(38, 50, 56) !important; +} + +.mdl-color--blue-grey-900 { + background-color: rgb(38, 50, 56) !important; +} + +.mdl-color--black { + background-color: rgb(0, 0, 0) !important; +} + +.mdl-color-text--black { + color: rgb(0, 0, 0) !important; +} + +.mdl-color--white { + background-color: rgb(255, 255, 255) !important; +} + +.mdl-color-text--white { + color: rgb(255, 255, 255) !important; +} + +.mdl-color--primary { + background-color: rgb(63, 81, 181) !important; +} + +.mdl-color--primary-contrast { + background-color: rgb(255, 255, 255) !important; +} + +.mdl-color--primary-dark { + background-color: rgb(48, 63, 159) !important; +} + +.mdl-color--accent { + background-color: rgb(255, 64, 129) !important; +} + +.mdl-color--accent-contrast { + background-color: rgb(255, 255, 255) !important; +} + +.mdl-color-text--primary { + color: rgb(63, 81, 181) !important; +} + +.mdl-color-text--primary-contrast { + color: rgb(255, 255, 255) !important; +} + +.mdl-color-text--primary-dark { + color: rgb(48, 63, 159) !important; +} + +.mdl-color-text--accent { + color: rgb(255, 64, 129) !important; +} + +.mdl-color-text--accent-contrast { + color: rgb(255, 255, 255) !important; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.mdl-ripple { + background: rgb(0, 0, 0); + 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: width 0.3s cubic-bezier(0, 0, 0.2, 1), height 0.3s cubic-bezier(0, 0, 0.2, 1), opacity 0.6s cubic-bezier(0, 0, 0.2, 1), -webkit-transform 0.3s cubic-bezier(0, 0, 0.2, 1); + transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1), width 0.3s cubic-bezier(0, 0, 0.2, 1), height 0.3s cubic-bezier(0, 0, 0.2, 1), opacity 0.6s cubic-bezier(0, 0, 0.2, 1); + transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1), width 0.3s cubic-bezier(0, 0, 0.2, 1), height 0.3s cubic-bezier(0, 0, 0.2, 1), opacity 0.6s cubic-bezier(0, 0, 0.2, 1), -webkit-transform 0.3s cubic-bezier(0, 0, 0.2, 1); +} + +.mdl-ripple.is-visible { + opacity: 0.3; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.mdl-animation--default { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.mdl-animation--fast-out-slow-in { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.mdl-animation--linear-out-slow-in { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} + +.mdl-animation--fast-out-linear-in { + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.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"; + font-weight: 600; + font-size: 12px; + width: 22px; + height: 22px; + border-radius: 50%; + background: rgb(255, 64, 129); + 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(255, 64, 129); + background: rgba(255, 255, 255, 0.2); + box-shadow: 0 0 1px gray; +} + +.mdl-badge.mdl-badge--overlap { + margin-right: 10px; +} + +.mdl-badge.mdl-badge--overlap:after { + right: -10px; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.mdl-button { + background: transparent; + border: none; + border-radius: 2px; + color: rgb(0, 0, 0); + position: relative; + height: 36px; + margin: 0; + min-width: 64px; + padding: 0 16px; + display: inline-block; + font-family: "Roboto"; + font-size: 14px; + font-weight: 500; + text-transform: uppercase; + line-height: 1; + letter-spacing: 0; + overflow: hidden; + will-change: box-shadow; + transition: box-shadow 0.2s cubic-bezier(0.4, 0, 1, 1), background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s cubic-bezier(0.4, 0, 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, 0.20); +} + +.mdl-button:focus:not(:active) { + background-color: rgba(0, 0, 0, 0.12); +} + +.mdl-button:active { + background-color: rgba(158, 158, 158, 0.40); +} + +.mdl-button.mdl-button--colored { + color: rgb(63, 81, 181); +} + +.mdl-button.mdl-button--colored:focus:not(:active) { + background-color: rgba(0, 0, 0, 0.12); +} + +input.mdl-button[type="submit"] { + -webkit-appearance: none; +} + +.mdl-button--raised { + background: rgba(158, 158, 158, 0.20); + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); +} + +.mdl-button--raised:active { + box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); + background-color: rgba(158, 158, 158, 0.40); +} + +.mdl-button--raised:focus:not(:active) { + box-shadow: 0 0 8px rgba(0, 0, 0, 0.18), 0 8px 16px rgba(0, 0, 0, 0.36); + background-color: rgba(158, 158, 158, 0.40); +} + +.mdl-button--raised.mdl-button--colored { + background: rgb(63, 81, 181); + color: rgb(255, 255, 255); +} + +.mdl-button--raised.mdl-button--colored:hover { + background-color: rgb(63, 81, 181); +} + +.mdl-button--raised.mdl-button--colored:active { + background-color: rgb(63, 81, 181); +} + +.mdl-button--raised.mdl-button--colored:focus:not(:active) { + background-color: rgb(63, 81, 181); +} + +.mdl-button--raised.mdl-button--colored .mdl-ripple { + background: rgb(255, 255, 255); +} + +.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, 0.20); + box-shadow: 0 1px 1.5px 0 rgba(0, 0, 0, 0.12), 0 1px 1px 0 rgba(0, 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, white, black); +} + +.mdl-button--fab:active { + box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); + background-color: rgba(158, 158, 158, 0.40); +} + +.mdl-button--fab:focus:not(:active) { + box-shadow: 0 0 8px rgba(0, 0, 0, 0.18), 0 8px 16px rgba(0, 0, 0, 0.36); + background-color: rgba(158, 158, 158, 0.40); +} + +.mdl-button--fab.mdl-button--colored { + background: rgb(255, 64, 129); + color: rgb(255, 255, 255); +} + +.mdl-button--fab.mdl-button--colored:hover { + background-color: rgb(255, 64, 129); +} + +.mdl-button--fab.mdl-button--colored:focus:not(:active) { + background-color: rgb(255, 64, 129); +} + +.mdl-button--fab.mdl-button--colored:active { + background-color: rgb(255, 64, 129); +} + +.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: 0px; + left: 0px; +} + +.mdl-button--icon .mdl-button__ripple-container { + border-radius: 50%; + -webkit-mask-image: -webkit-radial-gradient(circle, white, black); +} + +.mdl-button__ripple-container { + display: block; + height: 100%; + left: 0px; + position: absolute; + top: 0px; + 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(63, 81, 181); +} + +.mdl-button--primary.mdl-button--primary .mdl-ripple { + background: rgb(255, 255, 255); +} + +.mdl-button--primary.mdl-button--primary.mdl-button--raised, .mdl-button--primary.mdl-button--primary.mdl-button--fab { + color: rgb(255, 255, 255); + background-color: rgb(63, 81, 181); +} + +.mdl-button--accent.mdl-button--accent { + color: rgb(255, 64, 129); +} + +.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(255, 64, 129); +} + +.mdl-button[disabled][disabled], .mdl-button.mdl-button--disabled.mdl-button--disabled { + color: rgba(0, 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, 0.12); + color: rgba(0, 0, 0, 0.26); +} + +.mdl-button--raised[disabled][disabled], .mdl-button--raised.mdl-button--disabled.mdl-button--disabled { + background-color: rgba(0, 0, 0, 0.12); + color: rgba(0, 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, 0.26); +} + +.mdl-button .material-icons { + vertical-align: middle; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.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: rgb(255, 255, 255); + border-radius: 2px; + box-sizing: border-box; +} + +.mdl-card__media { + background-color: rgb(255, 64, 129); + 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: rgb(0, 0, 0); + 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 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, 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, 0.54); + margin: 0; +} + +.mdl-card__supporting-text { + color: rgba(0, 0, 0, 0.54); + font-size: 1rem; + line-height: 18px; + overflow: hidden; + padding: 16px 16px; + width: 90%; +} + +.mdl-card__supporting-text.mdl-card--border { + border-bottom: 1px solid rgba(0, 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, 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; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.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, 0.54); + border-radius: 2px; + z-index: 2; +} + +.mdl-checkbox.is-checked .mdl-checkbox__box-outline { + border: 2px solid rgb(63, 81, 181); +} + +fieldset[disabled] .mdl-checkbox .mdl-checkbox__box-outline, +.mdl-checkbox.is-disabled .mdl-checkbox__box-outline { + border: 2px solid rgba(0, 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 0px 8px rgba(0, 0, 0, 0.1); + background-color: rgba(0, 0, 0, 0.1); +} + +.mdl-checkbox.is-focused.is-checked .mdl-checkbox__focus-helper { + box-shadow: 0 0 0px 8px rgba(63, 81, 181, 0.26); + background-color: rgba(63, 81, 181, 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: transparent; + transition-duration: 0.28s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-property: background; +} + +.mdl-checkbox.is-checked .mdl-checkbox__tick-outline { + background: rgb(63, 81, 181) 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, 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, 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, white, black); +} + +.mdl-checkbox__ripple-container .mdl-ripple { + background: rgb(63, 81, 181); +} + +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: transparent; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.mdl-chip { + height: 32px; + font-family: "Roboto"; + line-height: 32px; + padding: 0 12px; + border: 0; + border-radius: 16px; + background-color: #dedede; + display: inline-block; + color: rgba(0, 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: transparent; + opacity: 0.54; + display: inline-block; + cursor: pointer; + text-align: center; + vertical-align: middle; + padding: 0; + margin: 0 0 0 4px; + font-size: 13px; + text-decoration: none; + color: rgba(0, 0, 0, 0.87); + border: none; + outline: none; + overflow: hidden; +} + +.mdl-chip__contact { + height: 32px; + width: 32px; + border-radius: 16px; + display: inline-block; + vertical-align: middle; + margin-right: 8px; + overflow: hidden; + text-align: center; + font-size: 18px; + line-height: 32px; +} + +.mdl-chip:focus { + outline: 0; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); +} + +.mdl-chip:active { + background-color: #d6d6d6; +} + +.mdl-chip--deletable { + padding-right: 4px; +} + +.mdl-chip--contact { + padding-left: 0; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.mdl-data-table { + position: relative; + border: 1px solid rgba(0, 0, 0, 0.12); + border-collapse: collapse; + white-space: nowrap; + font-size: 13px; + background-color: rgb(255, 255, 255); +} + +.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: 0.28s; + transition-timing-function: cubic-bezier(0.4, 0, 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: #eeeeee; +} + +.mdl-data-table td, .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; + vertical-align: middle; + height: 48px; + border-top: 1px solid rgba(0, 0, 0, 0.12); + border-bottom: 1px solid rgba(0, 0, 0, 0.12); + padding-top: 12px; + box-sizing: border-box; +} + +.mdl-data-table td .mdl-data-table__select { + vertical-align: middle; +} + +.mdl-data-table th { + position: relative; + vertical-align: bottom; + text-overflow: ellipsis; + font-size: 14px; + font-weight: bold; + line-height: 24px; + letter-spacing: 0; + height: 48px; + font-size: 12px; + color: rgba(0, 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, 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: normal; + 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; + 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, 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; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.mdl-dialog { + border: none; + box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 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 0; +} + +.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 24px; + color: rgba(0, 0, 0, 0.54); +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.mdl-mega-footer { + padding: 16px 40px; + color: rgb(158, 158, 158); + background-color: rgb(66, 66, 66); +} + +.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 { + margin-bottom: 16px; +} + +.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: rgb(158, 158, 158); + 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: 0; + margin-top: -16px; + 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: rgb(224, 224, 224); +} + +.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; + margin: 0; + padding: 0; + margin-bottom: 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; + line-height: 24px; + 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: white; +} + +.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; + } +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.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: rgb(158, 158, 158); + background-color: rgb(66, 66, 66); +} + +.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: rgb(158, 158, 158); + border: none; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.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: rgb(97, 97, 97); + border-radius: 50%; + padding: 0; + margin-left: 0; + margin-right: 0; + text-align: center; + background-color: transparent; + will-change: background-color; + transition: background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s cubic-bezier(0.4, 0, 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(63, 81, 181); +} + +.mdl-icon-toggle.is-disabled .mdl-icon-toggle__label { + color: rgba(0, 0, 0, 0.26); + cursor: auto; + transition: none; +} + +.mdl-icon-toggle.is-focused .mdl-icon-toggle__label { + background-color: rgba(0, 0, 0, 0.12); +} + +.mdl-icon-toggle.is-focused.is-checked .mdl-icon-toggle__label { + background-color: rgba(63, 81, 181, 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, white, black); +} + +.mdl-icon-toggle__ripple-container .mdl-ripple { + background: rgb(97, 97, 97); +} + +.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: transparent; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.mdl-list { + display: block; + padding: 8px 0; + list-style: none; +} + +.mdl-list__item { + font-family: "Roboto"; + font-size: 16px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0.04em; + line-height: 1; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + min-height: 48px; + box-sizing: border-box; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + -webkit-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + padding: 16px; + cursor: default; + color: rgba(0, 0, 0, 0.87); + overflow: hidden; +} + +.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; + 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 .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, 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: rgb(117, 117, 117); +} + +.mdl-list__item-avatar, +.mdl-list__item-avatar.material-icons { + height: 40px; + width: 40px; + box-sizing: border-box; + border-radius: 50%; + background-color: rgb(117, 117, 117); + font-size: 40px; + color: white; +} + +.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; + line-height: 24px; + letter-spacing: 0; + line-height: 18px; + color: rgba(0, 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; + line-height: 24px; + letter-spacing: 0; + line-height: 18px; + height: 52px; + color: rgba(0, 0, 0, 0.54); + display: block; + padding: 0; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.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: rgb(255, 255, 255); + 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, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); + will-change: transform; + transition: opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 0.3s cubic-bezier(0.4, 0, 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 0.2s cubic-bezier(0.4, 0, 0.2, 1), clip 0.3s cubic-bezier(0.4, 0, 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, 0.87); + background-color: transparent; + text-align: left; + margin: 0; + padding: 0 16px; + outline-color: rgb(189, 189, 189); + position: relative; + overflow: hidden; + font-size: 14px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + text-decoration: none; + cursor: pointer; + height: 48px; + line-height: 48px; + white-space: nowrap; + opacity: 0; + transition: opacity 0.2s cubic-bezier(0.4, 0, 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, 0.12); +} + +.mdl-menu__item[disabled], .mdl-menu__item[data-mdl-disabled] { + color: rgb(189, 189, 189); + 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: transparent; +} + +.mdl-menu__item:hover { + background-color: rgb(238, 238, 238); +} + +.mdl-menu__item:focus { + outline: none; + background-color: rgb(238, 238, 238); +} + +.mdl-menu__item:active { + background-color: rgb(224, 224, 224); +} + +.mdl-menu__item--ripple-container { + display: block; + height: 100%; + left: 0px; + position: absolute; + top: 0px; + width: 100%; + z-index: 0; + overflow: hidden; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.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 0.2s cubic-bezier(0.4, 0, 0.2, 1); +} + +.mdl-progress > .progressbar { + background-color: rgb(63, 81, 181); + z-index: 1; + left: 0; +} + +.mdl-progress > .bufferbar { + background-image: linear-gradient(to right, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.7)), linear-gradient(to right, rgb(63, 81, 181), rgb(63, 81, 181)); + 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(255, 255, 255, 0.7), rgba(255, 255, 255, 0.7)), linear-gradient(to right, rgb(63, 81, 181), rgb(63, 81, 181)); + -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(255, 255, 255, 0.9), rgba(255, 255, 255, 0.9)), linear-gradient(to right, rgb(63, 81, 181), rgb(63, 81, 181)); +} + +.mdl-progress.mdl-progress--indeterminate > .bar1, +.mdl-progress.mdl-progress__indeterminate > .bar1 { + background-color: rgb(63, 81, 181); + -webkit-animation-name: indeterminate1; + animation-name: indeterminate1; + -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; + background-color: rgb(63, 81, 181); + -webkit-animation-name: indeterminate2; + animation-name: indeterminate2; + -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; +} + +@-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% { + left: 0%; + width: 0%; + } + 50% { + left: 0%; + width: 0%; + } + 75% { + left: 0%; + width: 25%; + } + 100% { + left: 100%; + width: 0%; + } +} + +@keyframes indeterminate2 { + 0% { + left: 0%; + width: 0%; + } + 50% { + left: 0%; + width: 0%; + } + 75% { + left: 0%; + width: 25%; + } + 100% { + left: 100%; + width: 0%; + } +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.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: rgb(66, 66, 66); + text-decoration: none; + margin: 0; + font-size: 14px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + opacity: 0.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"; + font-size: 20px; + font-weight: 500; + line-height: 1; + letter-spacing: 0.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, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); + box-sizing: border-box; + border-right: 1px solid rgb(224, 224, 224); + background: rgb(250, 250, 250); + -webkit-transform: translateX(-250px); + transform: translateX(-250px); + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + will-change: transform; + transition-duration: 0.2s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-property: -webkit-transform; + transition-property: transform; + transition-property: transform, -webkit-transform; + color: rgb(66, 66, 66); + 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 16px; + } +} + +.mdl-layout__drawer .mdl-navigation .mdl-navigation__link:hover { + background-color: rgb(224, 224, 224); +} + +.mdl-layout__drawer .mdl-navigation .mdl-navigation__link--current { + background-color: rgb(224, 224, 224); + color: rgb(0, 0, 0); +} + +@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: Roboto; + margin: 8px 12px; + top: 0; + left: 0; + color: rgb(255, 255, 255); + 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, 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(63, 81, 181); + color: rgb(255, 255, 255); + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); + transition-duration: 0.2s; + transition-timing-function: cubic-bezier(0.4, 0, 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 { + box-shadow: none; +} + +.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, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 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(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: 0.2s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.mdl-layout__obfuscator.is-visible { + background-color: rgba(0, 0, 0, 0.5); + visibility: visible; +} + +@supports (pointer-events: auto) { + .mdl-layout__obfuscator { + background-color: rgba(0, 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(63, 81, 181); + 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(63, 81, 181); + 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(255, 255, 255); +} + +.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 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(255, 255, 255, 0.6); + overflow: hidden; +} + +@media screen and (max-width: 1024px) { + .mdl-layout__tab { + padding: 0 12px 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(255, 255, 255); +} + +.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(255, 64, 129); + -webkit-animation: border-expand 0.2s cubic-bezier(0.4, 0, 0.4, 1) 0.01s alternate forwards; + animation: border-expand 0.2s cubic-bezier(0.4, 0, 0.4, 1) 0.01s alternate forwards; + transition: all 1s cubic-bezier(0.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(255, 255, 255); +} + +.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; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.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, 0.54); + border-radius: 50%; + z-index: 2; +} + +.mdl-radio.is-checked .mdl-radio__outer-circle { + border: 2px solid rgb(63, 81, 181); +} + +.mdl-radio__outer-circle fieldset[disabled] .mdl-radio, +.mdl-radio.is-disabled .mdl-radio__outer-circle { + border: 2px solid rgba(0, 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: 0.28s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-property: -webkit-transform; + transition-property: transform; + transition-property: transform, -webkit-transform; + -webkit-transform: scale(0, 0); + transform: scale(0, 0); + border-radius: 50%; + background: rgb(63, 81, 181); +} + +.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, 0.26); + cursor: auto; +} + +.mdl-radio.is-focused .mdl-radio__inner-circle { + box-shadow: 0 0 0px 10px rgba(0, 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, 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, white, black); +} + +.mdl-radio__ripple-container .mdl-ripple { + background: rgb(63, 81, 181); +} + +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: transparent; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +_:-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: transparent; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + outline: 0; + padding: 0; + color: rgb(63, 81, 181); + -webkit-align-self: center; + -ms-flex-item-align: center; + -ms-grid-row-align: center; + align-self: center; + z-index: 1; + cursor: pointer; + /**************************** Tracks ****************************/ + /**************************** Thumbs ****************************/ + /**************************** 0-value ****************************/ + /**************************** Disabled ****************************/ +} + +.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: transparent; +} + +.mdl-slider.is-upgraded::-moz-range-track { + background: transparent; + border: none; +} + +.mdl-slider.is-upgraded::-ms-track { + background: none; + 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(63, 81, 181) 16px, rgb(63, 81, 181) 0); +} + +.mdl-slider.is-upgraded::-ms-fill-upper { + padding: 0; + background: linear-gradient(to left, transparent, transparent 16px, rgba(0, 0, 0, 0.26) 16px, rgba(0, 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(63, 81, 181); + border: none; + transition: border 0.18s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.18s cubic-bezier(0.4, 0, 0.2, 1), background 0.28s cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 0.18s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1), border 0.18s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.18s cubic-bezier(0.4, 0, 0.2, 1), background 0.28s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1), border 0.18s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.18s cubic-bezier(0.4, 0, 0.2, 1), background 0.28s cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 0.18s cubic-bezier(0.4, 0, 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(63, 81, 181); + border: none; +} + +.mdl-slider.is-upgraded:focus:not(:active)::-webkit-slider-thumb { + box-shadow: 0 0 0 10px rgba(63, 81, 181, 0.26); +} + +.mdl-slider.is-upgraded:focus:not(:active)::-moz-range-thumb { + box-shadow: 0 0 0 10px rgba(63, 81, 181, 0.26); +} + +.mdl-slider.is-upgraded:active::-webkit-slider-thumb { + background-image: none; + background: rgb(63, 81, 181); + -webkit-transform: scale(1.5); + transform: scale(1.5); +} + +.mdl-slider.is-upgraded:active::-moz-range-thumb { + background-image: none; + background: rgb(63, 81, 181); + transform: scale(1.5); +} + +.mdl-slider.is-upgraded::-ms-thumb { + width: 32px; + height: 32px; + border: none; + border-radius: 50%; + background: rgb(63, 81, 181); + transform: scale(0.375); + transition: background 0.28s cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 0.18s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1), background 0.28s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1), background 0.28s cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 0.18s cubic-bezier(0.4, 0, 0.2, 1); +} + +.mdl-slider.is-upgraded:focus:not(:active)::-ms-thumb { + background: radial-gradient(circle closest-side, rgb(63, 81, 181) 0%, rgb(63, 81, 181) 37.5%, rgba(63, 81, 181, 0.26) 37.5%, rgba(63, 81, 181, 0.26) 100%); + transform: scale(1); +} + +.mdl-slider.is-upgraded:active::-ms-thumb { + background: rgb(63, 81, 181); + transform: scale(0.5625); +} + +.mdl-slider.is-upgraded.is-lowest-value::-webkit-slider-thumb { + border: 2px solid rgba(0, 0, 0, 0.26); + background: transparent; +} + +.mdl-slider.is-upgraded.is-lowest-value::-moz-range-thumb { + border: 2px solid rgba(0, 0, 0, 0.26); + background: transparent; +} + +.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, 0.12); + background: rgba(0, 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, 0.12); + background: rgba(0, 0, 0, 0.12); +} + +.mdl-slider.is-upgraded.is-lowest-value:active::-webkit-slider-thumb { + border: 1.6px solid rgba(0, 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, 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, 0.26) 66.67%, rgba(0, 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, 0.12) 0%, rgba(0, 0, 0, 0.12) 25%, rgba(0, 0, 0, 0.26) 25%, rgba(0, 0, 0, 0.26) 37.5%, rgba(0, 0, 0, 0.12) 37.5%, rgba(0, 0, 0, 0.12) 100%); + transform: scale(1); +} + +.mdl-slider.is-upgraded.is-lowest-value:active::-ms-thumb { + transform: scale(0.5625); + background: radial-gradient(circle closest-side, transparent 0%, transparent 77.78%, rgba(0, 0, 0, 0.26) 77.78%, rgba(0, 0, 0, 0.26) 100%); +} + +.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-lower { + background: transparent; +} + +.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(0.667); + transform: scale(0.667); + background: rgba(0, 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(0.667); + background: rgba(0, 0, 0, 0.26); +} + +.mdl-slider.is-upgraded:disabled + +.mdl-slider__background-flex > .mdl-slider__background-lower { + background-color: rgba(0, 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, 0.26); + background: transparent; + -webkit-transform: scale(0.667); + transform: scale(0.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, 0.26); + background: transparent; + transform: scale(0.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(0.25); + background: rgba(0, 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(0.25); + background: radial-gradient(circle closest-side, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.26) 50%, rgba(0, 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, 0.26) 25px, rgba(0, 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; + background: none; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; +} + +.mdl-slider__background-flex { + background: transparent; + position: absolute; + height: 2px; + width: calc(100% - 52px); + top: 50%; + left: 0; + margin: 0 26px; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + overflow: hidden; + border: 0; + padding: 0; + -webkit-transform: translate(0, -1px); + transform: translate(0, -1px); +} + +.mdl-slider__background-lower { + background: rgb(63, 81, 181); + -webkit-flex: 0; + -ms-flex: 0; + flex: 0; + position: relative; + border: 0; + padding: 0; +} + +.mdl-slider__background-upper { + background: rgba(0, 0, 0, 0.26); + -webkit-flex: 0; + -ms-flex: 0; + flex: 0; + position: relative; + border: 0; + padding: 0; + transition: left 0.18s cubic-bezier(0.4, 0, 0.2, 1); +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.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"; + will-change: transform; + -webkit-transform: translate(0, 80px); + transform: translate(0, 80px); + transition: -webkit-transform 0.25s cubic-bezier(0.4, 0, 1, 1); + transition: transform 0.25s cubic-bezier(0.4, 0, 1, 1); + transition: transform 0.25s cubic-bezier(0.4, 0, 1, 1), -webkit-transform 0.25s cubic-bezier(0.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: -webkit-transform 0.25s cubic-bezier(0, 0, 0.2, 1); + transition: transform 0.25s cubic-bezier(0, 0, 0.2, 1); + transition: transform 0.25s cubic-bezier(0, 0, 0.2, 1), -webkit-transform 0.25s cubic-bezier(0, 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: white; + float: left; +} + +.mdl-snackbar__action { + background: transparent; + border: none; + color: rgb(255, 64, 129); + float: right; + text-transform: uppercase; + padding: 14px 24px 14px 12px; + font-family: "Roboto"; + 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; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.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: rgb(66, 165, 245); +} + +.mdl-spinner--single-color .mdl-spinner__layer-1 { + border-color: rgb(63, 81, 181); +} + +.mdl-spinner.is-active .mdl-spinner__layer-1 { + -webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; +} + +.mdl-spinner__layer-2 { + border-color: rgb(244, 67, 54); +} + +.mdl-spinner--single-color .mdl-spinner__layer-2 { + border-color: rgb(63, 81, 181); +} + +.mdl-spinner.is-active .mdl-spinner__layer-2 { + -webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; +} + +.mdl-spinner__layer-3 { + border-color: rgb(253, 216, 53); +} + +.mdl-spinner--single-color .mdl-spinner__layer-3 { + border-color: rgb(63, 81, 181); +} + +.mdl-spinner.is-active .mdl-spinner__layer-3 { + -webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; +} + +.mdl-spinner__layer-4 { + border-color: rgb(76, 175, 80); +} + +.mdl-spinner--single-color .mdl-spinner__layer-4 { + border-color: rgb(63, 81, 181); +} + +.mdl-spinner.is-active .mdl-spinner__layer-4 { + -webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0, 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); + } +} + +/** +* HACK: Even though the intention is to have the current .mdl-spinner__layer-N +* at `opacity: 1`, we set it to `opacity: 0.99` instead since this forces Chrome +* to do proper subpixel rendering for the elements being animated. This is +* especially visible in Chrome 39 on Ubuntu 14.04. See: +* +* - https://github.com/Polymer/paper-spinner/issues/9 +* - https://code.google.com/p/chromium/issues/detail?id=436255 +*/ +@-webkit-keyframes mdl-spinner__layer-1-fade-in-out { + from { + opacity: 0.99; + } + 25% { + opacity: 0.99; + } + 26% { + opacity: 0; + } + 89% { + opacity: 0; + } + 90% { + opacity: 0.99; + } + 100% { + opacity: 0.99; + } +} + +@keyframes mdl-spinner__layer-1-fade-in-out { + from { + opacity: 0.99; + } + 25% { + opacity: 0.99; + } + 26% { + opacity: 0; + } + 89% { + opacity: 0; + } + 90% { + opacity: 0.99; + } + 100% { + opacity: 0.99; + } +} + +@-webkit-keyframes mdl-spinner__layer-2-fade-in-out { + from { + opacity: 0; + } + 15% { + opacity: 0; + } + 25% { + opacity: 0.99; + } + 50% { + opacity: 0.99; + } + 51% { + opacity: 0; + } +} + +@keyframes mdl-spinner__layer-2-fade-in-out { + from { + opacity: 0; + } + 15% { + opacity: 0; + } + 25% { + opacity: 0.99; + } + 50% { + opacity: 0.99; + } + 51% { + opacity: 0; + } +} + +@-webkit-keyframes mdl-spinner__layer-3-fade-in-out { + from { + opacity: 0; + } + 40% { + opacity: 0; + } + 50% { + opacity: 0.99; + } + 75% { + opacity: 0.99; + } + 76% { + opacity: 0; + } +} + +@keyframes mdl-spinner__layer-3-fade-in-out { + from { + opacity: 0; + } + 40% { + opacity: 0; + } + 50% { + opacity: 0.99; + } + 75% { + opacity: 0.99; + } + 76% { + opacity: 0; + } +} + +@-webkit-keyframes mdl-spinner__layer-4-fade-in-out { + from { + opacity: 0; + } + 65% { + opacity: 0; + } + 75% { + opacity: 0.99; + } + 90% { + opacity: 0.99; + } + 100% { + opacity: 0; + } +} + +@keyframes mdl-spinner__layer-4-fade-in-out { + from { + opacity: 0; + } + 65% { + opacity: 0; + } + 75% { + opacity: 0.99; + } + 90% { + opacity: 0.99; + } + 100% { + opacity: 0; + } +} + +/** +* Patch the gap that appear between the two adjacent +* div.mdl-spinner__circle-clipper while the spinner is rotating +* (appears on Chrome 38, Safari 7.1, and IE 11). +* +* Update: the gap no longer appears on Chrome when .mdl-spinner__layer-N's +* opacity is 0.99, but still does on Safari and IE. +*/ +.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(0.4, 0, 0.2, 1) infinite both; + animation: mdl-spinner__left-spin 1333ms cubic-bezier(0.4, 0, 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(0.4, 0, 0.2, 1) infinite both; + animation: mdl-spinner__right-spin 1333ms cubic-bezier(0.4, 0, 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); + } +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.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, 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(63, 81, 181, 0.5); +} + +.mdl-switch__track fieldset[disabled] .mdl-switch, +.mdl-switch.is-disabled .mdl-switch__track { + background: rgba(0, 0, 0, 0.12); + cursor: auto; +} + +.mdl-switch__thumb { + background: rgb(250, 250, 250); + 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, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); + transition-duration: 0.28s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-property: left; +} + +.mdl-switch.is-checked .mdl-switch__thumb { + background: rgb(63, 81, 181); + left: 16px; + box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.2), 0 1px 8px 0 rgba(0, 0, 0, 0.12); +} + +.mdl-switch__thumb fieldset[disabled] .mdl-switch, +.mdl-switch.is-disabled .mdl-switch__thumb { + background: rgb(189, 189, 189); + 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 0px 20px rgba(0, 0, 0, 0.1); + background-color: rgba(0, 0, 0, 0.1); +} + +.mdl-switch.is-focused.is-checked .mdl-switch__focus-helper { + box-shadow: 0 0 0px 20px rgba(63, 81, 181, 0.26); + background-color: rgba(63, 81, 181, 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: rgb(189, 189, 189); + 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, white, black); + transition-duration: 0.40s; + transition-timing-function: step-end; + transition-property: left; +} + +.mdl-switch__ripple-container .mdl-ripple { + background: rgb(63, 81, 181); +} + +.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: transparent; +} + +.mdl-switch.is-checked .mdl-switch__ripple-container { + left: 2px; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.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 0 0 0; + margin: 0; + border-bottom: 1px solid rgb(224, 224, 224); +} + +.mdl-tabs__tab { + margin: 0; + border: none; + padding: 0 24px 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, 0.54); + overflow: hidden; +} + +.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active { + color: rgba(0, 0, 0, 0.87); +} + +.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active:after { + height: 2px; + width: 100%; + display: block; + content: " "; + bottom: 0px; + left: 0px; + position: absolute; + background: rgb(63, 81, 181); + -webkit-animation: border-expand 0.2s cubic-bezier(0.4, 0, 0.4, 1) 0.01s alternate forwards; + animation: border-expand 0.2s cubic-bezier(0.4, 0, 0.4, 1) 0.01s alternate forwards; + transition: all 1s cubic-bezier(0.4, 0, 1, 1); +} + +.mdl-tabs__tab .mdl-tabs__ripple-container { + display: block; + position: absolute; + height: 100%; + width: 100%; + left: 0px; + top: 0px; + z-index: 1; + overflow: hidden; +} + +.mdl-tabs__tab .mdl-tabs__ripple-container .mdl-ripple { + background: rgb(63, 81, 181); +} + +.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%; + } +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.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, 0.12); + display: block; + font-size: 16px; + font-family: "Roboto"; + margin: 0; + padding: 4px 0; + width: 100%; + background: none; + 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: rgb(213, 0, 0); + 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, 0.12); + color: rgba(0, 0, 0, 0.26); +} + +.mdl-textfield textarea.mdl-textfield__input { + display: block; +} + +.mdl-textfield__label { + bottom: 0; + color: rgba(0, 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: 0.2s; + transition-timing-function: cubic-bezier(0.4, 0, 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, 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(63, 81, 181); + 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: rgb(213, 0, 0); + font-size: 12px; +} + +.mdl-textfield__label:after { + background-color: rgb(63, 81, 181); + bottom: 20px; + content: ''; + height: 2px; + left: 45%; + position: absolute; + transition-duration: 0.2s; + transition-timing-function: cubic-bezier(0.4, 0, 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: rgb(213, 0, 0); +} + +.mdl-textfield__error { + color: rgb(213, 0, 0); + 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: 0.2s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + display: inline-block; + max-width: 0.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; +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.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, 0.9); + border-radius: 2px; + color: rgb(255, 255, 255); + 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, 0.2, 1) forwards; + animation: pulse 200ms cubic-bezier(0, 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(0.99); + transform: scale(0.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(0.99); + transform: scale(0.99); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + opacity: 1; + visibility: visible; + } +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* Typography */ +/* Shadows */ +/* Animations */ +/* Dialog */ +.mdl-shadow--2dp { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); +} + +.mdl-shadow--3dp { + box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.2), 0 1px 8px 0 rgba(0, 0, 0, 0.12); +} + +.mdl-shadow--4dp { + box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); +} + +.mdl-shadow--6dp { + box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.2); +} + +.mdl-shadow--8dp { + box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); +} + +.mdl-shadow--16dp { + box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2); +} + +.mdl-shadow--24dp { + box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2); +} + +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* +* NOTE: Some rules here are applied using duplicate selectors. +* This is on purpose to increase their specificity when applied. +* For example: `.mdl-cell--1-col-phone.mdl-cell--1-col-phone` +*/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/*------------------------------------* $CONTENTS +\*------------------------------------*/ +/** + * STYLE GUIDE VARIABLES------------------Declarations of Sass variables + * -----Typography + * -----Colors + * -----Textfield + * -----Switch + * -----Spinner + * -----Radio + * -----Menu + * -----List + * -----Layout + * -----Icon toggles + * -----Footer + * -----Column + * -----Checkbox + * -----Card + * -----Button + * -----Animation + * -----Progress + * -----Badge + * -----Shadows + * -----Grid + * -----Data table + * -----Dialog + * -----Snackbar + * -----Tooltip + * -----Chip + * + * Even though all variables have the `!default` directive, most of them + * should not be changed as they are dependent one another. This can cause + * visual distortions (like alignment issues) that are hard to track down + * and fix. + */ +/* ========== TYPOGRAPHY ========== */ +/* We're splitting fonts into "preferred" and "performance" in order to optimize + page loading. For important text, such as the body, we want it to load + immediately and not wait for the web font load, whereas for other sections, + such as headers and titles, we're OK with things taking a bit longer to load. + We do have some optional classes and parameters in the mixins, in case you + definitely want to make sure you're using the preferred font and don't mind + the performance hit. + We should be able to improve on this once CSS Font Loading L3 becomes more + widely available. +*/ +/* ========== COLORS ========== */ +/** +* +* Material design color palettes. +* @see http://www.google.com/design/spec/style/color.html +* +**/ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== Color Palettes ========== */ +/* colors.scss */ +/** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ +/* ========== IMAGES ========== */ +/* ========== Color & Themes ========== */ +/* ========== Typography ========== */ +/* ========== Components ========== */ +/* ========== Standard Buttons ========== */ +/* ========== Icon Toggles ========== */ +/* ========== Radio Buttons ========== */ +/* ========== Ripple effect ========== */ +/* ========== Layout ========== */ +/* ========== Content Tabs ========== */ +/* ========== Checkboxes ========== */ +/* ========== Switches ========== */ +/* ========== Spinner ========== */ +/* ========== Text fields ========== */ +/* ========== Card ========== */ +/* ========== Sliders ========== */ +/* ========== Progress ========== */ +/* ========== List ========== */ +/* ========== Item ========== */ +/* ========== Dropdown menu ========== */ +/* ========== Tooltips ========== */ +/* ========== Footer ========== */ +/* TEXTFIELD */ +/* SWITCH */ +/* SPINNER */ +/* RADIO */ +/* MENU */ +/* LIST */ +/* LAYOUT */ +/* ICON TOGGLE */ +/* FOOTER */ +/*mega-footer*/ +/*mini-footer*/ +/* CHECKBOX */ +/* CARD */ +/* Card dimensions */ +/* Cover image */ +/* BUTTON */ +/** + * + * Dimensions + * + */ +/* ANIMATION */ +/* PROGRESS */ +/* BADGE */ +/* SHADOWS */ +/* GRID */ +/* DATA TABLE */ +/* DIALOG */ +/* SNACKBAR */ +/* TOOLTIP */ +/* CHIP */ +.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 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%; + } +}
\ No newline at end of file diff --git a/src/material.js b/src/material.js new file mode 100644 index 0000000..cd63c92 --- /dev/null +++ b/src/material.js @@ -0,0 +1,4010 @@ +;(function () { + "use strict"; + + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + + /** + * A component handler interface using the revealing module design pattern. + * More details on this design pattern here: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @author Jason Mayes. + */ + /* exported componentHandler */ + +// Pre-defining the componentHandler interface, for closure documentation and +// static verification. + var componentHandler = { + /** + * Searches existing DOM for elements of our component type and upgrades them + * if they have not already been upgraded. + * + * @param {string=} optJsClass the programatic name of the element class we + * need to create a new instance of. + * @param {string=} optCssClass the name of the CSS class elements of this + * type will have. + */ + upgradeDom: function (optJsClass, optCssClass) { + }, + /** + * Upgrades a specific element rather than all in the DOM. + * + * @param {!Element} element The element we wish to upgrade. + * @param {string=} optJsClass Optional name of the class we want to upgrade + * the element to. + */ + upgradeElement: function (element, optJsClass) { + }, + /** + * Upgrades a specific list of elements rather than all in the DOM. + * + * @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements + * The elements we wish to upgrade. + */ + upgradeElements: function (elements) { + }, + /** + * Upgrades all registered components found in the current DOM. This is + * automatically called on window load. + */ + upgradeAllRegistered: function () { + }, + /** + * Allows user to be alerted to any upgrades that are performed for a given + * component type + * + * @param {string} jsClass The class name of the MDL component we wish + * to hook into for any upgrades performed. + * @param {function(!HTMLElement)} callback The function to call upon an + * upgrade. This function should expect 1 parameter - the HTMLElement which + * got upgraded. + */ + registerUpgradedCallback: function (jsClass, callback) { + }, + /** + * Registers a class for future use and attempts to upgrade existing DOM. + * + * @param {componentHandler.ComponentConfigPublic} config the registration configuration + */ + register: function (config) { + }, + /** + * Downgrade either a given node, an array of nodes, or a NodeList. + * + * @param {!Node|!Array<!Node>|!NodeList} nodes + */ + downgradeElements: function (nodes) { + } + }; + + componentHandler = (function () { + 'use strict'; + + /** @type {!Array<componentHandler.ComponentConfig>} */ + var registeredComponents_ = []; + + /** @type {!Array<componentHandler.Component>} */ + var createdComponents_ = []; + + var componentConfigProperty_ = 'mdlComponentConfigInternal_'; + + /** + * Searches registered components for a class we are interested in using. + * Optionally replaces a match with passed object if specified. + * + * @param {string} name The name of a class we want to use. + * @param {componentHandler.ComponentConfig=} optReplace Optional object to replace match with. + * @return {!Object|boolean} + * @private + */ + function findRegisteredClass_(name, optReplace) { + for (var i = 0; i < registeredComponents_.length; i++) { + if (registeredComponents_[i].className === name) { + if (typeof optReplace !== 'undefined') { + registeredComponents_[i] = optReplace; + } + return registeredComponents_[i]; + } + } + return false; + } + + /** + * Returns an array of the classNames of the upgraded classes on the element. + * + * @param {!Element} element The element to fetch data from. + * @return {!Array<string>} + * @private + */ + function getUpgradedListOfElement_(element) { + var dataUpgraded = element.getAttribute('data-upgraded'); + // Use `['']` as default value to conform the `,name,name...` style. + return dataUpgraded === null ? [''] : dataUpgraded.split(','); + } + + /** + * Returns true if the given element has already been upgraded for the given + * class. + * + * @param {!Element} element The element we want to check. + * @param {string} jsClass The class to check for. + * @returns {boolean} + * @private + */ + function isElementUpgraded_(element, jsClass) { + var upgradedList = getUpgradedListOfElement_(element); + return upgradedList.indexOf(jsClass) !== -1; + } + + /** + * Create an event object. + * + * @param {string} eventType The type name of the event. + * @param {boolean} bubbles Whether the event should bubble up the DOM. + * @param {boolean} cancelable Whether the event can be canceled. + * @returns {!Event} + */ + function createEvent_(eventType, bubbles, cancelable) { + if ('CustomEvent' in window && typeof window.CustomEvent === 'function') { + return new CustomEvent(eventType, { + bubbles: bubbles, + cancelable: cancelable + }); + } else { + var ev = document.createEvent('Events'); + ev.initEvent(eventType, bubbles, cancelable); + return ev; + } + } + + /** + * Searches existing DOM for elements of our component type and upgrades them + * if they have not already been upgraded. + * + * @param {string=} optJsClass the programatic name of the element class we + * need to create a new instance of. + * @param {string=} optCssClass the name of the CSS class elements of this + * type will have. + */ + function upgradeDomInternal(optJsClass, optCssClass) { + if (typeof optJsClass === 'undefined' && + typeof optCssClass === 'undefined') { + for (var i = 0; i < registeredComponents_.length; i++) { + upgradeDomInternal(registeredComponents_[i].className, + registeredComponents_[i].cssClass); + } + } else { + var jsClass = /** @type {string} */ (optJsClass); + if (typeof optCssClass === 'undefined') { + var registeredClass = findRegisteredClass_(jsClass); + if (registeredClass) { + optCssClass = registeredClass.cssClass; + } + } + + var elements = document.querySelectorAll('.' + optCssClass); + for (var n = 0; n < elements.length; n++) { + upgradeElementInternal(elements[n], jsClass); + } + } + } + + /** + * Upgrades a specific element rather than all in the DOM. + * + * @param {!Element} element The element we wish to upgrade. + * @param {string=} optJsClass Optional name of the class we want to upgrade + * the element to. + */ + function upgradeElementInternal(element, optJsClass) { + // Verify argument type. + if (!(typeof element === 'object' && element instanceof Element)) { + throw new Error('Invalid argument provided to upgrade MDL element.'); + } + // Allow upgrade to be canceled by canceling emitted event. + var upgradingEv = createEvent_('mdl-componentupgrading', true, true); + element.dispatchEvent(upgradingEv); + if (upgradingEv.defaultPrevented) { + return; + } + + var upgradedList = getUpgradedListOfElement_(element); + var classesToUpgrade = []; + // If jsClass is not provided scan the registered components to find the + // ones matching the element's CSS classList. + if (!optJsClass) { + var classList = element.classList; + registeredComponents_.forEach(function (component) { + // Match CSS & Not to be upgraded & Not upgraded. + if (classList.contains(component.cssClass) && + classesToUpgrade.indexOf(component) === -1 && + !isElementUpgraded_(element, component.className)) { + classesToUpgrade.push(component); + } + }); + } else if (!isElementUpgraded_(element, optJsClass)) { + classesToUpgrade.push(findRegisteredClass_(optJsClass)); + } + + // Upgrade the element for each classes. + for (var i = 0, n = classesToUpgrade.length, registeredClass; i < n; i++) { + registeredClass = classesToUpgrade[i]; + if (registeredClass) { + // Mark element as upgraded. + upgradedList.push(registeredClass.className); + element.setAttribute('data-upgraded', upgradedList.join(',')); + var instance = new registeredClass.classConstructor(element); + instance[componentConfigProperty_] = registeredClass; + createdComponents_.push(instance); + // Call any callbacks the user has registered with this component type. + for (var j = 0, m = registeredClass.callbacks.length; j < m; j++) { + registeredClass.callbacks[j](element); + } + + if (registeredClass.widget) { + // Assign per element instance for control over API + element[registeredClass.className] = instance; + } + } else { + throw new Error( + 'Unable to find a registered component for the given class.'); + } + + var upgradedEv = createEvent_('mdl-componentupgraded', true, false); + element.dispatchEvent(upgradedEv); + } + } + + /** + * Upgrades a specific list of elements rather than all in the DOM. + * + * @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements + * The elements we wish to upgrade. + */ + function upgradeElementsInternal(elements) { + if (!Array.isArray(elements)) { + if (elements instanceof Element) { + elements = [elements]; + } else { + elements = Array.prototype.slice.call(elements); + } + } + for (var i = 0, n = elements.length, element; i < n; i++) { + element = elements[i]; + if (element instanceof HTMLElement) { + upgradeElementInternal(element); + if (element.children.length > 0) { + upgradeElementsInternal(element.children); + } + } + } + } + + /** + * Registers a class for future use and attempts to upgrade existing DOM. + * + * @param {componentHandler.ComponentConfigPublic} config + */ + function registerInternal(config) { + // In order to support both Closure-compiled and uncompiled code accessing + // this method, we need to allow for both the dot and array syntax for + // property access. You'll therefore see the `foo.bar || foo['bar']` + // pattern repeated across this method. + var widgetMissing = (typeof config.widget === 'undefined' && + typeof config['widget'] === 'undefined'); + var widget = true; + + if (!widgetMissing) { + widget = config.widget || config['widget']; + } + + var newConfig = /** @type {componentHandler.ComponentConfig} */ ({ + classConstructor: config.constructor || config['constructor'], + className: config.classAsString || config['classAsString'], + cssClass: config.cssClass || config['cssClass'], + widget: widget, + callbacks: [] + }); + + registeredComponents_.forEach(function (item) { + if (item.cssClass === newConfig.cssClass) { + throw new Error('The provided cssClass has already been registered: ' + item.cssClass); + } + if (item.className === newConfig.className) { + throw new Error('The provided className has already been registered'); + } + }); + + if (config.constructor.prototype + .hasOwnProperty(componentConfigProperty_)) { + throw new Error( + 'MDL component classes must not have ' + componentConfigProperty_ + + ' defined as a property.'); + } + + var found = findRegisteredClass_(config.classAsString, newConfig); + + if (!found) { + registeredComponents_.push(newConfig); + } + } + + /** + * Allows user to be alerted to any upgrades that are performed for a given + * component type + * + * @param {string} jsClass The class name of the MDL component we wish + * to hook into for any upgrades performed. + * @param {function(!HTMLElement)} callback The function to call upon an + * upgrade. This function should expect 1 parameter - the HTMLElement which + * got upgraded. + */ + function registerUpgradedCallbackInternal(jsClass, callback) { + var regClass = findRegisteredClass_(jsClass); + if (regClass) { + regClass.callbacks.push(callback); + } + } + + /** + * Upgrades all registered components found in the current DOM. This is + * automatically called on window load. + */ + function upgradeAllRegisteredInternal() { + for (var n = 0; n < registeredComponents_.length; n++) { + upgradeDomInternal(registeredComponents_[n].className); + } + } + + /** + * Check the component for the downgrade method. + * Execute if found. + * Remove component from createdComponents list. + * + * @param {?componentHandler.Component} component + */ + function deconstructComponentInternal(component) { + if (component) { + var componentIndex = createdComponents_.indexOf(component); + createdComponents_.splice(componentIndex, 1); + + var upgrades = component.element_.getAttribute('data-upgraded').split(','); + var componentPlace = upgrades.indexOf(component[componentConfigProperty_].classAsString); + upgrades.splice(componentPlace, 1); + component.element_.setAttribute('data-upgraded', upgrades.join(',')); + + var ev = createEvent_('mdl-componentdowngraded', true, false); + component.element_.dispatchEvent(ev); + } + } + + /** + * Downgrade either a given node, an array of nodes, or a NodeList. + * + * @param {!Node|!Array<!Node>|!NodeList} nodes + */ + function downgradeNodesInternal(nodes) { + /** + * Auxiliary function to downgrade a single node. + * @param {!Node} node the node to be downgraded + */ + var downgradeNode = function (node) { + createdComponents_.filter(function (item) { + return item.element_ === node; + }).forEach(deconstructComponentInternal); + }; + if (nodes instanceof Array || nodes instanceof NodeList) { + for (var n = 0; n < nodes.length; n++) { + downgradeNode(nodes[n]); + } + } else if (nodes instanceof Node) { + downgradeNode(nodes); + } else { + throw new Error('Invalid argument provided to downgrade MDL nodes.'); + } + } + + // Now return the functions that should be made public with their publicly + // facing names... + return { + upgradeDom: upgradeDomInternal, + upgradeElement: upgradeElementInternal, + upgradeElements: upgradeElementsInternal, + upgradeAllRegistered: upgradeAllRegisteredInternal, + registerUpgradedCallback: registerUpgradedCallbackInternal, + register: registerInternal, + downgradeElements: downgradeNodesInternal + }; + })(); + + /** + * Describes the type of a registered component type managed by + * componentHandler. Provided for benefit of the Closure compiler. + * + * @typedef {{ + * constructor: Function, + * classAsString: string, + * cssClass: string, + * widget: (string|boolean|undefined) + * }} + */ + componentHandler.ComponentConfigPublic; // jshint ignore:line + + /** + * Describes the type of a registered component type managed by + * componentHandler. Provided for benefit of the Closure compiler. + * + * @typedef {{ + * constructor: !Function, + * className: string, + * cssClass: string, + * widget: (string|boolean), + * callbacks: !Array<function(!HTMLElement)> + * }} + */ + componentHandler.ComponentConfig; // jshint ignore:line + + /** + * Created component (i.e., upgraded element) type as managed by + * componentHandler. Provided for benefit of the Closure compiler. + * + * @typedef {{ + * element_: !HTMLElement, + * className: string, + * classAsString: string, + * cssClass: string, + * widget: string + * }} + */ + componentHandler.Component; // jshint ignore:line + +// Export all symbols, for the benefit of Closure compiler. +// No effect on uncompiled code. + componentHandler['upgradeDom'] = componentHandler.upgradeDom; + componentHandler['upgradeElement'] = componentHandler.upgradeElement; + componentHandler['upgradeElements'] = componentHandler.upgradeElements; + componentHandler['upgradeAllRegistered'] = + componentHandler.upgradeAllRegistered; + componentHandler['registerUpgradedCallback'] = + componentHandler.registerUpgradedCallback; + componentHandler['register'] = componentHandler.register; + componentHandler['downgradeElements'] = componentHandler.downgradeElements; + window.componentHandler = componentHandler; + window['componentHandler'] = componentHandler; + + window.addEventListener('load', function () { + 'use strict'; + + /** + * Performs a "Cutting the mustard" test. If the browser supports the features + * tested, adds a mdl-js class to the <html> element. It then upgrades all MDL + * components requiring JavaScript. + */ + if ('classList' in document.createElement('div') && + 'querySelector' in document && + 'addEventListener' in window && Array.prototype.forEach) { + document.documentElement.classList.add('mdl-js'); + componentHandler.upgradeAllRegistered(); + } else { + /** + * Dummy function to avoid JS errors. + */ + componentHandler.upgradeElement = function () { + }; + /** + * Dummy function to avoid JS errors. + */ + componentHandler.register = function () { + }; + } + }); + +// Source: https://github.com/darius/requestAnimationFrame/blob/master/requestAnimationFrame.js +// Adapted from https://gist.github.com/paulirish/1579671 which derived from +// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ +// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating +// requestAnimationFrame polyfill by Erik Möller. +// Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon +// MIT license + if (!Date.now) { + /** + * Date.now polyfill. + * @return {number} the current Date + */ + Date.now = function () { + return new Date().getTime(); + }; + Date['now'] = Date.now; + } + var vendors = [ + 'webkit', + 'moz' + ]; + for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { + var vp = vendors[i]; + window.requestAnimationFrame = window[vp + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame']; + window['requestAnimationFrame'] = window.requestAnimationFrame; + window['cancelAnimationFrame'] = window.cancelAnimationFrame; + } + if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) { + var lastTime = 0; + /** + * requestAnimationFrame polyfill. + * @param {!Function} callback the callback function. + */ + window.requestAnimationFrame = function (callback) { + var now = Date.now(); + var nextTime = Math.max(lastTime + 16, now); + return setTimeout(function () { + callback(lastTime = nextTime); + }, nextTime - now); + }; + window.cancelAnimationFrame = clearTimeout; + window['requestAnimationFrame'] = window.requestAnimationFrame; + window['cancelAnimationFrame'] = window.cancelAnimationFrame; + } + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Button MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialButton = function MaterialButton(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialButton'] = MaterialButton; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialButton.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialButton.prototype.CssClasses_ = { + RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_CONTAINER: 'mdl-button__ripple-container', + RIPPLE: 'mdl-ripple' + }; + /** + * Handle blur of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialButton.prototype.blurHandler_ = function (event) { + if (event) { + this.element_.blur(); + } + }; +// Public methods. + /** + * Disable button. + * + * @public + */ + MaterialButton.prototype.disable = function () { + this.element_.disabled = true; + }; + MaterialButton.prototype['disable'] = MaterialButton.prototype.disable; + /** + * Enable button. + * + * @public + */ + MaterialButton.prototype.enable = function () { + this.element_.disabled = false; + }; + MaterialButton.prototype['enable'] = MaterialButton.prototype.enable; + /** + * Initialize element. + */ + MaterialButton.prototype.init = function () { + if (this.element_) { + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { + var rippleContainer = document.createElement('span'); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + this.rippleElement_ = document.createElement('span'); + this.rippleElement_.classList.add(this.CssClasses_.RIPPLE); + rippleContainer.appendChild(this.rippleElement_); + this.boundRippleBlurHandler = this.blurHandler_.bind(this); + this.rippleElement_.addEventListener('mouseup', this.boundRippleBlurHandler); + this.element_.appendChild(rippleContainer); + } + this.boundButtonBlurHandler = this.blurHandler_.bind(this); + this.element_.addEventListener('mouseup', this.boundButtonBlurHandler); + this.element_.addEventListener('mouseleave', this.boundButtonBlurHandler); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialButton, + classAsString: 'MaterialButton', + cssClass: 'mdl-js-button', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Checkbox MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialCheckbox = function MaterialCheckbox(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialCheckbox'] = MaterialCheckbox; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialCheckbox.prototype.Constant_ = {TINY_TIMEOUT: 0.001}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialCheckbox.prototype.CssClasses_ = { + INPUT: 'mdl-checkbox__input', + BOX_OUTLINE: 'mdl-checkbox__box-outline', + FOCUS_HELPER: 'mdl-checkbox__focus-helper', + TICK_OUTLINE: 'mdl-checkbox__tick-outline', + RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE_CONTAINER: 'mdl-checkbox__ripple-container', + RIPPLE_CENTER: 'mdl-ripple--center', + RIPPLE: 'mdl-ripple', + IS_FOCUSED: 'is-focused', + IS_DISABLED: 'is-disabled', + IS_CHECKED: 'is-checked', + IS_UPGRADED: 'is-upgraded' + }; + /** + * Handle change of state. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialCheckbox.prototype.onChange_ = function (event) { + this.updateClasses_(); + }; + /** + * Handle focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialCheckbox.prototype.onFocus_ = function (event) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle lost focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialCheckbox.prototype.onBlur_ = function (event) { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle mouseup. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialCheckbox.prototype.onMouseUp_ = function (event) { + this.blur_(); + }; + /** + * Handle class updates. + * + * @private + */ + MaterialCheckbox.prototype.updateClasses_ = function () { + this.checkDisabled(); + this.checkToggleState(); + }; + /** + * Add blur. + * + * @private + */ + MaterialCheckbox.prototype.blur_ = function () { + // TODO: figure out why there's a focus event being fired after our blur, + // so that we can avoid this hack. + window.setTimeout(function () { + this.inputElement_.blur(); + }.bind(this), this.Constant_.TINY_TIMEOUT); + }; +// Public methods. + /** + * Check the inputs toggle state and update display. + * + * @public + */ + MaterialCheckbox.prototype.checkToggleState = function () { + if (this.inputElement_.checked) { + this.element_.classList.add(this.CssClasses_.IS_CHECKED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_CHECKED); + } + }; + MaterialCheckbox.prototype['checkToggleState'] = MaterialCheckbox.prototype.checkToggleState; + /** + * Check the inputs disabled state and update display. + * + * @public + */ + MaterialCheckbox.prototype.checkDisabled = function () { + if (this.inputElement_.disabled) { + this.element_.classList.add(this.CssClasses_.IS_DISABLED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DISABLED); + } + }; + MaterialCheckbox.prototype['checkDisabled'] = MaterialCheckbox.prototype.checkDisabled; + /** + * Disable checkbox. + * + * @public + */ + MaterialCheckbox.prototype.disable = function () { + this.inputElement_.disabled = true; + this.updateClasses_(); + }; + MaterialCheckbox.prototype['disable'] = MaterialCheckbox.prototype.disable; + /** + * Enable checkbox. + * + * @public + */ + MaterialCheckbox.prototype.enable = function () { + this.inputElement_.disabled = false; + this.updateClasses_(); + }; + MaterialCheckbox.prototype['enable'] = MaterialCheckbox.prototype.enable; + /** + * Check checkbox. + * + * @public + */ + MaterialCheckbox.prototype.check = function () { + this.inputElement_.checked = true; + this.updateClasses_(); + }; + MaterialCheckbox.prototype['check'] = MaterialCheckbox.prototype.check; + /** + * Uncheck checkbox. + * + * @public + */ + MaterialCheckbox.prototype.uncheck = function () { + this.inputElement_.checked = false; + this.updateClasses_(); + }; + MaterialCheckbox.prototype['uncheck'] = MaterialCheckbox.prototype.uncheck; + /** + * Initialize element. + */ + MaterialCheckbox.prototype.init = function () { + if (this.element_) { + this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); + var boxOutline = document.createElement('span'); + boxOutline.classList.add(this.CssClasses_.BOX_OUTLINE); + var tickContainer = document.createElement('span'); + tickContainer.classList.add(this.CssClasses_.FOCUS_HELPER); + var tickOutline = document.createElement('span'); + tickOutline.classList.add(this.CssClasses_.TICK_OUTLINE); + boxOutline.appendChild(tickOutline); + this.element_.appendChild(tickContainer); + this.element_.appendChild(boxOutline); + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + this.rippleContainerElement_ = document.createElement('span'); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER); + this.boundRippleMouseUp = this.onMouseUp_.bind(this); + this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp); + var ripple = document.createElement('span'); + ripple.classList.add(this.CssClasses_.RIPPLE); + this.rippleContainerElement_.appendChild(ripple); + this.element_.appendChild(this.rippleContainerElement_); + } + this.boundInputOnChange = this.onChange_.bind(this); + this.boundInputOnFocus = this.onFocus_.bind(this); + this.boundInputOnBlur = this.onBlur_.bind(this); + this.boundElementMouseUp = this.onMouseUp_.bind(this); + this.inputElement_.addEventListener('change', this.boundInputOnChange); + this.inputElement_.addEventListener('focus', this.boundInputOnFocus); + this.inputElement_.addEventListener('blur', this.boundInputOnBlur); + this.element_.addEventListener('mouseup', this.boundElementMouseUp); + this.updateClasses_(); + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialCheckbox, + classAsString: 'MaterialCheckbox', + cssClass: 'mdl-js-checkbox', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for icon toggle MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialIconToggle = function MaterialIconToggle(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialIconToggle'] = MaterialIconToggle; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialIconToggle.prototype.Constant_ = {TINY_TIMEOUT: 0.001}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialIconToggle.prototype.CssClasses_ = { + INPUT: 'mdl-icon-toggle__input', + JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE_CONTAINER: 'mdl-icon-toggle__ripple-container', + RIPPLE_CENTER: 'mdl-ripple--center', + RIPPLE: 'mdl-ripple', + IS_FOCUSED: 'is-focused', + IS_DISABLED: 'is-disabled', + IS_CHECKED: 'is-checked' + }; + /** + * Handle change of state. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialIconToggle.prototype.onChange_ = function (event) { + this.updateClasses_(); + }; + /** + * Handle focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialIconToggle.prototype.onFocus_ = function (event) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle lost focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialIconToggle.prototype.onBlur_ = function (event) { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle mouseup. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialIconToggle.prototype.onMouseUp_ = function (event) { + this.blur_(); + }; + /** + * Handle class updates. + * + * @private + */ + MaterialIconToggle.prototype.updateClasses_ = function () { + this.checkDisabled(); + this.checkToggleState(); + }; + /** + * Add blur. + * + * @private + */ + MaterialIconToggle.prototype.blur_ = function () { + // TODO: figure out why there's a focus event being fired after our blur, + // so that we can avoid this hack. + window.setTimeout(function () { + this.inputElement_.blur(); + }.bind(this), this.Constant_.TINY_TIMEOUT); + }; +// Public methods. + /** + * Check the inputs toggle state and update display. + * + * @public + */ + MaterialIconToggle.prototype.checkToggleState = function () { + if (this.inputElement_.checked) { + this.element_.classList.add(this.CssClasses_.IS_CHECKED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_CHECKED); + } + }; + MaterialIconToggle.prototype['checkToggleState'] = MaterialIconToggle.prototype.checkToggleState; + /** + * Check the inputs disabled state and update display. + * + * @public + */ + MaterialIconToggle.prototype.checkDisabled = function () { + if (this.inputElement_.disabled) { + this.element_.classList.add(this.CssClasses_.IS_DISABLED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DISABLED); + } + }; + MaterialIconToggle.prototype['checkDisabled'] = MaterialIconToggle.prototype.checkDisabled; + /** + * Disable icon toggle. + * + * @public + */ + MaterialIconToggle.prototype.disable = function () { + this.inputElement_.disabled = true; + this.updateClasses_(); + }; + MaterialIconToggle.prototype['disable'] = MaterialIconToggle.prototype.disable; + /** + * Enable icon toggle. + * + * @public + */ + MaterialIconToggle.prototype.enable = function () { + this.inputElement_.disabled = false; + this.updateClasses_(); + }; + MaterialIconToggle.prototype['enable'] = MaterialIconToggle.prototype.enable; + /** + * Check icon toggle. + * + * @public + */ + MaterialIconToggle.prototype.check = function () { + this.inputElement_.checked = true; + this.updateClasses_(); + }; + MaterialIconToggle.prototype['check'] = MaterialIconToggle.prototype.check; + /** + * Uncheck icon toggle. + * + * @public + */ + MaterialIconToggle.prototype.uncheck = function () { + this.inputElement_.checked = false; + this.updateClasses_(); + }; + MaterialIconToggle.prototype['uncheck'] = MaterialIconToggle.prototype.uncheck; + /** + * Initialize element. + */ + MaterialIconToggle.prototype.init = function () { + if (this.element_) { + this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); + if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + this.rippleContainerElement_ = document.createElement('span'); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER); + this.boundRippleMouseUp = this.onMouseUp_.bind(this); + this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp); + var ripple = document.createElement('span'); + ripple.classList.add(this.CssClasses_.RIPPLE); + this.rippleContainerElement_.appendChild(ripple); + this.element_.appendChild(this.rippleContainerElement_); + } + this.boundInputOnChange = this.onChange_.bind(this); + this.boundInputOnFocus = this.onFocus_.bind(this); + this.boundInputOnBlur = this.onBlur_.bind(this); + this.boundElementOnMouseUp = this.onMouseUp_.bind(this); + this.inputElement_.addEventListener('change', this.boundInputOnChange); + this.inputElement_.addEventListener('focus', this.boundInputOnFocus); + this.inputElement_.addEventListener('blur', this.boundInputOnBlur); + this.element_.addEventListener('mouseup', this.boundElementOnMouseUp); + this.updateClasses_(); + this.element_.classList.add('is-upgraded'); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialIconToggle, + classAsString: 'MaterialIconToggle', + cssClass: 'mdl-js-icon-toggle', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for dropdown MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialMenu = function MaterialMenu(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialMenu'] = MaterialMenu; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialMenu.prototype.Constant_ = { + // Total duration of the menu animation. + TRANSITION_DURATION_SECONDS: 0.3, + // The fraction of the total duration we want to use for menu item animations. + TRANSITION_DURATION_FRACTION: 0.8, + // How long the menu stays open after choosing an option (so the user can see + // the ripple). + CLOSE_TIMEOUT: 150 + }; + /** + * Keycodes, for code readability. + * + * @enum {number} + * @private + */ + MaterialMenu.prototype.Keycodes_ = { + ENTER: 13, + ESCAPE: 27, + SPACE: 32, + UP_ARROW: 38, + DOWN_ARROW: 40 + }; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialMenu.prototype.CssClasses_ = { + CONTAINER: 'mdl-menu__container', + OUTLINE: 'mdl-menu__outline', + ITEM: 'mdl-menu__item', + ITEM_RIPPLE_CONTAINER: 'mdl-menu__item-ripple-container', + RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE: 'mdl-ripple', + // Statuses + IS_UPGRADED: 'is-upgraded', + IS_VISIBLE: 'is-visible', + IS_ANIMATING: 'is-animating', + // Alignment options + BOTTOM_LEFT: 'mdl-menu--bottom-left', + // This is the default. + BOTTOM_RIGHT: 'mdl-menu--bottom-right', + TOP_LEFT: 'mdl-menu--top-left', + TOP_RIGHT: 'mdl-menu--top-right', + UNALIGNED: 'mdl-menu--unaligned' + }; + /** + * Initialize element. + */ + MaterialMenu.prototype.init = function () { + if (this.element_) { + // Create container for the menu. + var container = document.createElement('div'); + container.classList.add(this.CssClasses_.CONTAINER); + this.element_.parentElement.insertBefore(container, this.element_); + this.element_.parentElement.removeChild(this.element_); + container.appendChild(this.element_); + this.container_ = container; + // Create outline for the menu (shadow and background). + var outline = document.createElement('div'); + outline.classList.add(this.CssClasses_.OUTLINE); + this.outline_ = outline; + container.insertBefore(outline, this.element_); + // Find the "for" element and bind events to it. + var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for'); + var forEl = null; + if (forElId) { + forEl = document.getElementById(forElId); + if (forEl) { + this.forElement_ = forEl; + forEl.addEventListener('click', this.handleForClick_.bind(this)); + forEl.addEventListener('keydown', this.handleForKeyboardEvent_.bind(this)); + } + } + var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); + this.boundItemKeydown_ = this.handleItemKeyboardEvent_.bind(this); + this.boundItemClick_ = this.handleItemClick_.bind(this); + for (var i = 0; i < items.length; i++) { + // Add a listener to each menu item. + items[i].addEventListener('click', this.boundItemClick_); + // Add a tab index to each menu item. + items[i].tabIndex = '-1'; + // Add a keyboard listener to each menu item. + items[i].addEventListener('keydown', this.boundItemKeydown_); + } + // Add ripple classes to each item, if the user has enabled ripples. + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + for (i = 0; i < items.length; i++) { + var item = items[i]; + var rippleContainer = document.createElement('span'); + rippleContainer.classList.add(this.CssClasses_.ITEM_RIPPLE_CONTAINER); + var ripple = document.createElement('span'); + ripple.classList.add(this.CssClasses_.RIPPLE); + rippleContainer.appendChild(ripple); + item.appendChild(rippleContainer); + item.classList.add(this.CssClasses_.RIPPLE_EFFECT); + } + } + // Copy alignment classes to the container, so the outline can use them. + if (this.element_.classList.contains(this.CssClasses_.BOTTOM_LEFT)) { + this.outline_.classList.add(this.CssClasses_.BOTTOM_LEFT); + } + if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) { + this.outline_.classList.add(this.CssClasses_.BOTTOM_RIGHT); + } + if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) { + this.outline_.classList.add(this.CssClasses_.TOP_LEFT); + } + if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { + this.outline_.classList.add(this.CssClasses_.TOP_RIGHT); + } + if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) { + this.outline_.classList.add(this.CssClasses_.UNALIGNED); + } + container.classList.add(this.CssClasses_.IS_UPGRADED); + } + }; + /** + * Handles a click on the "for" element, by positioning the menu and then + * toggling it. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialMenu.prototype.handleForClick_ = function (evt) { + if (this.element_ && this.forElement_) { + var rect = this.forElement_.getBoundingClientRect(); + var forRect = this.forElement_.parentElement.getBoundingClientRect(); + if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) { + } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) { + // Position below the "for" element, aligned to its right. + this.container_.style.right = forRect.right - rect.right + 'px'; + this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px'; + } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) { + // Position above the "for" element, aligned to its left. + this.container_.style.left = this.forElement_.offsetLeft + 'px'; + this.container_.style.bottom = forRect.bottom - rect.top + 'px'; + } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { + // Position above the "for" element, aligned to its right. + this.container_.style.right = forRect.right - rect.right + 'px'; + this.container_.style.bottom = forRect.bottom - rect.top + 'px'; + } else { + // Default: position below the "for" element, aligned to its left. + this.container_.style.left = this.forElement_.offsetLeft + 'px'; + this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px'; + } + } + this.toggle(evt); + }; + /** + * Handles a keyboard event on the "for" element. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialMenu.prototype.handleForKeyboardEvent_ = function (evt) { + if (this.element_ && this.container_ && this.forElement_) { + var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])'); + if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) { + if (evt.keyCode === this.Keycodes_.UP_ARROW) { + evt.preventDefault(); + items[items.length - 1].focus(); + } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) { + evt.preventDefault(); + items[0].focus(); + } + } + } + }; + /** + * Handles a keyboard event on an item. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialMenu.prototype.handleItemKeyboardEvent_ = function (evt) { + if (this.element_ && this.container_) { + var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])'); + if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) { + var currentIndex = Array.prototype.slice.call(items).indexOf(evt.target); + if (evt.keyCode === this.Keycodes_.UP_ARROW) { + evt.preventDefault(); + if (currentIndex > 0) { + items[currentIndex - 1].focus(); + } else { + items[items.length - 1].focus(); + } + } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) { + evt.preventDefault(); + if (items.length > currentIndex + 1) { + items[currentIndex + 1].focus(); + } else { + items[0].focus(); + } + } else if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) { + evt.preventDefault(); + // Send mousedown and mouseup to trigger ripple. + var e = new MouseEvent('mousedown'); + evt.target.dispatchEvent(e); + e = new MouseEvent('mouseup'); + evt.target.dispatchEvent(e); + // Send click. + evt.target.click(); + } else if (evt.keyCode === this.Keycodes_.ESCAPE) { + evt.preventDefault(); + this.hide(); + } + } + } + }; + /** + * Handles a click event on an item. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialMenu.prototype.handleItemClick_ = function (evt) { + if (evt.target.hasAttribute('disabled')) { + evt.stopPropagation(); + } else { + // Wait some time before closing menu, so the user can see the ripple. + this.closing_ = true; + window.setTimeout(function (evt) { + this.hide(); + this.closing_ = false; + }.bind(this), this.Constant_.CLOSE_TIMEOUT); + } + }; + /** + * Calculates the initial clip (for opening the menu) or final clip (for closing + * it), and applies it. This allows us to animate from or to the correct point, + * that is, the point it's aligned to in the "for" element. + * + * @param {number} height Height of the clip rectangle + * @param {number} width Width of the clip rectangle + * @private + */ + MaterialMenu.prototype.applyClip_ = function (height, width) { + if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) { + // Do not clip. + this.element_.style.clip = ''; + } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) { + // Clip to the top right corner of the menu. + this.element_.style.clip = 'rect(0 ' + width + 'px ' + '0 ' + width + 'px)'; + } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) { + // Clip to the bottom left corner of the menu. + this.element_.style.clip = 'rect(' + height + 'px 0 ' + height + 'px 0)'; + } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { + // Clip to the bottom right corner of the menu. + this.element_.style.clip = 'rect(' + height + 'px ' + width + 'px ' + height + 'px ' + width + 'px)'; + } else { + // Default: do not clip (same as clipping to the top left corner). + this.element_.style.clip = ''; + } + }; + /** + * Cleanup function to remove animation listeners. + * + * @param {Event} evt + * @private + */ + MaterialMenu.prototype.removeAnimationEndListener_ = function (evt) { + evt.target.classList.remove(MaterialMenu.prototype.CssClasses_.IS_ANIMATING); + }; + /** + * Adds an event listener to clean up after the animation ends. + * + * @private + */ + MaterialMenu.prototype.addAnimationEndListener_ = function () { + this.element_.addEventListener('transitionend', this.removeAnimationEndListener_); + this.element_.addEventListener('webkitTransitionEnd', this.removeAnimationEndListener_); + }; + /** + * Displays the menu. + * + * @public + */ + MaterialMenu.prototype.show = function (evt) { + if (this.element_ && this.container_ && this.outline_) { + // Measure the inner element. + var height = this.element_.getBoundingClientRect().height; + var width = this.element_.getBoundingClientRect().width; + // Apply the inner element's size to the container and outline. + this.container_.style.width = width + 'px'; + this.container_.style.height = height + 'px'; + this.outline_.style.width = width + 'px'; + this.outline_.style.height = height + 'px'; + var transitionDuration = this.Constant_.TRANSITION_DURATION_SECONDS * this.Constant_.TRANSITION_DURATION_FRACTION; + // Calculate transition delays for individual menu items, so that they fade + // in one at a time. + var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); + for (var i = 0; i < items.length; i++) { + var itemDelay = null; + if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT) || this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { + itemDelay = (height - items[i].offsetTop - items[i].offsetHeight) / height * transitionDuration + 's'; + } else { + itemDelay = items[i].offsetTop / height * transitionDuration + 's'; + } + items[i].style.transitionDelay = itemDelay; + } + // Apply the initial clip to the text before we start animating. + this.applyClip_(height, width); + // Wait for the next frame, turn on animation, and apply the final clip. + // Also make it visible. This triggers the transitions. + window.requestAnimationFrame(function () { + this.element_.classList.add(this.CssClasses_.IS_ANIMATING); + this.element_.style.clip = 'rect(0 ' + width + 'px ' + height + 'px 0)'; + this.container_.classList.add(this.CssClasses_.IS_VISIBLE); + }.bind(this)); + // Clean up after the animation is complete. + this.addAnimationEndListener_(); + // Add a click listener to the document, to close the menu. + var callback = function (e) { + // Check to see if the document is processing the same event that + // displayed the menu in the first place. If so, do nothing. + // Also check to see if the menu is in the process of closing itself, and + // do nothing in that case. + // Also check if the clicked element is a menu item + // if so, do nothing. + if (e !== evt && !this.closing_ && e.target.parentNode !== this.element_) { + document.removeEventListener('click', callback); + this.hide(); + } + }.bind(this); + document.addEventListener('click', callback); + } + }; + MaterialMenu.prototype['show'] = MaterialMenu.prototype.show; + /** + * Hides the menu. + * + * @public + */ + MaterialMenu.prototype.hide = function () { + if (this.element_ && this.container_ && this.outline_) { + var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); + // Remove all transition delays; menu items fade out concurrently. + for (var i = 0; i < items.length; i++) { + items[i].style.removeProperty('transition-delay'); + } + // Measure the inner element. + var rect = this.element_.getBoundingClientRect(); + var height = rect.height; + var width = rect.width; + // Turn on animation, and apply the final clip. Also make invisible. + // This triggers the transitions. + this.element_.classList.add(this.CssClasses_.IS_ANIMATING); + this.applyClip_(height, width); + this.container_.classList.remove(this.CssClasses_.IS_VISIBLE); + // Clean up after the animation is complete. + this.addAnimationEndListener_(); + } + }; + MaterialMenu.prototype['hide'] = MaterialMenu.prototype.hide; + /** + * Displays or hides the menu, depending on current state. + * + * @public + */ + MaterialMenu.prototype.toggle = function (evt) { + if (this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) { + this.hide(); + } else { + this.show(evt); + } + }; + MaterialMenu.prototype['toggle'] = MaterialMenu.prototype.toggle; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialMenu, + classAsString: 'MaterialMenu', + cssClass: 'mdl-js-menu', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Progress MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialProgress = function MaterialProgress(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialProgress'] = MaterialProgress; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialProgress.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialProgress.prototype.CssClasses_ = {INDETERMINATE_CLASS: 'mdl-progress__indeterminate'}; + /** + * Set the current progress of the progressbar. + * + * @param {number} p Percentage of the progress (0-100) + * @public + */ + MaterialProgress.prototype.setProgress = function (p) { + if (this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)) { + return; + } + this.progressbar_.style.width = p + '%'; + }; + MaterialProgress.prototype['setProgress'] = MaterialProgress.prototype.setProgress; + /** + * Set the current progress of the buffer. + * + * @param {number} p Percentage of the buffer (0-100) + * @public + */ + MaterialProgress.prototype.setBuffer = function (p) { + this.bufferbar_.style.width = p + '%'; + this.auxbar_.style.width = 100 - p + '%'; + }; + MaterialProgress.prototype['setBuffer'] = MaterialProgress.prototype.setBuffer; + /** + * Initialize element. + */ + MaterialProgress.prototype.init = function () { + if (this.element_) { + var el = document.createElement('div'); + el.className = 'progressbar bar bar1'; + this.element_.appendChild(el); + this.progressbar_ = el; + el = document.createElement('div'); + el.className = 'bufferbar bar bar2'; + this.element_.appendChild(el); + this.bufferbar_ = el; + el = document.createElement('div'); + el.className = 'auxbar bar bar3'; + this.element_.appendChild(el); + this.auxbar_ = el; + this.progressbar_.style.width = '0%'; + this.bufferbar_.style.width = '100%'; + this.auxbar_.style.width = '0%'; + this.element_.classList.add('is-upgraded'); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialProgress, + classAsString: 'MaterialProgress', + cssClass: 'mdl-js-progress', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Radio MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialRadio = function MaterialRadio(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialRadio'] = MaterialRadio; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialRadio.prototype.Constant_ = {TINY_TIMEOUT: 0.001}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialRadio.prototype.CssClasses_ = { + IS_FOCUSED: 'is-focused', + IS_DISABLED: 'is-disabled', + IS_CHECKED: 'is-checked', + IS_UPGRADED: 'is-upgraded', + JS_RADIO: 'mdl-js-radio', + RADIO_BTN: 'mdl-radio__button', + RADIO_OUTER_CIRCLE: 'mdl-radio__outer-circle', + RADIO_INNER_CIRCLE: 'mdl-radio__inner-circle', + RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE_CONTAINER: 'mdl-radio__ripple-container', + RIPPLE_CENTER: 'mdl-ripple--center', + RIPPLE: 'mdl-ripple' + }; + /** + * Handle change of state. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRadio.prototype.onChange_ = function (event) { + // Since other radio buttons don't get change events, we need to look for + // them to update their classes. + var radios = document.getElementsByClassName(this.CssClasses_.JS_RADIO); + for (var i = 0; i < radios.length; i++) { + var button = radios[i].querySelector('.' + this.CssClasses_.RADIO_BTN); + // Different name == different group, so no point updating those. + if (button.getAttribute('name') === this.btnElement_.getAttribute('name')) { + if (typeof radios[i]['MaterialRadio'] !== 'undefined') { + radios[i]['MaterialRadio'].updateClasses_(); + } + } + } + }; + /** + * Handle focus. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRadio.prototype.onFocus_ = function (event) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle lost focus. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRadio.prototype.onBlur_ = function (event) { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle mouseup. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRadio.prototype.onMouseup_ = function (event) { + this.blur_(); + }; + /** + * Update classes. + * + * @private + */ + MaterialRadio.prototype.updateClasses_ = function () { + this.checkDisabled(); + this.checkToggleState(); + }; + /** + * Add blur. + * + * @private + */ + MaterialRadio.prototype.blur_ = function () { + // TODO: figure out why there's a focus event being fired after our blur, + // so that we can avoid this hack. + window.setTimeout(function () { + this.btnElement_.blur(); + }.bind(this), this.Constant_.TINY_TIMEOUT); + }; +// Public methods. + /** + * Check the components disabled state. + * + * @public + */ + MaterialRadio.prototype.checkDisabled = function () { + if (this.btnElement_.disabled) { + this.element_.classList.add(this.CssClasses_.IS_DISABLED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DISABLED); + } + }; + MaterialRadio.prototype['checkDisabled'] = MaterialRadio.prototype.checkDisabled; + /** + * Check the components toggled state. + * + * @public + */ + MaterialRadio.prototype.checkToggleState = function () { + if (this.btnElement_.checked) { + this.element_.classList.add(this.CssClasses_.IS_CHECKED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_CHECKED); + } + }; + MaterialRadio.prototype['checkToggleState'] = MaterialRadio.prototype.checkToggleState; + /** + * Disable radio. + * + * @public + */ + MaterialRadio.prototype.disable = function () { + this.btnElement_.disabled = true; + this.updateClasses_(); + }; + MaterialRadio.prototype['disable'] = MaterialRadio.prototype.disable; + /** + * Enable radio. + * + * @public + */ + MaterialRadio.prototype.enable = function () { + this.btnElement_.disabled = false; + this.updateClasses_(); + }; + MaterialRadio.prototype['enable'] = MaterialRadio.prototype.enable; + /** + * Check radio. + * + * @public + */ + MaterialRadio.prototype.check = function () { + this.btnElement_.checked = true; + this.onChange_(null); + }; + MaterialRadio.prototype['check'] = MaterialRadio.prototype.check; + /** + * Uncheck radio. + * + * @public + */ + MaterialRadio.prototype.uncheck = function () { + this.btnElement_.checked = false; + this.onChange_(null); + }; + MaterialRadio.prototype['uncheck'] = MaterialRadio.prototype.uncheck; + /** + * Initialize element. + */ + MaterialRadio.prototype.init = function () { + if (this.element_) { + this.btnElement_ = this.element_.querySelector('.' + this.CssClasses_.RADIO_BTN); + this.boundChangeHandler_ = this.onChange_.bind(this); + this.boundFocusHandler_ = this.onChange_.bind(this); + this.boundBlurHandler_ = this.onBlur_.bind(this); + this.boundMouseUpHandler_ = this.onMouseup_.bind(this); + var outerCircle = document.createElement('span'); + outerCircle.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE); + var innerCircle = document.createElement('span'); + innerCircle.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE); + this.element_.appendChild(outerCircle); + this.element_.appendChild(innerCircle); + var rippleContainer; + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + rippleContainer = document.createElement('span'); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER); + rippleContainer.addEventListener('mouseup', this.boundMouseUpHandler_); + var ripple = document.createElement('span'); + ripple.classList.add(this.CssClasses_.RIPPLE); + rippleContainer.appendChild(ripple); + this.element_.appendChild(rippleContainer); + } + this.btnElement_.addEventListener('change', this.boundChangeHandler_); + this.btnElement_.addEventListener('focus', this.boundFocusHandler_); + this.btnElement_.addEventListener('blur', this.boundBlurHandler_); + this.element_.addEventListener('mouseup', this.boundMouseUpHandler_); + this.updateClasses_(); + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialRadio, + classAsString: 'MaterialRadio', + cssClass: 'mdl-js-radio', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Slider MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialSlider = function MaterialSlider(element) { + this.element_ = element; + // Browser feature detection. + this.isIE_ = window.navigator.msPointerEnabled; + // Initialize instance. + this.init(); + }; + window['MaterialSlider'] = MaterialSlider; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialSlider.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialSlider.prototype.CssClasses_ = { + IE_CONTAINER: 'mdl-slider__ie-container', + SLIDER_CONTAINER: 'mdl-slider__container', + BACKGROUND_FLEX: 'mdl-slider__background-flex', + BACKGROUND_LOWER: 'mdl-slider__background-lower', + BACKGROUND_UPPER: 'mdl-slider__background-upper', + IS_LOWEST_VALUE: 'is-lowest-value', + IS_UPGRADED: 'is-upgraded' + }; + /** + * Handle input on element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSlider.prototype.onInput_ = function (event) { + this.updateValueStyles_(); + }; + /** + * Handle change on element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSlider.prototype.onChange_ = function (event) { + this.updateValueStyles_(); + }; + /** + * Handle mouseup on element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSlider.prototype.onMouseUp_ = function (event) { + event.target.blur(); + }; + /** + * Handle mousedown on container element. + * This handler is purpose is to not require the use to click + * exactly on the 2px slider element, as FireFox seems to be very + * strict about this. + * + * @param {Event} event The event that fired. + * @private + * @suppress {missingProperties} + */ + MaterialSlider.prototype.onContainerMouseDown_ = function (event) { + // If this click is not on the parent element (but rather some child) + // ignore. It may still bubble up. + if (event.target !== this.element_.parentElement) { + return; + } + // Discard the original event and create a new event that + // is on the slider element. + event.preventDefault(); + var newEvent = new MouseEvent('mousedown', { + target: event.target, + buttons: event.buttons, + clientX: event.clientX, + clientY: this.element_.getBoundingClientRect().y + }); + this.element_.dispatchEvent(newEvent); + }; + /** + * Handle updating of values. + * + * @private + */ + MaterialSlider.prototype.updateValueStyles_ = function () { + // Calculate and apply percentages to div structure behind slider. + var fraction = (this.element_.value - this.element_.min) / (this.element_.max - this.element_.min); + if (fraction === 0) { + this.element_.classList.add(this.CssClasses_.IS_LOWEST_VALUE); + } else { + this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE); + } + if (!this.isIE_) { + this.backgroundLower_.style.flex = fraction; + this.backgroundLower_.style.webkitFlex = fraction; + this.backgroundUpper_.style.flex = 1 - fraction; + this.backgroundUpper_.style.webkitFlex = 1 - fraction; + } + }; +// Public methods. + /** + * Disable slider. + * + * @public + */ + MaterialSlider.prototype.disable = function () { + this.element_.disabled = true; + }; + MaterialSlider.prototype['disable'] = MaterialSlider.prototype.disable; + /** + * Enable slider. + * + * @public + */ + MaterialSlider.prototype.enable = function () { + this.element_.disabled = false; + }; + MaterialSlider.prototype['enable'] = MaterialSlider.prototype.enable; + /** + * Update slider value. + * + * @param {number} value The value to which to set the control (optional). + * @public + */ + MaterialSlider.prototype.change = function (value) { + if (typeof value !== 'undefined') { + this.element_.value = value; + } + this.updateValueStyles_(); + }; + MaterialSlider.prototype['change'] = MaterialSlider.prototype.change; + /** + * Initialize element. + */ + MaterialSlider.prototype.init = function () { + if (this.element_) { + if (this.isIE_) { + // Since we need to specify a very large height in IE due to + // implementation limitations, we add a parent here that trims it down to + // a reasonable size. + var containerIE = document.createElement('div'); + containerIE.classList.add(this.CssClasses_.IE_CONTAINER); + this.element_.parentElement.insertBefore(containerIE, this.element_); + this.element_.parentElement.removeChild(this.element_); + containerIE.appendChild(this.element_); + } else { + // For non-IE browsers, we need a div structure that sits behind the + // slider and allows us to style the left and right sides of it with + // different colors. + var container = document.createElement('div'); + container.classList.add(this.CssClasses_.SLIDER_CONTAINER); + this.element_.parentElement.insertBefore(container, this.element_); + this.element_.parentElement.removeChild(this.element_); + container.appendChild(this.element_); + var backgroundFlex = document.createElement('div'); + backgroundFlex.classList.add(this.CssClasses_.BACKGROUND_FLEX); + container.appendChild(backgroundFlex); + this.backgroundLower_ = document.createElement('div'); + this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER); + backgroundFlex.appendChild(this.backgroundLower_); + this.backgroundUpper_ = document.createElement('div'); + this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER); + backgroundFlex.appendChild(this.backgroundUpper_); + } + this.boundInputHandler = this.onInput_.bind(this); + this.boundChangeHandler = this.onChange_.bind(this); + this.boundMouseUpHandler = this.onMouseUp_.bind(this); + this.boundContainerMouseDownHandler = this.onContainerMouseDown_.bind(this); + this.element_.addEventListener('input', this.boundInputHandler); + this.element_.addEventListener('change', this.boundChangeHandler); + this.element_.addEventListener('mouseup', this.boundMouseUpHandler); + this.element_.parentElement.addEventListener('mousedown', this.boundContainerMouseDownHandler); + this.updateValueStyles_(); + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialSlider, + classAsString: 'MaterialSlider', + cssClass: 'mdl-js-slider', + widget: true + }); + /** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Snackbar MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialSnackbar = function MaterialSnackbar(element) { + this.element_ = element; + this.textElement_ = this.element_.querySelector('.' + this.cssClasses_.MESSAGE); + this.actionElement_ = this.element_.querySelector('.' + this.cssClasses_.ACTION); + if (!this.textElement_) { + throw new Error('There must be a message element for a snackbar.'); + } + if (!this.actionElement_) { + throw new Error('There must be an action element for a snackbar.'); + } + this.active = false; + this.actionHandler_ = undefined; + this.message_ = undefined; + this.actionText_ = undefined; + this.queuedNotifications_ = []; + this.setActionHidden_(true); + }; + window['MaterialSnackbar'] = MaterialSnackbar; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialSnackbar.prototype.Constant_ = { + // The duration of the snackbar show/hide animation, in ms. + ANIMATION_LENGTH: 250 + }; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialSnackbar.prototype.cssClasses_ = { + SNACKBAR: 'mdl-snackbar', + MESSAGE: 'mdl-snackbar__text', + ACTION: 'mdl-snackbar__action', + ACTIVE: 'mdl-snackbar--active' + }; + /** + * Display the snackbar. + * + * @private + */ + MaterialSnackbar.prototype.displaySnackbar_ = function () { + this.element_.setAttribute('aria-hidden', 'true'); + if (this.actionHandler_) { + this.actionElement_.textContent = this.actionText_; + this.actionElement_.addEventListener('click', this.actionHandler_); + this.setActionHidden_(false); + } + this.textElement_.textContent = this.message_; + this.element_.classList.add(this.cssClasses_.ACTIVE); + this.element_.setAttribute('aria-hidden', 'false'); + setTimeout(this.cleanup_.bind(this), this.timeout_); + }; + /** + * Show the snackbar. + * + * @param {Object} data The data for the notification. + * @public + */ + MaterialSnackbar.prototype.showSnackbar = function (data) { + if (data === undefined) { + throw new Error('Please provide a data object with at least a message to display.'); + } + if (data['message'] === undefined) { + throw new Error('Please provide a message to be displayed.'); + } + if (data['actionHandler'] && !data['actionText']) { + throw new Error('Please provide action text with the handler.'); + } + if (this.active) { + this.queuedNotifications_.push(data); + } else { + this.active = true; + this.message_ = data['message']; + if (data['timeout']) { + this.timeout_ = data['timeout']; + } else { + this.timeout_ = 2750; + } + if (data['actionHandler']) { + this.actionHandler_ = data['actionHandler']; + } + if (data['actionText']) { + this.actionText_ = data['actionText']; + } + this.displaySnackbar_(); + } + }; + MaterialSnackbar.prototype['showSnackbar'] = MaterialSnackbar.prototype.showSnackbar; + /** + * Check if the queue has items within it. + * If it does, display the next entry. + * + * @private + */ + MaterialSnackbar.prototype.checkQueue_ = function () { + if (this.queuedNotifications_.length > 0) { + this.showSnackbar(this.queuedNotifications_.shift()); + } + }; + /** + * Cleanup the snackbar event listeners and accessiblity attributes. + * + * @private + */ + MaterialSnackbar.prototype.cleanup_ = function () { + this.element_.classList.remove(this.cssClasses_.ACTIVE); + setTimeout(function () { + this.element_.setAttribute('aria-hidden', 'true'); + this.textElement_.textContent = ''; + if (!Boolean(this.actionElement_.getAttribute('aria-hidden'))) { + this.setActionHidden_(true); + this.actionElement_.textContent = ''; + this.actionElement_.removeEventListener('click', this.actionHandler_); + } + this.actionHandler_ = undefined; + this.message_ = undefined; + this.actionText_ = undefined; + this.active = false; + this.checkQueue_(); + }.bind(this), this.Constant_.ANIMATION_LENGTH); + }; + /** + * Set the action handler hidden state. + * + * @param {boolean} value + * @private + */ + MaterialSnackbar.prototype.setActionHidden_ = function (value) { + if (value) { + this.actionElement_.setAttribute('aria-hidden', 'true'); + } else { + this.actionElement_.removeAttribute('aria-hidden'); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialSnackbar, + classAsString: 'MaterialSnackbar', + cssClass: 'mdl-js-snackbar', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Spinner MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @param {HTMLElement} element The element that will be upgraded. + * @constructor + */ + var MaterialSpinner = function MaterialSpinner(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialSpinner'] = MaterialSpinner; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialSpinner.prototype.Constant_ = {MDL_SPINNER_LAYER_COUNT: 4}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialSpinner.prototype.CssClasses_ = { + MDL_SPINNER_LAYER: 'mdl-spinner__layer', + MDL_SPINNER_CIRCLE_CLIPPER: 'mdl-spinner__circle-clipper', + MDL_SPINNER_CIRCLE: 'mdl-spinner__circle', + MDL_SPINNER_GAP_PATCH: 'mdl-spinner__gap-patch', + MDL_SPINNER_LEFT: 'mdl-spinner__left', + MDL_SPINNER_RIGHT: 'mdl-spinner__right' + }; + /** + * Auxiliary method to create a spinner layer. + * + * @param {number} index Index of the layer to be created. + * @public + */ + MaterialSpinner.prototype.createLayer = function (index) { + var layer = document.createElement('div'); + layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER); + layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER + '-' + index); + var leftClipper = document.createElement('div'); + leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER); + leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_LEFT); + var gapPatch = document.createElement('div'); + gapPatch.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH); + var rightClipper = document.createElement('div'); + rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER); + rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT); + var circleOwners = [ + leftClipper, + gapPatch, + rightClipper + ]; + for (var i = 0; i < circleOwners.length; i++) { + var circle = document.createElement('div'); + circle.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE); + circleOwners[i].appendChild(circle); + } + layer.appendChild(leftClipper); + layer.appendChild(gapPatch); + layer.appendChild(rightClipper); + this.element_.appendChild(layer); + }; + MaterialSpinner.prototype['createLayer'] = MaterialSpinner.prototype.createLayer; + /** + * Stops the spinner animation. + * Public method for users who need to stop the spinner for any reason. + * + * @public + */ + MaterialSpinner.prototype.stop = function () { + this.element_.classList.remove('is-active'); + }; + MaterialSpinner.prototype['stop'] = MaterialSpinner.prototype.stop; + /** + * Starts the spinner animation. + * Public method for users who need to manually start the spinner for any reason + * (instead of just adding the 'is-active' class to their markup). + * + * @public + */ + MaterialSpinner.prototype.start = function () { + this.element_.classList.add('is-active'); + }; + MaterialSpinner.prototype['start'] = MaterialSpinner.prototype.start; + /** + * Initialize element. + */ + MaterialSpinner.prototype.init = function () { + if (this.element_) { + for (var i = 1; i <= this.Constant_.MDL_SPINNER_LAYER_COUNT; i++) { + this.createLayer(i); + } + this.element_.classList.add('is-upgraded'); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialSpinner, + classAsString: 'MaterialSpinner', + cssClass: 'mdl-js-spinner', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Checkbox MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialSwitch = function MaterialSwitch(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialSwitch'] = MaterialSwitch; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialSwitch.prototype.Constant_ = {TINY_TIMEOUT: 0.001}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialSwitch.prototype.CssClasses_ = { + INPUT: 'mdl-switch__input', + TRACK: 'mdl-switch__track', + THUMB: 'mdl-switch__thumb', + FOCUS_HELPER: 'mdl-switch__focus-helper', + RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE_CONTAINER: 'mdl-switch__ripple-container', + RIPPLE_CENTER: 'mdl-ripple--center', + RIPPLE: 'mdl-ripple', + IS_FOCUSED: 'is-focused', + IS_DISABLED: 'is-disabled', + IS_CHECKED: 'is-checked' + }; + /** + * Handle change of state. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSwitch.prototype.onChange_ = function (event) { + this.updateClasses_(); + }; + /** + * Handle focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSwitch.prototype.onFocus_ = function (event) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle lost focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSwitch.prototype.onBlur_ = function (event) { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle mouseup. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSwitch.prototype.onMouseUp_ = function (event) { + this.blur_(); + }; + /** + * Handle class updates. + * + * @private + */ + MaterialSwitch.prototype.updateClasses_ = function () { + this.checkDisabled(); + this.checkToggleState(); + }; + /** + * Add blur. + * + * @private + */ + MaterialSwitch.prototype.blur_ = function () { + // TODO: figure out why there's a focus event being fired after our blur, + // so that we can avoid this hack. + window.setTimeout(function () { + this.inputElement_.blur(); + }.bind(this), this.Constant_.TINY_TIMEOUT); + }; +// Public methods. + /** + * Check the components disabled state. + * + * @public + */ + MaterialSwitch.prototype.checkDisabled = function () { + if (this.inputElement_.disabled) { + this.element_.classList.add(this.CssClasses_.IS_DISABLED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DISABLED); + } + }; + MaterialSwitch.prototype['checkDisabled'] = MaterialSwitch.prototype.checkDisabled; + /** + * Check the components toggled state. + * + * @public + */ + MaterialSwitch.prototype.checkToggleState = function () { + if (this.inputElement_.checked) { + this.element_.classList.add(this.CssClasses_.IS_CHECKED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_CHECKED); + } + }; + MaterialSwitch.prototype['checkToggleState'] = MaterialSwitch.prototype.checkToggleState; + /** + * Disable switch. + * + * @public + */ + MaterialSwitch.prototype.disable = function () { + this.inputElement_.disabled = true; + this.updateClasses_(); + }; + MaterialSwitch.prototype['disable'] = MaterialSwitch.prototype.disable; + /** + * Enable switch. + * + * @public + */ + MaterialSwitch.prototype.enable = function () { + this.inputElement_.disabled = false; + this.updateClasses_(); + }; + MaterialSwitch.prototype['enable'] = MaterialSwitch.prototype.enable; + /** + * Activate switch. + * + * @public + */ + MaterialSwitch.prototype.on = function () { + this.inputElement_.checked = true; + this.updateClasses_(); + }; + MaterialSwitch.prototype['on'] = MaterialSwitch.prototype.on; + /** + * Deactivate switch. + * + * @public + */ + MaterialSwitch.prototype.off = function () { + this.inputElement_.checked = false; + this.updateClasses_(); + }; + MaterialSwitch.prototype['off'] = MaterialSwitch.prototype.off; + /** + * Initialize element. + */ + MaterialSwitch.prototype.init = function () { + if (this.element_) { + this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); + var track = document.createElement('div'); + track.classList.add(this.CssClasses_.TRACK); + var thumb = document.createElement('div'); + thumb.classList.add(this.CssClasses_.THUMB); + var focusHelper = document.createElement('span'); + focusHelper.classList.add(this.CssClasses_.FOCUS_HELPER); + thumb.appendChild(focusHelper); + this.element_.appendChild(track); + this.element_.appendChild(thumb); + this.boundMouseUpHandler = this.onMouseUp_.bind(this); + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + this.rippleContainerElement_ = document.createElement('span'); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER); + this.rippleContainerElement_.addEventListener('mouseup', this.boundMouseUpHandler); + var ripple = document.createElement('span'); + ripple.classList.add(this.CssClasses_.RIPPLE); + this.rippleContainerElement_.appendChild(ripple); + this.element_.appendChild(this.rippleContainerElement_); + } + this.boundChangeHandler = this.onChange_.bind(this); + this.boundFocusHandler = this.onFocus_.bind(this); + this.boundBlurHandler = this.onBlur_.bind(this); + this.inputElement_.addEventListener('change', this.boundChangeHandler); + this.inputElement_.addEventListener('focus', this.boundFocusHandler); + this.inputElement_.addEventListener('blur', this.boundBlurHandler); + this.element_.addEventListener('mouseup', this.boundMouseUpHandler); + this.updateClasses_(); + this.element_.classList.add('is-upgraded'); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialSwitch, + classAsString: 'MaterialSwitch', + cssClass: 'mdl-js-switch', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Tabs MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {Element} element The element that will be upgraded. + */ + var MaterialTabs = function MaterialTabs(element) { + // Stores the HTML element. + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialTabs'] = MaterialTabs; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string} + * @private + */ + MaterialTabs.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialTabs.prototype.CssClasses_ = { + TAB_CLASS: 'mdl-tabs__tab', + PANEL_CLASS: 'mdl-tabs__panel', + ACTIVE_CLASS: 'is-active', + UPGRADED_CLASS: 'is-upgraded', + MDL_JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect', + MDL_RIPPLE_CONTAINER: 'mdl-tabs__ripple-container', + MDL_RIPPLE: 'mdl-ripple', + MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events' + }; + /** + * Handle clicks to a tabs component + * + * @private + */ + MaterialTabs.prototype.initTabs_ = function () { + if (this.element_.classList.contains(this.CssClasses_.MDL_JS_RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS); + } + // Select element tabs, document panels + this.tabs_ = this.element_.querySelectorAll('.' + this.CssClasses_.TAB_CLASS); + this.panels_ = this.element_.querySelectorAll('.' + this.CssClasses_.PANEL_CLASS); + // Create new tabs for each tab element + for (var i = 0; i < this.tabs_.length; i++) { + new MaterialTab(this.tabs_[i], this); + } + this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS); + }; + /** + * Reset tab state, dropping active classes + * + * @private + */ + MaterialTabs.prototype.resetTabState_ = function () { + for (var k = 0; k < this.tabs_.length; k++) { + this.tabs_[k].classList.remove(this.CssClasses_.ACTIVE_CLASS); + } + }; + /** + * Reset panel state, droping active classes + * + * @private + */ + MaterialTabs.prototype.resetPanelState_ = function () { + for (var j = 0; j < this.panels_.length; j++) { + this.panels_[j].classList.remove(this.CssClasses_.ACTIVE_CLASS); + } + }; + /** + * Initialize element. + */ + MaterialTabs.prototype.init = function () { + if (this.element_) { + this.initTabs_(); + } + }; + + /** + * Constructor for an individual tab. + * + * @constructor + * @param {Element} tab The HTML element for the tab. + * @param {MaterialTabs} ctx The MaterialTabs object that owns the tab. + */ + function MaterialTab(tab, ctx) { + if (tab) { + if (ctx.element_.classList.contains(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT)) { + var rippleContainer = document.createElement('span'); + rippleContainer.classList.add(ctx.CssClasses_.MDL_RIPPLE_CONTAINER); + rippleContainer.classList.add(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT); + var ripple = document.createElement('span'); + ripple.classList.add(ctx.CssClasses_.MDL_RIPPLE); + rippleContainer.appendChild(ripple); + tab.appendChild(rippleContainer); + } + tab.addEventListener('click', function (e) { + if (tab.getAttribute('href').charAt(0) === '#') { + e.preventDefault(); + var href = tab.href.split('#')[1]; + var panel = ctx.element_.querySelector('#' + href); + ctx.resetTabState_(); + ctx.resetPanelState_(); + tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS); + panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS); + } + }); + } + } + +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialTabs, + classAsString: 'MaterialTabs', + cssClass: 'mdl-js-tabs' + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Textfield MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialTextfield = function MaterialTextfield(element) { + this.element_ = element; + this.maxRows = this.Constant_.NO_MAX_ROWS; + // Initialize instance. + this.init(); + }; + window['MaterialTextfield'] = MaterialTextfield; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialTextfield.prototype.Constant_ = { + NO_MAX_ROWS: -1, + MAX_ROWS_ATTRIBUTE: 'maxrows' + }; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialTextfield.prototype.CssClasses_ = { + LABEL: 'mdl-textfield__label', + INPUT: 'mdl-textfield__input', + IS_DIRTY: 'is-dirty', + IS_FOCUSED: 'is-focused', + IS_DISABLED: 'is-disabled', + IS_INVALID: 'is-invalid', + IS_UPGRADED: 'is-upgraded', + HAS_PLACEHOLDER: 'has-placeholder' + }; + /** + * Handle input being entered. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialTextfield.prototype.onKeyDown_ = function (event) { + var currentRowCount = event.target.value.split('\n').length; + if (event.keyCode === 13) { + if (currentRowCount >= this.maxRows) { + event.preventDefault(); + } + } + }; + /** + * Handle focus. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialTextfield.prototype.onFocus_ = function (event) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle lost focus. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialTextfield.prototype.onBlur_ = function (event) { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle reset event from out side. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialTextfield.prototype.onReset_ = function (event) { + this.updateClasses_(); + }; + /** + * Handle class updates. + * + * @private + */ + MaterialTextfield.prototype.updateClasses_ = function () { + this.checkDisabled(); + this.checkValidity(); + this.checkDirty(); + this.checkFocus(); + }; +// Public methods. + /** + * Check the disabled state and update field accordingly. + * + * @public + */ + MaterialTextfield.prototype.checkDisabled = function () { + if (this.input_.disabled) { + this.element_.classList.add(this.CssClasses_.IS_DISABLED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DISABLED); + } + }; + MaterialTextfield.prototype['checkDisabled'] = MaterialTextfield.prototype.checkDisabled; + /** + * Check the focus state and update field accordingly. + * + * @public + */ + MaterialTextfield.prototype.checkFocus = function () { + if (Boolean(this.element_.querySelector(':focus'))) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + } + }; + MaterialTextfield.prototype['checkFocus'] = MaterialTextfield.prototype.checkFocus; + /** + * Check the validity state and update field accordingly. + * + * @public + */ + MaterialTextfield.prototype.checkValidity = function () { + if (this.input_.validity) { + if (this.input_.validity.valid) { + this.element_.classList.remove(this.CssClasses_.IS_INVALID); + } else { + this.element_.classList.add(this.CssClasses_.IS_INVALID); + } + } + }; + MaterialTextfield.prototype['checkValidity'] = MaterialTextfield.prototype.checkValidity; + /** + * Check the dirty state and update field accordingly. + * + * @public + */ + MaterialTextfield.prototype.checkDirty = function () { + if (this.input_.value && this.input_.value.length > 0) { + this.element_.classList.add(this.CssClasses_.IS_DIRTY); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DIRTY); + } + }; + MaterialTextfield.prototype['checkDirty'] = MaterialTextfield.prototype.checkDirty; + /** + * Disable text field. + * + * @public + */ + MaterialTextfield.prototype.disable = function () { + this.input_.disabled = true; + this.updateClasses_(); + }; + MaterialTextfield.prototype['disable'] = MaterialTextfield.prototype.disable; + /** + * Enable text field. + * + * @public + */ + MaterialTextfield.prototype.enable = function () { + this.input_.disabled = false; + this.updateClasses_(); + }; + MaterialTextfield.prototype['enable'] = MaterialTextfield.prototype.enable; + /** + * Update text field value. + * + * @param {string} value The value to which to set the control (optional). + * @public + */ + MaterialTextfield.prototype.change = function (value) { + this.input_.value = value || ''; + this.updateClasses_(); + }; + MaterialTextfield.prototype['change'] = MaterialTextfield.prototype.change; + /** + * Initialize element. + */ + MaterialTextfield.prototype.init = function () { + if (this.element_) { + this.label_ = this.element_.querySelector('.' + this.CssClasses_.LABEL); + this.input_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); + if (this.input_) { + if (this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)) { + this.maxRows = parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE), 10); + if (isNaN(this.maxRows)) { + this.maxRows = this.Constant_.NO_MAX_ROWS; + } + } + if (this.input_.hasAttribute('placeholder')) { + this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER); + } + this.boundUpdateClassesHandler = this.updateClasses_.bind(this); + this.boundFocusHandler = this.onFocus_.bind(this); + this.boundBlurHandler = this.onBlur_.bind(this); + this.boundResetHandler = this.onReset_.bind(this); + this.input_.addEventListener('input', this.boundUpdateClassesHandler); + this.input_.addEventListener('focus', this.boundFocusHandler); + this.input_.addEventListener('blur', this.boundBlurHandler); + this.input_.addEventListener('reset', this.boundResetHandler); + if (this.maxRows !== this.Constant_.NO_MAX_ROWS) { + // TODO: This should handle pasting multi line text. + // Currently doesn't. + this.boundKeyDownHandler = this.onKeyDown_.bind(this); + this.input_.addEventListener('keydown', this.boundKeyDownHandler); + } + var invalid = this.element_.classList.contains(this.CssClasses_.IS_INVALID); + this.updateClasses_(); + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + if (invalid) { + this.element_.classList.add(this.CssClasses_.IS_INVALID); + } + if (this.input_.hasAttribute('autofocus')) { + this.element_.focus(); + this.checkFocus(); + } + } + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialTextfield, + classAsString: 'MaterialTextfield', + cssClass: 'mdl-js-textfield', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Tooltip MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialTooltip = function MaterialTooltip(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialTooltip'] = MaterialTooltip; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialTooltip.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialTooltip.prototype.CssClasses_ = { + IS_ACTIVE: 'is-active', + BOTTOM: 'mdl-tooltip--bottom', + LEFT: 'mdl-tooltip--left', + RIGHT: 'mdl-tooltip--right', + TOP: 'mdl-tooltip--top' + }; + /** + * Handle mouseenter for tooltip. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialTooltip.prototype.handleMouseEnter_ = function (event) { + var props = event.target.getBoundingClientRect(); + var left = props.left + props.width / 2; + var top = props.top + props.height / 2; + var marginLeft = -1 * (this.element_.offsetWidth / 2); + var marginTop = -1 * (this.element_.offsetHeight / 2); + if (this.element_.classList.contains(this.CssClasses_.LEFT) || this.element_.classList.contains(this.CssClasses_.RIGHT)) { + left = props.width / 2; + if (top + marginTop < 0) { + this.element_.style.top = '0'; + this.element_.style.marginTop = '0'; + } else { + this.element_.style.top = top + 'px'; + this.element_.style.marginTop = marginTop + 'px'; + } + } else { + if (left + marginLeft < 0) { + this.element_.style.left = '0'; + this.element_.style.marginLeft = '0'; + } else { + this.element_.style.left = left + 'px'; + this.element_.style.marginLeft = marginLeft + 'px'; + } + } + if (this.element_.classList.contains(this.CssClasses_.TOP)) { + this.element_.style.top = props.top - this.element_.offsetHeight - 10 + 'px'; + } else if (this.element_.classList.contains(this.CssClasses_.RIGHT)) { + this.element_.style.left = props.left + props.width + 10 + 'px'; + } else if (this.element_.classList.contains(this.CssClasses_.LEFT)) { + this.element_.style.left = props.left - this.element_.offsetWidth - 10 + 'px'; + } else { + this.element_.style.top = props.top + props.height + 10 + 'px'; + } + this.element_.classList.add(this.CssClasses_.IS_ACTIVE); + }; + /** + * Hide tooltip on mouseleave or scroll + * + * @private + */ + MaterialTooltip.prototype.hideTooltip_ = function () { + this.element_.classList.remove(this.CssClasses_.IS_ACTIVE); + }; + /** + * Initialize element. + */ + MaterialTooltip.prototype.init = function () { + if (this.element_) { + var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for'); + if (forElId) { + this.forElement_ = document.getElementById(forElId); + } + if (this.forElement_) { + // It's left here because it prevents accidental text selection on Android + if (!this.forElement_.hasAttribute('tabindex')) { + this.forElement_.setAttribute('tabindex', '0'); + } + this.boundMouseEnterHandler = this.handleMouseEnter_.bind(this); + this.boundMouseLeaveAndScrollHandler = this.hideTooltip_.bind(this); + this.forElement_.addEventListener('mouseenter', this.boundMouseEnterHandler, false); + this.forElement_.addEventListener('touchend', this.boundMouseEnterHandler, false); + this.forElement_.addEventListener('mouseleave', this.boundMouseLeaveAndScrollHandler, false); + window.addEventListener('scroll', this.boundMouseLeaveAndScrollHandler, true); + window.addEventListener('touchstart', this.boundMouseLeaveAndScrollHandler); + } + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialTooltip, + classAsString: 'MaterialTooltip', + cssClass: 'mdl-tooltip' + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Layout MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialLayout = function MaterialLayout(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialLayout'] = MaterialLayout; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialLayout.prototype.Constant_ = { + MAX_WIDTH: '(max-width: 1024px)', + TAB_SCROLL_PIXELS: 100, + RESIZE_TIMEOUT: 100, + MENU_ICON: '', + CHEVRON_LEFT: 'chevron_left', + CHEVRON_RIGHT: 'chevron_right' + }; + /** + * Keycodes, for code readability. + * + * @enum {number} + * @private + */ + MaterialLayout.prototype.Keycodes_ = { + ENTER: 13, + ESCAPE: 27, + SPACE: 32 + }; + /** + * Modes. + * + * @enum {number} + * @private + */ + MaterialLayout.prototype.Mode_ = { + STANDARD: 0, + SEAMED: 1, + WATERFALL: 2, + SCROLL: 3 + }; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialLayout.prototype.CssClasses_ = { + CONTAINER: 'mdl-layout__container', + HEADER: 'mdl-layout__header', + DRAWER: 'mdl-layout__drawer', + CONTENT: 'mdl-layout__content', + DRAWER_BTN: 'mdl-layout__drawer-button', + ICON: 'material-icons', + JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_CONTAINER: 'mdl-layout__tab-ripple-container', + RIPPLE: 'mdl-ripple', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + HEADER_SEAMED: 'mdl-layout__header--seamed', + HEADER_WATERFALL: 'mdl-layout__header--waterfall', + HEADER_SCROLL: 'mdl-layout__header--scroll', + FIXED_HEADER: 'mdl-layout--fixed-header', + OBFUSCATOR: 'mdl-layout__obfuscator', + TAB_BAR: 'mdl-layout__tab-bar', + TAB_CONTAINER: 'mdl-layout__tab-bar-container', + TAB: 'mdl-layout__tab', + TAB_BAR_BUTTON: 'mdl-layout__tab-bar-button', + TAB_BAR_LEFT_BUTTON: 'mdl-layout__tab-bar-left-button', + TAB_BAR_RIGHT_BUTTON: 'mdl-layout__tab-bar-right-button', + TAB_MANUAL_SWITCH: 'mdl-layout__tab-manual-switch', + PANEL: 'mdl-layout__tab-panel', + HAS_DRAWER: 'has-drawer', + HAS_TABS: 'has-tabs', + HAS_SCROLLING_HEADER: 'has-scrolling-header', + CASTING_SHADOW: 'is-casting-shadow', + IS_COMPACT: 'is-compact', + IS_SMALL_SCREEN: 'is-small-screen', + IS_DRAWER_OPEN: 'is-visible', + IS_ACTIVE: 'is-active', + IS_UPGRADED: 'is-upgraded', + IS_ANIMATING: 'is-animating', + ON_LARGE_SCREEN: 'mdl-layout--large-screen-only', + ON_SMALL_SCREEN: 'mdl-layout--small-screen-only' + }; + /** + * Handles scrolling on the content. + * + * @private + */ + MaterialLayout.prototype.contentScrollHandler_ = function () { + if (this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)) { + return; + } + var headerVisible = !this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN) || this.element_.classList.contains(this.CssClasses_.FIXED_HEADER); + if (this.content_.scrollTop > 0 && !this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) { + this.header_.classList.add(this.CssClasses_.CASTING_SHADOW); + this.header_.classList.add(this.CssClasses_.IS_COMPACT); + if (headerVisible) { + this.header_.classList.add(this.CssClasses_.IS_ANIMATING); + } + } else if (this.content_.scrollTop <= 0 && this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) { + this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW); + this.header_.classList.remove(this.CssClasses_.IS_COMPACT); + if (headerVisible) { + this.header_.classList.add(this.CssClasses_.IS_ANIMATING); + } + } + }; + /** + * Handles a keyboard event on the drawer. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialLayout.prototype.keyboardEventHandler_ = function (evt) { + // Only react when the drawer is open. + if (evt.keyCode === this.Keycodes_.ESCAPE && this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) { + this.toggleDrawer(); + } + }; + /** + * Handles changes in screen size. + * + * @private + */ + MaterialLayout.prototype.screenSizeHandler_ = function () { + if (this.screenSizeMediaQuery_.matches) { + this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN); + } else { + this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN); + // Collapse drawer (if any) when moving to a large screen size. + if (this.drawer_) { + this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN); + this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN); + } + } + }; + /** + * Handles events of drawer button. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialLayout.prototype.drawerToggleHandler_ = function (evt) { + if (evt && evt.type === 'keydown') { + if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) { + // prevent scrolling in drawer nav + evt.preventDefault(); + } else { + // prevent other keys + return; + } + } + this.toggleDrawer(); + }; + /** + * Handles (un)setting the `is-animating` class + * + * @private + */ + MaterialLayout.prototype.headerTransitionEndHandler_ = function () { + this.header_.classList.remove(this.CssClasses_.IS_ANIMATING); + }; + /** + * Handles expanding the header on click + * + * @private + */ + MaterialLayout.prototype.headerClickHandler_ = function () { + if (this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) { + this.header_.classList.remove(this.CssClasses_.IS_COMPACT); + this.header_.classList.add(this.CssClasses_.IS_ANIMATING); + } + }; + /** + * Reset tab state, dropping active classes + * + * @private + */ + MaterialLayout.prototype.resetTabState_ = function (tabBar) { + for (var k = 0; k < tabBar.length; k++) { + tabBar[k].classList.remove(this.CssClasses_.IS_ACTIVE); + } + }; + /** + * Reset panel state, droping active classes + * + * @private + */ + MaterialLayout.prototype.resetPanelState_ = function (panels) { + for (var j = 0; j < panels.length; j++) { + panels[j].classList.remove(this.CssClasses_.IS_ACTIVE); + } + }; + /** + * Toggle drawer state + * + * @public + */ + MaterialLayout.prototype.toggleDrawer = function () { + var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN); + this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN); + this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN); + // Set accessibility properties. + if (this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) { + this.drawer_.setAttribute('aria-hidden', 'false'); + drawerButton.setAttribute('aria-expanded', 'true'); + } else { + this.drawer_.setAttribute('aria-hidden', 'true'); + drawerButton.setAttribute('aria-expanded', 'false'); + } + }; + MaterialLayout.prototype['toggleDrawer'] = MaterialLayout.prototype.toggleDrawer; + /** + * Initialize element. + */ + MaterialLayout.prototype.init = function () { + if (this.element_) { + var container = document.createElement('div'); + container.classList.add(this.CssClasses_.CONTAINER); + var focusedElement = this.element_.querySelector(':focus'); + this.element_.parentElement.insertBefore(container, this.element_); + this.element_.parentElement.removeChild(this.element_); + container.appendChild(this.element_); + if (focusedElement) { + focusedElement.focus(); + } + var directChildren = this.element_.childNodes; + var numChildren = directChildren.length; + for (var c = 0; c < numChildren; c++) { + var child = directChildren[c]; + if (child.classList && child.classList.contains(this.CssClasses_.HEADER)) { + this.header_ = child; + } + if (child.classList && child.classList.contains(this.CssClasses_.DRAWER)) { + this.drawer_ = child; + } + if (child.classList && child.classList.contains(this.CssClasses_.CONTENT)) { + this.content_ = child; + } + } + window.addEventListener('pageshow', function (e) { + if (e.persisted) { + // when page is loaded from back/forward cache + // trigger repaint to let layout scroll in safari + this.element_.style.overflowY = 'hidden'; + requestAnimationFrame(function () { + this.element_.style.overflowY = ''; + }.bind(this)); + } + }.bind(this), false); + if (this.header_) { + this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR); + } + var mode = this.Mode_.STANDARD; + if (this.header_) { + if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) { + mode = this.Mode_.SEAMED; + } else if (this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)) { + mode = this.Mode_.WATERFALL; + this.header_.addEventListener('transitionend', this.headerTransitionEndHandler_.bind(this)); + this.header_.addEventListener('click', this.headerClickHandler_.bind(this)); + } else if (this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)) { + mode = this.Mode_.SCROLL; + container.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER); + } + if (mode === this.Mode_.STANDARD) { + this.header_.classList.add(this.CssClasses_.CASTING_SHADOW); + if (this.tabBar_) { + this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW); + } + } else if (mode === this.Mode_.SEAMED || mode === this.Mode_.SCROLL) { + this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW); + if (this.tabBar_) { + this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW); + } + } else if (mode === this.Mode_.WATERFALL) { + // Add and remove shadows depending on scroll position. + // Also add/remove auxiliary class for styling of the compact version of + // the header. + this.content_.addEventListener('scroll', this.contentScrollHandler_.bind(this)); + this.contentScrollHandler_(); + } + } + // Add drawer toggling button to our layout, if we have an openable drawer. + if (this.drawer_) { + var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN); + if (!drawerButton) { + drawerButton = document.createElement('div'); + drawerButton.setAttribute('aria-expanded', 'false'); + drawerButton.setAttribute('role', 'button'); + drawerButton.setAttribute('tabindex', '0'); + drawerButton.classList.add(this.CssClasses_.DRAWER_BTN); + var drawerButtonIcon = document.createElement('i'); + drawerButtonIcon.classList.add(this.CssClasses_.ICON); + drawerButtonIcon.innerHTML = this.Constant_.MENU_ICON; + drawerButton.appendChild(drawerButtonIcon); + } + if (this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)) { + //If drawer has ON_LARGE_SCREEN class then add it to the drawer toggle button as well. + drawerButton.classList.add(this.CssClasses_.ON_LARGE_SCREEN); + } else if (this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)) { + //If drawer has ON_SMALL_SCREEN class then add it to the drawer toggle button as well. + drawerButton.classList.add(this.CssClasses_.ON_SMALL_SCREEN); + } + drawerButton.addEventListener('click', this.drawerToggleHandler_.bind(this)); + drawerButton.addEventListener('keydown', this.drawerToggleHandler_.bind(this)); + // Add a class if the layout has a drawer, for altering the left padding. + // Adds the HAS_DRAWER to the elements since this.header_ may or may + // not be present. + this.element_.classList.add(this.CssClasses_.HAS_DRAWER); + // If we have a fixed header, add the button to the header rather than + // the layout. + if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) { + this.header_.insertBefore(drawerButton, this.header_.firstChild); + } else { + this.element_.insertBefore(drawerButton, this.content_); + } + var obfuscator = document.createElement('div'); + obfuscator.classList.add(this.CssClasses_.OBFUSCATOR); + this.element_.appendChild(obfuscator); + obfuscator.addEventListener('click', this.drawerToggleHandler_.bind(this)); + this.obfuscator_ = obfuscator; + this.drawer_.addEventListener('keydown', this.keyboardEventHandler_.bind(this)); + this.drawer_.setAttribute('aria-hidden', 'true'); + } + // Keep an eye on screen size, and add/remove auxiliary class for styling + // of small screens. + this.screenSizeMediaQuery_ = window.matchMedia(this.Constant_.MAX_WIDTH); + this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this)); + this.screenSizeHandler_(); + // Initialize tabs, if any. + if (this.header_ && this.tabBar_) { + this.element_.classList.add(this.CssClasses_.HAS_TABS); + var tabContainer = document.createElement('div'); + tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER); + this.header_.insertBefore(tabContainer, this.tabBar_); + this.header_.removeChild(this.tabBar_); + var leftButton = document.createElement('div'); + leftButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON); + leftButton.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON); + var leftButtonIcon = document.createElement('i'); + leftButtonIcon.classList.add(this.CssClasses_.ICON); + leftButtonIcon.textContent = this.Constant_.CHEVRON_LEFT; + leftButton.appendChild(leftButtonIcon); + leftButton.addEventListener('click', function () { + this.tabBar_.scrollLeft -= this.Constant_.TAB_SCROLL_PIXELS; + }.bind(this)); + var rightButton = document.createElement('div'); + rightButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON); + rightButton.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON); + var rightButtonIcon = document.createElement('i'); + rightButtonIcon.classList.add(this.CssClasses_.ICON); + rightButtonIcon.textContent = this.Constant_.CHEVRON_RIGHT; + rightButton.appendChild(rightButtonIcon); + rightButton.addEventListener('click', function () { + this.tabBar_.scrollLeft += this.Constant_.TAB_SCROLL_PIXELS; + }.bind(this)); + tabContainer.appendChild(leftButton); + tabContainer.appendChild(this.tabBar_); + tabContainer.appendChild(rightButton); + // Add and remove tab buttons depending on scroll position and total + // window size. + var tabUpdateHandler = function () { + if (this.tabBar_.scrollLeft > 0) { + leftButton.classList.add(this.CssClasses_.IS_ACTIVE); + } else { + leftButton.classList.remove(this.CssClasses_.IS_ACTIVE); + } + if (this.tabBar_.scrollLeft < this.tabBar_.scrollWidth - this.tabBar_.offsetWidth) { + rightButton.classList.add(this.CssClasses_.IS_ACTIVE); + } else { + rightButton.classList.remove(this.CssClasses_.IS_ACTIVE); + } + }.bind(this); + this.tabBar_.addEventListener('scroll', tabUpdateHandler); + tabUpdateHandler(); + // Update tabs when the window resizes. + var windowResizeHandler = function () { + // Use timeouts to make sure it doesn't happen too often. + if (this.resizeTimeoutId_) { + clearTimeout(this.resizeTimeoutId_); + } + this.resizeTimeoutId_ = setTimeout(function () { + tabUpdateHandler(); + this.resizeTimeoutId_ = null; + }.bind(this), this.Constant_.RESIZE_TIMEOUT); + }.bind(this); + window.addEventListener('resize', windowResizeHandler); + if (this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) { + this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + } + // Select element tabs, document panels + var tabs = this.tabBar_.querySelectorAll('.' + this.CssClasses_.TAB); + var panels = this.content_.querySelectorAll('.' + this.CssClasses_.PANEL); + // Create new tabs for each tab element + for (var i = 0; i < tabs.length; i++) { + new MaterialLayoutTab(tabs[i], tabs, panels, this); + } + } + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + } + }; + + /** + * Constructor for an individual tab. + * + * @constructor + * @param {HTMLElement} tab The HTML element for the tab. + * @param {!Array<HTMLElement>} tabs Array with HTML elements for all tabs. + * @param {!Array<HTMLElement>} panels Array with HTML elements for all panels. + * @param {MaterialLayout} layout The MaterialLayout object that owns the tab. + */ + function MaterialLayoutTab(tab, tabs, panels, layout) { + /** + * Auxiliary method to programmatically select a tab in the UI. + */ + function selectTab() { + var href = tab.href.split('#')[1]; + var panel = layout.content_.querySelector('#' + href); + layout.resetTabState_(tabs); + layout.resetPanelState_(panels); + tab.classList.add(layout.CssClasses_.IS_ACTIVE); + panel.classList.add(layout.CssClasses_.IS_ACTIVE); + } + + if (layout.tabBar_.classList.contains(layout.CssClasses_.JS_RIPPLE_EFFECT)) { + var rippleContainer = document.createElement('span'); + rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER); + rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT); + var ripple = document.createElement('span'); + ripple.classList.add(layout.CssClasses_.RIPPLE); + rippleContainer.appendChild(ripple); + tab.appendChild(rippleContainer); + } + if (!layout.tabBar_.classList.contains(layout.CssClasses_.TAB_MANUAL_SWITCH)) { + tab.addEventListener('click', function (e) { + if (tab.getAttribute('href').charAt(0) === '#') { + e.preventDefault(); + selectTab(); + } + }); + } + tab.show = selectTab; + } + + window['MaterialLayoutTab'] = MaterialLayoutTab; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialLayout, + classAsString: 'MaterialLayout', + cssClass: 'mdl-js-layout' + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Data Table Card MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {Element} element The element that will be upgraded. + */ + var MaterialDataTable = function MaterialDataTable(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialDataTable'] = MaterialDataTable; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialDataTable.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialDataTable.prototype.CssClasses_ = { + DATA_TABLE: 'mdl-data-table', + SELECTABLE: 'mdl-data-table--selectable', + SELECT_ELEMENT: 'mdl-data-table__select', + IS_SELECTED: 'is-selected', + IS_UPGRADED: 'is-upgraded' + }; + /** + * Generates and returns a function that toggles the selection state of a + * single row (or multiple rows). + * + * @param {Element} checkbox Checkbox that toggles the selection state. + * @param {Element} row Row to toggle when checkbox changes. + * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes. + * @private + */ + MaterialDataTable.prototype.selectRow_ = function (checkbox, row, opt_rows) { + if (row) { + return function () { + if (checkbox.checked) { + row.classList.add(this.CssClasses_.IS_SELECTED); + } else { + row.classList.remove(this.CssClasses_.IS_SELECTED); + } + }.bind(this); + } + if (opt_rows) { + return function () { + var i; + var el; + if (checkbox.checked) { + for (i = 0; i < opt_rows.length; i++) { + el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox'); + el['MaterialCheckbox'].check(); + opt_rows[i].classList.add(this.CssClasses_.IS_SELECTED); + } + } else { + for (i = 0; i < opt_rows.length; i++) { + el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox'); + el['MaterialCheckbox'].uncheck(); + opt_rows[i].classList.remove(this.CssClasses_.IS_SELECTED); + } + } + }.bind(this); + } + }; + /** + * Creates a checkbox for a single or or multiple rows and hooks up the + * event handling. + * + * @param {Element} row Row to toggle when checkbox changes. + * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes. + * @private + */ + MaterialDataTable.prototype.createCheckbox_ = function (row, opt_rows) { + var label = document.createElement('label'); + var labelClasses = [ + 'mdl-checkbox', + 'mdl-js-checkbox', + 'mdl-js-ripple-effect', + this.CssClasses_.SELECT_ELEMENT + ]; + label.className = labelClasses.join(' '); + var checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + checkbox.classList.add('mdl-checkbox__input'); + if (row) { + checkbox.checked = row.classList.contains(this.CssClasses_.IS_SELECTED); + checkbox.addEventListener('change', this.selectRow_(checkbox, row)); + } else if (opt_rows) { + checkbox.addEventListener('change', this.selectRow_(checkbox, null, opt_rows)); + } + label.appendChild(checkbox); + componentHandler.upgradeElement(label, 'MaterialCheckbox'); + return label; + }; + /** + * Initialize element. + */ + MaterialDataTable.prototype.init = function () { + if (this.element_) { + var firstHeader = this.element_.querySelector('th'); + var bodyRows = Array.prototype.slice.call(this.element_.querySelectorAll('tbody tr')); + var footRows = Array.prototype.slice.call(this.element_.querySelectorAll('tfoot tr')); + var rows = bodyRows.concat(footRows); + if (this.element_.classList.contains(this.CssClasses_.SELECTABLE)) { + var th = document.createElement('th'); + var headerCheckbox = this.createCheckbox_(null, rows); + th.appendChild(headerCheckbox); + firstHeader.parentElement.insertBefore(th, firstHeader); + for (var i = 0; i < rows.length; i++) { + var firstCell = rows[i].querySelector('td'); + if (firstCell) { + var td = document.createElement('td'); + if (rows[i].parentNode.nodeName.toUpperCase() === 'TBODY') { + var rowCheckbox = this.createCheckbox_(rows[i]); + td.appendChild(rowCheckbox); + } + rows[i].insertBefore(td, firstCell); + } + } + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + } + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialDataTable, + classAsString: 'MaterialDataTable', + cssClass: 'mdl-js-data-table' + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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. + */ + /** + * Class constructor for Ripple MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialRipple = function MaterialRipple(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialRipple'] = MaterialRipple; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialRipple.prototype.Constant_ = { + INITIAL_SCALE: 'scale(0.0001, 0.0001)', + INITIAL_SIZE: '1px', + INITIAL_OPACITY: '0.4', + FINAL_OPACITY: '0', + FINAL_SCALE: '' + }; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialRipple.prototype.CssClasses_ = { + RIPPLE_CENTER: 'mdl-ripple--center', + RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE: 'mdl-ripple', + IS_ANIMATING: 'is-animating', + IS_VISIBLE: 'is-visible' + }; + /** + * Handle mouse / finger down on element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRipple.prototype.downHandler_ = function (event) { + if (!this.rippleElement_.style.width && !this.rippleElement_.style.height) { + var rect = this.element_.getBoundingClientRect(); + this.boundHeight = rect.height; + this.boundWidth = rect.width; + this.rippleSize_ = Math.sqrt(rect.width * rect.width + rect.height * rect.height) * 2 + 2; + this.rippleElement_.style.width = this.rippleSize_ + 'px'; + this.rippleElement_.style.height = this.rippleSize_ + 'px'; + } + this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE); + if (event.type === 'mousedown' && this.ignoringMouseDown_) { + this.ignoringMouseDown_ = false; + } else { + if (event.type === 'touchstart') { + this.ignoringMouseDown_ = true; + } + var frameCount = this.getFrameCount(); + if (frameCount > 0) { + return; + } + this.setFrameCount(1); + var bound = event.currentTarget.getBoundingClientRect(); + var x; + var y; + // Check if we are handling a keyboard click. + if (event.clientX === 0 && event.clientY === 0) { + x = Math.round(bound.width / 2); + y = Math.round(bound.height / 2); + } else { + var clientX = event.clientX !== undefined ? event.clientX : event.touches[0].clientX; + var clientY = event.clientY !== undefined ? event.clientY : event.touches[0].clientY; + x = Math.round(clientX - bound.left); + y = Math.round(clientY - bound.top); + } + this.setRippleXY(x, y); + this.setRippleStyles(true); + window.requestAnimationFrame(this.animFrameHandler.bind(this)); + } + }; + /** + * Handle mouse / finger up on element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRipple.prototype.upHandler_ = function (event) { + // Don't fire for the artificial "mouseup" generated by a double-click. + if (event && event.detail !== 2) { + // Allow a repaint to occur before removing this class, so the animation + // shows for tap events, which seem to trigger a mouseup too soon after + // mousedown. + window.setTimeout(function () { + this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE); + }.bind(this), 0); + } + }; + /** + * Initialize element. + */ + MaterialRipple.prototype.init = function () { + if (this.element_) { + var recentering = this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER); + if (!this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)) { + this.rippleElement_ = this.element_.querySelector('.' + this.CssClasses_.RIPPLE); + this.frameCount_ = 0; + this.rippleSize_ = 0; + this.x_ = 0; + this.y_ = 0; + // Touch start produces a compat mouse down event, which would cause a + // second ripples. To avoid that, we use this property to ignore the first + // mouse down after a touch start. + this.ignoringMouseDown_ = false; + this.boundDownHandler = this.downHandler_.bind(this); + this.element_.addEventListener('mousedown', this.boundDownHandler); + this.element_.addEventListener('touchstart', this.boundDownHandler); + this.boundUpHandler = this.upHandler_.bind(this); + this.element_.addEventListener('mouseup', this.boundUpHandler); + this.element_.addEventListener('mouseleave', this.boundUpHandler); + this.element_.addEventListener('touchend', this.boundUpHandler); + this.element_.addEventListener('blur', this.boundUpHandler); + /** + * Getter for frameCount_. + * @return {number} the frame count. + */ + this.getFrameCount = function () { + return this.frameCount_; + }; + /** + * Setter for frameCount_. + * @param {number} fC the frame count. + */ + this.setFrameCount = function (fC) { + this.frameCount_ = fC; + }; + /** + * Getter for rippleElement_. + * @return {Element} the ripple element. + */ + this.getRippleElement = function () { + return this.rippleElement_; + }; + /** + * Sets the ripple X and Y coordinates. + * @param {number} newX the new X coordinate + * @param {number} newY the new Y coordinate + */ + this.setRippleXY = function (newX, newY) { + this.x_ = newX; + this.y_ = newY; + }; + /** + * Sets the ripple styles. + * @param {boolean} start whether or not this is the start frame. + */ + this.setRippleStyles = function (start) { + if (this.rippleElement_ !== null) { + var transformString; + var scale; + var size; + var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)'; + if (start) { + scale = this.Constant_.INITIAL_SCALE; + size = this.Constant_.INITIAL_SIZE; + } else { + scale = this.Constant_.FINAL_SCALE; + size = this.rippleSize_ + 'px'; + if (recentering) { + offset = 'translate(' + this.boundWidth / 2 + 'px, ' + this.boundHeight / 2 + 'px)'; + } + } + transformString = 'translate(-50%, -50%) ' + offset + scale; + this.rippleElement_.style.webkitTransform = transformString; + this.rippleElement_.style.msTransform = transformString; + this.rippleElement_.style.transform = transformString; + if (start) { + this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING); + } else { + this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING); + } + } + }; + /** + * Handles an animation frame. + */ + this.animFrameHandler = function () { + if (this.frameCount_-- > 0) { + window.requestAnimationFrame(this.animFrameHandler.bind(this)); + } else { + this.setRippleStyles(false); + } + }; + } + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialRipple, + classAsString: 'MaterialRipple', + cssClass: 'mdl-js-ripple-effect', + widget: false + }); +}()); diff --git a/src/material.min.css b/src/material.min.css new file mode 100644 index 0000000..e0ba7eb --- /dev/null +++ b/src/material.min.css @@ -0,0 +1,9 @@ +/** + * material-design-lite - Material Design Components in CSS, JS and HTML + * @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%;margin:0}main{display:block}*[hidden]{display:none!important}html,body{font-family:"Roboto";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:#ff4081;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:#3f51b5 !important}.mdl-color--primary-contrast{background-color:#fff !important}.mdl-color--primary-dark{background-color:#303f9f !important}.mdl-color--accent{background-color:#ff4081 !important}.mdl-color--accent-contrast{background-color:#fff !important}.mdl-color-text--primary{color:#3f51b5 !important}.mdl-color-text--primary-contrast{color:#fff !important}.mdl-color-text--primary-dark{color:#303f9f !important}.mdl-color-text--accent{color:#ff4081 !important}.mdl-color-text--accent-contrast{color:#fff !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:#ff4081;color:#fff}.mdl-button .mdl-badge[data-badge]:after{top:-10px;right:-5px}.mdl-badge.mdl-badge--no-background[data-badge]:after{color:#ff4081;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:#3f51b5}.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:#3f51b5;color:#fff}.mdl-button--raised.mdl-button--colored:hover{background-color:#3f51b5}.mdl-button--raised.mdl-button--colored:active{background-color:#3f51b5}.mdl-button--raised.mdl-button--colored:focus:not(:active){background-color:#3f51b5}.mdl-button--raised.mdl-button--colored .mdl-ripple{background:#fff}.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:#ff4081;color:#fff}.mdl-button--fab.mdl-button--colored:hover{background-color:#ff4081}.mdl-button--fab.mdl-button--colored:focus:not(:active){background-color:#ff4081}.mdl-button--fab.mdl-button--colored:active{background-color:#ff4081}.mdl-button--fab.mdl-button--colored .mdl-ripple{background:#fff}.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:#3f51b5}.mdl-button--primary.mdl-button--primary .mdl-ripple{background:#fff}.mdl-button--primary.mdl-button--primary.mdl-button--raised,.mdl-button--primary.mdl-button--primary.mdl-button--fab{color:#fff;background-color:#3f51b5}.mdl-button--accent.mdl-button--accent{color:#ff4081}.mdl-button--accent.mdl-button--accent .mdl-ripple{background:#fff}.mdl-button--accent.mdl-button--accent.mdl-button--raised,.mdl-button--accent.mdl-button--accent.mdl-button--fab{color:#fff;background-color:#ff4081}.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:#ff4081;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 #3f51b5}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(63,81,181,.26);background-color:rgba(63,81,181,.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:#3f51b5 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:#3f51b5}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:#3f51b5}.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(63,81,181,.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:#3f51b5;z-index:1;left:0}.mdl-progress>.bufferbar{background-image:linear-gradient(to right,rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(to right,#3f51b5 ,#3f51b5);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(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(to right,#3f51b5 ,#3f51b5);-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(255,255,255,.9),rgba(255,255,255,.9)),linear-gradient(to right,#3f51b5 ,#3f51b5)}.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:#3f51b5;-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:#fff;z-index:4}.mdl-layout__header .mdl-layout__drawer-button{position:absolute;color:#fff;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:#3f51b5;color:#fff;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:black;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:#3f51b5;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:#3f51b5;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:#fff}.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(255,255,255,.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:#fff}.mdl-layout.is-upgraded .mdl-layout__tab.is-active::after{height:2px;width:100%;display:block;content:" ";bottom:0;left:0;position:absolute;background:#ff4081;-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:#fff}.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 #3f51b5}.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:#3f51b5}.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:#3f51b5}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:#3f51b5;-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,#3f51b5 16px,#3f51b5 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:#3f51b5;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:#3f51b5;border:none}.mdl-slider.is-upgraded:focus:not(:active)::-webkit-slider-thumb{box-shadow:0 0 0 10px rgba(63,81,181,.26)}.mdl-slider.is-upgraded:focus:not(:active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(63,81,181,.26)}.mdl-slider.is-upgraded:active::-webkit-slider-thumb{background-image:none;background:#3f51b5;-webkit-transform:scale(1.5);transform:scale(1.5)}.mdl-slider.is-upgraded:active::-moz-range-thumb{background-image:none;background:#3f51b5;transform:scale(1.5)}.mdl-slider.is-upgraded::-ms-thumb{width:32px;height:32px;border:none;border-radius:50%;background:#3f51b5;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,#3f51b5 0%,#3f51b5 37.5%,rgba(63,81,181,.26)37.5%,rgba(63,81,181,.26)100%);transform:scale(1)}.mdl-slider.is-upgraded:active::-ms-thumb{background:#3f51b5;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:#3f51b5}.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:#ff4081;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:#3f51b5}.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:#3f51b5}.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:#3f51b5}.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:#3f51b5}.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(63,81,181,.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:#3f51b5;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(63,81,181,.26);background-color:rgba(63,81,181,.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:#3f51b5}.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:#3f51b5;-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:#3f51b5}.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:"Roboto";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:#3f51b5;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:#3f51b5;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%}} +/*# sourceMappingURL=material.min.css.map */ diff --git a/src/material.min.js b/src/material.min.js new file mode 100644 index 0000000..46524fb --- /dev/null +++ b/src/material.min.js @@ -0,0 +1,10 @@ +/** + * material-design-lite - Material Design Components in CSS, JS and HTML + * @version v1.3.0 + * @license Apache-2.0 + * @copyright 2015 Google, Inc. + * @link https://github.com/google/material-design-lite + */ +!function(){"use strict";function e(e,t){if(e){if(t.element_.classList.contains(t.CssClasses_.MDL_JS_RIPPLE_EFFECT)){var s=document.createElement("span");s.classList.add(t.CssClasses_.MDL_RIPPLE_CONTAINER),s.classList.add(t.CssClasses_.MDL_JS_RIPPLE_EFFECT);var i=document.createElement("span");i.classList.add(t.CssClasses_.MDL_RIPPLE),s.appendChild(i),e.appendChild(s)}e.addEventListener("click",function(s){if("#"===e.getAttribute("href").charAt(0)){s.preventDefault();var i=e.href.split("#")[1],n=t.element_.querySelector("#"+i);t.resetTabState_(),t.resetPanelState_(),e.classList.add(t.CssClasses_.ACTIVE_CLASS),n.classList.add(t.CssClasses_.ACTIVE_CLASS)}})}}function t(e,t,s,i){function n(){var n=e.href.split("#")[1],a=i.content_.querySelector("#"+n);i.resetTabState_(t),i.resetPanelState_(s),e.classList.add(i.CssClasses_.IS_ACTIVE),a.classList.add(i.CssClasses_.IS_ACTIVE)}if(i.tabBar_.classList.contains(i.CssClasses_.JS_RIPPLE_EFFECT)){var a=document.createElement("span");a.classList.add(i.CssClasses_.RIPPLE_CONTAINER),a.classList.add(i.CssClasses_.JS_RIPPLE_EFFECT);var l=document.createElement("span");l.classList.add(i.CssClasses_.RIPPLE),a.appendChild(l),e.appendChild(a)}i.tabBar_.classList.contains(i.CssClasses_.TAB_MANUAL_SWITCH)||e.addEventListener("click",function(t){"#"===e.getAttribute("href").charAt(0)&&(t.preventDefault(),n())}),e.show=n}var s={upgradeDom:function(e,t){},upgradeElement:function(e,t){},upgradeElements:function(e){},upgradeAllRegistered:function(){},registerUpgradedCallback:function(e,t){},register:function(e){},downgradeElements:function(e){}};s=function(){function e(e,t){for(var s=0;s<c.length;s++)if(c[s].className===e)return"undefined"!=typeof t&&(c[s]=t),c[s];return!1}function t(e){var t=e.getAttribute("data-upgraded");return null===t?[""]:t.split(",")}function s(e,s){var i=t(e);return i.indexOf(s)!==-1}function i(e,t,s){if("CustomEvent"in window&&"function"==typeof window.CustomEvent)return new CustomEvent(e,{bubbles:t,cancelable:s});var i=document.createEvent("Events");return i.initEvent(e,t,s),i}function n(t,s){if("undefined"==typeof t&&"undefined"==typeof s)for(var i=0;i<c.length;i++)n(c[i].className,c[i].cssClass);else{var l=t;if("undefined"==typeof s){var o=e(l);o&&(s=o.cssClass)}for(var r=document.querySelectorAll("."+s),_=0;_<r.length;_++)a(r[_],l)}}function a(n,a){if(!("object"==typeof n&&n instanceof Element))throw new Error("Invalid argument provided to upgrade MDL element.");var l=i("mdl-componentupgrading",!0,!0);if(n.dispatchEvent(l),!l.defaultPrevented){var o=t(n),r=[];if(a)s(n,a)||r.push(e(a));else{var _=n.classList;c.forEach(function(e){_.contains(e.cssClass)&&r.indexOf(e)===-1&&!s(n,e.className)&&r.push(e)})}for(var d,h=0,u=r.length;h<u;h++){if(d=r[h],!d)throw new Error("Unable to find a registered component for the given class.");o.push(d.className),n.setAttribute("data-upgraded",o.join(","));var E=new d.classConstructor(n);E[C]=d,p.push(E);for(var m=0,L=d.callbacks.length;m<L;m++)d.callbacks[m](n);d.widget&&(n[d.className]=E);var I=i("mdl-componentupgraded",!0,!1);n.dispatchEvent(I)}}}function l(e){Array.isArray(e)||(e=e instanceof Element?[e]:Array.prototype.slice.call(e));for(var t,s=0,i=e.length;s<i;s++)t=e[s],t instanceof HTMLElement&&(a(t),t.children.length>0&&l(t.children))}function o(t){var s="undefined"==typeof t.widget&&"undefined"==typeof t.widget,i=!0;s||(i=t.widget||t.widget);var n={classConstructor:t.constructor||t.constructor,className:t.classAsString||t.classAsString,cssClass:t.cssClass||t.cssClass,widget:i,callbacks:[]};if(c.forEach(function(e){if(e.cssClass===n.cssClass)throw new Error("The provided cssClass has already been registered: "+e.cssClass);if(e.className===n.className)throw new Error("The provided className has already been registered")}),t.constructor.prototype.hasOwnProperty(C))throw new Error("MDL component classes must not have "+C+" defined as a property.");var a=e(t.classAsString,n);a||c.push(n)}function r(t,s){var i=e(t);i&&i.callbacks.push(s)}function _(){for(var e=0;e<c.length;e++)n(c[e].className)}function d(e){if(e){var t=p.indexOf(e);p.splice(t,1);var s=e.element_.getAttribute("data-upgraded").split(","),n=s.indexOf(e[C].classAsString);s.splice(n,1),e.element_.setAttribute("data-upgraded",s.join(","));var a=i("mdl-componentdowngraded",!0,!1);e.element_.dispatchEvent(a)}}function h(e){var t=function(e){p.filter(function(t){return t.element_===e}).forEach(d)};if(e instanceof Array||e instanceof NodeList)for(var s=0;s<e.length;s++)t(e[s]);else{if(!(e instanceof Node))throw new Error("Invalid argument provided to downgrade MDL nodes.");t(e)}}var c=[],p=[],C="mdlComponentConfigInternal_";return{upgradeDom:n,upgradeElement:a,upgradeElements:l,upgradeAllRegistered:_,registerUpgradedCallback:r,register:o,downgradeElements:h}}(),s.ComponentConfigPublic,s.ComponentConfig,s.Component,s.upgradeDom=s.upgradeDom,s.upgradeElement=s.upgradeElement,s.upgradeElements=s.upgradeElements,s.upgradeAllRegistered=s.upgradeAllRegistered,s.registerUpgradedCallback=s.registerUpgradedCallback,s.register=s.register,s.downgradeElements=s.downgradeElements,window.componentHandler=s,window.componentHandler=s,window.addEventListener("load",function(){"classList"in document.createElement("div")&&"querySelector"in document&&"addEventListener"in window&&Array.prototype.forEach?(document.documentElement.classList.add("mdl-js"),s.upgradeAllRegistered()):(s.upgradeElement=function(){},s.register=function(){})}),Date.now||(Date.now=function(){return(new Date).getTime()},Date.now=Date.now);for(var i=["webkit","moz"],n=0;n<i.length&&!window.requestAnimationFrame;++n){var a=i[n];window.requestAnimationFrame=window[a+"RequestAnimationFrame"],window.cancelAnimationFrame=window[a+"CancelAnimationFrame"]||window[a+"CancelRequestAnimationFrame"],window.requestAnimationFrame=window.requestAnimationFrame,window.cancelAnimationFrame=window.cancelAnimationFrame}if(/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent)||!window.requestAnimationFrame||!window.cancelAnimationFrame){var l=0;window.requestAnimationFrame=function(e){var t=Date.now(),s=Math.max(l+16,t);return setTimeout(function(){e(l=s)},s-t)},window.cancelAnimationFrame=clearTimeout,window.requestAnimationFrame=window.requestAnimationFrame,window.cancelAnimationFrame=window.cancelAnimationFrame}var o=function(e){this.element_=e,this.init()};window.MaterialButton=o,o.prototype.Constant_={},o.prototype.CssClasses_={RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_CONTAINER:"mdl-button__ripple-container",RIPPLE:"mdl-ripple"},o.prototype.blurHandler_=function(e){e&&this.element_.blur()},o.prototype.disable=function(){this.element_.disabled=!0},o.prototype.disable=o.prototype.disable,o.prototype.enable=function(){this.element_.disabled=!1},o.prototype.enable=o.prototype.enable,o.prototype.init=function(){if(this.element_){if(this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)){var e=document.createElement("span");e.classList.add(this.CssClasses_.RIPPLE_CONTAINER),this.rippleElement_=document.createElement("span"),this.rippleElement_.classList.add(this.CssClasses_.RIPPLE),e.appendChild(this.rippleElement_),this.boundRippleBlurHandler=this.blurHandler_.bind(this),this.rippleElement_.addEventListener("mouseup",this.boundRippleBlurHandler),this.element_.appendChild(e)}this.boundButtonBlurHandler=this.blurHandler_.bind(this),this.element_.addEventListener("mouseup",this.boundButtonBlurHandler),this.element_.addEventListener("mouseleave",this.boundButtonBlurHandler)}},s.register({constructor:o,classAsString:"MaterialButton",cssClass:"mdl-js-button",widget:!0});var r=function(e){this.element_=e,this.init()};window.MaterialCheckbox=r,r.prototype.Constant_={TINY_TIMEOUT:.001},r.prototype.CssClasses_={INPUT:"mdl-checkbox__input",BOX_OUTLINE:"mdl-checkbox__box-outline",FOCUS_HELPER:"mdl-checkbox__focus-helper",TICK_OUTLINE:"mdl-checkbox__tick-outline",RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE_CONTAINER:"mdl-checkbox__ripple-container",RIPPLE_CENTER:"mdl-ripple--center",RIPPLE:"mdl-ripple",IS_FOCUSED:"is-focused",IS_DISABLED:"is-disabled",IS_CHECKED:"is-checked",IS_UPGRADED:"is-upgraded"},r.prototype.onChange_=function(e){this.updateClasses_()},r.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},r.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},r.prototype.onMouseUp_=function(e){this.blur_()},r.prototype.updateClasses_=function(){this.checkDisabled(),this.checkToggleState()},r.prototype.blur_=function(){window.setTimeout(function(){this.inputElement_.blur()}.bind(this),this.Constant_.TINY_TIMEOUT)},r.prototype.checkToggleState=function(){this.inputElement_.checked?this.element_.classList.add(this.CssClasses_.IS_CHECKED):this.element_.classList.remove(this.CssClasses_.IS_CHECKED)},r.prototype.checkToggleState=r.prototype.checkToggleState,r.prototype.checkDisabled=function(){this.inputElement_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},r.prototype.checkDisabled=r.prototype.checkDisabled,r.prototype.disable=function(){this.inputElement_.disabled=!0,this.updateClasses_()},r.prototype.disable=r.prototype.disable,r.prototype.enable=function(){this.inputElement_.disabled=!1,this.updateClasses_()},r.prototype.enable=r.prototype.enable,r.prototype.check=function(){this.inputElement_.checked=!0,this.updateClasses_()},r.prototype.check=r.prototype.check,r.prototype.uncheck=function(){this.inputElement_.checked=!1,this.updateClasses_()},r.prototype.uncheck=r.prototype.uncheck,r.prototype.init=function(){if(this.element_){this.inputElement_=this.element_.querySelector("."+this.CssClasses_.INPUT);var e=document.createElement("span");e.classList.add(this.CssClasses_.BOX_OUTLINE);var t=document.createElement("span");t.classList.add(this.CssClasses_.FOCUS_HELPER);var s=document.createElement("span");if(s.classList.add(this.CssClasses_.TICK_OUTLINE),e.appendChild(s),this.element_.appendChild(t),this.element_.appendChild(e),this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)){this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS),this.rippleContainerElement_=document.createElement("span"),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER),this.boundRippleMouseUp=this.onMouseUp_.bind(this),this.rippleContainerElement_.addEventListener("mouseup",this.boundRippleMouseUp);var i=document.createElement("span");i.classList.add(this.CssClasses_.RIPPLE),this.rippleContainerElement_.appendChild(i),this.element_.appendChild(this.rippleContainerElement_)}this.boundInputOnChange=this.onChange_.bind(this),this.boundInputOnFocus=this.onFocus_.bind(this),this.boundInputOnBlur=this.onBlur_.bind(this),this.boundElementMouseUp=this.onMouseUp_.bind(this),this.inputElement_.addEventListener("change",this.boundInputOnChange),this.inputElement_.addEventListener("focus",this.boundInputOnFocus),this.inputElement_.addEventListener("blur",this.boundInputOnBlur),this.element_.addEventListener("mouseup",this.boundElementMouseUp),this.updateClasses_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED)}},s.register({constructor:r,classAsString:"MaterialCheckbox",cssClass:"mdl-js-checkbox",widget:!0});var _=function(e){this.element_=e,this.init()};window.MaterialIconToggle=_,_.prototype.Constant_={TINY_TIMEOUT:.001},_.prototype.CssClasses_={INPUT:"mdl-icon-toggle__input",JS_RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE_CONTAINER:"mdl-icon-toggle__ripple-container",RIPPLE_CENTER:"mdl-ripple--center",RIPPLE:"mdl-ripple",IS_FOCUSED:"is-focused",IS_DISABLED:"is-disabled",IS_CHECKED:"is-checked"},_.prototype.onChange_=function(e){this.updateClasses_()},_.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},_.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},_.prototype.onMouseUp_=function(e){this.blur_()},_.prototype.updateClasses_=function(){this.checkDisabled(),this.checkToggleState()},_.prototype.blur_=function(){window.setTimeout(function(){this.inputElement_.blur()}.bind(this),this.Constant_.TINY_TIMEOUT)},_.prototype.checkToggleState=function(){this.inputElement_.checked?this.element_.classList.add(this.CssClasses_.IS_CHECKED):this.element_.classList.remove(this.CssClasses_.IS_CHECKED)},_.prototype.checkToggleState=_.prototype.checkToggleState,_.prototype.checkDisabled=function(){this.inputElement_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},_.prototype.checkDisabled=_.prototype.checkDisabled,_.prototype.disable=function(){this.inputElement_.disabled=!0,this.updateClasses_()},_.prototype.disable=_.prototype.disable,_.prototype.enable=function(){this.inputElement_.disabled=!1,this.updateClasses_()},_.prototype.enable=_.prototype.enable,_.prototype.check=function(){this.inputElement_.checked=!0,this.updateClasses_()},_.prototype.check=_.prototype.check,_.prototype.uncheck=function(){this.inputElement_.checked=!1,this.updateClasses_()},_.prototype.uncheck=_.prototype.uncheck,_.prototype.init=function(){if(this.element_){if(this.inputElement_=this.element_.querySelector("."+this.CssClasses_.INPUT),this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)){this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS),this.rippleContainerElement_=document.createElement("span"),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER),this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER),this.boundRippleMouseUp=this.onMouseUp_.bind(this),this.rippleContainerElement_.addEventListener("mouseup",this.boundRippleMouseUp);var e=document.createElement("span");e.classList.add(this.CssClasses_.RIPPLE),this.rippleContainerElement_.appendChild(e),this.element_.appendChild(this.rippleContainerElement_)}this.boundInputOnChange=this.onChange_.bind(this),this.boundInputOnFocus=this.onFocus_.bind(this),this.boundInputOnBlur=this.onBlur_.bind(this),this.boundElementOnMouseUp=this.onMouseUp_.bind(this),this.inputElement_.addEventListener("change",this.boundInputOnChange),this.inputElement_.addEventListener("focus",this.boundInputOnFocus),this.inputElement_.addEventListener("blur",this.boundInputOnBlur),this.element_.addEventListener("mouseup",this.boundElementOnMouseUp),this.updateClasses_(),this.element_.classList.add("is-upgraded")}},s.register({constructor:_,classAsString:"MaterialIconToggle",cssClass:"mdl-js-icon-toggle",widget:!0});var d=function(e){this.element_=e,this.init()};window.MaterialMenu=d,d.prototype.Constant_={TRANSITION_DURATION_SECONDS:.3,TRANSITION_DURATION_FRACTION:.8,CLOSE_TIMEOUT:150},d.prototype.Keycodes_={ENTER:13,ESCAPE:27,SPACE:32,UP_ARROW:38,DOWN_ARROW:40},d.prototype.CssClasses_={CONTAINER:"mdl-menu__container",OUTLINE:"mdl-menu__outline",ITEM:"mdl-menu__item",ITEM_RIPPLE_CONTAINER:"mdl-menu__item-ripple-container",RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE:"mdl-ripple",IS_UPGRADED:"is-upgraded",IS_VISIBLE:"is-visible",IS_ANIMATING:"is-animating",BOTTOM_LEFT:"mdl-menu--bottom-left",BOTTOM_RIGHT:"mdl-menu--bottom-right",TOP_LEFT:"mdl-menu--top-left",TOP_RIGHT:"mdl-menu--top-right",UNALIGNED:"mdl-menu--unaligned"},d.prototype.init=function(){if(this.element_){var e=document.createElement("div");e.classList.add(this.CssClasses_.CONTAINER),this.element_.parentElement.insertBefore(e,this.element_),this.element_.parentElement.removeChild(this.element_),e.appendChild(this.element_),this.container_=e;var t=document.createElement("div");t.classList.add(this.CssClasses_.OUTLINE),this.outline_=t,e.insertBefore(t,this.element_);var s=this.element_.getAttribute("for")||this.element_.getAttribute("data-mdl-for"),i=null;s&&(i=document.getElementById(s),i&&(this.forElement_=i,i.addEventListener("click",this.handleForClick_.bind(this)),i.addEventListener("keydown",this.handleForKeyboardEvent_.bind(this))));var n=this.element_.querySelectorAll("."+this.CssClasses_.ITEM);this.boundItemKeydown_=this.handleItemKeyboardEvent_.bind(this),this.boundItemClick_=this.handleItemClick_.bind(this);for(var a=0;a<n.length;a++)n[a].addEventListener("click",this.boundItemClick_),n[a].tabIndex="-1",n[a].addEventListener("keydown",this.boundItemKeydown_);if(this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT))for(this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS),a=0;a<n.length;a++){var l=n[a],o=document.createElement("span");o.classList.add(this.CssClasses_.ITEM_RIPPLE_CONTAINER);var r=document.createElement("span");r.classList.add(this.CssClasses_.RIPPLE),o.appendChild(r),l.appendChild(o),l.classList.add(this.CssClasses_.RIPPLE_EFFECT)}this.element_.classList.contains(this.CssClasses_.BOTTOM_LEFT)&&this.outline_.classList.add(this.CssClasses_.BOTTOM_LEFT),this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)&&this.outline_.classList.add(this.CssClasses_.BOTTOM_RIGHT),this.element_.classList.contains(this.CssClasses_.TOP_LEFT)&&this.outline_.classList.add(this.CssClasses_.TOP_LEFT),this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)&&this.outline_.classList.add(this.CssClasses_.TOP_RIGHT),this.element_.classList.contains(this.CssClasses_.UNALIGNED)&&this.outline_.classList.add(this.CssClasses_.UNALIGNED),e.classList.add(this.CssClasses_.IS_UPGRADED)}},d.prototype.handleForClick_=function(e){if(this.element_&&this.forElement_){var t=this.forElement_.getBoundingClientRect(),s=this.forElement_.parentElement.getBoundingClientRect();this.element_.classList.contains(this.CssClasses_.UNALIGNED)||(this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)?(this.container_.style.right=s.right-t.right+"px",this.container_.style.top=this.forElement_.offsetTop+this.forElement_.offsetHeight+"px"):this.element_.classList.contains(this.CssClasses_.TOP_LEFT)?(this.container_.style.left=this.forElement_.offsetLeft+"px",this.container_.style.bottom=s.bottom-t.top+"px"):this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)?(this.container_.style.right=s.right-t.right+"px",this.container_.style.bottom=s.bottom-t.top+"px"):(this.container_.style.left=this.forElement_.offsetLeft+"px",this.container_.style.top=this.forElement_.offsetTop+this.forElement_.offsetHeight+"px"))}this.toggle(e)},d.prototype.handleForKeyboardEvent_=function(e){if(this.element_&&this.container_&&this.forElement_){var t=this.element_.querySelectorAll("."+this.CssClasses_.ITEM+":not([disabled])");t&&t.length>0&&this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)&&(e.keyCode===this.Keycodes_.UP_ARROW?(e.preventDefault(),t[t.length-1].focus()):e.keyCode===this.Keycodes_.DOWN_ARROW&&(e.preventDefault(),t[0].focus()))}},d.prototype.handleItemKeyboardEvent_=function(e){if(this.element_&&this.container_){var t=this.element_.querySelectorAll("."+this.CssClasses_.ITEM+":not([disabled])");if(t&&t.length>0&&this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)){var s=Array.prototype.slice.call(t).indexOf(e.target);if(e.keyCode===this.Keycodes_.UP_ARROW)e.preventDefault(),s>0?t[s-1].focus():t[t.length-1].focus();else if(e.keyCode===this.Keycodes_.DOWN_ARROW)e.preventDefault(),t.length>s+1?t[s+1].focus():t[0].focus();else if(e.keyCode===this.Keycodes_.SPACE||e.keyCode===this.Keycodes_.ENTER){e.preventDefault();var i=new MouseEvent("mousedown");e.target.dispatchEvent(i),i=new MouseEvent("mouseup"),e.target.dispatchEvent(i),e.target.click()}else e.keyCode===this.Keycodes_.ESCAPE&&(e.preventDefault(),this.hide())}}},d.prototype.handleItemClick_=function(e){e.target.hasAttribute("disabled")?e.stopPropagation():(this.closing_=!0,window.setTimeout(function(e){this.hide(),this.closing_=!1}.bind(this),this.Constant_.CLOSE_TIMEOUT))},d.prototype.applyClip_=function(e,t){this.element_.classList.contains(this.CssClasses_.UNALIGNED)?this.element_.style.clip="":this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)?this.element_.style.clip="rect(0 "+t+"px 0 "+t+"px)":this.element_.classList.contains(this.CssClasses_.TOP_LEFT)?this.element_.style.clip="rect("+e+"px 0 "+e+"px 0)":this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)?this.element_.style.clip="rect("+e+"px "+t+"px "+e+"px "+t+"px)":this.element_.style.clip=""},d.prototype.removeAnimationEndListener_=function(e){e.target.classList.remove(d.prototype.CssClasses_.IS_ANIMATING)},d.prototype.addAnimationEndListener_=function(){this.element_.addEventListener("transitionend",this.removeAnimationEndListener_),this.element_.addEventListener("webkitTransitionEnd",this.removeAnimationEndListener_)},d.prototype.show=function(e){if(this.element_&&this.container_&&this.outline_){var t=this.element_.getBoundingClientRect().height,s=this.element_.getBoundingClientRect().width;this.container_.style.width=s+"px",this.container_.style.height=t+"px",this.outline_.style.width=s+"px",this.outline_.style.height=t+"px";for(var i=this.Constant_.TRANSITION_DURATION_SECONDS*this.Constant_.TRANSITION_DURATION_FRACTION,n=this.element_.querySelectorAll("."+this.CssClasses_.ITEM),a=0;a<n.length;a++){var l=null;l=this.element_.classList.contains(this.CssClasses_.TOP_LEFT)||this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)?(t-n[a].offsetTop-n[a].offsetHeight)/t*i+"s":n[a].offsetTop/t*i+"s",n[a].style.transitionDelay=l}this.applyClip_(t,s),window.requestAnimationFrame(function(){this.element_.classList.add(this.CssClasses_.IS_ANIMATING),this.element_.style.clip="rect(0 "+s+"px "+t+"px 0)",this.container_.classList.add(this.CssClasses_.IS_VISIBLE)}.bind(this)),this.addAnimationEndListener_();var o=function(t){t===e||this.closing_||t.target.parentNode===this.element_||(document.removeEventListener("click",o),this.hide())}.bind(this);document.addEventListener("click",o)}},d.prototype.show=d.prototype.show,d.prototype.hide=function(){if(this.element_&&this.container_&&this.outline_){for(var e=this.element_.querySelectorAll("."+this.CssClasses_.ITEM),t=0;t<e.length;t++)e[t].style.removeProperty("transition-delay");var s=this.element_.getBoundingClientRect(),i=s.height,n=s.width;this.element_.classList.add(this.CssClasses_.IS_ANIMATING),this.applyClip_(i,n),this.container_.classList.remove(this.CssClasses_.IS_VISIBLE),this.addAnimationEndListener_()}},d.prototype.hide=d.prototype.hide,d.prototype.toggle=function(e){this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)?this.hide():this.show(e)},d.prototype.toggle=d.prototype.toggle,s.register({constructor:d,classAsString:"MaterialMenu",cssClass:"mdl-js-menu",widget:!0});var h=function(e){this.element_=e,this.init()};window.MaterialProgress=h,h.prototype.Constant_={},h.prototype.CssClasses_={INDETERMINATE_CLASS:"mdl-progress__indeterminate"},h.prototype.setProgress=function(e){this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)||(this.progressbar_.style.width=e+"%")},h.prototype.setProgress=h.prototype.setProgress,h.prototype.setBuffer=function(e){this.bufferbar_.style.width=e+"%",this.auxbar_.style.width=100-e+"%"},h.prototype.setBuffer=h.prototype.setBuffer,h.prototype.init=function(){if(this.element_){var e=document.createElement("div");e.className="progressbar bar bar1",this.element_.appendChild(e),this.progressbar_=e,e=document.createElement("div"),e.className="bufferbar bar bar2",this.element_.appendChild(e),this.bufferbar_=e,e=document.createElement("div"),e.className="auxbar bar bar3",this.element_.appendChild(e),this.auxbar_=e,this.progressbar_.style.width="0%",this.bufferbar_.style.width="100%",this.auxbar_.style.width="0%",this.element_.classList.add("is-upgraded")}},s.register({constructor:h,classAsString:"MaterialProgress",cssClass:"mdl-js-progress",widget:!0});var c=function(e){this.element_=e,this.init()};window.MaterialRadio=c,c.prototype.Constant_={TINY_TIMEOUT:.001},c.prototype.CssClasses_={IS_FOCUSED:"is-focused",IS_DISABLED:"is-disabled",IS_CHECKED:"is-checked",IS_UPGRADED:"is-upgraded",JS_RADIO:"mdl-js-radio",RADIO_BTN:"mdl-radio__button",RADIO_OUTER_CIRCLE:"mdl-radio__outer-circle",RADIO_INNER_CIRCLE:"mdl-radio__inner-circle",RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE_CONTAINER:"mdl-radio__ripple-container",RIPPLE_CENTER:"mdl-ripple--center",RIPPLE:"mdl-ripple"},c.prototype.onChange_=function(e){for(var t=document.getElementsByClassName(this.CssClasses_.JS_RADIO),s=0;s<t.length;s++){var i=t[s].querySelector("."+this.CssClasses_.RADIO_BTN);i.getAttribute("name")===this.btnElement_.getAttribute("name")&&"undefined"!=typeof t[s].MaterialRadio&&t[s].MaterialRadio.updateClasses_()}},c.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},c.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},c.prototype.onMouseup_=function(e){this.blur_()},c.prototype.updateClasses_=function(){this.checkDisabled(),this.checkToggleState()},c.prototype.blur_=function(){window.setTimeout(function(){this.btnElement_.blur()}.bind(this),this.Constant_.TINY_TIMEOUT)},c.prototype.checkDisabled=function(){this.btnElement_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},c.prototype.checkDisabled=c.prototype.checkDisabled,c.prototype.checkToggleState=function(){this.btnElement_.checked?this.element_.classList.add(this.CssClasses_.IS_CHECKED):this.element_.classList.remove(this.CssClasses_.IS_CHECKED)},c.prototype.checkToggleState=c.prototype.checkToggleState,c.prototype.disable=function(){this.btnElement_.disabled=!0,this.updateClasses_()},c.prototype.disable=c.prototype.disable,c.prototype.enable=function(){this.btnElement_.disabled=!1,this.updateClasses_()},c.prototype.enable=c.prototype.enable,c.prototype.check=function(){this.btnElement_.checked=!0,this.onChange_(null)},c.prototype.check=c.prototype.check,c.prototype.uncheck=function(){this.btnElement_.checked=!1,this.onChange_(null)},c.prototype.uncheck=c.prototype.uncheck,c.prototype.init=function(){if(this.element_){this.btnElement_=this.element_.querySelector("."+this.CssClasses_.RADIO_BTN),this.boundChangeHandler_=this.onChange_.bind(this),this.boundFocusHandler_=this.onChange_.bind(this),this.boundBlurHandler_=this.onBlur_.bind(this),this.boundMouseUpHandler_=this.onMouseup_.bind(this);var e=document.createElement("span");e.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE);var t=document.createElement("span");t.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE),this.element_.appendChild(e),this.element_.appendChild(t);var s;if(this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)){this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS),s=document.createElement("span"),s.classList.add(this.CssClasses_.RIPPLE_CONTAINER),s.classList.add(this.CssClasses_.RIPPLE_EFFECT),s.classList.add(this.CssClasses_.RIPPLE_CENTER),s.addEventListener("mouseup",this.boundMouseUpHandler_);var i=document.createElement("span");i.classList.add(this.CssClasses_.RIPPLE),s.appendChild(i),this.element_.appendChild(s)}this.btnElement_.addEventListener("change",this.boundChangeHandler_),this.btnElement_.addEventListener("focus",this.boundFocusHandler_),this.btnElement_.addEventListener("blur",this.boundBlurHandler_),this.element_.addEventListener("mouseup",this.boundMouseUpHandler_),this.updateClasses_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED)}},s.register({constructor:c,classAsString:"MaterialRadio",cssClass:"mdl-js-radio",widget:!0});var p=function(e){this.element_=e,this.isIE_=window.navigator.msPointerEnabled,this.init()};window.MaterialSlider=p,p.prototype.Constant_={},p.prototype.CssClasses_={IE_CONTAINER:"mdl-slider__ie-container",SLIDER_CONTAINER:"mdl-slider__container",BACKGROUND_FLEX:"mdl-slider__background-flex",BACKGROUND_LOWER:"mdl-slider__background-lower",BACKGROUND_UPPER:"mdl-slider__background-upper",IS_LOWEST_VALUE:"is-lowest-value",IS_UPGRADED:"is-upgraded"},p.prototype.onInput_=function(e){this.updateValueStyles_()},p.prototype.onChange_=function(e){this.updateValueStyles_()},p.prototype.onMouseUp_=function(e){e.target.blur()},p.prototype.onContainerMouseDown_=function(e){if(e.target===this.element_.parentElement){e.preventDefault();var t=new MouseEvent("mousedown",{target:e.target,buttons:e.buttons,clientX:e.clientX,clientY:this.element_.getBoundingClientRect().y});this.element_.dispatchEvent(t)}},p.prototype.updateValueStyles_=function(){var e=(this.element_.value-this.element_.min)/(this.element_.max-this.element_.min);0===e?this.element_.classList.add(this.CssClasses_.IS_LOWEST_VALUE):this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE),this.isIE_||(this.backgroundLower_.style.flex=e,this.backgroundLower_.style.webkitFlex=e,this.backgroundUpper_.style.flex=1-e,this.backgroundUpper_.style.webkitFlex=1-e)},p.prototype.disable=function(){this.element_.disabled=!0},p.prototype.disable=p.prototype.disable,p.prototype.enable=function(){this.element_.disabled=!1},p.prototype.enable=p.prototype.enable,p.prototype.change=function(e){"undefined"!=typeof e&&(this.element_.value=e),this.updateValueStyles_()},p.prototype.change=p.prototype.change,p.prototype.init=function(){if(this.element_){if(this.isIE_){var e=document.createElement("div");e.classList.add(this.CssClasses_.IE_CONTAINER),this.element_.parentElement.insertBefore(e,this.element_),this.element_.parentElement.removeChild(this.element_),e.appendChild(this.element_)}else{var t=document.createElement("div");t.classList.add(this.CssClasses_.SLIDER_CONTAINER),this.element_.parentElement.insertBefore(t,this.element_),this.element_.parentElement.removeChild(this.element_),t.appendChild(this.element_);var s=document.createElement("div");s.classList.add(this.CssClasses_.BACKGROUND_FLEX),t.appendChild(s),this.backgroundLower_=document.createElement("div"),this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER),s.appendChild(this.backgroundLower_),this.backgroundUpper_=document.createElement("div"),this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER),s.appendChild(this.backgroundUpper_)}this.boundInputHandler=this.onInput_.bind(this),this.boundChangeHandler=this.onChange_.bind(this),this.boundMouseUpHandler=this.onMouseUp_.bind(this),this.boundContainerMouseDownHandler=this.onContainerMouseDown_.bind(this),this.element_.addEventListener("input",this.boundInputHandler),this.element_.addEventListener("change",this.boundChangeHandler),this.element_.addEventListener("mouseup",this.boundMouseUpHandler),this.element_.parentElement.addEventListener("mousedown",this.boundContainerMouseDownHandler),this.updateValueStyles_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED)}},s.register({constructor:p,classAsString:"MaterialSlider",cssClass:"mdl-js-slider",widget:!0});var C=function(e){if(this.element_=e,this.textElement_=this.element_.querySelector("."+this.cssClasses_.MESSAGE),this.actionElement_=this.element_.querySelector("."+this.cssClasses_.ACTION),!this.textElement_)throw new Error("There must be a message element for a snackbar.");if(!this.actionElement_)throw new Error("There must be an action element for a snackbar.");this.active=!1,this.actionHandler_=void 0,this.message_=void 0,this.actionText_=void 0,this.queuedNotifications_=[],this.setActionHidden_(!0)};window.MaterialSnackbar=C,C.prototype.Constant_={ANIMATION_LENGTH:250},C.prototype.cssClasses_={SNACKBAR:"mdl-snackbar",MESSAGE:"mdl-snackbar__text",ACTION:"mdl-snackbar__action",ACTIVE:"mdl-snackbar--active"},C.prototype.displaySnackbar_=function(){this.element_.setAttribute("aria-hidden","true"), +this.actionHandler_&&(this.actionElement_.textContent=this.actionText_,this.actionElement_.addEventListener("click",this.actionHandler_),this.setActionHidden_(!1)),this.textElement_.textContent=this.message_,this.element_.classList.add(this.cssClasses_.ACTIVE),this.element_.setAttribute("aria-hidden","false"),setTimeout(this.cleanup_.bind(this),this.timeout_)},C.prototype.showSnackbar=function(e){if(void 0===e)throw new Error("Please provide a data object with at least a message to display.");if(void 0===e.message)throw new Error("Please provide a message to be displayed.");if(e.actionHandler&&!e.actionText)throw new Error("Please provide action text with the handler.");this.active?this.queuedNotifications_.push(e):(this.active=!0,this.message_=e.message,e.timeout?this.timeout_=e.timeout:this.timeout_=2750,e.actionHandler&&(this.actionHandler_=e.actionHandler),e.actionText&&(this.actionText_=e.actionText),this.displaySnackbar_())},C.prototype.showSnackbar=C.prototype.showSnackbar,C.prototype.checkQueue_=function(){this.queuedNotifications_.length>0&&this.showSnackbar(this.queuedNotifications_.shift())},C.prototype.cleanup_=function(){this.element_.classList.remove(this.cssClasses_.ACTIVE),setTimeout(function(){this.element_.setAttribute("aria-hidden","true"),this.textElement_.textContent="",Boolean(this.actionElement_.getAttribute("aria-hidden"))||(this.setActionHidden_(!0),this.actionElement_.textContent="",this.actionElement_.removeEventListener("click",this.actionHandler_)),this.actionHandler_=void 0,this.message_=void 0,this.actionText_=void 0,this.active=!1,this.checkQueue_()}.bind(this),this.Constant_.ANIMATION_LENGTH)},C.prototype.setActionHidden_=function(e){e?this.actionElement_.setAttribute("aria-hidden","true"):this.actionElement_.removeAttribute("aria-hidden")},s.register({constructor:C,classAsString:"MaterialSnackbar",cssClass:"mdl-js-snackbar",widget:!0});var u=function(e){this.element_=e,this.init()};window.MaterialSpinner=u,u.prototype.Constant_={MDL_SPINNER_LAYER_COUNT:4},u.prototype.CssClasses_={MDL_SPINNER_LAYER:"mdl-spinner__layer",MDL_SPINNER_CIRCLE_CLIPPER:"mdl-spinner__circle-clipper",MDL_SPINNER_CIRCLE:"mdl-spinner__circle",MDL_SPINNER_GAP_PATCH:"mdl-spinner__gap-patch",MDL_SPINNER_LEFT:"mdl-spinner__left",MDL_SPINNER_RIGHT:"mdl-spinner__right"},u.prototype.createLayer=function(e){var t=document.createElement("div");t.classList.add(this.CssClasses_.MDL_SPINNER_LAYER),t.classList.add(this.CssClasses_.MDL_SPINNER_LAYER+"-"+e);var s=document.createElement("div");s.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER),s.classList.add(this.CssClasses_.MDL_SPINNER_LEFT);var i=document.createElement("div");i.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH);var n=document.createElement("div");n.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER),n.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT);for(var a=[s,i,n],l=0;l<a.length;l++){var o=document.createElement("div");o.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE),a[l].appendChild(o)}t.appendChild(s),t.appendChild(i),t.appendChild(n),this.element_.appendChild(t)},u.prototype.createLayer=u.prototype.createLayer,u.prototype.stop=function(){this.element_.classList.remove("is-active")},u.prototype.stop=u.prototype.stop,u.prototype.start=function(){this.element_.classList.add("is-active")},u.prototype.start=u.prototype.start,u.prototype.init=function(){if(this.element_){for(var e=1;e<=this.Constant_.MDL_SPINNER_LAYER_COUNT;e++)this.createLayer(e);this.element_.classList.add("is-upgraded")}},s.register({constructor:u,classAsString:"MaterialSpinner",cssClass:"mdl-js-spinner",widget:!0});var E=function(e){this.element_=e,this.init()};window.MaterialSwitch=E,E.prototype.Constant_={TINY_TIMEOUT:.001},E.prototype.CssClasses_={INPUT:"mdl-switch__input",TRACK:"mdl-switch__track",THUMB:"mdl-switch__thumb",FOCUS_HELPER:"mdl-switch__focus-helper",RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE_CONTAINER:"mdl-switch__ripple-container",RIPPLE_CENTER:"mdl-ripple--center",RIPPLE:"mdl-ripple",IS_FOCUSED:"is-focused",IS_DISABLED:"is-disabled",IS_CHECKED:"is-checked"},E.prototype.onChange_=function(e){this.updateClasses_()},E.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},E.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},E.prototype.onMouseUp_=function(e){this.blur_()},E.prototype.updateClasses_=function(){this.checkDisabled(),this.checkToggleState()},E.prototype.blur_=function(){window.setTimeout(function(){this.inputElement_.blur()}.bind(this),this.Constant_.TINY_TIMEOUT)},E.prototype.checkDisabled=function(){this.inputElement_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},E.prototype.checkDisabled=E.prototype.checkDisabled,E.prototype.checkToggleState=function(){this.inputElement_.checked?this.element_.classList.add(this.CssClasses_.IS_CHECKED):this.element_.classList.remove(this.CssClasses_.IS_CHECKED)},E.prototype.checkToggleState=E.prototype.checkToggleState,E.prototype.disable=function(){this.inputElement_.disabled=!0,this.updateClasses_()},E.prototype.disable=E.prototype.disable,E.prototype.enable=function(){this.inputElement_.disabled=!1,this.updateClasses_()},E.prototype.enable=E.prototype.enable,E.prototype.on=function(){this.inputElement_.checked=!0,this.updateClasses_()},E.prototype.on=E.prototype.on,E.prototype.off=function(){this.inputElement_.checked=!1,this.updateClasses_()},E.prototype.off=E.prototype.off,E.prototype.init=function(){if(this.element_){this.inputElement_=this.element_.querySelector("."+this.CssClasses_.INPUT);var e=document.createElement("div");e.classList.add(this.CssClasses_.TRACK);var t=document.createElement("div");t.classList.add(this.CssClasses_.THUMB);var s=document.createElement("span");if(s.classList.add(this.CssClasses_.FOCUS_HELPER),t.appendChild(s),this.element_.appendChild(e),this.element_.appendChild(t),this.boundMouseUpHandler=this.onMouseUp_.bind(this),this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)){this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS),this.rippleContainerElement_=document.createElement("span"),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT),this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER),this.rippleContainerElement_.addEventListener("mouseup",this.boundMouseUpHandler);var i=document.createElement("span");i.classList.add(this.CssClasses_.RIPPLE),this.rippleContainerElement_.appendChild(i),this.element_.appendChild(this.rippleContainerElement_)}this.boundChangeHandler=this.onChange_.bind(this),this.boundFocusHandler=this.onFocus_.bind(this),this.boundBlurHandler=this.onBlur_.bind(this),this.inputElement_.addEventListener("change",this.boundChangeHandler),this.inputElement_.addEventListener("focus",this.boundFocusHandler),this.inputElement_.addEventListener("blur",this.boundBlurHandler),this.element_.addEventListener("mouseup",this.boundMouseUpHandler),this.updateClasses_(),this.element_.classList.add("is-upgraded")}},s.register({constructor:E,classAsString:"MaterialSwitch",cssClass:"mdl-js-switch",widget:!0});var m=function(e){this.element_=e,this.init()};window.MaterialTabs=m,m.prototype.Constant_={},m.prototype.CssClasses_={TAB_CLASS:"mdl-tabs__tab",PANEL_CLASS:"mdl-tabs__panel",ACTIVE_CLASS:"is-active",UPGRADED_CLASS:"is-upgraded",MDL_JS_RIPPLE_EFFECT:"mdl-js-ripple-effect",MDL_RIPPLE_CONTAINER:"mdl-tabs__ripple-container",MDL_RIPPLE:"mdl-ripple",MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events"},m.prototype.initTabs_=function(){this.element_.classList.contains(this.CssClasses_.MDL_JS_RIPPLE_EFFECT)&&this.element_.classList.add(this.CssClasses_.MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS),this.tabs_=this.element_.querySelectorAll("."+this.CssClasses_.TAB_CLASS),this.panels_=this.element_.querySelectorAll("."+this.CssClasses_.PANEL_CLASS);for(var t=0;t<this.tabs_.length;t++)new e(this.tabs_[t],this);this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS)},m.prototype.resetTabState_=function(){for(var e=0;e<this.tabs_.length;e++)this.tabs_[e].classList.remove(this.CssClasses_.ACTIVE_CLASS)},m.prototype.resetPanelState_=function(){for(var e=0;e<this.panels_.length;e++)this.panels_[e].classList.remove(this.CssClasses_.ACTIVE_CLASS)},m.prototype.init=function(){this.element_&&this.initTabs_()},s.register({constructor:m,classAsString:"MaterialTabs",cssClass:"mdl-js-tabs"});var L=function(e){this.element_=e,this.maxRows=this.Constant_.NO_MAX_ROWS,this.init()};window.MaterialTextfield=L,L.prototype.Constant_={NO_MAX_ROWS:-1,MAX_ROWS_ATTRIBUTE:"maxrows"},L.prototype.CssClasses_={LABEL:"mdl-textfield__label",INPUT:"mdl-textfield__input",IS_DIRTY:"is-dirty",IS_FOCUSED:"is-focused",IS_DISABLED:"is-disabled",IS_INVALID:"is-invalid",IS_UPGRADED:"is-upgraded",HAS_PLACEHOLDER:"has-placeholder"},L.prototype.onKeyDown_=function(e){var t=e.target.value.split("\n").length;13===e.keyCode&&t>=this.maxRows&&e.preventDefault()},L.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},L.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},L.prototype.onReset_=function(e){this.updateClasses_()},L.prototype.updateClasses_=function(){this.checkDisabled(),this.checkValidity(),this.checkDirty(),this.checkFocus()},L.prototype.checkDisabled=function(){this.input_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},L.prototype.checkDisabled=L.prototype.checkDisabled,L.prototype.checkFocus=function(){Boolean(this.element_.querySelector(":focus"))?this.element_.classList.add(this.CssClasses_.IS_FOCUSED):this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},L.prototype.checkFocus=L.prototype.checkFocus,L.prototype.checkValidity=function(){this.input_.validity&&(this.input_.validity.valid?this.element_.classList.remove(this.CssClasses_.IS_INVALID):this.element_.classList.add(this.CssClasses_.IS_INVALID))},L.prototype.checkValidity=L.prototype.checkValidity,L.prototype.checkDirty=function(){this.input_.value&&this.input_.value.length>0?this.element_.classList.add(this.CssClasses_.IS_DIRTY):this.element_.classList.remove(this.CssClasses_.IS_DIRTY)},L.prototype.checkDirty=L.prototype.checkDirty,L.prototype.disable=function(){this.input_.disabled=!0,this.updateClasses_()},L.prototype.disable=L.prototype.disable,L.prototype.enable=function(){this.input_.disabled=!1,this.updateClasses_()},L.prototype.enable=L.prototype.enable,L.prototype.change=function(e){this.input_.value=e||"",this.updateClasses_()},L.prototype.change=L.prototype.change,L.prototype.init=function(){if(this.element_&&(this.label_=this.element_.querySelector("."+this.CssClasses_.LABEL),this.input_=this.element_.querySelector("."+this.CssClasses_.INPUT),this.input_)){this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)&&(this.maxRows=parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE),10),isNaN(this.maxRows)&&(this.maxRows=this.Constant_.NO_MAX_ROWS)),this.input_.hasAttribute("placeholder")&&this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER),this.boundUpdateClassesHandler=this.updateClasses_.bind(this),this.boundFocusHandler=this.onFocus_.bind(this),this.boundBlurHandler=this.onBlur_.bind(this),this.boundResetHandler=this.onReset_.bind(this),this.input_.addEventListener("input",this.boundUpdateClassesHandler),this.input_.addEventListener("focus",this.boundFocusHandler),this.input_.addEventListener("blur",this.boundBlurHandler),this.input_.addEventListener("reset",this.boundResetHandler),this.maxRows!==this.Constant_.NO_MAX_ROWS&&(this.boundKeyDownHandler=this.onKeyDown_.bind(this),this.input_.addEventListener("keydown",this.boundKeyDownHandler));var e=this.element_.classList.contains(this.CssClasses_.IS_INVALID);this.updateClasses_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED),e&&this.element_.classList.add(this.CssClasses_.IS_INVALID),this.input_.hasAttribute("autofocus")&&(this.element_.focus(),this.checkFocus())}},s.register({constructor:L,classAsString:"MaterialTextfield",cssClass:"mdl-js-textfield",widget:!0});var I=function(e){this.element_=e,this.init()};window.MaterialTooltip=I,I.prototype.Constant_={},I.prototype.CssClasses_={IS_ACTIVE:"is-active",BOTTOM:"mdl-tooltip--bottom",LEFT:"mdl-tooltip--left",RIGHT:"mdl-tooltip--right",TOP:"mdl-tooltip--top"},I.prototype.handleMouseEnter_=function(e){var t=e.target.getBoundingClientRect(),s=t.left+t.width/2,i=t.top+t.height/2,n=-1*(this.element_.offsetWidth/2),a=-1*(this.element_.offsetHeight/2);this.element_.classList.contains(this.CssClasses_.LEFT)||this.element_.classList.contains(this.CssClasses_.RIGHT)?(s=t.width/2,i+a<0?(this.element_.style.top="0",this.element_.style.marginTop="0"):(this.element_.style.top=i+"px",this.element_.style.marginTop=a+"px")):s+n<0?(this.element_.style.left="0",this.element_.style.marginLeft="0"):(this.element_.style.left=s+"px",this.element_.style.marginLeft=n+"px"),this.element_.classList.contains(this.CssClasses_.TOP)?this.element_.style.top=t.top-this.element_.offsetHeight-10+"px":this.element_.classList.contains(this.CssClasses_.RIGHT)?this.element_.style.left=t.left+t.width+10+"px":this.element_.classList.contains(this.CssClasses_.LEFT)?this.element_.style.left=t.left-this.element_.offsetWidth-10+"px":this.element_.style.top=t.top+t.height+10+"px",this.element_.classList.add(this.CssClasses_.IS_ACTIVE)},I.prototype.hideTooltip_=function(){this.element_.classList.remove(this.CssClasses_.IS_ACTIVE)},I.prototype.init=function(){if(this.element_){var e=this.element_.getAttribute("for")||this.element_.getAttribute("data-mdl-for");e&&(this.forElement_=document.getElementById(e)),this.forElement_&&(this.forElement_.hasAttribute("tabindex")||this.forElement_.setAttribute("tabindex","0"),this.boundMouseEnterHandler=this.handleMouseEnter_.bind(this),this.boundMouseLeaveAndScrollHandler=this.hideTooltip_.bind(this),this.forElement_.addEventListener("mouseenter",this.boundMouseEnterHandler,!1),this.forElement_.addEventListener("touchend",this.boundMouseEnterHandler,!1),this.forElement_.addEventListener("mouseleave",this.boundMouseLeaveAndScrollHandler,!1),window.addEventListener("scroll",this.boundMouseLeaveAndScrollHandler,!0),window.addEventListener("touchstart",this.boundMouseLeaveAndScrollHandler))}},s.register({constructor:I,classAsString:"MaterialTooltip",cssClass:"mdl-tooltip"});var f=function(e){this.element_=e,this.init()};window.MaterialLayout=f,f.prototype.Constant_={MAX_WIDTH:"(max-width: 1024px)",TAB_SCROLL_PIXELS:100,RESIZE_TIMEOUT:100,MENU_ICON:"",CHEVRON_LEFT:"chevron_left",CHEVRON_RIGHT:"chevron_right"},f.prototype.Keycodes_={ENTER:13,ESCAPE:27,SPACE:32},f.prototype.Mode_={STANDARD:0,SEAMED:1,WATERFALL:2,SCROLL:3},f.prototype.CssClasses_={CONTAINER:"mdl-layout__container",HEADER:"mdl-layout__header",DRAWER:"mdl-layout__drawer",CONTENT:"mdl-layout__content",DRAWER_BTN:"mdl-layout__drawer-button",ICON:"material-icons",JS_RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_CONTAINER:"mdl-layout__tab-ripple-container",RIPPLE:"mdl-ripple",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",HEADER_SEAMED:"mdl-layout__header--seamed",HEADER_WATERFALL:"mdl-layout__header--waterfall",HEADER_SCROLL:"mdl-layout__header--scroll",FIXED_HEADER:"mdl-layout--fixed-header",OBFUSCATOR:"mdl-layout__obfuscator",TAB_BAR:"mdl-layout__tab-bar",TAB_CONTAINER:"mdl-layout__tab-bar-container",TAB:"mdl-layout__tab",TAB_BAR_BUTTON:"mdl-layout__tab-bar-button",TAB_BAR_LEFT_BUTTON:"mdl-layout__tab-bar-left-button",TAB_BAR_RIGHT_BUTTON:"mdl-layout__tab-bar-right-button",TAB_MANUAL_SWITCH:"mdl-layout__tab-manual-switch",PANEL:"mdl-layout__tab-panel",HAS_DRAWER:"has-drawer",HAS_TABS:"has-tabs",HAS_SCROLLING_HEADER:"has-scrolling-header",CASTING_SHADOW:"is-casting-shadow",IS_COMPACT:"is-compact",IS_SMALL_SCREEN:"is-small-screen",IS_DRAWER_OPEN:"is-visible",IS_ACTIVE:"is-active",IS_UPGRADED:"is-upgraded",IS_ANIMATING:"is-animating",ON_LARGE_SCREEN:"mdl-layout--large-screen-only",ON_SMALL_SCREEN:"mdl-layout--small-screen-only"},f.prototype.contentScrollHandler_=function(){if(!this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)){var e=!this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN)||this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);this.content_.scrollTop>0&&!this.header_.classList.contains(this.CssClasses_.IS_COMPACT)?(this.header_.classList.add(this.CssClasses_.CASTING_SHADOW),this.header_.classList.add(this.CssClasses_.IS_COMPACT),e&&this.header_.classList.add(this.CssClasses_.IS_ANIMATING)):this.content_.scrollTop<=0&&this.header_.classList.contains(this.CssClasses_.IS_COMPACT)&&(this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW),this.header_.classList.remove(this.CssClasses_.IS_COMPACT),e&&this.header_.classList.add(this.CssClasses_.IS_ANIMATING))}},f.prototype.keyboardEventHandler_=function(e){e.keyCode===this.Keycodes_.ESCAPE&&this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)&&this.toggleDrawer()},f.prototype.screenSizeHandler_=function(){this.screenSizeMediaQuery_.matches?this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN):(this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN),this.drawer_&&(this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN),this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN)))},f.prototype.drawerToggleHandler_=function(e){if(e&&"keydown"===e.type){if(e.keyCode!==this.Keycodes_.SPACE&&e.keyCode!==this.Keycodes_.ENTER)return;e.preventDefault()}this.toggleDrawer()},f.prototype.headerTransitionEndHandler_=function(){this.header_.classList.remove(this.CssClasses_.IS_ANIMATING)},f.prototype.headerClickHandler_=function(){this.header_.classList.contains(this.CssClasses_.IS_COMPACT)&&(this.header_.classList.remove(this.CssClasses_.IS_COMPACT),this.header_.classList.add(this.CssClasses_.IS_ANIMATING))},f.prototype.resetTabState_=function(e){for(var t=0;t<e.length;t++)e[t].classList.remove(this.CssClasses_.IS_ACTIVE)},f.prototype.resetPanelState_=function(e){for(var t=0;t<e.length;t++)e[t].classList.remove(this.CssClasses_.IS_ACTIVE)},f.prototype.toggleDrawer=function(){var e=this.element_.querySelector("."+this.CssClasses_.DRAWER_BTN);this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN),this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN),this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)?(this.drawer_.setAttribute("aria-hidden","false"),e.setAttribute("aria-expanded","true")):(this.drawer_.setAttribute("aria-hidden","true"),e.setAttribute("aria-expanded","false"))},f.prototype.toggleDrawer=f.prototype.toggleDrawer,f.prototype.init=function(){if(this.element_){var e=document.createElement("div");e.classList.add(this.CssClasses_.CONTAINER);var s=this.element_.querySelector(":focus");this.element_.parentElement.insertBefore(e,this.element_),this.element_.parentElement.removeChild(this.element_),e.appendChild(this.element_),s&&s.focus();for(var i=this.element_.childNodes,n=i.length,a=0;a<n;a++){var l=i[a];l.classList&&l.classList.contains(this.CssClasses_.HEADER)&&(this.header_=l),l.classList&&l.classList.contains(this.CssClasses_.DRAWER)&&(this.drawer_=l),l.classList&&l.classList.contains(this.CssClasses_.CONTENT)&&(this.content_=l)}window.addEventListener("pageshow",function(e){e.persisted&&(this.element_.style.overflowY="hidden",requestAnimationFrame(function(){this.element_.style.overflowY=""}.bind(this)))}.bind(this),!1),this.header_&&(this.tabBar_=this.header_.querySelector("."+this.CssClasses_.TAB_BAR));var o=this.Mode_.STANDARD;if(this.header_&&(this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)?o=this.Mode_.SEAMED:this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)?(o=this.Mode_.WATERFALL,this.header_.addEventListener("transitionend",this.headerTransitionEndHandler_.bind(this)),this.header_.addEventListener("click",this.headerClickHandler_.bind(this))):this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)&&(o=this.Mode_.SCROLL,e.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER)),o===this.Mode_.STANDARD?(this.header_.classList.add(this.CssClasses_.CASTING_SHADOW),this.tabBar_&&this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW)):o===this.Mode_.SEAMED||o===this.Mode_.SCROLL?(this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW),this.tabBar_&&this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW)):o===this.Mode_.WATERFALL&&(this.content_.addEventListener("scroll",this.contentScrollHandler_.bind(this)),this.contentScrollHandler_())),this.drawer_){var r=this.element_.querySelector("."+this.CssClasses_.DRAWER_BTN);if(!r){r=document.createElement("div"),r.setAttribute("aria-expanded","false"),r.setAttribute("role","button"),r.setAttribute("tabindex","0"),r.classList.add(this.CssClasses_.DRAWER_BTN);var _=document.createElement("i");_.classList.add(this.CssClasses_.ICON),_.innerHTML=this.Constant_.MENU_ICON,r.appendChild(_)}this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)?r.classList.add(this.CssClasses_.ON_LARGE_SCREEN):this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)&&r.classList.add(this.CssClasses_.ON_SMALL_SCREEN),r.addEventListener("click",this.drawerToggleHandler_.bind(this)),r.addEventListener("keydown",this.drawerToggleHandler_.bind(this)),this.element_.classList.add(this.CssClasses_.HAS_DRAWER),this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)?this.header_.insertBefore(r,this.header_.firstChild):this.element_.insertBefore(r,this.content_);var d=document.createElement("div");d.classList.add(this.CssClasses_.OBFUSCATOR),this.element_.appendChild(d),d.addEventListener("click",this.drawerToggleHandler_.bind(this)),this.obfuscator_=d,this.drawer_.addEventListener("keydown",this.keyboardEventHandler_.bind(this)),this.drawer_.setAttribute("aria-hidden","true")}if(this.screenSizeMediaQuery_=window.matchMedia(this.Constant_.MAX_WIDTH),this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this)),this.screenSizeHandler_(),this.header_&&this.tabBar_){this.element_.classList.add(this.CssClasses_.HAS_TABS);var h=document.createElement("div");h.classList.add(this.CssClasses_.TAB_CONTAINER),this.header_.insertBefore(h,this.tabBar_),this.header_.removeChild(this.tabBar_);var c=document.createElement("div");c.classList.add(this.CssClasses_.TAB_BAR_BUTTON),c.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);var p=document.createElement("i");p.classList.add(this.CssClasses_.ICON),p.textContent=this.Constant_.CHEVRON_LEFT,c.appendChild(p),c.addEventListener("click",function(){this.tabBar_.scrollLeft-=this.Constant_.TAB_SCROLL_PIXELS}.bind(this));var C=document.createElement("div");C.classList.add(this.CssClasses_.TAB_BAR_BUTTON),C.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);var u=document.createElement("i");u.classList.add(this.CssClasses_.ICON),u.textContent=this.Constant_.CHEVRON_RIGHT,C.appendChild(u),C.addEventListener("click",function(){this.tabBar_.scrollLeft+=this.Constant_.TAB_SCROLL_PIXELS}.bind(this)),h.appendChild(c),h.appendChild(this.tabBar_),h.appendChild(C);var E=function(){this.tabBar_.scrollLeft>0?c.classList.add(this.CssClasses_.IS_ACTIVE):c.classList.remove(this.CssClasses_.IS_ACTIVE),this.tabBar_.scrollLeft<this.tabBar_.scrollWidth-this.tabBar_.offsetWidth?C.classList.add(this.CssClasses_.IS_ACTIVE):C.classList.remove(this.CssClasses_.IS_ACTIVE)}.bind(this);this.tabBar_.addEventListener("scroll",E),E();var m=function(){this.resizeTimeoutId_&&clearTimeout(this.resizeTimeoutId_),this.resizeTimeoutId_=setTimeout(function(){E(),this.resizeTimeoutId_=null}.bind(this),this.Constant_.RESIZE_TIMEOUT)}.bind(this);window.addEventListener("resize",m),this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)&&this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);for(var L=this.tabBar_.querySelectorAll("."+this.CssClasses_.TAB),I=this.content_.querySelectorAll("."+this.CssClasses_.PANEL),f=0;f<L.length;f++)new t(L[f],L,I,this)}this.element_.classList.add(this.CssClasses_.IS_UPGRADED)}},window.MaterialLayoutTab=t,s.register({constructor:f,classAsString:"MaterialLayout",cssClass:"mdl-js-layout"});var b=function(e){this.element_=e,this.init()};window.MaterialDataTable=b,b.prototype.Constant_={},b.prototype.CssClasses_={DATA_TABLE:"mdl-data-table",SELECTABLE:"mdl-data-table--selectable",SELECT_ELEMENT:"mdl-data-table__select",IS_SELECTED:"is-selected",IS_UPGRADED:"is-upgraded"},b.prototype.selectRow_=function(e,t,s){return t?function(){e.checked?t.classList.add(this.CssClasses_.IS_SELECTED):t.classList.remove(this.CssClasses_.IS_SELECTED)}.bind(this):s?function(){var t,i;if(e.checked)for(t=0;t<s.length;t++)i=s[t].querySelector("td").querySelector(".mdl-checkbox"),i.MaterialCheckbox.check(),s[t].classList.add(this.CssClasses_.IS_SELECTED);else for(t=0;t<s.length;t++)i=s[t].querySelector("td").querySelector(".mdl-checkbox"),i.MaterialCheckbox.uncheck(),s[t].classList.remove(this.CssClasses_.IS_SELECTED)}.bind(this):void 0},b.prototype.createCheckbox_=function(e,t){var i=document.createElement("label"),n=["mdl-checkbox","mdl-js-checkbox","mdl-js-ripple-effect",this.CssClasses_.SELECT_ELEMENT];i.className=n.join(" ");var a=document.createElement("input");return a.type="checkbox",a.classList.add("mdl-checkbox__input"),e?(a.checked=e.classList.contains(this.CssClasses_.IS_SELECTED),a.addEventListener("change",this.selectRow_(a,e))):t&&a.addEventListener("change",this.selectRow_(a,null,t)),i.appendChild(a),s.upgradeElement(i,"MaterialCheckbox"),i},b.prototype.init=function(){if(this.element_){var e=this.element_.querySelector("th"),t=Array.prototype.slice.call(this.element_.querySelectorAll("tbody tr")),s=Array.prototype.slice.call(this.element_.querySelectorAll("tfoot tr")),i=t.concat(s);if(this.element_.classList.contains(this.CssClasses_.SELECTABLE)){var n=document.createElement("th"),a=this.createCheckbox_(null,i);n.appendChild(a),e.parentElement.insertBefore(n,e);for(var l=0;l<i.length;l++){var o=i[l].querySelector("td");if(o){var r=document.createElement("td");if("TBODY"===i[l].parentNode.nodeName.toUpperCase()){var _=this.createCheckbox_(i[l]);r.appendChild(_)}i[l].insertBefore(r,o)}}this.element_.classList.add(this.CssClasses_.IS_UPGRADED)}}},s.register({constructor:b,classAsString:"MaterialDataTable",cssClass:"mdl-js-data-table"});var S=function(e){this.element_=e,this.init()};window.MaterialRipple=S,S.prototype.Constant_={INITIAL_SCALE:"scale(0.0001, 0.0001)",INITIAL_SIZE:"1px",INITIAL_OPACITY:"0.4",FINAL_OPACITY:"0",FINAL_SCALE:""},S.prototype.CssClasses_={RIPPLE_CENTER:"mdl-ripple--center",RIPPLE_EFFECT_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",RIPPLE:"mdl-ripple",IS_ANIMATING:"is-animating",IS_VISIBLE:"is-visible"},S.prototype.downHandler_=function(e){if(!this.rippleElement_.style.width&&!this.rippleElement_.style.height){var t=this.element_.getBoundingClientRect();this.boundHeight=t.height,this.boundWidth=t.width,this.rippleSize_=2*Math.sqrt(t.width*t.width+t.height*t.height)+2,this.rippleElement_.style.width=this.rippleSize_+"px",this.rippleElement_.style.height=this.rippleSize_+"px"}if(this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE),"mousedown"===e.type&&this.ignoringMouseDown_)this.ignoringMouseDown_=!1;else{"touchstart"===e.type&&(this.ignoringMouseDown_=!0);var s=this.getFrameCount();if(s>0)return;this.setFrameCount(1);var i,n,a=e.currentTarget.getBoundingClientRect();if(0===e.clientX&&0===e.clientY)i=Math.round(a.width/2),n=Math.round(a.height/2);else{var l=void 0!==e.clientX?e.clientX:e.touches[0].clientX,o=void 0!==e.clientY?e.clientY:e.touches[0].clientY;i=Math.round(l-a.left),n=Math.round(o-a.top)}this.setRippleXY(i,n),this.setRippleStyles(!0),window.requestAnimationFrame(this.animFrameHandler.bind(this))}},S.prototype.upHandler_=function(e){e&&2!==e.detail&&window.setTimeout(function(){this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE)}.bind(this),0)},S.prototype.init=function(){if(this.element_){var e=this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)||(this.rippleElement_=this.element_.querySelector("."+this.CssClasses_.RIPPLE),this.frameCount_=0,this.rippleSize_=0,this.x_=0,this.y_=0,this.ignoringMouseDown_=!1,this.boundDownHandler=this.downHandler_.bind(this),this.element_.addEventListener("mousedown",this.boundDownHandler),this.element_.addEventListener("touchstart",this.boundDownHandler),this.boundUpHandler=this.upHandler_.bind(this),this.element_.addEventListener("mouseup",this.boundUpHandler),this.element_.addEventListener("mouseleave",this.boundUpHandler),this.element_.addEventListener("touchend",this.boundUpHandler),this.element_.addEventListener("blur",this.boundUpHandler),this.getFrameCount=function(){return this.frameCount_},this.setFrameCount=function(e){this.frameCount_=e},this.getRippleElement=function(){return this.rippleElement_},this.setRippleXY=function(e,t){this.x_=e,this.y_=t},this.setRippleStyles=function(t){if(null!==this.rippleElement_){var s,i,n,a="translate("+this.x_+"px, "+this.y_+"px)";t?(i=this.Constant_.INITIAL_SCALE,n=this.Constant_.INITIAL_SIZE):(i=this.Constant_.FINAL_SCALE,n=this.rippleSize_+"px",e&&(a="translate("+this.boundWidth/2+"px, "+this.boundHeight/2+"px)")),s="translate(-50%, -50%) "+a+i,this.rippleElement_.style.webkitTransform=s,this.rippleElement_.style.msTransform=s,this.rippleElement_.style.transform=s,t?this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING):this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING)}},this.animFrameHandler=function(){this.frameCount_-- >0?window.requestAnimationFrame(this.animFrameHandler.bind(this)):this.setRippleStyles(!1)})}},s.register({constructor:S,classAsString:"MaterialRipple",cssClass:"mdl-js-ripple-effect",widget:!1})}(); +//# sourceMappingURL=material.min.js.map diff --git a/src/material.min.js.map b/src/material.min.js.map new file mode 100644 index 0000000..6163150 --- /dev/null +++ b/src/material.min.js.map @@ -0,0 +1,630 @@ +{ + "version": 3, + "sources": [ + "tabs.js", + "layout.js", + "mdlComponentHandler.js", + "rAF.js", + "button.js", + "checkbox.js", + "icon-toggle.js", + "menu.js", + "progress.js", + "radio.js", + "slider.js", + "snackbar.js", + "spinner.js", + "switch.js", + "textfield.js", + "tooltip.js", + "data-table.js", + "ripple.js" + ], + "names": [ + "MaterialTab", + "tab", + "ctx", + "element_", + "classList", + "contains", + "CssClasses_", + "MDL_JS_RIPPLE_EFFECT", + "rippleContainer", + "document", + "createElement", + "add", + "MDL_RIPPLE_CONTAINER", + "ripple", + "MDL_RIPPLE", + "appendChild", + "addEventListener", + "e", + "getAttribute", + "charAt", + "preventDefault", + "href", + "split", + "panel", + "querySelector", + "resetTabState_", + "resetPanelState_", + "ACTIVE_CLASS", + "MaterialLayoutTab", + "tabs", + "panels", + "layout", + "selectTab", + "content_", + "IS_ACTIVE", + "tabBar_", + "JS_RIPPLE_EFFECT", + "RIPPLE_CONTAINER", + "RIPPLE", + "TAB_MANUAL_SWITCH", + "show", + "componentHandler", + "upgradeDom", + "optJsClass", + "optCssClass", + "upgradeElement", + "element", + "upgradeElements", + "elements", + "upgradeAllRegistered", + "registerUpgradedCallback", + "jsClass", + "callback", + "register", + "config", + "downgradeElements", + "nodes", + "findRegisteredClass_", + "name", + "optReplace", + "i", + "registeredComponents_", + "length", + "className", + "getUpgradedListOfElement_", + "dataUpgraded", + "isElementUpgraded_", + "upgradedList", + "indexOf", + "createEvent_", + "eventType", + "bubbles", + "cancelable", + "window", + "CustomEvent", + "ev", + "createEvent", + "initEvent", + "upgradeDomInternal", + "cssClass", + "registeredClass", + "querySelectorAll", + "n", + "upgradeElementInternal", + "Element", + "Error", + "upgradingEv", + "dispatchEvent", + "defaultPrevented", + "classesToUpgrade", + "push", + "forEach", + "component", + "setAttribute", + "join", + "instance", + "classConstructor", + "componentConfigProperty_", + "createdComponents_", + "j", + "m", + "callbacks", + "widget", + "upgradedEv", + "upgradeElementsInternal", + "Array", + "isArray", + "prototype", + "slice", + "call", + "HTMLElement", + "children", + "registerInternal", + "widgetMissing", + "newConfig", + "constructor", + "classAsString", + "item", + "hasOwnProperty", + "found", + "registerUpgradedCallbackInternal", + "regClass", + "upgradeAllRegisteredInternal", + "deconstructComponentInternal", + "componentIndex", + "splice", + "upgrades", + "componentPlace", + "downgradeNodesInternal", + "downgradeNode", + "node", + "filter", + "NodeList", + "Node", + "ComponentConfigPublic", + "ComponentConfig", + "Component", + "documentElement", + "Date", + "now", + "getTime", + "vendors", + "requestAnimationFrame", + "vp", + "cancelAnimationFrame", + "test", + "navigator", + "userAgent", + "lastTime", + "nextTime", + "Math", + "max", + "setTimeout", + "clearTimeout", + "MaterialButton", + "this", + "init", + "Constant_", + "RIPPLE_EFFECT", + "blurHandler_", + "event", + "blur", + "disable", + "disabled", + "enable", + "rippleElement_", + "boundRippleBlurHandler", + "bind", + "boundButtonBlurHandler", + "MaterialCheckbox", + "TINY_TIMEOUT", + "INPUT", + "BOX_OUTLINE", + "FOCUS_HELPER", + "TICK_OUTLINE", + "RIPPLE_IGNORE_EVENTS", + "RIPPLE_CENTER", + "IS_FOCUSED", + "IS_DISABLED", + "IS_CHECKED", + "IS_UPGRADED", + "onChange_", + "updateClasses_", + "onFocus_", + "onBlur_", + "remove", + "onMouseUp_", + "blur_", + "checkDisabled", + "checkToggleState", + "inputElement_", + "checked", + "check", + "uncheck", + "boxOutline", + "tickContainer", + "tickOutline", + "rippleContainerElement_", + "boundRippleMouseUp", + "boundInputOnChange", + "boundInputOnFocus", + "boundInputOnBlur", + "boundElementMouseUp", + "MaterialIconToggle", + "boundElementOnMouseUp", + "MaterialMenu", + "TRANSITION_DURATION_SECONDS", + "TRANSITION_DURATION_FRACTION", + "CLOSE_TIMEOUT", + "Keycodes_", + "ENTER", + "ESCAPE", + "SPACE", + "UP_ARROW", + "DOWN_ARROW", + "CONTAINER", + "OUTLINE", + "ITEM", + "ITEM_RIPPLE_CONTAINER", + "IS_VISIBLE", + "IS_ANIMATING", + "BOTTOM_LEFT", + "BOTTOM_RIGHT", + "TOP_LEFT", + "TOP_RIGHT", + "UNALIGNED", + "container", + "parentElement", + "insertBefore", + "removeChild", + "container_", + "outline", + "outline_", + "forElId", + "forEl", + "getElementById", + "forElement_", + "handleForClick_", + "handleForKeyboardEvent_", + "items", + "boundItemKeydown_", + "handleItemKeyboardEvent_", + "boundItemClick_", + "handleItemClick_", + "tabIndex", + "evt", + "rect", + "getBoundingClientRect", + "forRect", + "style", + "right", + "top", + "offsetTop", + "offsetHeight", + "left", + "offsetLeft", + "bottom", + "toggle", + "keyCode", + "focus", + "currentIndex", + "target", + "MouseEvent", + "click", + "hide", + "hasAttribute", + "stopPropagation", + "closing_", + "applyClip_", + "height", + "width", + "clip", + "removeAnimationEndListener_", + "addAnimationEndListener_", + "transitionDuration", + "itemDelay", + "transitionDelay", + "parentNode", + "removeEventListener", + "removeProperty", + "MaterialProgress", + "INDETERMINATE_CLASS", + "setProgress", + "p", + "progressbar_", + "setBuffer", + "bufferbar_", + "auxbar_", + "el", + "MaterialRadio", + "JS_RADIO", + "RADIO_BTN", + "RADIO_OUTER_CIRCLE", + "RADIO_INNER_CIRCLE", + "radios", + "getElementsByClassName", + "button", + "btnElement_", + "onMouseup_", + "boundChangeHandler_", + "boundFocusHandler_", + "boundBlurHandler_", + "boundMouseUpHandler_", + "outerCircle", + "innerCircle", + "MaterialSlider", + "isIE_", + "msPointerEnabled", + "IE_CONTAINER", + "SLIDER_CONTAINER", + "BACKGROUND_FLEX", + "BACKGROUND_LOWER", + "BACKGROUND_UPPER", + "IS_LOWEST_VALUE", + "onInput_", + "updateValueStyles_", + "onContainerMouseDown_", + "newEvent", + "buttons", + "clientX", + "clientY", + "y", + "fraction", + "value", + "min", + "backgroundLower_", + "flex", + "webkitFlex", + "backgroundUpper_", + "change", + "containerIE", + "backgroundFlex", + "boundInputHandler", + "boundChangeHandler", + "boundMouseUpHandler", + "boundContainerMouseDownHandler", + "MaterialSnackbar", + "textElement_", + "cssClasses_", + "MESSAGE", + "actionElement_", + "ACTION", + "active", + "actionHandler_", + "undefined", + "message_", + "actionText_", + "queuedNotifications_", + "setActionHidden_", + "ANIMATION_LENGTH", + "SNACKBAR", + "ACTIVE", + "displaySnackbar_", + "textContent", + "cleanup_", + "timeout_", + "showSnackbar", + "data", + "checkQueue_", + "shift", + "Boolean", + "removeAttribute", + "MaterialSpinner", + "MDL_SPINNER_LAYER_COUNT", + "MDL_SPINNER_LAYER", + "MDL_SPINNER_CIRCLE_CLIPPER", + "MDL_SPINNER_CIRCLE", + "MDL_SPINNER_GAP_PATCH", + "MDL_SPINNER_LEFT", + "MDL_SPINNER_RIGHT", + "createLayer", + "index", + "layer", + "leftClipper", + "gapPatch", + "rightClipper", + "circleOwners", + "circle", + "stop", + "start", + "MaterialSwitch", + "TRACK", + "THUMB", + "on", + "off", + "track", + "thumb", + "focusHelper", + "boundFocusHandler", + "boundBlurHandler", + "MaterialTabs", + "TAB_CLASS", + "PANEL_CLASS", + "UPGRADED_CLASS", + "MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS", + "initTabs_", + "tabs_", + "panels_", + "k", + "MaterialTextfield", + "maxRows", + "NO_MAX_ROWS", + "MAX_ROWS_ATTRIBUTE", + "LABEL", + "IS_DIRTY", + "IS_INVALID", + "HAS_PLACEHOLDER", + "onKeyDown_", + "currentRowCount", + "onReset_", + "checkValidity", + "checkDirty", + "checkFocus", + "input_", + "validity", + "valid", + "label_", + "parseInt", + "isNaN", + "boundUpdateClassesHandler", + "boundResetHandler", + "boundKeyDownHandler", + "invalid", + "MaterialTooltip", + "BOTTOM", + "LEFT", + "RIGHT", + "TOP", + "handleMouseEnter_", + "props", + "marginLeft", + "offsetWidth", + "marginTop", + "hideTooltip_", + "boundMouseEnterHandler", + "boundMouseLeaveAndScrollHandler", + "MaterialLayout", + "MAX_WIDTH", + "TAB_SCROLL_PIXELS", + "RESIZE_TIMEOUT", + "MENU_ICON", + "CHEVRON_LEFT", + "CHEVRON_RIGHT", + "Mode_", + "STANDARD", + "SEAMED", + "WATERFALL", + "SCROLL", + "HEADER", + "DRAWER", + "CONTENT", + "DRAWER_BTN", + "ICON", + "HEADER_SEAMED", + "HEADER_WATERFALL", + "HEADER_SCROLL", + "FIXED_HEADER", + "OBFUSCATOR", + "TAB_BAR", + "TAB_CONTAINER", + "TAB", + "TAB_BAR_BUTTON", + "TAB_BAR_LEFT_BUTTON", + "TAB_BAR_RIGHT_BUTTON", + "PANEL", + "HAS_DRAWER", + "HAS_TABS", + "HAS_SCROLLING_HEADER", + "CASTING_SHADOW", + "IS_COMPACT", + "IS_SMALL_SCREEN", + "IS_DRAWER_OPEN", + "ON_LARGE_SCREEN", + "ON_SMALL_SCREEN", + "contentScrollHandler_", + "header_", + "headerVisible", + "scrollTop", + "keyboardEventHandler_", + "drawer_", + "toggleDrawer", + "screenSizeHandler_", + "screenSizeMediaQuery_", + "matches", + "obfuscator_", + "drawerToggleHandler_", + "type", + "headerTransitionEndHandler_", + "headerClickHandler_", + "tabBar", + "drawerButton", + "focusedElement", + "directChildren", + "childNodes", + "numChildren", + "c", + "child", + "persisted", + "overflowY", + "mode", + "drawerButtonIcon", + "innerHTML", + "firstChild", + "obfuscator", + "matchMedia", + "addListener", + "tabContainer", + "leftButton", + "leftButtonIcon", + "scrollLeft", + "rightButton", + "rightButtonIcon", + "tabUpdateHandler", + "scrollWidth", + "windowResizeHandler", + "resizeTimeoutId_", + "MaterialDataTable", + "DATA_TABLE", + "SELECTABLE", + "SELECT_ELEMENT", + "IS_SELECTED", + "selectRow_", + "checkbox", + "row", + "opt_rows", + "createCheckbox_", + "label", + "labelClasses", + "firstHeader", + "bodyRows", + "footRows", + "rows", + "concat", + "th", + "headerCheckbox", + "firstCell", + "td", + "nodeName", + "toUpperCase", + "rowCheckbox", + "MaterialRipple", + "INITIAL_SCALE", + "INITIAL_SIZE", + "INITIAL_OPACITY", + "FINAL_OPACITY", + "FINAL_SCALE", + "RIPPLE_EFFECT_IGNORE_EVENTS", + "downHandler_", + "boundHeight", + "boundWidth", + "rippleSize_", + "sqrt", + "ignoringMouseDown_", + "frameCount", + "getFrameCount", + "setFrameCount", + "x", + "bound", + "currentTarget", + "round", + "touches", + "setRippleXY", + "setRippleStyles", + "animFrameHandler", + "upHandler_", + "detail", + "recentering", + "frameCount_", + "x_", + "y_", + "boundDownHandler", + "boundUpHandler", + "fC", + "getRippleElement", + "newX", + "newY", + "transformString", + "scale", + "size", + "offset", + "webkitTransform", + "msTransform", + "transform" + ], + "mappings": ";;;;;;;wBA6GA,SAAAA,GAAAC,EAAAC,GACA,GAAAD,EAAA,CACA,GAAAC,EAAAC,SAAAC,UAAAC,SAAAH,EAAAI,YAAAC,sBAAA,CACA,GAAAC,GAAAC,SAAAC,cAAA,OACAF,GAAAJ,UAAAO,IAAAT,EAAAI,YAAAM,sBACAJ,EAAAJ,UAAAO,IAAAT,EAAAI,YAAAC,qBACA,IAAAM,GAAAJ,SAAAC,cAAA,OACAG,GAAAT,UAAAO,IAAAT,EAAAI,YAAAQ,YACAN,EAAAO,YAAAF,GACAZ,EAAAc,YAAAP,GAEAP,EAAAe,iBAAA,QAAA,SAAAC,GACA,GAAA,MAAAhB,EAAAiB,aAAA,QAAAC,OAAA,GAAA,CACAF,EAAAG,gBACA,IAAAC,GAAApB,EAAAoB,KAAAC,MAAA,KAAA,GACAC,EAAArB,EAAAC,SAAAqB,cAAA,IAAAH,EACAnB,GAAAuB,iBACAvB,EAAAwB,mBACAzB,EAAAG,UAAAO,IAAAT,EAAAI,YAAAqB,cACAJ,EAAAnB,UAAAO,IAAAT,EAAAI,YAAAqB,kBCwTA,QAAAC,GAAA3B,EAAA4B,EAAAC,EAAAC,GAIA,QAAAC,KACA,GAAAX,GAAApB,EAAAoB,KAAAC,MAAA,KAAA,GACAC,EAAAQ,EAAAE,SAAAT,cAAA,IAAAH,EACAU,GAAAN,eAAAI,GACAE,EAAAL,iBAAAI,GACA7B,EAAAG,UAAAO,IAAAoB,EAAAzB,YAAA4B,WACAX,EAAAnB,UAAAO,IAAAoB,EAAAzB,YAAA4B,WAEA,GAAAH,EAAAI,QAAA/B,UAAAC,SAAA0B,EAAAzB,YAAA8B,kBAAA,CACA,GAAA5B,GAAAC,SAAAC,cAAA,OACAF,GAAAJ,UAAAO,IAAAoB,EAAAzB,YAAA+B,kBACA7B,EAAAJ,UAAAO,IAAAoB,EAAAzB,YAAA8B,iBACA,IAAAvB,GAAAJ,SAAAC,cAAA,OACAG,GAAAT,UAAAO,IAAAoB,EAAAzB,YAAAgC,QACA9B,EAAAO,YAAAF,GACAZ,EAAAc,YAAAP,GAEAuB,EAAAI,QAAA/B,UAAAC,SAAA0B,EAAAzB,YAAAiC,oBACAtC,EAAAe,iBAAA,QAAA,SAAAC,GACA,MAAAhB,EAAAiB,aAAA,QAAAC,OAAA,KACAF,EAAAG,iBACAY,OAIA/B,EAAAuC,KAAAR,ECzbA,GAAAS,IAUAC,WAAA,SAAAC,EAAAC,KAQAC,eAAA,SAAAC,EAAAH,KAOAI,gBAAA,SAAAC,KAKAC,qBAAA,aAWAC,yBAAA,SAAAC,EAAAC,KAMAC,SAAA,SAAAC,KAMAC,kBAAA,SAAAC,KAGAf,GAAA,WAoBA,QAAAgB,GAAAC,EAAAC,GACA,IAAA,GAAAC,GAAA,EAAAA,EAAAC,EAAAC,OAAAF,IACA,GAAAC,EAAAD,GAAAG,YAAAL,EAIA,MAHA,mBAAAC,KACAE,EAAAD,GAAAD,GAEAE,EAAAD,EAGA,QAAA,EAUA,QAAAI,GAAAlB,GACA,GAAAmB,GAAAnB,EAAA5B,aAAA,gBAEA,OAAA,QAAA+C,GAAA,IAAAA,EAAA3C,MAAA,KAYA,QAAA4C,GAAApB,EAAAK,GACA,GAAAgB,GAAAH,EAAAlB,EACA,OAAAqB,GAAAC,QAAAjB,MAAA,EAWA,QAAAkB,GAAAC,EAAAC,EAAAC,GACA,GAAA,eAAAC,SAAA,kBAAAA,QAAAC,YACA,MAAA,IAAAA,aAAAJ,GACAC,QAAAA,EACAC,WAAAA,GAGA,IAAAG,GAAAlE,SAAAmE,YAAA,SAEA,OADAD,GAAAE,UAAAP,EAAAC,EAAAC,GACAG,EAaA,QAAAG,GAAAnC,EAAAC,GACA,GAAA,mBAAAD,IACA,mBAAAC,GACA,IAAA,GAAAgB,GAAA,EAAAA,EAAAC,EAAAC,OAAAF,IACAkB,EAAAjB,EAAAD,GAAAG,UACAF,EAAAD,GAAAmB,cAEA,CACA,GAAA5B,GAAA,CACA,IAAA,mBAAAP,GAAA,CACA,GAAAoC,GAAAvB,EAAAN,EACA6B,KACApC,EAAAoC,EAAAD,UAKA,IAAA,GADA/B,GAAAvC,SAAAwE,iBAAA,IAAArC,GACAsC,EAAA,EAAAA,EAAAlC,EAAAc,OAAAoB,IACAC,EAAAnC,EAAAkC,GAAA/B,IAYA,QAAAgC,GAAArC,EAAAH,GAEA,KAAA,gBAAAG,IAAAA,YAAAsC,UACA,KAAA,IAAAC,OAAA,oDAGA,IAAAC,GAAAjB,EAAA,0BAAA,GAAA,EAEA,IADAvB,EAAAyC,cAAAD,IACAA,EAAAE,iBAAA,CAIA,GAAArB,GAAAH,EAAAlB,GACA2C,IAGA,IAAA9C,EAUAuB,EAAApB,EAAAH,IACA8C,EAAAC,KAAAjC,EAAAd,QAXA,CACA,GAAAvC,GAAA0C,EAAA1C,SACAyD,GAAA8B,QAAA,SAAAC,GAEAxF,EAAAC,SAAAuF,EAAAb,WACAU,EAAArB,QAAAwB,MAAA,IACA1B,EAAApB,EAAA8C,EAAA7B,YACA0B,EAAAC,KAAAE,KAQA,IAAA,GAAAZ,GAAApB,EAAA,EAAAsB,EAAAO,EAAA3B,OAAAF,EAAAsB,EAAAtB,IAAA,CAEA,GADAoB,EAAAS,EAAA7B,IACAoB,EAiBA,KAAA,IAAAK,OACA,6DAhBAlB,GAAAuB,KAAAV,EAAAjB,WACAjB,EAAA+C,aAAA,gBAAA1B,EAAA2B,KAAA,KACA,IAAAC,GAAA,GAAAf,GAAAgB,iBAAAlD,EACAiD,GAAAE,GAAAjB,EACAkB,EAAAR,KAAAK,EAEA,KAAA,GAAAI,GAAA,EAAAC,EAAApB,EAAAqB,UAAAvC,OAAAqC,EAAAC,EAAAD,IACAnB,EAAAqB,UAAAF,GAAArD,EAGAkC,GAAAsB,SAEAxD,EAAAkC,EAAAjB,WAAAgC,EAOA,IAAAQ,GAAAlC,EAAA,yBAAA,GAAA,EACAvB,GAAAyC,cAAAgB,KAUA,QAAAC,GAAAxD,GACAyD,MAAAC,QAAA1D,KAEAA,EADAA,YAAAoC,UACApC,GAEAyD,MAAAE,UAAAC,MAAAC,KAAA7D,GAGA,KAAA,GAAAF,GAAAc,EAAA,EAAAsB,EAAAlC,EAAAc,OAAAF,EAAAsB,EAAAtB,IACAd,EAAAE,EAAAY,GACAd,YAAAgE,eACA3B,EAAArC,GACAA,EAAAiE,SAAAjD,OAAA,GACA0C,EAAA1D,EAAAiE,WAWA,QAAAC,GAAA1D,GAKA,GAAA2D,GAAA,mBAAA3D,GAAAgD,QACA,mBAAAhD,GAAA,OACAgD,GAAA,CAEAW,KACAX,EAAAhD,EAAAgD,QAAAhD,EAAA,OAGA,IAAA4D,IACAlB,iBAAA1C,EAAA6D,aAAA7D,EAAA,YACAS,UAAAT,EAAA8D,eAAA9D,EAAA,cACAyB,SAAAzB,EAAAyB,UAAAzB,EAAA,SACAgD,OAAAA,EACAD,aAYA,IATAxC,EAAA8B,QAAA,SAAA0B,GACA,GAAAA,EAAAtC,WAAAmC,EAAAnC,SACA,KAAA,IAAAM,OAAA,sDAAAgC,EAAAtC,SAEA,IAAAsC,EAAAtD,YAAAmD,EAAAnD,UACA,KAAA,IAAAsB,OAAA,wDAIA/B,EAAA6D,YAAAR,UACAW,eAAArB,GACA,KAAA,IAAAZ,OACA,uCAAAY,EACA,0BAGA,IAAAsB,GAAA9D,EAAAH,EAAA8D,cAAAF,EAEAK,IACA1D,EAAA6B,KAAAwB,GAcA,QAAAM,GAAArE,EAAAC,GACA,GAAAqE,GAAAhE,EAAAN,EACAsE,IACAA,EAAApB,UAAAX,KAAAtC,GAQA,QAAAsE,KACA,IAAA,GAAAxC,GAAA,EAAAA,EAAArB,EAAAC,OAAAoB,IACAJ,EAAAjB,EAAAqB,GAAAnB,WAWA,QAAA4D,GAAA/B,GACA,GAAAA,EAAA,CACA,GAAAgC,GAAA1B,EAAA9B,QAAAwB,EACAM,GAAA2B,OAAAD,EAAA,EAEA,IAAAE,GAAAlC,EAAAzF,SAAAe,aAAA,iBAAAI,MAAA,KACAyG,EAAAD,EAAA1D,QAAAwB,EAAAK,GAAAmB,cACAU,GAAAD,OAAAE,EAAA,GACAnC,EAAAzF,SAAA0F,aAAA,gBAAAiC,EAAAhC,KAAA,KAEA,IAAAnB,GAAAN,EAAA,2BAAA,GAAA,EACAuB,GAAAzF,SAAAoF,cAAAZ,IASA,QAAAqD,GAAAxE,GAKA,GAAAyE,GAAA,SAAAC,GACAhC,EAAAiC,OAAA,SAAAd,GACA,MAAAA,GAAAlH,WAAA+H,IACAvC,QAAAgC,GAEA,IAAAnE,YAAAiD,QAAAjD,YAAA4E,UACA,IAAA,GAAAlD,GAAA,EAAAA,EAAA1B,EAAAM,OAAAoB,IACA+C,EAAAzE,EAAA0B,QAEA,CAAA,KAAA1B,YAAA6E,OAGA,KAAA,IAAAhD,OAAA,oDAFA4C,GAAAzE,IA7TA,GAAAK,MAGAqC,KAEAD,EAAA,6BAgUA,QACAvD,WAAAoC,EACAjC,eAAAsC,EACApC,gBAAAyD,EACAvD,qBAAAyE,EACAxE,yBAAAsE,EACAnE,SAAA2D,EACAzD,kBAAAyE,MAeAvF,EAAA6F,sBAcA7F,EAAA8F,gBAcA9F,EAAA+F,UAIA/F,EAAA,WAAAA,EAAAC,WACAD,EAAA,eAAAA,EAAAI,eACAJ,EAAA,gBAAAA,EAAAM,gBACAN,EAAA,qBACAA,EAAAQ,qBACAR,EAAA,yBACAA,EAAAS,yBACAT,EAAA,SAAAA,EAAAY,SACAZ,EAAA,kBAAAA,EAAAc,kBACAkB,OAAAhC,iBAAAA,EACAgC,OAAA,iBAAAhC,EAEAgC,OAAAzD,iBAAA,OAAA,WAQA,aAAAP,UAAAC,cAAA,QACA,iBAAAD,WACA,oBAAAgE,SAAAgC,MAAAE,UAAAhB,SACAlF,SAAAgI,gBAAArI,UAAAO,IAAA,UACA8B,EAAAQ,yBAKAR,EAAAI,eAAA,aAIAJ,EAAAY,SAAA,gBC7eAqF,KAAAC,MAKAD,KAAAC,IAAA,WACA,OAAA,GAAAD,OAAAE,WAEAF,KAAA,IAAAA,KAAAC,IAMA,KAAA,GAJAE,IACA,SACA,OAEAjF,EAAA,EAAAA,EAAAiF,EAAA/E,SAAAW,OAAAqE,wBAAAlF,EAAA,CACA,GAAAmF,GAAAF,EAAAjF,EACAa,QAAAqE,sBAAArE,OAAAsE,EAAA,yBACAtE,OAAAuE,qBAAAvE,OAAAsE,EAAA,yBAAAtE,OAAAsE,EAAA,+BACAtE,OAAA,sBAAAA,OAAAqE,sBACArE,OAAA,qBAAAA,OAAAuE,qBAEA,GAAA,uBAAAC,KAAAxE,OAAAyE,UAAAC,aAAA1E,OAAAqE,wBAAArE,OAAAuE,qBAAA,CACA,GAAAI,GAAA,CAKA3E,QAAAqE,sBAAA,SAAA1F,GACA,GAAAuF,GAAAD,KAAAC,MACAU,EAAAC,KAAAC,IAAAH,EAAA,GAAAT,EACA,OAAAa,YAAA,WACApG,EAAAgG,EAAAC,IACAA,EAAAV,IAEAlE,OAAAuE,qBAAAS,aACAhF,OAAA,sBAAAA,OAAAqE,sBACArE,OAAA,qBAAAA,OAAAuE,qBCpBA,GAAAU,GAAA,SAAA5G,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,eAAAiF,EAOAA,EAAA/C,UAAAkD,aASAH,EAAA/C,UAAArG,aACAwJ,cAAA,uBACAzH,iBAAA,+BACAC,OAAA,cAQAoH,EAAA/C,UAAAoD,aAAA,SAAAC,GACAA,GACAL,KAAAxJ,SAAA8J,QASAP,EAAA/C,UAAAuD,QAAA,WACAP,KAAAxJ,SAAAgK,UAAA,GAEAT,EAAA/C,UAAA,QAAA+C,EAAA/C,UAAAuD,QAMAR,EAAA/C,UAAAyD,OAAA,WACAT,KAAAxJ,SAAAgK,UAAA,GAEAT,EAAA/C,UAAA,OAAA+C,EAAA/C,UAAAyD,OAIAV,EAAA/C,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACA,GAAAwJ,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAwJ,eAAA,CACA,GAAAtJ,GAAAC,SAAAC,cAAA,OACAF,GAAAJ,UAAAO,IAAAgJ,KAAArJ,YAAA+B,kBACAsH,KAAAU,eAAA5J,SAAAC,cAAA,QACAiJ,KAAAU,eAAAjK,UAAAO,IAAAgJ,KAAArJ,YAAAgC,QACA9B,EAAAO,YAAA4I,KAAAU,gBACAV,KAAAW,uBAAAX,KAAAI,aAAAQ,KAAAZ,MACAA,KAAAU,eAAArJ,iBAAA,UAAA2I,KAAAW,wBACAX,KAAAxJ,SAAAY,YAAAP,GAEAmJ,KAAAa,uBAAAb,KAAAI,aAAAQ,KAAAZ,MACAA,KAAAxJ,SAAAa,iBAAA,UAAA2I,KAAAa,wBACAb,KAAAxJ,SAAAa,iBAAA,aAAA2I,KAAAa,0BAKA/H,EAAAY,UACA8D,YAAAuC,EACAtC,cAAA,iBACArC,SAAA,gBACAuB,QAAA,GCjFA,IAAAmE,GAAA,SAAA3H,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,iBAAAgG,EAOAA,EAAA9D,UAAAkD,WAAAa,aAAA,MASAD,EAAA9D,UAAArG,aACAqK,MAAA,sBACAC,YAAA,4BACAC,aAAA,6BACAC,aAAA,6BACAhB,cAAA,uBACAiB,qBAAA,sCACA1I,iBAAA,iCACA2I,cAAA,qBACA1I,OAAA,aACA2I,WAAA,aACAC,YAAA,cACAC,WAAA,aACAC,YAAA,eAQAX,EAAA9D,UAAA0E,UAAA,SAAArB,GACAL,KAAA2B,kBAQAb,EAAA9D,UAAA4E,SAAA,SAAAvB,GACAL,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA2K,aAQAR,EAAA9D,UAAA6E,QAAA,SAAAxB,GACAL,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA2K,aAQAR,EAAA9D,UAAA+E,WAAA,SAAA1B,GACAL,KAAAgC,SAOAlB,EAAA9D,UAAA2E,eAAA,WACA3B,KAAAiC,gBACAjC,KAAAkC,oBAOApB,EAAA9D,UAAAgF,MAAA,WAGAlH,OAAA+E,WAAA,WACAG,KAAAmC,cAAA7B,QACAM,KAAAZ,MAAAA,KAAAE,UAAAa,eAQAD,EAAA9D,UAAAkF,iBAAA,WACAlC,KAAAmC,cAAAC,QACApC,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA6K,YAEAxB,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA6K,aAGAV,EAAA9D,UAAA,iBAAA8D,EAAA9D,UAAAkF,iBAMApB,EAAA9D,UAAAiF,cAAA,WACAjC,KAAAmC,cAAA3B,SACAR,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA4K,aAEAvB,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA4K,cAGAT,EAAA9D,UAAA,cAAA8D,EAAA9D,UAAAiF,cAMAnB,EAAA9D,UAAAuD,QAAA,WACAP,KAAAmC,cAAA3B,UAAA,EACAR,KAAA2B,kBAEAb,EAAA9D,UAAA,QAAA8D,EAAA9D,UAAAuD,QAMAO,EAAA9D,UAAAyD,OAAA,WACAT,KAAAmC,cAAA3B,UAAA,EACAR,KAAA2B,kBAEAb,EAAA9D,UAAA,OAAA8D,EAAA9D,UAAAyD,OAMAK,EAAA9D,UAAAqF,MAAA,WACArC,KAAAmC,cAAAC,SAAA,EACApC,KAAA2B,kBAEAb,EAAA9D,UAAA,MAAA8D,EAAA9D,UAAAqF,MAMAvB,EAAA9D,UAAAsF,QAAA,WACAtC,KAAAmC,cAAAC,SAAA,EACApC,KAAA2B,kBAEAb,EAAA9D,UAAA,QAAA8D,EAAA9D,UAAAsF,QAIAxB,EAAA9D,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACAwJ,KAAAmC,cAAAnC,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAArJ,YAAAqK,MACA,IAAAuB,GAAAzL,SAAAC,cAAA,OACAwL,GAAA9L,UAAAO,IAAAgJ,KAAArJ,YAAAsK,YACA,IAAAuB,GAAA1L,SAAAC,cAAA,OACAyL,GAAA/L,UAAAO,IAAAgJ,KAAArJ,YAAAuK,aACA,IAAAuB,GAAA3L,SAAAC,cAAA,OAKA,IAJA0L,EAAAhM,UAAAO,IAAAgJ,KAAArJ,YAAAwK,cACAoB,EAAAnL,YAAAqL,GACAzC,KAAAxJ,SAAAY,YAAAoL,GACAxC,KAAAxJ,SAAAY,YAAAmL,GACAvC,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAwJ,eAAA,CACAH,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAyK,sBACApB,KAAA0C,wBAAA5L,SAAAC,cAAA,QACAiJ,KAAA0C,wBAAAjM,UAAAO,IAAAgJ,KAAArJ,YAAA+B,kBACAsH,KAAA0C,wBAAAjM,UAAAO,IAAAgJ,KAAArJ,YAAAwJ,eACAH,KAAA0C,wBAAAjM,UAAAO,IAAAgJ,KAAArJ,YAAA0K,eACArB,KAAA2C,mBAAA3C,KAAA+B,WAAAnB,KAAAZ,MACAA,KAAA0C,wBAAArL,iBAAA,UAAA2I,KAAA2C,mBACA,IAAAzL,GAAAJ,SAAAC,cAAA,OACAG,GAAAT,UAAAO,IAAAgJ,KAAArJ,YAAAgC,QACAqH,KAAA0C,wBAAAtL,YAAAF,GACA8I,KAAAxJ,SAAAY,YAAA4I,KAAA0C,yBAEA1C,KAAA4C,mBAAA5C,KAAA0B,UAAAd,KAAAZ,MACAA,KAAA6C,kBAAA7C,KAAA4B,SAAAhB,KAAAZ,MACAA,KAAA8C,iBAAA9C,KAAA6B,QAAAjB,KAAAZ,MACAA,KAAA+C,oBAAA/C,KAAA+B,WAAAnB,KAAAZ,MACAA,KAAAmC,cAAA9K,iBAAA,SAAA2I,KAAA4C,oBACA5C,KAAAmC,cAAA9K,iBAAA,QAAA2I,KAAA6C,mBACA7C,KAAAmC,cAAA9K,iBAAA,OAAA2I,KAAA8C,kBACA9C,KAAAxJ,SAAAa,iBAAA,UAAA2I,KAAA+C,qBACA/C,KAAA2B,iBACA3B,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA8K,eAKA3I,EAAAY,UACA8D,YAAAsD,EACArD,cAAA,mBACArC,SAAA,kBACAuB,QAAA,GC9MA,IAAAqG,GAAA,SAAA7J,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,mBAAAkI,EAOAA,EAAAhG,UAAAkD,WAAAa,aAAA,MASAiC,EAAAhG,UAAArG,aACAqK,MAAA,yBACAvI,iBAAA,uBACA2I,qBAAA,sCACA1I,iBAAA,oCACA2I,cAAA,qBACA1I,OAAA,aACA2I,WAAA,aACAC,YAAA,cACAC,WAAA,cAQAwB,EAAAhG,UAAA0E,UAAA,SAAArB,GACAL,KAAA2B,kBAQAqB,EAAAhG,UAAA4E,SAAA,SAAAvB,GACAL,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA2K,aAQA0B,EAAAhG,UAAA6E,QAAA,SAAAxB,GACAL,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA2K,aAQA0B,EAAAhG,UAAA+E,WAAA,SAAA1B,GACAL,KAAAgC,SAOAgB,EAAAhG,UAAA2E,eAAA,WACA3B,KAAAiC,gBACAjC,KAAAkC,oBAOAc,EAAAhG,UAAAgF,MAAA,WAGAlH,OAAA+E,WAAA,WACAG,KAAAmC,cAAA7B,QACAM,KAAAZ,MAAAA,KAAAE,UAAAa,eAQAiC,EAAAhG,UAAAkF,iBAAA,WACAlC,KAAAmC,cAAAC,QACApC,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA6K,YAEAxB,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA6K,aAGAwB,EAAAhG,UAAA,iBAAAgG,EAAAhG,UAAAkF,iBAMAc,EAAAhG,UAAAiF,cAAA,WACAjC,KAAAmC,cAAA3B,SACAR,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA4K,aAEAvB,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA4K,cAGAyB,EAAAhG,UAAA,cAAAgG,EAAAhG,UAAAiF,cAMAe,EAAAhG,UAAAuD,QAAA,WACAP,KAAAmC,cAAA3B,UAAA,EACAR,KAAA2B,kBAEAqB,EAAAhG,UAAA,QAAAgG,EAAAhG,UAAAuD,QAMAyC,EAAAhG,UAAAyD,OAAA,WACAT,KAAAmC,cAAA3B,UAAA,EACAR,KAAA2B,kBAEAqB,EAAAhG,UAAA,OAAAgG,EAAAhG,UAAAyD,OAMAuC,EAAAhG,UAAAqF,MAAA,WACArC,KAAAmC,cAAAC,SAAA,EACApC,KAAA2B,kBAEAqB,EAAAhG,UAAA,MAAAgG,EAAAhG,UAAAqF,MAMAW,EAAAhG,UAAAsF,QAAA,WACAtC,KAAAmC,cAAAC,SAAA,EACApC,KAAA2B,kBAEAqB,EAAAhG,UAAA,QAAAgG,EAAAhG,UAAAsF,QAIAU,EAAAhG,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CAEA,GADAwJ,KAAAmC,cAAAnC,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAArJ,YAAAqK,OACAhB,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA8B,kBAAA,CACAuH,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAyK,sBACApB,KAAA0C,wBAAA5L,SAAAC,cAAA,QACAiJ,KAAA0C,wBAAAjM,UAAAO,IAAAgJ,KAAArJ,YAAA+B,kBACAsH,KAAA0C,wBAAAjM,UAAAO,IAAAgJ,KAAArJ,YAAA8B,kBACAuH,KAAA0C,wBAAAjM,UAAAO,IAAAgJ,KAAArJ,YAAA0K,eACArB,KAAA2C,mBAAA3C,KAAA+B,WAAAnB,KAAAZ,MACAA,KAAA0C,wBAAArL,iBAAA,UAAA2I,KAAA2C,mBACA,IAAAzL,GAAAJ,SAAAC,cAAA,OACAG,GAAAT,UAAAO,IAAAgJ,KAAArJ,YAAAgC,QACAqH,KAAA0C,wBAAAtL,YAAAF,GACA8I,KAAAxJ,SAAAY,YAAA4I,KAAA0C,yBAEA1C,KAAA4C,mBAAA5C,KAAA0B,UAAAd,KAAAZ,MACAA,KAAA6C,kBAAA7C,KAAA4B,SAAAhB,KAAAZ,MACAA,KAAA8C,iBAAA9C,KAAA6B,QAAAjB,KAAAZ,MACAA,KAAAiD,sBAAAjD,KAAA+B,WAAAnB,KAAAZ,MACAA,KAAAmC,cAAA9K,iBAAA,SAAA2I,KAAA4C,oBACA5C,KAAAmC,cAAA9K,iBAAA,QAAA2I,KAAA6C,mBACA7C,KAAAmC,cAAA9K,iBAAA,OAAA2I,KAAA8C,kBACA9C,KAAAxJ,SAAAa,iBAAA,UAAA2I,KAAAiD,uBACAjD,KAAA2B,iBACA3B,KAAAxJ,SAAAC,UAAAO,IAAA,iBAKA8B,EAAAY,UACA8D,YAAAwF,EACAvF,cAAA,qBACArC,SAAA,qBACAuB,QAAA,GCjMA,IAAAuG,GAAA,SAAA/J,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,aAAAoI,EAOAA,EAAAlG,UAAAkD,WAEAiD,4BAAA,GAEAC,6BAAA,GAGAC,cAAA,KAQAH,EAAAlG,UAAAsG,WACAC,MAAA,GACAC,OAAA,GACAC,MAAA,GACAC,SAAA,GACAC,WAAA,IAUAT,EAAAlG,UAAArG,aACAiN,UAAA,sBACAC,QAAA,oBACAC,KAAA,iBACAC,sBAAA,kCACA5D,cAAA,uBACAiB,qBAAA,sCACAzI,OAAA,aAEA8I,YAAA,cACAuC,WAAA,aACAC,aAAA,eAEAC,YAAA,wBAEAC,aAAA,yBACAC,SAAA,qBACAC,UAAA,sBACAC,UAAA,uBAKApB,EAAAlG,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CAEA,GAAA+N,GAAAzN,SAAAC,cAAA,MACAwN,GAAA9N,UAAAO,IAAAgJ,KAAArJ,YAAAiN,WACA5D,KAAAxJ,SAAAgO,cAAAC,aAAAF,EAAAvE,KAAAxJ,UACAwJ,KAAAxJ,SAAAgO,cAAAE,YAAA1E,KAAAxJ,UACA+N,EAAAnN,YAAA4I,KAAAxJ,UACAwJ,KAAA2E,WAAAJ,CAEA,IAAAK,GAAA9N,SAAAC,cAAA,MACA6N,GAAAnO,UAAAO,IAAAgJ,KAAArJ,YAAAkN,SACA7D,KAAA6E,SAAAD,EACAL,EAAAE,aAAAG,EAAA5E,KAAAxJ,SAEA,IAAAsO,GAAA9E,KAAAxJ,SAAAe,aAAA,QAAAyI,KAAAxJ,SAAAe,aAAA,gBACAwN,EAAA,IACAD,KACAC,EAAAjO,SAAAkO,eAAAF,GACAC,IACA/E,KAAAiF,YAAAF,EACAA,EAAA1N,iBAAA,QAAA2I,KAAAkF,gBAAAtE,KAAAZ,OACA+E,EAAA1N,iBAAA,UAAA2I,KAAAmF,wBAAAvE,KAAAZ,QAGA,IAAAoF,GAAApF,KAAAxJ,SAAA8E,iBAAA,IAAA0E,KAAArJ,YAAAmN,KACA9D,MAAAqF,kBAAArF,KAAAsF,yBAAA1E,KAAAZ,MACAA,KAAAuF,gBAAAvF,KAAAwF,iBAAA5E,KAAAZ,KACA,KAAA,GAAA/F,GAAA,EAAAA,EAAAmL,EAAAjL,OAAAF,IAEAmL,EAAAnL,GAAA5C,iBAAA,QAAA2I,KAAAuF,iBAEAH,EAAAnL,GAAAwL,SAAA,KAEAL,EAAAnL,GAAA5C,iBAAA,UAAA2I,KAAAqF,kBAGA,IAAArF,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAwJ,eAEA,IADAH,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAyK,sBACAnH,EAAA,EAAAA,EAAAmL,EAAAjL,OAAAF,IAAA,CACA,GAAAyD,GAAA0H,EAAAnL,GACApD,EAAAC,SAAAC,cAAA,OACAF,GAAAJ,UAAAO,IAAAgJ,KAAArJ,YAAAoN,sBACA,IAAA7M,GAAAJ,SAAAC,cAAA,OACAG,GAAAT,UAAAO,IAAAgJ,KAAArJ,YAAAgC,QACA9B,EAAAO,YAAAF,GACAwG,EAAAtG,YAAAP,GACA6G,EAAAjH,UAAAO,IAAAgJ,KAAArJ,YAAAwJ,eAIAH,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAuN,cACAlE,KAAA6E,SAAApO,UAAAO,IAAAgJ,KAAArJ,YAAAuN,aAEAlE,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAwN,eACAnE,KAAA6E,SAAApO,UAAAO,IAAAgJ,KAAArJ,YAAAwN,cAEAnE,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAyN,WACApE,KAAA6E,SAAApO,UAAAO,IAAAgJ,KAAArJ,YAAAyN,UAEApE,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA0N,YACArE,KAAA6E,SAAApO,UAAAO,IAAAgJ,KAAArJ,YAAA0N,WAEArE,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA2N,YACAtE,KAAA6E,SAAApO,UAAAO,IAAAgJ,KAAArJ,YAAA2N,WAEAC,EAAA9N,UAAAO,IAAAgJ,KAAArJ,YAAA8K,eAUAyB,EAAAlG,UAAAkI,gBAAA,SAAAQ,GACA,GAAA1F,KAAAxJ,UAAAwJ,KAAAiF,YAAA,CACA,GAAAU,GAAA3F,KAAAiF,YAAAW,wBACAC,EAAA7F,KAAAiF,YAAAT,cAAAoB,uBACA5F,MAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA2N,aACAtE,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAwN,eAEAnE,KAAA2E,WAAAmB,MAAAC,MAAAF,EAAAE,MAAAJ,EAAAI,MAAA,KACA/F,KAAA2E,WAAAmB,MAAAE,IAAAhG,KAAAiF,YAAAgB,UAAAjG,KAAAiF,YAAAiB,aAAA,MACAlG,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAyN,WAEApE,KAAA2E,WAAAmB,MAAAK,KAAAnG,KAAAiF,YAAAmB,WAAA,KACApG,KAAA2E,WAAAmB,MAAAO,OAAAR,EAAAQ,OAAAV,EAAAK,IAAA,MACAhG,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA0N,YAEArE,KAAA2E,WAAAmB,MAAAC,MAAAF,EAAAE,MAAAJ,EAAAI,MAAA,KACA/F,KAAA2E,WAAAmB,MAAAO,OAAAR,EAAAQ,OAAAV,EAAAK,IAAA,OAGAhG,KAAA2E,WAAAmB,MAAAK,KAAAnG,KAAAiF,YAAAmB,WAAA,KACApG,KAAA2E,WAAAmB,MAAAE,IAAAhG,KAAAiF,YAAAgB,UAAAjG,KAAAiF,YAAAiB,aAAA,OAGAlG,KAAAsG,OAAAZ,IAQAxC,EAAAlG,UAAAmI,wBAAA,SAAAO,GACA,GAAA1F,KAAAxJ,UAAAwJ,KAAA2E,YAAA3E,KAAAiF,YAAA,CACA,GAAAG,GAAApF,KAAAxJ,SAAA8E,iBAAA,IAAA0E,KAAArJ,YAAAmN,KAAA,mBACAsB,IAAAA,EAAAjL,OAAA,GAAA6F,KAAA2E,WAAAlO,UAAAC,SAAAsJ,KAAArJ,YAAAqN,cACA0B,EAAAa,UAAAvG,KAAAsD,UAAAI,UACAgC,EAAAjO,iBACA2N,EAAAA,EAAAjL,OAAA,GAAAqM,SACAd,EAAAa,UAAAvG,KAAAsD,UAAAK,aACA+B,EAAAjO,iBACA2N,EAAA,GAAAoB,YAWAtD,EAAAlG,UAAAsI,yBAAA,SAAAI,GACA,GAAA1F,KAAAxJ,UAAAwJ,KAAA2E,WAAA,CACA,GAAAS,GAAApF,KAAAxJ,SAAA8E,iBAAA,IAAA0E,KAAArJ,YAAAmN,KAAA,mBACA,IAAAsB,GAAAA,EAAAjL,OAAA,GAAA6F,KAAA2E,WAAAlO,UAAAC,SAAAsJ,KAAArJ,YAAAqN,YAAA,CACA,GAAAyC,GAAA3J,MAAAE,UAAAC,MAAAC,KAAAkI,GAAA3K,QAAAiL,EAAAgB,OACA,IAAAhB,EAAAa,UAAAvG,KAAAsD,UAAAI,SACAgC,EAAAjO,iBACAgP,EAAA,EACArB,EAAAqB,EAAA,GAAAD,QAEApB,EAAAA,EAAAjL,OAAA,GAAAqM,YAEA,IAAAd,EAAAa,UAAAvG,KAAAsD,UAAAK,WACA+B,EAAAjO,iBACA2N,EAAAjL,OAAAsM,EAAA,EACArB,EAAAqB,EAAA,GAAAD,QAEApB,EAAA,GAAAoB,YAEA,IAAAd,EAAAa,UAAAvG,KAAAsD,UAAAG,OAAAiC,EAAAa,UAAAvG,KAAAsD,UAAAC,MAAA,CACAmC,EAAAjO,gBAEA,IAAAH,GAAA,GAAAqP,YAAA,YACAjB,GAAAgB,OAAA9K,cAAAtE,GACAA,EAAA,GAAAqP,YAAA,WACAjB,EAAAgB,OAAA9K,cAAAtE,GAEAoO,EAAAgB,OAAAE,YACAlB,GAAAa,UAAAvG,KAAAsD,UAAAE,SACAkC,EAAAjO,iBACAuI,KAAA6G,WAWA3D,EAAAlG,UAAAwI,iBAAA,SAAAE,GACAA,EAAAgB,OAAAI,aAAA,YACApB,EAAAqB,mBAGA/G,KAAAgH,UAAA,EACAlM,OAAA+E,WAAA,SAAA6F,GACA1F,KAAA6G,OACA7G,KAAAgH,UAAA,GACApG,KAAAZ,MAAAA,KAAAE,UAAAmD,iBAYAH,EAAAlG,UAAAiK,WAAA,SAAAC,EAAAC,GACAnH,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA2N,WAEAtE,KAAAxJ,SAAAsP,MAAAsB,KAAA,GACApH,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAwN,cAEAnE,KAAAxJ,SAAAsP,MAAAsB,KAAA,UAAAD,EAAA,QAAAA,EAAA,MACAnH,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAyN,UAEApE,KAAAxJ,SAAAsP,MAAAsB,KAAA,QAAAF,EAAA,QAAAA,EAAA,QACAlH,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA0N,WAEArE,KAAAxJ,SAAAsP,MAAAsB,KAAA,QAAAF,EAAA,MAAAC,EAAA,MAAAD,EAAA,MAAAC,EAAA,MAGAnH,KAAAxJ,SAAAsP,MAAAsB,KAAA,IASAlE,EAAAlG,UAAAqK,4BAAA,SAAA3B,GACAA,EAAAgB,OAAAjQ,UAAAqL,OAAAoB,EAAAlG,UAAArG,YAAAsN,eAOAf,EAAAlG,UAAAsK,yBAAA,WACAtH,KAAAxJ,SAAAa,iBAAA,gBAAA2I,KAAAqH,6BACArH,KAAAxJ,SAAAa,iBAAA,sBAAA2I,KAAAqH,8BAOAnE,EAAAlG,UAAAnE,KAAA,SAAA6M,GACA,GAAA1F,KAAAxJ,UAAAwJ,KAAA2E,YAAA3E,KAAA6E,SAAA,CAEA,GAAAqC,GAAAlH,KAAAxJ,SAAAoP,wBAAAsB,OACAC,EAAAnH,KAAAxJ,SAAAoP,wBAAAuB,KAEAnH,MAAA2E,WAAAmB,MAAAqB,MAAAA,EAAA,KACAnH,KAAA2E,WAAAmB,MAAAoB,OAAAA,EAAA,KACAlH,KAAA6E,SAAAiB,MAAAqB,MAAAA,EAAA,KACAnH,KAAA6E,SAAAiB,MAAAoB,OAAAA,EAAA,IAKA,KAAA,GAJAK,GAAAvH,KAAAE,UAAAiD,4BAAAnD,KAAAE,UAAAkD,6BAGAgC,EAAApF,KAAAxJ,SAAA8E,iBAAA,IAAA0E,KAAArJ,YAAAmN,MACA7J,EAAA,EAAAA,EAAAmL,EAAAjL,OAAAF,IAAA,CACA,GAAAuN,GAAA,IAEAA,GADAxH,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAyN,WAAApE,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA0N,YACA6C,EAAA9B,EAAAnL,GAAAgM,UAAAb,EAAAnL,GAAAiM,cAAAgB,EAAAK,EAAA,IAEAnC,EAAAnL,GAAAgM,UAAAiB,EAAAK,EAAA,IAEAnC,EAAAnL,GAAA6L,MAAA2B,gBAAAD,EAGAxH,KAAAiH,WAAAC,EAAAC,GAGArM,OAAAqE,sBAAA,WACAa,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAsN,cACAjE,KAAAxJ,SAAAsP,MAAAsB,KAAA,UAAAD,EAAA,MAAAD,EAAA,QACAlH,KAAA2E,WAAAlO,UAAAO,IAAAgJ,KAAArJ,YAAAqN,aACApD,KAAAZ,OAEAA,KAAAsH,0BAEA,IAAA7N,GAAA,SAAAnC,GAOAA,IAAAoO,GAAA1F,KAAAgH,UAAA1P,EAAAoP,OAAAgB,aAAA1H,KAAAxJ,WACAM,SAAA6Q,oBAAA,QAAAlO,GACAuG,KAAA6G,SAEAjG,KAAAZ,KACAlJ,UAAAO,iBAAA,QAAAoC,KAGAyJ,EAAAlG,UAAA,KAAAkG,EAAAlG,UAAAnE,KAMAqK,EAAAlG,UAAA6J,KAAA,WACA,GAAA7G,KAAAxJ,UAAAwJ,KAAA2E,YAAA3E,KAAA6E,SAAA,CAGA,IAAA,GAFAO,GAAApF,KAAAxJ,SAAA8E,iBAAA,IAAA0E,KAAArJ,YAAAmN,MAEA7J,EAAA,EAAAA,EAAAmL,EAAAjL,OAAAF,IACAmL,EAAAnL,GAAA6L,MAAA8B,eAAA,mBAGA,IAAAjC,GAAA3F,KAAAxJ,SAAAoP,wBACAsB,EAAAvB,EAAAuB,OACAC,EAAAxB,EAAAwB,KAGAnH,MAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAsN,cACAjE,KAAAiH,WAAAC,EAAAC,GACAnH,KAAA2E,WAAAlO,UAAAqL,OAAA9B,KAAArJ,YAAAqN,YAEAhE,KAAAsH,6BAGApE,EAAAlG,UAAA,KAAAkG,EAAAlG,UAAA6J,KAMA3D,EAAAlG,UAAAsJ,OAAA,SAAAZ,GACA1F,KAAA2E,WAAAlO,UAAAC,SAAAsJ,KAAArJ,YAAAqN,YACAhE,KAAA6G,OAEA7G,KAAAnH,KAAA6M,IAGAxC,EAAAlG,UAAA,OAAAkG,EAAAlG,UAAAsJ,OAGAxN,EAAAY,UACA8D,YAAA0F,EACAzF,cAAA,eACArC,SAAA,cACAuB,QAAA,GCvYA,IAAAkL,GAAA,SAAA1O,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,iBAAA+M,EAOAA,EAAA7K,UAAAkD,aASA2H,EAAA7K,UAAArG,aAAAmR,oBAAA,+BAOAD,EAAA7K,UAAA+K,YAAA,SAAAC,GACAhI,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAmR,uBAGA9H,KAAAiI,aAAAnC,MAAAqB,MAAAa,EAAA,MAEAH,EAAA7K,UAAA,YAAA6K,EAAA7K,UAAA+K,YAOAF,EAAA7K,UAAAkL,UAAA,SAAAF,GACAhI,KAAAmI,WAAArC,MAAAqB,MAAAa,EAAA,IACAhI,KAAAoI,QAAAtC,MAAAqB,MAAA,IAAAa,EAAA,KAEAH,EAAA7K,UAAA,UAAA6K,EAAA7K,UAAAkL,UAIAL,EAAA7K,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACA,GAAA6R,GAAAvR,SAAAC,cAAA,MACAsR,GAAAjO,UAAA,uBACA4F,KAAAxJ,SAAAY,YAAAiR,GACArI,KAAAiI,aAAAI,EACAA,EAAAvR,SAAAC,cAAA,OACAsR,EAAAjO,UAAA,qBACA4F,KAAAxJ,SAAAY,YAAAiR,GACArI,KAAAmI,WAAAE,EACAA,EAAAvR,SAAAC,cAAA,OACAsR,EAAAjO,UAAA,kBACA4F,KAAAxJ,SAAAY,YAAAiR,GACArI,KAAAoI,QAAAC,EACArI,KAAAiI,aAAAnC,MAAAqB,MAAA,KACAnH,KAAAmI,WAAArC,MAAAqB,MAAA,OACAnH,KAAAoI,QAAAtC,MAAAqB,MAAA,KACAnH,KAAAxJ,SAAAC,UAAAO,IAAA,iBAKA8B,EAAAY,UACA8D,YAAAqK,EACApK,cAAA,mBACArC,SAAA,kBACAuB,QAAA,GC3EA,IAAA2L,GAAA,SAAAnP,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,cAAAwN,EAOAA,EAAAtL,UAAAkD,WAAAa,aAAA,MASAuH,EAAAtL,UAAArG,aACA2K,WAAA,aACAC,YAAA,cACAC,WAAA,aACAC,YAAA,cACA8G,SAAA,eACAC,UAAA,oBACAC,mBAAA,0BACAC,mBAAA,0BACAvI,cAAA,uBACAiB,qBAAA,sCACA1I,iBAAA,8BACA2I,cAAA,qBACA1I,OAAA,cAQA2P,EAAAtL,UAAA0E,UAAA,SAAArB,GAIA,IAAA,GADAsI,GAAA7R,SAAA8R,uBAAA5I,KAAArJ,YAAA4R,UACAtO,EAAA,EAAAA,EAAA0O,EAAAxO,OAAAF,IAAA,CACA,GAAA4O,GAAAF,EAAA1O,GAAApC,cAAA,IAAAmI,KAAArJ,YAAA6R,UAEAK,GAAAtR,aAAA,UAAAyI,KAAA8I,YAAAvR,aAAA,SACA,mBAAAoR,GAAA1O,GAAA,eACA0O,EAAA1O,GAAA,cAAA0H,mBAWA2G,EAAAtL,UAAA4E,SAAA,SAAAvB,GACAL,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA2K,aAQAgH,EAAAtL,UAAA6E,QAAA,SAAAxB,GACAL,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA2K,aAQAgH,EAAAtL,UAAA+L,WAAA,SAAA1I,GACAL,KAAAgC,SAOAsG,EAAAtL,UAAA2E,eAAA,WACA3B,KAAAiC,gBACAjC,KAAAkC,oBAOAoG,EAAAtL,UAAAgF,MAAA,WAGAlH,OAAA+E,WAAA,WACAG,KAAA8I,YAAAxI,QACAM,KAAAZ,MAAAA,KAAAE,UAAAa,eAQAuH,EAAAtL,UAAAiF,cAAA,WACAjC,KAAA8I,YAAAtI,SACAR,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA4K,aAEAvB,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA4K,cAGA+G,EAAAtL,UAAA,cAAAsL,EAAAtL,UAAAiF,cAMAqG,EAAAtL,UAAAkF,iBAAA,WACAlC,KAAA8I,YAAA1G,QACApC,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA6K,YAEAxB,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA6K,aAGA8G,EAAAtL,UAAA,iBAAAsL,EAAAtL,UAAAkF,iBAMAoG,EAAAtL,UAAAuD,QAAA,WACAP,KAAA8I,YAAAtI,UAAA,EACAR,KAAA2B,kBAEA2G,EAAAtL,UAAA,QAAAsL,EAAAtL,UAAAuD,QAMA+H,EAAAtL,UAAAyD,OAAA,WACAT,KAAA8I,YAAAtI,UAAA,EACAR,KAAA2B,kBAEA2G,EAAAtL,UAAA,OAAAsL,EAAAtL,UAAAyD,OAMA6H,EAAAtL,UAAAqF,MAAA,WACArC,KAAA8I,YAAA1G,SAAA,EACApC,KAAA0B,UAAA,OAEA4G,EAAAtL,UAAA,MAAAsL,EAAAtL,UAAAqF,MAMAiG,EAAAtL,UAAAsF,QAAA,WACAtC,KAAA8I,YAAA1G,SAAA,EACApC,KAAA0B,UAAA,OAEA4G,EAAAtL,UAAA,QAAAsL,EAAAtL,UAAAsF,QAIAgG,EAAAtL,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACAwJ,KAAA8I,YAAA9I,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAArJ,YAAA6R,WACAxI,KAAAgJ,oBAAAhJ,KAAA0B,UAAAd,KAAAZ,MACAA,KAAAiJ,mBAAAjJ,KAAA0B,UAAAd,KAAAZ,MACAA,KAAAkJ,kBAAAlJ,KAAA6B,QAAAjB,KAAAZ,MACAA,KAAAmJ,qBAAAnJ,KAAA+I,WAAAnI,KAAAZ,KACA,IAAAoJ,GAAAtS,SAAAC,cAAA,OACAqS,GAAA3S,UAAAO,IAAAgJ,KAAArJ,YAAA8R,mBACA,IAAAY,GAAAvS,SAAAC,cAAA,OACAsS,GAAA5S,UAAAO,IAAAgJ,KAAArJ,YAAA+R,oBACA1I,KAAAxJ,SAAAY,YAAAgS,GACApJ,KAAAxJ,SAAAY,YAAAiS,EACA,IAAAxS,EACA,IAAAmJ,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAwJ,eAAA,CACAH,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAyK,sBACAvK,EAAAC,SAAAC,cAAA,QACAF,EAAAJ,UAAAO,IAAAgJ,KAAArJ,YAAA+B,kBACA7B,EAAAJ,UAAAO,IAAAgJ,KAAArJ,YAAAwJ,eACAtJ,EAAAJ,UAAAO,IAAAgJ,KAAArJ,YAAA0K,eACAxK,EAAAQ,iBAAA,UAAA2I,KAAAmJ,qBACA,IAAAjS,GAAAJ,SAAAC,cAAA,OACAG,GAAAT,UAAAO,IAAAgJ,KAAArJ,YAAAgC,QACA9B,EAAAO,YAAAF,GACA8I,KAAAxJ,SAAAY,YAAAP,GAEAmJ,KAAA8I,YAAAzR,iBAAA,SAAA2I,KAAAgJ,qBACAhJ,KAAA8I,YAAAzR,iBAAA,QAAA2I,KAAAiJ,oBACAjJ,KAAA8I,YAAAzR,iBAAA,OAAA2I,KAAAkJ,mBACAlJ,KAAAxJ,SAAAa,iBAAA,UAAA2I,KAAAmJ,sBACAnJ,KAAA2B,iBACA3B,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA8K,eAKA3I,EAAAY,UACA8D,YAAA8K,EACA7K,cAAA,gBACArC,SAAA,eACAuB,QAAA,GCtNA,IAAA2M,GAAA,SAAAnQ,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAuJ,MAAAzO,OAAAyE,UAAAiK,iBAEAxJ,KAAAC,OAEAnF,QAAA,eAAAwO,EAOAA,EAAAtM,UAAAkD,aASAoJ,EAAAtM,UAAArG,aACA8S,aAAA,2BACAC,iBAAA,wBACAC,gBAAA,8BACAC,iBAAA,+BACAC,iBAAA,+BACAC,gBAAA,kBACArI,YAAA,eAQA6H,EAAAtM,UAAA+M,SAAA,SAAA1J,GACAL,KAAAgK,sBAQAV,EAAAtM,UAAA0E,UAAA,SAAArB,GACAL,KAAAgK,sBAQAV,EAAAtM,UAAA+E,WAAA,SAAA1B,GACAA,EAAAqG,OAAApG,QAYAgJ,EAAAtM,UAAAiN,sBAAA,SAAA5J,GAGA,GAAAA,EAAAqG,SAAA1G,KAAAxJ,SAAAgO,cAAA,CAKAnE,EAAA5I,gBACA,IAAAyS,GAAA,GAAAvD,YAAA,aACAD,OAAArG,EAAAqG,OACAyD,QAAA9J,EAAA8J,QACAC,QAAA/J,EAAA+J,QACAC,QAAArK,KAAAxJ,SAAAoP,wBAAA0E,GAEAtK,MAAAxJ,SAAAoF,cAAAsO,KAOAZ,EAAAtM,UAAAgN,mBAAA,WAEA,GAAAO,IAAAvK,KAAAxJ,SAAAgU,MAAAxK,KAAAxJ,SAAAiU,MAAAzK,KAAAxJ,SAAAoJ,IAAAI,KAAAxJ,SAAAiU,IACA,KAAAF,EACAvK,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAmT,iBAEA9J,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAAmT,iBAEA9J,KAAAuJ,QACAvJ,KAAA0K,iBAAA5E,MAAA6E,KAAAJ,EACAvK,KAAA0K,iBAAA5E,MAAA8E,WAAAL,EACAvK,KAAA6K,iBAAA/E,MAAA6E,KAAA,EAAAJ,EACAvK,KAAA6K,iBAAA/E,MAAA8E,WAAA,EAAAL,IASAjB,EAAAtM,UAAAuD,QAAA,WACAP,KAAAxJ,SAAAgK,UAAA,GAEA8I,EAAAtM,UAAA,QAAAsM,EAAAtM,UAAAuD,QAMA+I,EAAAtM,UAAAyD,OAAA,WACAT,KAAAxJ,SAAAgK,UAAA,GAEA8I,EAAAtM,UAAA,OAAAsM,EAAAtM,UAAAyD,OAOA6I,EAAAtM,UAAA8N,OAAA,SAAAN,GACA,mBAAAA,KACAxK,KAAAxJ,SAAAgU,MAAAA,GAEAxK,KAAAgK,sBAEAV,EAAAtM,UAAA,OAAAsM,EAAAtM,UAAA8N,OAIAxB,EAAAtM,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACA,GAAAwJ,KAAAuJ,MAAA,CAIA,GAAAwB,GAAAjU,SAAAC,cAAA,MACAgU,GAAAtU,UAAAO,IAAAgJ,KAAArJ,YAAA8S,cACAzJ,KAAAxJ,SAAAgO,cAAAC,aAAAsG,EAAA/K,KAAAxJ,UACAwJ,KAAAxJ,SAAAgO,cAAAE,YAAA1E,KAAAxJ,UACAuU,EAAA3T,YAAA4I,KAAAxJ,cACA,CAIA,GAAA+N,GAAAzN,SAAAC,cAAA,MACAwN,GAAA9N,UAAAO,IAAAgJ,KAAArJ,YAAA+S,kBACA1J,KAAAxJ,SAAAgO,cAAAC,aAAAF,EAAAvE,KAAAxJ,UACAwJ,KAAAxJ,SAAAgO,cAAAE,YAAA1E,KAAAxJ,UACA+N,EAAAnN,YAAA4I,KAAAxJ,SACA,IAAAwU,GAAAlU,SAAAC,cAAA,MACAiU,GAAAvU,UAAAO,IAAAgJ,KAAArJ,YAAAgT,iBACApF,EAAAnN,YAAA4T,GACAhL,KAAA0K,iBAAA5T,SAAAC,cAAA,OACAiJ,KAAA0K,iBAAAjU,UAAAO,IAAAgJ,KAAArJ,YAAAiT,kBACAoB,EAAA5T,YAAA4I,KAAA0K,kBACA1K,KAAA6K,iBAAA/T,SAAAC,cAAA,OACAiJ,KAAA6K,iBAAApU,UAAAO,IAAAgJ,KAAArJ,YAAAkT,kBACAmB,EAAA5T,YAAA4I,KAAA6K,kBAEA7K,KAAAiL,kBAAAjL,KAAA+J,SAAAnJ,KAAAZ,MACAA,KAAAkL,mBAAAlL,KAAA0B,UAAAd,KAAAZ,MACAA,KAAAmL,oBAAAnL,KAAA+B,WAAAnB,KAAAZ,MACAA,KAAAoL,+BAAApL,KAAAiK,sBAAArJ,KAAAZ,MACAA,KAAAxJ,SAAAa,iBAAA,QAAA2I,KAAAiL,mBACAjL,KAAAxJ,SAAAa,iBAAA,SAAA2I,KAAAkL,oBACAlL,KAAAxJ,SAAAa,iBAAA,UAAA2I,KAAAmL,qBACAnL,KAAAxJ,SAAAgO,cAAAnN,iBAAA,YAAA2I,KAAAoL,gCACApL,KAAAgK,qBACAhK,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA8K,eAKA3I,EAAAY,UACA8D,YAAA8L,EACA7L,cAAA,iBACArC,SAAA,gBACAuB,QAAA,GC9LA,IAAA0O,GAAA,SAAAlS,GAIA,GAHA6G,KAAAxJ,SAAA2C,EACA6G,KAAAsL,aAAAtL,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAAuL,YAAAC,SACAxL,KAAAyL,eAAAzL,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAAuL,YAAAG,SACA1L,KAAAsL,aACA,KAAA,IAAA5P,OAAA,kDAEA,KAAAsE,KAAAyL,eACA,KAAA,IAAA/P,OAAA,kDAEAsE,MAAA2L,QAAA,EACA3L,KAAA4L,eAAAC,OACA7L,KAAA8L,SAAAD,OACA7L,KAAA+L,YAAAF,OACA7L,KAAAgM,wBACAhM,KAAAiM,kBAAA,GAEAnR,QAAA,iBAAAuQ,EAOAA,EAAArO,UAAAkD,WAEAgM,iBAAA,KAUAb,EAAArO,UAAAuO,aACAY,SAAA,eACAX,QAAA,qBACAE,OAAA,uBACAU,OAAA,wBAOAf,EAAArO,UAAAqP,iBAAA,WACArM,KAAAxJ,SAAA0F,aAAA,cAAA;AACA8D,KAAA4L,iBACA5L,KAAAyL,eAAAa,YAAAtM,KAAA+L,YACA/L,KAAAyL,eAAApU,iBAAA,QAAA2I,KAAA4L,gBACA5L,KAAAiM,kBAAA,IAEAjM,KAAAsL,aAAAgB,YAAAtM,KAAA8L,SACA9L,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAAuL,YAAAa,QACApM,KAAAxJ,SAAA0F,aAAA,cAAA,SACA2D,WAAAG,KAAAuM,SAAA3L,KAAAZ,MAAAA,KAAAwM,WAQAnB,EAAArO,UAAAyP,aAAA,SAAAC,GACA,GAAAb,SAAAa,EACA,KAAA,IAAAhR,OAAA,mEAEA,IAAAmQ,SAAAa,EAAA,QACA,KAAA,IAAAhR,OAAA,4CAEA,IAAAgR,EAAA,gBAAAA,EAAA,WACA,KAAA,IAAAhR,OAAA,+CAEAsE,MAAA2L,OACA3L,KAAAgM,qBAAAjQ,KAAA2Q,IAEA1M,KAAA2L,QAAA,EACA3L,KAAA8L,SAAAY,EAAA,QACAA,EAAA,QACA1M,KAAAwM,SAAAE,EAAA,QAEA1M,KAAAwM,SAAA,KAEAE,EAAA,gBACA1M,KAAA4L,eAAAc,EAAA,eAEAA,EAAA,aACA1M,KAAA+L,YAAAW,EAAA,YAEA1M,KAAAqM,qBAGAhB,EAAArO,UAAA,aAAAqO,EAAArO,UAAAyP,aAOApB,EAAArO,UAAA2P,YAAA,WACA3M,KAAAgM,qBAAA7R,OAAA,GACA6F,KAAAyM,aAAAzM,KAAAgM,qBAAAY,UAQAvB,EAAArO,UAAAuP,SAAA,WACAvM,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAAuL,YAAAa,QACAvM,WAAA,WACAG,KAAAxJ,SAAA0F,aAAA,cAAA,QACA8D,KAAAsL,aAAAgB,YAAA,GACAO,QAAA7M,KAAAyL,eAAAlU,aAAA,kBACAyI,KAAAiM,kBAAA,GACAjM,KAAAyL,eAAAa,YAAA,GACAtM,KAAAyL,eAAA9D,oBAAA,QAAA3H,KAAA4L,iBAEA5L,KAAA4L,eAAAC,OACA7L,KAAA8L,SAAAD,OACA7L,KAAA+L,YAAAF,OACA7L,KAAA2L,QAAA,EACA3L,KAAA2M,eACA/L,KAAAZ,MAAAA,KAAAE,UAAAgM,mBAQAb,EAAArO,UAAAiP,iBAAA,SAAAzB,GACAA,EACAxK,KAAAyL,eAAAvP,aAAA,cAAA,QAEA8D,KAAAyL,eAAAqB,gBAAA,gBAKAhU,EAAAY,UACA8D,YAAA6N,EACA5N,cAAA,mBACArC,SAAA,kBACAuB,QAAA,GClJA,IAAAoQ,GAAA,SAAA5T,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,gBAAAiS,EAOAA,EAAA/P,UAAAkD,WAAA8M,wBAAA,GASAD,EAAA/P,UAAArG,aACAsW,kBAAA,qBACAC,2BAAA,8BACAC,mBAAA,sBACAC,sBAAA,yBACAC,iBAAA,oBACAC,kBAAA,sBAQAP,EAAA/P,UAAAuQ,YAAA,SAAAC,GACA,GAAAC,GAAA3W,SAAAC,cAAA,MACA0W,GAAAhX,UAAAO,IAAAgJ,KAAArJ,YAAAsW,mBACAQ,EAAAhX,UAAAO,IAAAgJ,KAAArJ,YAAAsW,kBAAA,IAAAO,EACA,IAAAE,GAAA5W,SAAAC,cAAA,MACA2W,GAAAjX,UAAAO,IAAAgJ,KAAArJ,YAAAuW,4BACAQ,EAAAjX,UAAAO,IAAAgJ,KAAArJ,YAAA0W,iBACA,IAAAM,GAAA7W,SAAAC,cAAA,MACA4W,GAAAlX,UAAAO,IAAAgJ,KAAArJ,YAAAyW,sBACA,IAAAQ,GAAA9W,SAAAC,cAAA,MACA6W,GAAAnX,UAAAO,IAAAgJ,KAAArJ,YAAAuW,4BACAU,EAAAnX,UAAAO,IAAAgJ,KAAArJ,YAAA2W,kBAMA,KAAA,GALAO,IACAH,EACAC,EACAC,GAEA3T,EAAA,EAAAA,EAAA4T,EAAA1T,OAAAF,IAAA,CACA,GAAA6T,GAAAhX,SAAAC,cAAA,MACA+W,GAAArX,UAAAO,IAAAgJ,KAAArJ,YAAAwW,oBACAU,EAAA5T,GAAA7C,YAAA0W,GAEAL,EAAArW,YAAAsW,GACAD,EAAArW,YAAAuW,GACAF,EAAArW,YAAAwW,GACA5N,KAAAxJ,SAAAY,YAAAqW,IAEAV,EAAA/P,UAAA,YAAA+P,EAAA/P,UAAAuQ,YAOAR,EAAA/P,UAAA+Q,KAAA,WACA/N,KAAAxJ,SAAAC,UAAAqL,OAAA,cAEAiL,EAAA/P,UAAA,KAAA+P,EAAA/P,UAAA+Q,KAQAhB,EAAA/P,UAAAgR,MAAA,WACAhO,KAAAxJ,SAAAC,UAAAO,IAAA,cAEA+V,EAAA/P,UAAA,MAAA+P,EAAA/P,UAAAgR,MAIAjB,EAAA/P,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACA,IAAA,GAAAyD,GAAA,EAAAA,GAAA+F,KAAAE,UAAA8M,wBAAA/S,IACA+F,KAAAuN,YAAAtT,EAEA+F,MAAAxJ,SAAAC,UAAAO,IAAA,iBAKA8B,EAAAY,UACA8D,YAAAuP,EACAtP,cAAA,kBACArC,SAAA,iBACAuB,QAAA,GCrGA,IAAAsR,GAAA,SAAA9U,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,eAAAmT,EAOAA,EAAAjR,UAAAkD,WAAAa,aAAA,MASAkN,EAAAjR,UAAArG,aACAqK,MAAA,oBACAkN,MAAA,oBACAC,MAAA,oBACAjN,aAAA,2BACAf,cAAA,uBACAiB,qBAAA,sCACA1I,iBAAA,+BACA2I,cAAA,qBACA1I,OAAA,aACA2I,WAAA,aACAC,YAAA,cACAC,WAAA,cAQAyM,EAAAjR,UAAA0E,UAAA,SAAArB,GACAL,KAAA2B,kBAQAsM,EAAAjR,UAAA4E,SAAA,SAAAvB,GACAL,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA2K,aAQA2M,EAAAjR,UAAA6E,QAAA,SAAAxB,GACAL,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA2K,aAQA2M,EAAAjR,UAAA+E,WAAA,SAAA1B,GACAL,KAAAgC,SAOAiM,EAAAjR,UAAA2E,eAAA,WACA3B,KAAAiC,gBACAjC,KAAAkC,oBAOA+L,EAAAjR,UAAAgF,MAAA,WAGAlH,OAAA+E,WAAA,WACAG,KAAAmC,cAAA7B,QACAM,KAAAZ,MAAAA,KAAAE,UAAAa,eAQAkN,EAAAjR,UAAAiF,cAAA,WACAjC,KAAAmC,cAAA3B,SACAR,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA4K,aAEAvB,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA4K,cAGA0M,EAAAjR,UAAA,cAAAiR,EAAAjR,UAAAiF,cAMAgM,EAAAjR,UAAAkF,iBAAA,WACAlC,KAAAmC,cAAAC,QACApC,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA6K,YAEAxB,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA6K,aAGAyM,EAAAjR,UAAA,iBAAAiR,EAAAjR,UAAAkF,iBAMA+L,EAAAjR,UAAAuD,QAAA,WACAP,KAAAmC,cAAA3B,UAAA,EACAR,KAAA2B,kBAEAsM,EAAAjR,UAAA,QAAAiR,EAAAjR,UAAAuD,QAMA0N,EAAAjR,UAAAyD,OAAA,WACAT,KAAAmC,cAAA3B,UAAA,EACAR,KAAA2B,kBAEAsM,EAAAjR,UAAA,OAAAiR,EAAAjR,UAAAyD,OAMAwN,EAAAjR,UAAAoR,GAAA,WACApO,KAAAmC,cAAAC,SAAA,EACApC,KAAA2B,kBAEAsM,EAAAjR,UAAA,GAAAiR,EAAAjR,UAAAoR,GAMAH,EAAAjR,UAAAqR,IAAA,WACArO,KAAAmC,cAAAC,SAAA,EACApC,KAAA2B,kBAEAsM,EAAAjR,UAAA,IAAAiR,EAAAjR,UAAAqR,IAIAJ,EAAAjR,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACAwJ,KAAAmC,cAAAnC,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAArJ,YAAAqK,MACA,IAAAsN,GAAAxX,SAAAC,cAAA,MACAuX,GAAA7X,UAAAO,IAAAgJ,KAAArJ,YAAAuX,MACA,IAAAK,GAAAzX,SAAAC,cAAA,MACAwX,GAAA9X,UAAAO,IAAAgJ,KAAArJ,YAAAwX,MACA,IAAAK,GAAA1X,SAAAC,cAAA,OAMA,IALAyX,EAAA/X,UAAAO,IAAAgJ,KAAArJ,YAAAuK,cACAqN,EAAAnX,YAAAoX,GACAxO,KAAAxJ,SAAAY,YAAAkX,GACAtO,KAAAxJ,SAAAY,YAAAmX,GACAvO,KAAAmL,oBAAAnL,KAAA+B,WAAAnB,KAAAZ,MACAA,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAwJ,eAAA,CACAH,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAyK,sBACApB,KAAA0C,wBAAA5L,SAAAC,cAAA,QACAiJ,KAAA0C,wBAAAjM,UAAAO,IAAAgJ,KAAArJ,YAAA+B,kBACAsH,KAAA0C,wBAAAjM,UAAAO,IAAAgJ,KAAArJ,YAAAwJ,eACAH,KAAA0C,wBAAAjM,UAAAO,IAAAgJ,KAAArJ,YAAA0K,eACArB,KAAA0C,wBAAArL,iBAAA,UAAA2I,KAAAmL,oBACA,IAAAjU,GAAAJ,SAAAC,cAAA,OACAG,GAAAT,UAAAO,IAAAgJ,KAAArJ,YAAAgC,QACAqH,KAAA0C,wBAAAtL,YAAAF,GACA8I,KAAAxJ,SAAAY,YAAA4I,KAAA0C,yBAEA1C,KAAAkL,mBAAAlL,KAAA0B,UAAAd,KAAAZ,MACAA,KAAAyO,kBAAAzO,KAAA4B,SAAAhB,KAAAZ,MACAA,KAAA0O,iBAAA1O,KAAA6B,QAAAjB,KAAAZ,MACAA,KAAAmC,cAAA9K,iBAAA,SAAA2I,KAAAkL,oBACAlL,KAAAmC,cAAA9K,iBAAA,QAAA2I,KAAAyO,mBACAzO,KAAAmC,cAAA9K,iBAAA,OAAA2I,KAAA0O,kBACA1O,KAAAxJ,SAAAa,iBAAA,UAAA2I,KAAAmL,qBACAnL,KAAA2B,iBACA3B,KAAAxJ,SAAAC,UAAAO,IAAA,iBAKA8B,EAAAY,UACA8D,YAAAyQ,EACAxQ,cAAA,iBACArC,SAAA,gBACAuB,QAAA,Gb5MA,IAAAgS,GAAA,SAAAxV,GAEA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,aAAA6T,EAOAA,EAAA3R,UAAAkD,aASAyO,EAAA3R,UAAArG,aACAiY,UAAA,gBACAC,YAAA,kBACA7W,aAAA,YACA8W,eAAA,cACAlY,qBAAA,uBACAK,qBAAA,6BACAE,WAAA,aACA4X,mCAAA,uCAOAJ,EAAA3R,UAAAgS,UAAA,WACAhP,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAC,uBACAoJ,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAoY,oCAGA/O,KAAAiP,MAAAjP,KAAAxJ,SAAA8E,iBAAA,IAAA0E,KAAArJ,YAAAiY,WACA5O,KAAAkP,QAAAlP,KAAAxJ,SAAA8E,iBAAA,IAAA0E,KAAArJ,YAAAkY,YAEA,KAAA,GAAA5U,GAAA,EAAAA,EAAA+F,KAAAiP,MAAA9U,OAAAF,IACA,GAAA5D,GAAA2J,KAAAiP,MAAAhV,GAAA+F,KAEAA,MAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAmY,iBAOAH,EAAA3R,UAAAlF,eAAA,WACA,IAAA,GAAAqX,GAAA,EAAAA,EAAAnP,KAAAiP,MAAA9U,OAAAgV,IACAnP,KAAAiP,MAAAE,GAAA1Y,UAAAqL,OAAA9B,KAAArJ,YAAAqB,eAQA2W,EAAA3R,UAAAjF,iBAAA,WACA,IAAA,GAAAyE,GAAA,EAAAA,EAAAwD,KAAAkP,QAAA/U,OAAAqC,IACAwD,KAAAkP,QAAA1S,GAAA/F,UAAAqL,OAAA9B,KAAArJ,YAAAqB,eAMA2W,EAAA3R,UAAAiD,KAAA,WACAD,KAAAxJ,UACAwJ,KAAAgP,aAoCAlW,EAAAY,UACA8D,YAAAmR,EACAlR,cAAA,eACArC,SAAA,eclHA,IAAAgU,GAAA,SAAAjW,GACA6G,KAAAxJ,SAAA2C,EACA6G,KAAAqP,QAAArP,KAAAE,UAAAoP,YAEAtP,KAAAC,OAEAnF,QAAA,kBAAAsU,EAOAA,EAAApS,UAAAkD,WACAoP,aAAA,EACAC,mBAAA,WAUAH,EAAApS,UAAArG,aACA6Y,MAAA,uBACAxO,MAAA,uBACAyO,SAAA,WACAnO,WAAA,aACAC,YAAA,cACAmO,WAAA,aACAjO,YAAA,cACAkO,gBAAA,mBAQAP,EAAApS,UAAA4S,WAAA,SAAAvP,GACA,GAAAwP,GAAAxP,EAAAqG,OAAA8D,MAAA7S,MAAA,MAAAwC,MACA,MAAAkG,EAAAkG,SACAsJ,GAAA7P,KAAAqP,SACAhP,EAAA5I,kBAUA2X,EAAApS,UAAA4E,SAAA,SAAAvB,GACAL,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA2K,aAQA8N,EAAApS,UAAA6E,QAAA,SAAAxB,GACAL,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA2K,aAQA8N,EAAApS,UAAA8S,SAAA,SAAAzP,GACAL,KAAA2B,kBAOAyN,EAAApS,UAAA2E,eAAA,WACA3B,KAAAiC,gBACAjC,KAAA+P,gBACA/P,KAAAgQ,aACAhQ,KAAAiQ,cAQAb,EAAApS,UAAAiF,cAAA,WACAjC,KAAAkQ,OAAA1P,SACAR,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA4K,aAEAvB,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA4K,cAGA6N,EAAApS,UAAA,cAAAoS,EAAApS,UAAAiF,cAMAmN,EAAApS,UAAAiT,WAAA,WACApD,QAAA7M,KAAAxJ,SAAAqB,cAAA,WACAmI,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA2K,YAEAtB,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA2K,aAGA8N,EAAApS,UAAA,WAAAoS,EAAApS,UAAAiT,WAMAb,EAAApS,UAAA+S,cAAA,WACA/P,KAAAkQ,OAAAC,WACAnQ,KAAAkQ,OAAAC,SAAAC,MACApQ,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA+Y,YAEA1P,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA+Y,cAIAN,EAAApS,UAAA,cAAAoS,EAAApS,UAAA+S,cAMAX,EAAApS,UAAAgT,WAAA,WACAhQ,KAAAkQ,OAAA1F,OAAAxK,KAAAkQ,OAAA1F,MAAArQ,OAAA,EACA6F,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA8Y,UAEAzP,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA8Y,WAGAL,EAAApS,UAAA,WAAAoS,EAAApS,UAAAgT,WAMAZ,EAAApS,UAAAuD,QAAA,WACAP,KAAAkQ,OAAA1P,UAAA,EACAR,KAAA2B,kBAEAyN,EAAApS,UAAA,QAAAoS,EAAApS,UAAAuD,QAMA6O,EAAApS,UAAAyD,OAAA,WACAT,KAAAkQ,OAAA1P,UAAA,EACAR,KAAA2B,kBAEAyN,EAAApS,UAAA,OAAAoS,EAAApS,UAAAyD,OAOA2O,EAAApS,UAAA8N,OAAA,SAAAN,GACAxK,KAAAkQ,OAAA1F,MAAAA,GAAA,GACAxK,KAAA2B,kBAEAyN,EAAApS,UAAA,OAAAoS,EAAApS,UAAA8N,OAIAsE,EAAApS,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,WACAwJ,KAAAqQ,OAAArQ,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAArJ,YAAA6Y,OACAxP,KAAAkQ,OAAAlQ,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAArJ,YAAAqK,OACAhB,KAAAkQ,QAAA,CACAlQ,KAAAkQ,OAAApJ,aAAA9G,KAAAE,UAAAqP,sBACAvP,KAAAqP,QAAAiB,SAAAtQ,KAAAkQ,OAAA3Y,aAAAyI,KAAAE,UAAAqP,oBAAA,IACAgB,MAAAvQ,KAAAqP,WACArP,KAAAqP,QAAArP,KAAAE,UAAAoP,cAGAtP,KAAAkQ,OAAApJ,aAAA,gBACA9G,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAgZ,iBAEA3P,KAAAwQ,0BAAAxQ,KAAA2B,eAAAf,KAAAZ,MACAA,KAAAyO,kBAAAzO,KAAA4B,SAAAhB,KAAAZ,MACAA,KAAA0O,iBAAA1O,KAAA6B,QAAAjB,KAAAZ,MACAA,KAAAyQ,kBAAAzQ,KAAA8P,SAAAlP,KAAAZ,MACAA,KAAAkQ,OAAA7Y,iBAAA,QAAA2I,KAAAwQ,2BACAxQ,KAAAkQ,OAAA7Y,iBAAA,QAAA2I,KAAAyO,mBACAzO,KAAAkQ,OAAA7Y,iBAAA,OAAA2I,KAAA0O,kBACA1O,KAAAkQ,OAAA7Y,iBAAA,QAAA2I,KAAAyQ,mBACAzQ,KAAAqP,UAAArP,KAAAE,UAAAoP,cAGAtP,KAAA0Q,oBAAA1Q,KAAA4P,WAAAhP,KAAAZ,MACAA,KAAAkQ,OAAA7Y,iBAAA,UAAA2I,KAAA0Q,qBAEA,IAAAC,GAAA3Q,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA+Y,WACA1P,MAAA2B,iBACA3B,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA8K,aACAkP,GACA3Q,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA+Y,YAEA1P,KAAAkQ,OAAApJ,aAAA,eACA9G,KAAAxJ,SAAAgQ,QACAxG,KAAAiQ,gBAOAnX,EAAAY,UACA8D,YAAA4R,EACA3R,cAAA,oBACArC,SAAA,mBACAuB,QAAA,GC/NA,IAAAiU,GAAA,SAAAzX,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,gBAAA8V,EAOAA,EAAA5T,UAAAkD,aASA0Q,EAAA5T,UAAArG,aACA4B,UAAA,YACAsY,OAAA,sBACAC,KAAA,oBACAC,MAAA,qBACAC,IAAA,oBAQAJ,EAAA5T,UAAAiU,kBAAA,SAAA5Q,GACA,GAAA6Q,GAAA7Q,EAAAqG,OAAAd,wBACAO,EAAA+K,EAAA/K,KAAA+K,EAAA/J,MAAA,EACAnB,EAAAkL,EAAAlL,IAAAkL,EAAAhK,OAAA,EACAiK,GAAA,GAAAnR,KAAAxJ,SAAA4a,YAAA,GACAC,GAAA,GAAArR,KAAAxJ,SAAA0P,aAAA,EACAlG,MAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAma,OAAA9Q,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAoa,QACA5K,EAAA+K,EAAA/J,MAAA,EACAnB,EAAAqL,EAAA,GACArR,KAAAxJ,SAAAsP,MAAAE,IAAA,IACAhG,KAAAxJ,SAAAsP,MAAAuL,UAAA,MAEArR,KAAAxJ,SAAAsP,MAAAE,IAAAA,EAAA,KACAhG,KAAAxJ,SAAAsP,MAAAuL,UAAAA,EAAA,OAGAlL,EAAAgL,EAAA,GACAnR,KAAAxJ,SAAAsP,MAAAK,KAAA,IACAnG,KAAAxJ,SAAAsP,MAAAqL,WAAA,MAEAnR,KAAAxJ,SAAAsP,MAAAK,KAAAA,EAAA,KACAnG,KAAAxJ,SAAAsP,MAAAqL,WAAAA,EAAA,MAGAnR,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAqa,KACAhR,KAAAxJ,SAAAsP,MAAAE,IAAAkL,EAAAlL,IAAAhG,KAAAxJ,SAAA0P,aAAA,GAAA,KACAlG,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAoa,OACA/Q,KAAAxJ,SAAAsP,MAAAK,KAAA+K,EAAA/K,KAAA+K,EAAA/J,MAAA,GAAA,KACAnH,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAma,MACA9Q,KAAAxJ,SAAAsP,MAAAK,KAAA+K,EAAA/K,KAAAnG,KAAAxJ,SAAA4a,YAAA,GAAA,KAEApR,KAAAxJ,SAAAsP,MAAAE,IAAAkL,EAAAlL,IAAAkL,EAAAhK,OAAA,GAAA,KAEAlH,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA4B,YAOAqY,EAAA5T,UAAAsU,aAAA,WACAtR,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAA4B,YAKAqY,EAAA5T,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACA,GAAAsO,GAAA9E,KAAAxJ,SAAAe,aAAA,QAAAyI,KAAAxJ,SAAAe,aAAA,eACAuN,KACA9E,KAAAiF,YAAAnO,SAAAkO,eAAAF,IAEA9E,KAAAiF,cAEAjF,KAAAiF,YAAA6B,aAAA,aACA9G,KAAAiF,YAAA/I,aAAA,WAAA,KAEA8D,KAAAuR,uBAAAvR,KAAAiR,kBAAArQ,KAAAZ,MACAA,KAAAwR,gCAAAxR,KAAAsR,aAAA1Q,KAAAZ,MACAA,KAAAiF,YAAA5N,iBAAA,aAAA2I,KAAAuR,wBAAA,GACAvR,KAAAiF,YAAA5N,iBAAA,WAAA2I,KAAAuR,wBAAA,GACAvR,KAAAiF,YAAA5N,iBAAA,aAAA2I,KAAAwR,iCAAA,GACA1W,OAAAzD,iBAAA,SAAA2I,KAAAwR,iCAAA,GACA1W,OAAAzD,iBAAA,aAAA2I,KAAAwR,oCAMA1Y,EAAAY,UACA8D,YAAAoT,EACAnT,cAAA,kBACArC,SAAA,ed1GA,IAAAqW,GAAA,SAAAtY,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,eAAA2W,EAOAA,EAAAzU,UAAAkD,WACAwR,UAAA,sBACAC,kBAAA,IACAC,eAAA,IACAC,UAAA,WACAC,aAAA,eACAC,cAAA,iBAQAN,EAAAzU,UAAAsG,WACAC,MAAA,GACAC,OAAA,GACAC,MAAA,IAQAgO,EAAAzU,UAAAgV,OACAC,SAAA,EACAC,OAAA,EACAC,UAAA,EACAC,OAAA,GAUAX,EAAAzU,UAAArG,aACAiN,UAAA,wBACAyO,OAAA,qBACAC,OAAA,qBACAC,QAAA,sBACAC,WAAA,4BACAC,KAAA,iBACAha,iBAAA,uBACAC,iBAAA,mCACAC,OAAA,aACAyI,qBAAA,sCACAsR,cAAA,6BACAC,iBAAA,gCACAC,cAAA,6BACAC,aAAA,2BACAC,WAAA,yBACAC,QAAA,sBACAC,cAAA,gCACAC,IAAA,kBACAC,eAAA,6BACAC,oBAAA,kCACAC,qBAAA,mCACAxa,kBAAA,gCACAya,MAAA,wBACAC,WAAA,aACAC,SAAA,WACAC,qBAAA,uBACAC,eAAA,oBACAC,WAAA,aACAC,gBAAA,kBACAC,eAAA,aACArb,UAAA,YACAkJ,YAAA,cACAwC,aAAA,eACA4P,gBAAA,gCACAC,gBAAA,iCAOArC,EAAAzU,UAAA+W,sBAAA,WACA,IAAA/T,KAAAgU,QAAAvd,UAAAC,SAAAsJ,KAAArJ,YAAAsN,cAAA,CAGA,GAAAgQ,IAAAjU,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAgd,kBAAA3T,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAkc,aACA7S,MAAA1H,SAAA4b,UAAA,IAAAlU,KAAAgU,QAAAvd,UAAAC,SAAAsJ,KAAArJ,YAAA+c,aACA1T,KAAAgU,QAAAvd,UAAAO,IAAAgJ,KAAArJ,YAAA8c,gBACAzT,KAAAgU,QAAAvd,UAAAO,IAAAgJ,KAAArJ,YAAA+c,YACAO,GACAjU,KAAAgU,QAAAvd,UAAAO,IAAAgJ,KAAArJ,YAAAsN,eAEAjE,KAAA1H,SAAA4b,WAAA,GAAAlU,KAAAgU,QAAAvd,UAAAC,SAAAsJ,KAAArJ,YAAA+c,cACA1T,KAAAgU,QAAAvd,UAAAqL,OAAA9B,KAAArJ,YAAA8c,gBACAzT,KAAAgU,QAAAvd,UAAAqL,OAAA9B,KAAArJ,YAAA+c,YACAO,GACAjU,KAAAgU,QAAAvd,UAAAO,IAAAgJ,KAAArJ,YAAAsN,iBAUAwN,EAAAzU,UAAAmX,sBAAA,SAAAzO,GAEAA,EAAAa,UAAAvG,KAAAsD,UAAAE,QAAAxD,KAAAoU,QAAA3d,UAAAC,SAAAsJ,KAAArJ,YAAAid,iBACA5T,KAAAqU,gBAQA5C,EAAAzU,UAAAsX,mBAAA,WACAtU,KAAAuU,sBAAAC,QACAxU,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAAgd,kBAEA3T,KAAAxJ,SAAAC,UAAAqL,OAAA9B,KAAArJ,YAAAgd,iBAEA3T,KAAAoU,UACApU,KAAAoU,QAAA3d,UAAAqL,OAAA9B,KAAArJ,YAAAid,gBACA5T,KAAAyU,YAAAhe,UAAAqL,OAAA9B,KAAArJ,YAAAid,mBAUAnC,EAAAzU,UAAA0X,qBAAA,SAAAhP,GACA,GAAAA,GAAA,YAAAA,EAAAiP,KAAA,CACA,GAAAjP,EAAAa,UAAAvG,KAAAsD,UAAAG,OAAAiC,EAAAa,UAAAvG,KAAAsD,UAAAC,MAKA,MAHAmC,GAAAjO,iBAMAuI,KAAAqU,gBAOA5C,EAAAzU,UAAA4X,4BAAA,WACA5U,KAAAgU,QAAAvd,UAAAqL,OAAA9B,KAAArJ,YAAAsN,eAOAwN,EAAAzU,UAAA6X,oBAAA,WACA7U,KAAAgU,QAAAvd,UAAAC,SAAAsJ,KAAArJ,YAAA+c,cACA1T,KAAAgU,QAAAvd,UAAAqL,OAAA9B,KAAArJ,YAAA+c,YACA1T,KAAAgU,QAAAvd,UAAAO,IAAAgJ,KAAArJ,YAAAsN,gBAQAwN,EAAAzU,UAAAlF,eAAA,SAAAgd,GACA,IAAA,GAAA3F,GAAA,EAAAA,EAAA2F,EAAA3a,OAAAgV,IACA2F,EAAA3F,GAAA1Y,UAAAqL,OAAA9B,KAAArJ,YAAA4B,YAQAkZ,EAAAzU,UAAAjF,iBAAA,SAAAI,GACA,IAAA,GAAAqE,GAAA,EAAAA,EAAArE,EAAAgC,OAAAqC,IACArE,EAAAqE,GAAA/F,UAAAqL,OAAA9B,KAAArJ,YAAA4B,YAQAkZ,EAAAzU,UAAAqX,aAAA,WACA,GAAAU,GAAA/U,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAArJ,YAAA6b,WACAxS,MAAAoU,QAAA3d,UAAA6P,OAAAtG,KAAArJ,YAAAid,gBACA5T,KAAAyU,YAAAhe,UAAA6P,OAAAtG,KAAArJ,YAAAid,gBAEA5T,KAAAoU,QAAA3d,UAAAC,SAAAsJ,KAAArJ,YAAAid,iBACA5T,KAAAoU,QAAAlY,aAAA,cAAA,SACA6Y,EAAA7Y,aAAA,gBAAA,UAEA8D,KAAAoU,QAAAlY,aAAA,cAAA,QACA6Y,EAAA7Y,aAAA,gBAAA,WAGAuV,EAAAzU,UAAA,aAAAyU,EAAAzU,UAAAqX,aAIA5C,EAAAzU,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACA,GAAA+N,GAAAzN,SAAAC,cAAA,MACAwN,GAAA9N,UAAAO,IAAAgJ,KAAArJ,YAAAiN,UACA,IAAAoR,GAAAhV,KAAAxJ,SAAAqB,cAAA,SACAmI,MAAAxJ,SAAAgO,cAAAC,aAAAF,EAAAvE,KAAAxJ,UACAwJ,KAAAxJ,SAAAgO,cAAAE,YAAA1E,KAAAxJ,UACA+N,EAAAnN,YAAA4I,KAAAxJ,UACAwe,GACAA,EAAAxO,OAIA,KAAA,GAFAyO,GAAAjV,KAAAxJ,SAAA0e,WACAC,EAAAF,EAAA9a,OACAib,EAAA,EAAAA,EAAAD,EAAAC,IAAA,CACA,GAAAC,GAAAJ,EAAAG,EACAC,GAAA5e,WAAA4e,EAAA5e,UAAAC,SAAAsJ,KAAArJ,YAAA0b,UACArS,KAAAgU,QAAAqB,GAEAA,EAAA5e,WAAA4e,EAAA5e,UAAAC,SAAAsJ,KAAArJ,YAAA2b,UACAtS,KAAAoU,QAAAiB,GAEAA,EAAA5e,WAAA4e,EAAA5e,UAAAC,SAAAsJ,KAAArJ,YAAA4b,WACAvS,KAAA1H,SAAA+c,GAGAva,OAAAzD,iBAAA,WAAA,SAAAC,GACAA,EAAAge,YAGAtV,KAAAxJ,SAAAsP,MAAAyP,UAAA,SACApW,sBAAA,WACAa,KAAAxJ,SAAAsP,MAAAyP,UAAA,IACA3U,KAAAZ,SAEAY,KAAAZ,OAAA,GACAA,KAAAgU,UACAhU,KAAAxH,QAAAwH,KAAAgU,QAAAnc,cAAA,IAAAmI,KAAArJ,YAAAoc,SAEA,IAAAyC,GAAAxV,KAAAgS,MAAAC,QA+BA,IA9BAjS,KAAAgU,UACAhU,KAAAgU,QAAAvd,UAAAC,SAAAsJ,KAAArJ,YAAA+b,eACA8C,EAAAxV,KAAAgS,MAAAE,OACAlS,KAAAgU,QAAAvd,UAAAC,SAAAsJ,KAAArJ,YAAAgc,mBACA6C,EAAAxV,KAAAgS,MAAAG,UACAnS,KAAAgU,QAAA3c,iBAAA,gBAAA2I,KAAA4U,4BAAAhU,KAAAZ,OACAA,KAAAgU,QAAA3c,iBAAA,QAAA2I,KAAA6U,oBAAAjU,KAAAZ,QACAA,KAAAgU,QAAAvd,UAAAC,SAAAsJ,KAAArJ,YAAAic,iBACA4C,EAAAxV,KAAAgS,MAAAI,OACA7N,EAAA9N,UAAAO,IAAAgJ,KAAArJ,YAAA6c,uBAEAgC,IAAAxV,KAAAgS,MAAAC,UACAjS,KAAAgU,QAAAvd,UAAAO,IAAAgJ,KAAArJ,YAAA8c,gBACAzT,KAAAxH,SACAwH,KAAAxH,QAAA/B,UAAAO,IAAAgJ,KAAArJ,YAAA8c,iBAEA+B,IAAAxV,KAAAgS,MAAAE,QAAAsD,IAAAxV,KAAAgS,MAAAI,QACApS,KAAAgU,QAAAvd,UAAAqL,OAAA9B,KAAArJ,YAAA8c,gBACAzT,KAAAxH,SACAwH,KAAAxH,QAAA/B,UAAAqL,OAAA9B,KAAArJ,YAAA8c,iBAEA+B,IAAAxV,KAAAgS,MAAAG,YAIAnS,KAAA1H,SAAAjB,iBAAA,SAAA2I,KAAA+T,sBAAAnT,KAAAZ,OACAA,KAAA+T,0BAIA/T,KAAAoU,QAAA,CACA,GAAAW,GAAA/U,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAArJ,YAAA6b,WACA,KAAAuC,EAAA,CACAA,EAAAje,SAAAC,cAAA,OACAge,EAAA7Y,aAAA,gBAAA,SACA6Y,EAAA7Y,aAAA,OAAA,UACA6Y,EAAA7Y,aAAA,WAAA,KACA6Y,EAAAte,UAAAO,IAAAgJ,KAAArJ,YAAA6b,WACA,IAAAiD,GAAA3e,SAAAC,cAAA,IACA0e,GAAAhf,UAAAO,IAAAgJ,KAAArJ,YAAA8b,MACAgD,EAAAC,UAAA1V,KAAAE,UAAA2R,UACAkD,EAAA3d,YAAAqe,GAEAzV,KAAAoU,QAAA3d,UAAAC,SAAAsJ,KAAArJ,YAAAkd,iBAEAkB,EAAAte,UAAAO,IAAAgJ,KAAArJ,YAAAkd,iBACA7T,KAAAoU,QAAA3d,UAAAC,SAAAsJ,KAAArJ,YAAAmd,kBAEAiB,EAAAte,UAAAO,IAAAgJ,KAAArJ,YAAAmd,iBAEAiB,EAAA1d,iBAAA,QAAA2I,KAAA0U,qBAAA9T,KAAAZ,OACA+U,EAAA1d,iBAAA,UAAA2I,KAAA0U,qBAAA9T,KAAAZ,OAIAA,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA2c,YAGAtT,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAkc,cACA7S,KAAAgU,QAAAvP,aAAAsQ,EAAA/U,KAAAgU,QAAA2B,YAEA3V,KAAAxJ,SAAAiO,aAAAsQ,EAAA/U,KAAA1H,SAEA,IAAAsd,GAAA9e,SAAAC,cAAA,MACA6e,GAAAnf,UAAAO,IAAAgJ,KAAArJ,YAAAmc,YACA9S,KAAAxJ,SAAAY,YAAAwe,GACAA,EAAAve,iBAAA,QAAA2I,KAAA0U,qBAAA9T,KAAAZ,OACAA,KAAAyU,YAAAmB,EACA5V,KAAAoU,QAAA/c,iBAAA,UAAA2I,KAAAmU,sBAAAvT,KAAAZ,OACAA,KAAAoU,QAAAlY,aAAA,cAAA,QAQA,GAJA8D,KAAAuU,sBAAAzZ,OAAA+a,WAAA7V,KAAAE,UAAAwR,WACA1R,KAAAuU,sBAAAuB,YAAA9V,KAAAsU,mBAAA1T,KAAAZ,OACAA,KAAAsU,qBAEAtU,KAAAgU,SAAAhU,KAAAxH,QAAA,CACAwH,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA4c,SACA,IAAAwC,GAAAjf,SAAAC,cAAA,MACAgf,GAAAtf,UAAAO,IAAAgJ,KAAArJ,YAAAqc,eACAhT,KAAAgU,QAAAvP,aAAAsR,EAAA/V,KAAAxH,SACAwH,KAAAgU,QAAAtP,YAAA1E,KAAAxH,QACA,IAAAwd,GAAAlf,SAAAC,cAAA,MACAif,GAAAvf,UAAAO,IAAAgJ,KAAArJ,YAAAuc,gBACA8C,EAAAvf,UAAAO,IAAAgJ,KAAArJ,YAAAwc,oBACA,IAAA8C,GAAAnf,SAAAC,cAAA,IACAkf,GAAAxf,UAAAO,IAAAgJ,KAAArJ,YAAA8b,MACAwD,EAAA3J,YAAAtM,KAAAE,UAAA4R,aACAkE,EAAA5e,YAAA6e,GACAD,EAAA3e,iBAAA,QAAA,WACA2I,KAAAxH,QAAA0d,YAAAlW,KAAAE,UAAAyR,mBACA/Q,KAAAZ,MACA,IAAAmW,GAAArf,SAAAC,cAAA,MACAof,GAAA1f,UAAAO,IAAAgJ,KAAArJ,YAAAuc,gBACAiD,EAAA1f,UAAAO,IAAAgJ,KAAArJ,YAAAyc,qBACA,IAAAgD,GAAAtf,SAAAC,cAAA,IACAqf,GAAA3f,UAAAO,IAAAgJ,KAAArJ,YAAA8b,MACA2D,EAAA9J,YAAAtM,KAAAE,UAAA6R,cACAoE,EAAA/e,YAAAgf,GACAD,EAAA9e,iBAAA,QAAA,WACA2I,KAAAxH,QAAA0d,YAAAlW,KAAAE,UAAAyR,mBACA/Q,KAAAZ,OACA+V,EAAA3e,YAAA4e,GACAD,EAAA3e,YAAA4I,KAAAxH,SACAud,EAAA3e,YAAA+e,EAGA,IAAAE,GAAA,WACArW,KAAAxH,QAAA0d,WAAA,EACAF,EAAAvf,UAAAO,IAAAgJ,KAAArJ,YAAA4B,WAEAyd,EAAAvf,UAAAqL,OAAA9B,KAAArJ,YAAA4B,WAEAyH,KAAAxH,QAAA0d,WAAAlW,KAAAxH,QAAA8d,YAAAtW,KAAAxH,QAAA4Y,YACA+E,EAAA1f,UAAAO,IAAAgJ,KAAArJ,YAAA4B,WAEA4d,EAAA1f,UAAAqL,OAAA9B,KAAArJ,YAAA4B,YAEAqI,KAAAZ,KACAA,MAAAxH,QAAAnB,iBAAA,SAAAgf,GACAA,GAEA,IAAAE,GAAA,WAEAvW,KAAAwW,kBACA1W,aAAAE,KAAAwW,kBAEAxW,KAAAwW,iBAAA3W,WAAA,WACAwW,IACArW,KAAAwW,iBAAA,MACA5V,KAAAZ,MAAAA,KAAAE,UAAA0R,iBACAhR,KAAAZ,KACAlF,QAAAzD,iBAAA,SAAAkf,GACAvW,KAAAxH,QAAA/B,UAAAC,SAAAsJ,KAAArJ,YAAA8B,mBACAuH,KAAAxH,QAAA/B,UAAAO,IAAAgJ,KAAArJ,YAAAyK,qBAMA,KAAA,GAHAlJ,GAAA8H,KAAAxH,QAAA8C,iBAAA,IAAA0E,KAAArJ,YAAAsc,KACA9a,EAAA6H,KAAA1H,SAAAgD,iBAAA,IAAA0E,KAAArJ,YAAA0c,OAEApZ,EAAA,EAAAA,EAAA/B,EAAAiC,OAAAF,IACA,GAAAhC,GAAAC,EAAA+B,GAAA/B,EAAAC,EAAA6H,MAGAA,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA8K,eA2CA3G,OAAA,kBAAA7C,EAGAa,EAAAY,UACA8D,YAAAiU,EACAhU,cAAA,iBACArC,SAAA,iBercA,IAAAqb,GAAA,SAAAtd,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,kBAAA2b,EAOAA,EAAAzZ,UAAAkD,aASAuW,EAAAzZ,UAAArG,aACA+f,WAAA,iBACAC,WAAA,6BACAC,eAAA,yBACAC,YAAA,cACApV,YAAA,eAWAgV,EAAAzZ,UAAA8Z,WAAA,SAAAC,EAAAC,EAAAC,GACA,MAAAD,GACA,WACAD,EAAA3U,QACA4U,EAAAvgB,UAAAO,IAAAgJ,KAAArJ,YAAAkgB,aAEAG,EAAAvgB,UAAAqL,OAAA9B,KAAArJ,YAAAkgB,cAEAjW,KAAAZ,MAEAiX,EACA,WACA,GAAAhd,GACAoO,CACA,IAAA0O,EAAA3U,QACA,IAAAnI,EAAA,EAAAA,EAAAgd,EAAA9c,OAAAF,IACAoO,EAAA4O,EAAAhd,GAAApC,cAAA,MAAAA,cAAA,iBACAwQ,EAAA,iBAAAhG,QACA4U,EAAAhd,GAAAxD,UAAAO,IAAAgJ,KAAArJ,YAAAkgB,iBAGA,KAAA5c,EAAA,EAAAA,EAAAgd,EAAA9c,OAAAF,IACAoO,EAAA4O,EAAAhd,GAAApC,cAAA,MAAAA,cAAA,iBACAwQ,EAAA,iBAAA/F,UACA2U,EAAAhd,GAAAxD,UAAAqL,OAAA9B,KAAArJ,YAAAkgB,cAGAjW,KAAAZ,MAjBA,QA4BAyW,EAAAzZ,UAAAka,gBAAA,SAAAF,EAAAC,GACA,GAAAE,GAAArgB,SAAAC,cAAA,SACAqgB,GACA,eACA,kBACA,uBACApX,KAAArJ,YAAAigB,eAEAO,GAAA/c,UAAAgd,EAAAjb,KAAA,IACA,IAAA4a,GAAAjgB,SAAAC,cAAA,QAWA,OAVAggB,GAAApC,KAAA,WACAoC,EAAAtgB,UAAAO,IAAA,uBACAggB,GACAD,EAAA3U,QAAA4U,EAAAvgB,UAAAC,SAAAsJ,KAAArJ,YAAAkgB,aACAE,EAAA1f,iBAAA,SAAA2I,KAAA8W,WAAAC,EAAAC,KACAC,GACAF,EAAA1f,iBAAA,SAAA2I,KAAA8W,WAAAC,EAAA,KAAAE,IAEAE,EAAA/f,YAAA2f,GACAje,EAAAI,eAAAie,EAAA,oBACAA,GAKAV,EAAAzZ,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACA,GAAA6gB,GAAArX,KAAAxJ,SAAAqB,cAAA,MACAyf,EAAAxa,MAAAE,UAAAC,MAAAC,KAAA8C,KAAAxJ,SAAA8E,iBAAA,aACAic,EAAAza,MAAAE,UAAAC,MAAAC,KAAA8C,KAAAxJ,SAAA8E,iBAAA,aACAkc,EAAAF,EAAAG,OAAAF,EACA,IAAAvX,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAAggB,YAAA,CACA,GAAAe,GAAA5gB,SAAAC,cAAA,MACA4gB,EAAA3X,KAAAkX,gBAAA,KAAAM,EACAE,GAAAtgB,YAAAugB,GACAN,EAAA7S,cAAAC,aAAAiT,EAAAL,EACA,KAAA,GAAApd,GAAA,EAAAA,EAAAud,EAAArd,OAAAF,IAAA,CACA,GAAA2d,GAAAJ,EAAAvd,GAAApC,cAAA,KACA,IAAA+f,EAAA,CACA,GAAAC,GAAA/gB,SAAAC,cAAA,KACA,IAAA,UAAAygB,EAAAvd,GAAAyN,WAAAoQ,SAAAC,cAAA,CACA,GAAAC,GAAAhY,KAAAkX,gBAAAM,EAAAvd,GACA4d,GAAAzgB,YAAA4gB,GAEAR,EAAAvd,GAAAwK,aAAAoT,EAAAD,IAGA5X,KAAAxJ,SAAAC,UAAAO,IAAAgJ,KAAArJ,YAAA8K,gBAMA3I,EAAAY,UACA8D,YAAAiZ,EACAhZ,cAAA,oBACArC,SAAA,qBCnIA,IAAA6c,GAAA,SAAA9e,GACA6G,KAAAxJ,SAAA2C,EAEA6G,KAAAC,OAEAnF,QAAA,eAAAmd,EAOAA,EAAAjb,UAAAkD,WACAgY,cAAA,wBACAC,aAAA,MACAC,gBAAA,MACAC,cAAA,IACAC,YAAA,IAUAL,EAAAjb,UAAArG,aACA0K,cAAA,qBACAkX,4BAAA,sCACA5f,OAAA,aACAsL,aAAA,eACAD,WAAA,cAQAiU,EAAAjb,UAAAwb,aAAA,SAAAnY,GACA,IAAAL,KAAAU,eAAAoF,MAAAqB,QAAAnH,KAAAU,eAAAoF,MAAAoB,OAAA,CACA,GAAAvB,GAAA3F,KAAAxJ,SAAAoP,uBACA5F,MAAAyY,YAAA9S,EAAAuB,OACAlH,KAAA0Y,WAAA/S,EAAAwB,MACAnH,KAAA2Y,YAAA,EAAAhZ,KAAAiZ,KAAAjT,EAAAwB,MAAAxB,EAAAwB,MAAAxB,EAAAuB,OAAAvB,EAAAuB,QAAA,EACAlH,KAAAU,eAAAoF,MAAAqB,MAAAnH,KAAA2Y,YAAA,KACA3Y,KAAAU,eAAAoF,MAAAoB,OAAAlH,KAAA2Y,YAAA,KAGA,GADA3Y,KAAAU,eAAAjK,UAAAO,IAAAgJ,KAAArJ,YAAAqN,YACA,cAAA3D,EAAAsU,MAAA3U,KAAA6Y,mBACA7Y,KAAA6Y,oBAAA,MACA,CACA,eAAAxY,EAAAsU,OACA3U,KAAA6Y,oBAAA,EAEA,IAAAC,GAAA9Y,KAAA+Y,eACA,IAAAD,EAAA,EACA,MAEA9Y,MAAAgZ,cAAA,EACA,IACAC,GACA3O,EAFA4O,EAAA7Y,EAAA8Y,cAAAvT,uBAIA,IAAA,IAAAvF,EAAA+J,SAAA,IAAA/J,EAAAgK,QACA4O,EAAAtZ,KAAAyZ,MAAAF,EAAA/R,MAAA,GACAmD,EAAA3K,KAAAyZ,MAAAF,EAAAhS,OAAA,OACA,CACA,GAAAkD,GAAAyB,SAAAxL,EAAA+J,QAAA/J,EAAA+J,QAAA/J,EAAAgZ,QAAA,GAAAjP,QACAC,EAAAwB,SAAAxL,EAAAgK,QAAAhK,EAAAgK,QAAAhK,EAAAgZ,QAAA,GAAAhP,OACA4O,GAAAtZ,KAAAyZ,MAAAhP,EAAA8O,EAAA/S,MACAmE,EAAA3K,KAAAyZ,MAAA/O,EAAA6O,EAAAlT,KAEAhG,KAAAsZ,YAAAL,EAAA3O,GACAtK,KAAAuZ,iBAAA,GACAze,OAAAqE,sBAAAa,KAAAwZ,iBAAA5Y,KAAAZ,SASAiY,EAAAjb,UAAAyc,WAAA,SAAApZ,GAEAA,GAAA,IAAAA,EAAAqZ,QAIA5e,OAAA+E,WAAA,WACAG,KAAAU,eAAAjK,UAAAqL,OAAA9B,KAAArJ,YAAAqN,aACApD,KAAAZ,MAAA,IAMAiY,EAAAjb,UAAAiD,KAAA,WACA,GAAAD,KAAAxJ,SAAA,CACA,GAAAmjB,GAAA3Z,KAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA0K,cACArB,MAAAxJ,SAAAC,UAAAC,SAAAsJ,KAAArJ,YAAA4hB,+BACAvY,KAAAU,eAAAV,KAAAxJ,SAAAqB,cAAA,IAAAmI,KAAArJ,YAAAgC,QACAqH,KAAA4Z,YAAA,EACA5Z,KAAA2Y,YAAA,EACA3Y,KAAA6Z,GAAA,EACA7Z,KAAA8Z,GAAA,EAIA9Z,KAAA6Y,oBAAA,EACA7Y,KAAA+Z,iBAAA/Z,KAAAwY,aAAA5X,KAAAZ,MACAA,KAAAxJ,SAAAa,iBAAA,YAAA2I,KAAA+Z,kBACA/Z,KAAAxJ,SAAAa,iBAAA,aAAA2I,KAAA+Z,kBACA/Z,KAAAga,eAAAha,KAAAyZ,WAAA7Y,KAAAZ,MACAA,KAAAxJ,SAAAa,iBAAA,UAAA2I,KAAAga,gBACAha,KAAAxJ,SAAAa,iBAAA,aAAA2I,KAAAga,gBACAha,KAAAxJ,SAAAa,iBAAA,WAAA2I,KAAAga,gBACAha,KAAAxJ,SAAAa,iBAAA,OAAA2I,KAAAga,gBAKAha,KAAA+Y,cAAA,WACA,MAAA/Y,MAAA4Z,aAMA5Z,KAAAgZ,cAAA,SAAAiB,GACAja,KAAA4Z,YAAAK,GAMAja,KAAAka,iBAAA,WACA,MAAAla,MAAAU,gBAOAV,KAAAsZ,YAAA,SAAAa,EAAAC,GACApa,KAAA6Z,GAAAM,EACAna,KAAA8Z,GAAAM,GAMApa,KAAAuZ,gBAAA,SAAAvL,GACA,GAAA,OAAAhO,KAAAU,eAAA,CACA,GAAA2Z,GACAC,EACAC,EACAC,EAAA,aAAAxa,KAAA6Z,GAAA,OAAA7Z,KAAA8Z,GAAA,KACA9L,IACAsM,EAAAta,KAAAE,UAAAgY,cACAqC,EAAAva,KAAAE,UAAAiY,eAEAmC,EAAAta,KAAAE,UAAAoY,YACAiC,EAAAva,KAAA2Y,YAAA,KACAgB,IACAa,EAAA,aAAAxa,KAAA0Y,WAAA,EAAA,OAAA1Y,KAAAyY,YAAA,EAAA,QAGA4B,EAAA,yBAAAG,EAAAF,EACAta,KAAAU,eAAAoF,MAAA2U,gBAAAJ,EACAra,KAAAU,eAAAoF,MAAA4U,YAAAL,EACAra,KAAAU,eAAAoF,MAAA6U,UAAAN,EACArM,EACAhO,KAAAU,eAAAjK,UAAAqL,OAAA9B,KAAArJ,YAAAsN,cAEAjE,KAAAU,eAAAjK,UAAAO,IAAAgJ,KAAArJ,YAAAsN,gBAOAjE,KAAAwZ,iBAAA,WACAxZ,KAAA4Z,eAAA,EACA9e,OAAAqE,sBAAAa,KAAAwZ,iBAAA5Y,KAAAZ,OAEAA,KAAAuZ,iBAAA,OAQAzgB,EAAAY,UACA8D,YAAAya,EACAxa,cAAA,iBACArC,SAAA,uBACAuB,QAAA", + "file": "material.min.js", + "sourcesContent": [ + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Tabs MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {Element} element The element that will be upgraded.\n */\nvar MaterialTabs = function MaterialTabs(element) {\n // Stores the HTML element.\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialTabs'] = MaterialTabs;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string}\n * @private\n */\nMaterialTabs.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialTabs.prototype.CssClasses_ = {\n TAB_CLASS: 'mdl-tabs__tab',\n PANEL_CLASS: 'mdl-tabs__panel',\n ACTIVE_CLASS: 'is-active',\n UPGRADED_CLASS: 'is-upgraded',\n MDL_JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n MDL_RIPPLE_CONTAINER: 'mdl-tabs__ripple-container',\n MDL_RIPPLE: 'mdl-ripple',\n MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events'\n};\n/**\n * Handle clicks to a tabs component\n *\n * @private\n */\nMaterialTabs.prototype.initTabs_ = function () {\n if (this.element_.classList.contains(this.CssClasses_.MDL_JS_RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS);\n }\n // Select element tabs, document panels\n this.tabs_ = this.element_.querySelectorAll('.' + this.CssClasses_.TAB_CLASS);\n this.panels_ = this.element_.querySelectorAll('.' + this.CssClasses_.PANEL_CLASS);\n // Create new tabs for each tab element\n for (var i = 0; i < this.tabs_.length; i++) {\n new MaterialTab(this.tabs_[i], this);\n }\n this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS);\n};\n/**\n * Reset tab state, dropping active classes\n *\n * @private\n */\nMaterialTabs.prototype.resetTabState_ = function () {\n for (var k = 0; k < this.tabs_.length; k++) {\n this.tabs_[k].classList.remove(this.CssClasses_.ACTIVE_CLASS);\n }\n};\n/**\n * Reset panel state, droping active classes\n *\n * @private\n */\nMaterialTabs.prototype.resetPanelState_ = function () {\n for (var j = 0; j < this.panels_.length; j++) {\n this.panels_[j].classList.remove(this.CssClasses_.ACTIVE_CLASS);\n }\n};\n/**\n * Initialize element.\n */\nMaterialTabs.prototype.init = function () {\n if (this.element_) {\n this.initTabs_();\n }\n};\n/**\n * Constructor for an individual tab.\n *\n * @constructor\n * @param {Element} tab The HTML element for the tab.\n * @param {MaterialTabs} ctx The MaterialTabs object that owns the tab.\n */\nfunction MaterialTab(tab, ctx) {\n if (tab) {\n if (ctx.element_.classList.contains(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT)) {\n var rippleContainer = document.createElement('span');\n rippleContainer.classList.add(ctx.CssClasses_.MDL_RIPPLE_CONTAINER);\n rippleContainer.classList.add(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT);\n var ripple = document.createElement('span');\n ripple.classList.add(ctx.CssClasses_.MDL_RIPPLE);\n rippleContainer.appendChild(ripple);\n tab.appendChild(rippleContainer);\n }\n tab.addEventListener('click', function (e) {\n if (tab.getAttribute('href').charAt(0) === '#') {\n e.preventDefault();\n var href = tab.href.split('#')[1];\n var panel = ctx.element_.querySelector('#' + href);\n ctx.resetTabState_();\n ctx.resetPanelState_();\n tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS);\n panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS);\n }\n });\n }\n}\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialTabs,\n classAsString: 'MaterialTabs',\n cssClass: 'mdl-js-tabs'\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Layout MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialLayout = function MaterialLayout(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialLayout'] = MaterialLayout;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialLayout.prototype.Constant_ = {\n MAX_WIDTH: '(max-width: 1024px)',\n TAB_SCROLL_PIXELS: 100,\n RESIZE_TIMEOUT: 100,\n MENU_ICON: '',\n CHEVRON_LEFT: 'chevron_left',\n CHEVRON_RIGHT: 'chevron_right'\n};\n/**\n * Keycodes, for code readability.\n *\n * @enum {number}\n * @private\n */\nMaterialLayout.prototype.Keycodes_ = {\n ENTER: 13,\n ESCAPE: 27,\n SPACE: 32\n};\n/**\n * Modes.\n *\n * @enum {number}\n * @private\n */\nMaterialLayout.prototype.Mode_ = {\n STANDARD: 0,\n SEAMED: 1,\n WATERFALL: 2,\n SCROLL: 3\n};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialLayout.prototype.CssClasses_ = {\n CONTAINER: 'mdl-layout__container',\n HEADER: 'mdl-layout__header',\n DRAWER: 'mdl-layout__drawer',\n CONTENT: 'mdl-layout__content',\n DRAWER_BTN: 'mdl-layout__drawer-button',\n ICON: 'material-icons',\n JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_CONTAINER: 'mdl-layout__tab-ripple-container',\n RIPPLE: 'mdl-ripple',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n HEADER_SEAMED: 'mdl-layout__header--seamed',\n HEADER_WATERFALL: 'mdl-layout__header--waterfall',\n HEADER_SCROLL: 'mdl-layout__header--scroll',\n FIXED_HEADER: 'mdl-layout--fixed-header',\n OBFUSCATOR: 'mdl-layout__obfuscator',\n TAB_BAR: 'mdl-layout__tab-bar',\n TAB_CONTAINER: 'mdl-layout__tab-bar-container',\n TAB: 'mdl-layout__tab',\n TAB_BAR_BUTTON: 'mdl-layout__tab-bar-button',\n TAB_BAR_LEFT_BUTTON: 'mdl-layout__tab-bar-left-button',\n TAB_BAR_RIGHT_BUTTON: 'mdl-layout__tab-bar-right-button',\n TAB_MANUAL_SWITCH: 'mdl-layout__tab-manual-switch',\n PANEL: 'mdl-layout__tab-panel',\n HAS_DRAWER: 'has-drawer',\n HAS_TABS: 'has-tabs',\n HAS_SCROLLING_HEADER: 'has-scrolling-header',\n CASTING_SHADOW: 'is-casting-shadow',\n IS_COMPACT: 'is-compact',\n IS_SMALL_SCREEN: 'is-small-screen',\n IS_DRAWER_OPEN: 'is-visible',\n IS_ACTIVE: 'is-active',\n IS_UPGRADED: 'is-upgraded',\n IS_ANIMATING: 'is-animating',\n ON_LARGE_SCREEN: 'mdl-layout--large-screen-only',\n ON_SMALL_SCREEN: 'mdl-layout--small-screen-only'\n};\n/**\n * Handles scrolling on the content.\n *\n * @private\n */\nMaterialLayout.prototype.contentScrollHandler_ = function () {\n if (this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)) {\n return;\n }\n var headerVisible = !this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN) || this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);\n if (this.content_.scrollTop > 0 && !this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {\n this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);\n this.header_.classList.add(this.CssClasses_.IS_COMPACT);\n if (headerVisible) {\n this.header_.classList.add(this.CssClasses_.IS_ANIMATING);\n }\n } else if (this.content_.scrollTop <= 0 && this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {\n this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);\n this.header_.classList.remove(this.CssClasses_.IS_COMPACT);\n if (headerVisible) {\n this.header_.classList.add(this.CssClasses_.IS_ANIMATING);\n }\n }\n};\n/**\n * Handles a keyboard event on the drawer.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialLayout.prototype.keyboardEventHandler_ = function (evt) {\n // Only react when the drawer is open.\n if (evt.keyCode === this.Keycodes_.ESCAPE && this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {\n this.toggleDrawer();\n }\n};\n/**\n * Handles changes in screen size.\n *\n * @private\n */\nMaterialLayout.prototype.screenSizeHandler_ = function () {\n if (this.screenSizeMediaQuery_.matches) {\n this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN);\n // Collapse drawer (if any) when moving to a large screen size.\n if (this.drawer_) {\n this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);\n this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);\n }\n }\n};\n/**\n * Handles events of drawer button.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialLayout.prototype.drawerToggleHandler_ = function (evt) {\n if (evt && evt.type === 'keydown') {\n if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) {\n // prevent scrolling in drawer nav\n evt.preventDefault();\n } else {\n // prevent other keys\n return;\n }\n }\n this.toggleDrawer();\n};\n/**\n * Handles (un)setting the `is-animating` class\n *\n * @private\n */\nMaterialLayout.prototype.headerTransitionEndHandler_ = function () {\n this.header_.classList.remove(this.CssClasses_.IS_ANIMATING);\n};\n/**\n * Handles expanding the header on click\n *\n * @private\n */\nMaterialLayout.prototype.headerClickHandler_ = function () {\n if (this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {\n this.header_.classList.remove(this.CssClasses_.IS_COMPACT);\n this.header_.classList.add(this.CssClasses_.IS_ANIMATING);\n }\n};\n/**\n * Reset tab state, dropping active classes\n *\n * @private\n */\nMaterialLayout.prototype.resetTabState_ = function (tabBar) {\n for (var k = 0; k < tabBar.length; k++) {\n tabBar[k].classList.remove(this.CssClasses_.IS_ACTIVE);\n }\n};\n/**\n * Reset panel state, droping active classes\n *\n * @private\n */\nMaterialLayout.prototype.resetPanelState_ = function (panels) {\n for (var j = 0; j < panels.length; j++) {\n panels[j].classList.remove(this.CssClasses_.IS_ACTIVE);\n }\n};\n/**\n * Toggle drawer state\n *\n * @public\n */\nMaterialLayout.prototype.toggleDrawer = function () {\n var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN);\n this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);\n this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);\n // Set accessibility properties.\n if (this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {\n this.drawer_.setAttribute('aria-hidden', 'false');\n drawerButton.setAttribute('aria-expanded', 'true');\n } else {\n this.drawer_.setAttribute('aria-hidden', 'true');\n drawerButton.setAttribute('aria-expanded', 'false');\n }\n};\nMaterialLayout.prototype['toggleDrawer'] = MaterialLayout.prototype.toggleDrawer;\n/**\n * Initialize element.\n */\nMaterialLayout.prototype.init = function () {\n if (this.element_) {\n var container = document.createElement('div');\n container.classList.add(this.CssClasses_.CONTAINER);\n var focusedElement = this.element_.querySelector(':focus');\n this.element_.parentElement.insertBefore(container, this.element_);\n this.element_.parentElement.removeChild(this.element_);\n container.appendChild(this.element_);\n if (focusedElement) {\n focusedElement.focus();\n }\n var directChildren = this.element_.childNodes;\n var numChildren = directChildren.length;\n for (var c = 0; c < numChildren; c++) {\n var child = directChildren[c];\n if (child.classList && child.classList.contains(this.CssClasses_.HEADER)) {\n this.header_ = child;\n }\n if (child.classList && child.classList.contains(this.CssClasses_.DRAWER)) {\n this.drawer_ = child;\n }\n if (child.classList && child.classList.contains(this.CssClasses_.CONTENT)) {\n this.content_ = child;\n }\n }\n window.addEventListener('pageshow', function (e) {\n if (e.persisted) {\n // when page is loaded from back/forward cache\n // trigger repaint to let layout scroll in safari\n this.element_.style.overflowY = 'hidden';\n requestAnimationFrame(function () {\n this.element_.style.overflowY = '';\n }.bind(this));\n }\n }.bind(this), false);\n if (this.header_) {\n this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR);\n }\n var mode = this.Mode_.STANDARD;\n if (this.header_) {\n if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) {\n mode = this.Mode_.SEAMED;\n } else if (this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)) {\n mode = this.Mode_.WATERFALL;\n this.header_.addEventListener('transitionend', this.headerTransitionEndHandler_.bind(this));\n this.header_.addEventListener('click', this.headerClickHandler_.bind(this));\n } else if (this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)) {\n mode = this.Mode_.SCROLL;\n container.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER);\n }\n if (mode === this.Mode_.STANDARD) {\n this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);\n if (this.tabBar_) {\n this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW);\n }\n } else if (mode === this.Mode_.SEAMED || mode === this.Mode_.SCROLL) {\n this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);\n if (this.tabBar_) {\n this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW);\n }\n } else if (mode === this.Mode_.WATERFALL) {\n // Add and remove shadows depending on scroll position.\n // Also add/remove auxiliary class for styling of the compact version of\n // the header.\n this.content_.addEventListener('scroll', this.contentScrollHandler_.bind(this));\n this.contentScrollHandler_();\n }\n }\n // Add drawer toggling button to our layout, if we have an openable drawer.\n if (this.drawer_) {\n var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN);\n if (!drawerButton) {\n drawerButton = document.createElement('div');\n drawerButton.setAttribute('aria-expanded', 'false');\n drawerButton.setAttribute('role', 'button');\n drawerButton.setAttribute('tabindex', '0');\n drawerButton.classList.add(this.CssClasses_.DRAWER_BTN);\n var drawerButtonIcon = document.createElement('i');\n drawerButtonIcon.classList.add(this.CssClasses_.ICON);\n drawerButtonIcon.innerHTML = this.Constant_.MENU_ICON;\n drawerButton.appendChild(drawerButtonIcon);\n }\n if (this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)) {\n //If drawer has ON_LARGE_SCREEN class then add it to the drawer toggle button as well.\n drawerButton.classList.add(this.CssClasses_.ON_LARGE_SCREEN);\n } else if (this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)) {\n //If drawer has ON_SMALL_SCREEN class then add it to the drawer toggle button as well.\n drawerButton.classList.add(this.CssClasses_.ON_SMALL_SCREEN);\n }\n drawerButton.addEventListener('click', this.drawerToggleHandler_.bind(this));\n drawerButton.addEventListener('keydown', this.drawerToggleHandler_.bind(this));\n // Add a class if the layout has a drawer, for altering the left padding.\n // Adds the HAS_DRAWER to the elements since this.header_ may or may\n // not be present.\n this.element_.classList.add(this.CssClasses_.HAS_DRAWER);\n // If we have a fixed header, add the button to the header rather than\n // the layout.\n if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) {\n this.header_.insertBefore(drawerButton, this.header_.firstChild);\n } else {\n this.element_.insertBefore(drawerButton, this.content_);\n }\n var obfuscator = document.createElement('div');\n obfuscator.classList.add(this.CssClasses_.OBFUSCATOR);\n this.element_.appendChild(obfuscator);\n obfuscator.addEventListener('click', this.drawerToggleHandler_.bind(this));\n this.obfuscator_ = obfuscator;\n this.drawer_.addEventListener('keydown', this.keyboardEventHandler_.bind(this));\n this.drawer_.setAttribute('aria-hidden', 'true');\n }\n // Keep an eye on screen size, and add/remove auxiliary class for styling\n // of small screens.\n this.screenSizeMediaQuery_ = window.matchMedia(this.Constant_.MAX_WIDTH);\n this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this));\n this.screenSizeHandler_();\n // Initialize tabs, if any.\n if (this.header_ && this.tabBar_) {\n this.element_.classList.add(this.CssClasses_.HAS_TABS);\n var tabContainer = document.createElement('div');\n tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER);\n this.header_.insertBefore(tabContainer, this.tabBar_);\n this.header_.removeChild(this.tabBar_);\n var leftButton = document.createElement('div');\n leftButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);\n leftButton.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);\n var leftButtonIcon = document.createElement('i');\n leftButtonIcon.classList.add(this.CssClasses_.ICON);\n leftButtonIcon.textContent = this.Constant_.CHEVRON_LEFT;\n leftButton.appendChild(leftButtonIcon);\n leftButton.addEventListener('click', function () {\n this.tabBar_.scrollLeft -= this.Constant_.TAB_SCROLL_PIXELS;\n }.bind(this));\n var rightButton = document.createElement('div');\n rightButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);\n rightButton.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);\n var rightButtonIcon = document.createElement('i');\n rightButtonIcon.classList.add(this.CssClasses_.ICON);\n rightButtonIcon.textContent = this.Constant_.CHEVRON_RIGHT;\n rightButton.appendChild(rightButtonIcon);\n rightButton.addEventListener('click', function () {\n this.tabBar_.scrollLeft += this.Constant_.TAB_SCROLL_PIXELS;\n }.bind(this));\n tabContainer.appendChild(leftButton);\n tabContainer.appendChild(this.tabBar_);\n tabContainer.appendChild(rightButton);\n // Add and remove tab buttons depending on scroll position and total\n // window size.\n var tabUpdateHandler = function () {\n if (this.tabBar_.scrollLeft > 0) {\n leftButton.classList.add(this.CssClasses_.IS_ACTIVE);\n } else {\n leftButton.classList.remove(this.CssClasses_.IS_ACTIVE);\n }\n if (this.tabBar_.scrollLeft < this.tabBar_.scrollWidth - this.tabBar_.offsetWidth) {\n rightButton.classList.add(this.CssClasses_.IS_ACTIVE);\n } else {\n rightButton.classList.remove(this.CssClasses_.IS_ACTIVE);\n }\n }.bind(this);\n this.tabBar_.addEventListener('scroll', tabUpdateHandler);\n tabUpdateHandler();\n // Update tabs when the window resizes.\n var windowResizeHandler = function () {\n // Use timeouts to make sure it doesn't happen too often.\n if (this.resizeTimeoutId_) {\n clearTimeout(this.resizeTimeoutId_);\n }\n this.resizeTimeoutId_ = setTimeout(function () {\n tabUpdateHandler();\n this.resizeTimeoutId_ = null;\n }.bind(this), this.Constant_.RESIZE_TIMEOUT);\n }.bind(this);\n window.addEventListener('resize', windowResizeHandler);\n if (this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {\n this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n }\n // Select element tabs, document panels\n var tabs = this.tabBar_.querySelectorAll('.' + this.CssClasses_.TAB);\n var panels = this.content_.querySelectorAll('.' + this.CssClasses_.PANEL);\n // Create new tabs for each tab element\n for (var i = 0; i < tabs.length; i++) {\n new MaterialLayoutTab(tabs[i], tabs, panels, this);\n }\n }\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n};\n/**\n * Constructor for an individual tab.\n *\n * @constructor\n * @param {HTMLElement} tab The HTML element for the tab.\n * @param {!Array<HTMLElement>} tabs Array with HTML elements for all tabs.\n * @param {!Array<HTMLElement>} panels Array with HTML elements for all panels.\n * @param {MaterialLayout} layout The MaterialLayout object that owns the tab.\n */\nfunction MaterialLayoutTab(tab, tabs, panels, layout) {\n /**\n * Auxiliary method to programmatically select a tab in the UI.\n */\n function selectTab() {\n var href = tab.href.split('#')[1];\n var panel = layout.content_.querySelector('#' + href);\n layout.resetTabState_(tabs);\n layout.resetPanelState_(panels);\n tab.classList.add(layout.CssClasses_.IS_ACTIVE);\n panel.classList.add(layout.CssClasses_.IS_ACTIVE);\n }\n if (layout.tabBar_.classList.contains(layout.CssClasses_.JS_RIPPLE_EFFECT)) {\n var rippleContainer = document.createElement('span');\n rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER);\n rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT);\n var ripple = document.createElement('span');\n ripple.classList.add(layout.CssClasses_.RIPPLE);\n rippleContainer.appendChild(ripple);\n tab.appendChild(rippleContainer);\n }\n if (!layout.tabBar_.classList.contains(layout.CssClasses_.TAB_MANUAL_SWITCH)) {\n tab.addEventListener('click', function (e) {\n if (tab.getAttribute('href').charAt(0) === '#') {\n e.preventDefault();\n selectTab();\n }\n });\n }\n tab.show = selectTab;\n}\nwindow['MaterialLayoutTab'] = MaterialLayoutTab;\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialLayout,\n classAsString: 'MaterialLayout',\n cssClass: 'mdl-js-layout'\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * A component handler interface using the revealing module design pattern.\n * More details on this design pattern here:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @author Jason Mayes.\n */\n/* exported componentHandler */\n\n// Pre-defining the componentHandler interface, for closure documentation and\n// static verification.\nvar componentHandler = {\n /**\n * Searches existing DOM for elements of our component type and upgrades them\n * if they have not already been upgraded.\n *\n * @param {string=} optJsClass the programatic name of the element class we\n * need to create a new instance of.\n * @param {string=} optCssClass the name of the CSS class elements of this\n * type will have.\n */\n upgradeDom: function(optJsClass, optCssClass) {},\n /**\n * Upgrades a specific element rather than all in the DOM.\n *\n * @param {!Element} element The element we wish to upgrade.\n * @param {string=} optJsClass Optional name of the class we want to upgrade\n * the element to.\n */\n upgradeElement: function(element, optJsClass) {},\n /**\n * Upgrades a specific list of elements rather than all in the DOM.\n *\n * @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements\n * The elements we wish to upgrade.\n */\n upgradeElements: function(elements) {},\n /**\n * Upgrades all registered components found in the current DOM. This is\n * automatically called on window load.\n */\n upgradeAllRegistered: function() {},\n /**\n * Allows user to be alerted to any upgrades that are performed for a given\n * component type\n *\n * @param {string} jsClass The class name of the MDL component we wish\n * to hook into for any upgrades performed.\n * @param {function(!HTMLElement)} callback The function to call upon an\n * upgrade. This function should expect 1 parameter - the HTMLElement which\n * got upgraded.\n */\n registerUpgradedCallback: function(jsClass, callback) {},\n /**\n * Registers a class for future use and attempts to upgrade existing DOM.\n *\n * @param {componentHandler.ComponentConfigPublic} config the registration configuration\n */\n register: function(config) {},\n /**\n * Downgrade either a given node, an array of nodes, or a NodeList.\n *\n * @param {!Node|!Array<!Node>|!NodeList} nodes\n */\n downgradeElements: function(nodes) {}\n};\n\ncomponentHandler = (function() {\n 'use strict';\n\n /** @type {!Array<componentHandler.ComponentConfig>} */\n var registeredComponents_ = [];\n\n /** @type {!Array<componentHandler.Component>} */\n var createdComponents_ = [];\n\n var componentConfigProperty_ = 'mdlComponentConfigInternal_';\n\n /**\n * Searches registered components for a class we are interested in using.\n * Optionally replaces a match with passed object if specified.\n *\n * @param {string} name The name of a class we want to use.\n * @param {componentHandler.ComponentConfig=} optReplace Optional object to replace match with.\n * @return {!Object|boolean}\n * @private\n */\n function findRegisteredClass_(name, optReplace) {\n for (var i = 0; i < registeredComponents_.length; i++) {\n if (registeredComponents_[i].className === name) {\n if (typeof optReplace !== 'undefined') {\n registeredComponents_[i] = optReplace;\n }\n return registeredComponents_[i];\n }\n }\n return false;\n }\n\n /**\n * Returns an array of the classNames of the upgraded classes on the element.\n *\n * @param {!Element} element The element to fetch data from.\n * @return {!Array<string>}\n * @private\n */\n function getUpgradedListOfElement_(element) {\n var dataUpgraded = element.getAttribute('data-upgraded');\n // Use `['']` as default value to conform the `,name,name...` style.\n return dataUpgraded === null ? [''] : dataUpgraded.split(',');\n }\n\n /**\n * Returns true if the given element has already been upgraded for the given\n * class.\n *\n * @param {!Element} element The element we want to check.\n * @param {string} jsClass The class to check for.\n * @returns {boolean}\n * @private\n */\n function isElementUpgraded_(element, jsClass) {\n var upgradedList = getUpgradedListOfElement_(element);\n return upgradedList.indexOf(jsClass) !== -1;\n }\n\n /**\n * Create an event object.\n *\n * @param {string} eventType The type name of the event.\n * @param {boolean} bubbles Whether the event should bubble up the DOM.\n * @param {boolean} cancelable Whether the event can be canceled.\n * @returns {!Event}\n */\n function createEvent_(eventType, bubbles, cancelable) {\n if ('CustomEvent' in window && typeof window.CustomEvent === 'function') {\n return new CustomEvent(eventType, {\n bubbles: bubbles,\n cancelable: cancelable\n });\n } else {\n var ev = document.createEvent('Events');\n ev.initEvent(eventType, bubbles, cancelable);\n return ev;\n }\n }\n\n /**\n * Searches existing DOM for elements of our component type and upgrades them\n * if they have not already been upgraded.\n *\n * @param {string=} optJsClass the programatic name of the element class we\n * need to create a new instance of.\n * @param {string=} optCssClass the name of the CSS class elements of this\n * type will have.\n */\n function upgradeDomInternal(optJsClass, optCssClass) {\n if (typeof optJsClass === 'undefined' &&\n typeof optCssClass === 'undefined') {\n for (var i = 0; i < registeredComponents_.length; i++) {\n upgradeDomInternal(registeredComponents_[i].className,\n registeredComponents_[i].cssClass);\n }\n } else {\n var jsClass = /** @type {string} */ (optJsClass);\n if (typeof optCssClass === 'undefined') {\n var registeredClass = findRegisteredClass_(jsClass);\n if (registeredClass) {\n optCssClass = registeredClass.cssClass;\n }\n }\n\n var elements = document.querySelectorAll('.' + optCssClass);\n for (var n = 0; n < elements.length; n++) {\n upgradeElementInternal(elements[n], jsClass);\n }\n }\n }\n\n /**\n * Upgrades a specific element rather than all in the DOM.\n *\n * @param {!Element} element The element we wish to upgrade.\n * @param {string=} optJsClass Optional name of the class we want to upgrade\n * the element to.\n */\n function upgradeElementInternal(element, optJsClass) {\n // Verify argument type.\n if (!(typeof element === 'object' && element instanceof Element)) {\n throw new Error('Invalid argument provided to upgrade MDL element.');\n }\n // Allow upgrade to be canceled by canceling emitted event.\n var upgradingEv = createEvent_('mdl-componentupgrading', true, true);\n element.dispatchEvent(upgradingEv);\n if (upgradingEv.defaultPrevented) {\n return;\n }\n\n var upgradedList = getUpgradedListOfElement_(element);\n var classesToUpgrade = [];\n // If jsClass is not provided scan the registered components to find the\n // ones matching the element's CSS classList.\n if (!optJsClass) {\n var classList = element.classList;\n registeredComponents_.forEach(function(component) {\n // Match CSS & Not to be upgraded & Not upgraded.\n if (classList.contains(component.cssClass) &&\n classesToUpgrade.indexOf(component) === -1 &&\n !isElementUpgraded_(element, component.className)) {\n classesToUpgrade.push(component);\n }\n });\n } else if (!isElementUpgraded_(element, optJsClass)) {\n classesToUpgrade.push(findRegisteredClass_(optJsClass));\n }\n\n // Upgrade the element for each classes.\n for (var i = 0, n = classesToUpgrade.length, registeredClass; i < n; i++) {\n registeredClass = classesToUpgrade[i];\n if (registeredClass) {\n // Mark element as upgraded.\n upgradedList.push(registeredClass.className);\n element.setAttribute('data-upgraded', upgradedList.join(','));\n var instance = new registeredClass.classConstructor(element);\n instance[componentConfigProperty_] = registeredClass;\n createdComponents_.push(instance);\n // Call any callbacks the user has registered with this component type.\n for (var j = 0, m = registeredClass.callbacks.length; j < m; j++) {\n registeredClass.callbacks[j](element);\n }\n\n if (registeredClass.widget) {\n // Assign per element instance for control over API\n element[registeredClass.className] = instance;\n }\n } else {\n throw new Error(\n 'Unable to find a registered component for the given class.');\n }\n\n var upgradedEv = createEvent_('mdl-componentupgraded', true, false);\n element.dispatchEvent(upgradedEv);\n }\n }\n\n /**\n * Upgrades a specific list of elements rather than all in the DOM.\n *\n * @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements\n * The elements we wish to upgrade.\n */\n function upgradeElementsInternal(elements) {\n if (!Array.isArray(elements)) {\n if (elements instanceof Element) {\n elements = [elements];\n } else {\n elements = Array.prototype.slice.call(elements);\n }\n }\n for (var i = 0, n = elements.length, element; i < n; i++) {\n element = elements[i];\n if (element instanceof HTMLElement) {\n upgradeElementInternal(element);\n if (element.children.length > 0) {\n upgradeElementsInternal(element.children);\n }\n }\n }\n }\n\n /**\n * Registers a class for future use and attempts to upgrade existing DOM.\n *\n * @param {componentHandler.ComponentConfigPublic} config\n */\n function registerInternal(config) {\n // In order to support both Closure-compiled and uncompiled code accessing\n // this method, we need to allow for both the dot and array syntax for\n // property access. You'll therefore see the `foo.bar || foo['bar']`\n // pattern repeated across this method.\n var widgetMissing = (typeof config.widget === 'undefined' &&\n typeof config['widget'] === 'undefined');\n var widget = true;\n\n if (!widgetMissing) {\n widget = config.widget || config['widget'];\n }\n\n var newConfig = /** @type {componentHandler.ComponentConfig} */ ({\n classConstructor: config.constructor || config['constructor'],\n className: config.classAsString || config['classAsString'],\n cssClass: config.cssClass || config['cssClass'],\n widget: widget,\n callbacks: []\n });\n\n registeredComponents_.forEach(function(item) {\n if (item.cssClass === newConfig.cssClass) {\n throw new Error('The provided cssClass has already been registered: ' + item.cssClass);\n }\n if (item.className === newConfig.className) {\n throw new Error('The provided className has already been registered');\n }\n });\n\n if (config.constructor.prototype\n .hasOwnProperty(componentConfigProperty_)) {\n throw new Error(\n 'MDL component classes must not have ' + componentConfigProperty_ +\n ' defined as a property.');\n }\n\n var found = findRegisteredClass_(config.classAsString, newConfig);\n\n if (!found) {\n registeredComponents_.push(newConfig);\n }\n }\n\n /**\n * Allows user to be alerted to any upgrades that are performed for a given\n * component type\n *\n * @param {string} jsClass The class name of the MDL component we wish\n * to hook into for any upgrades performed.\n * @param {function(!HTMLElement)} callback The function to call upon an\n * upgrade. This function should expect 1 parameter - the HTMLElement which\n * got upgraded.\n */\n function registerUpgradedCallbackInternal(jsClass, callback) {\n var regClass = findRegisteredClass_(jsClass);\n if (regClass) {\n regClass.callbacks.push(callback);\n }\n }\n\n /**\n * Upgrades all registered components found in the current DOM. This is\n * automatically called on window load.\n */\n function upgradeAllRegisteredInternal() {\n for (var n = 0; n < registeredComponents_.length; n++) {\n upgradeDomInternal(registeredComponents_[n].className);\n }\n }\n\n /**\n * Check the component for the downgrade method.\n * Execute if found.\n * Remove component from createdComponents list.\n *\n * @param {?componentHandler.Component} component\n */\n function deconstructComponentInternal(component) {\n if (component) {\n var componentIndex = createdComponents_.indexOf(component);\n createdComponents_.splice(componentIndex, 1);\n\n var upgrades = component.element_.getAttribute('data-upgraded').split(',');\n var componentPlace = upgrades.indexOf(component[componentConfigProperty_].classAsString);\n upgrades.splice(componentPlace, 1);\n component.element_.setAttribute('data-upgraded', upgrades.join(','));\n\n var ev = createEvent_('mdl-componentdowngraded', true, false);\n component.element_.dispatchEvent(ev);\n }\n }\n\n /**\n * Downgrade either a given node, an array of nodes, or a NodeList.\n *\n * @param {!Node|!Array<!Node>|!NodeList} nodes\n */\n function downgradeNodesInternal(nodes) {\n /**\n * Auxiliary function to downgrade a single node.\n * @param {!Node} node the node to be downgraded\n */\n var downgradeNode = function(node) {\n createdComponents_.filter(function(item) {\n return item.element_ === node;\n }).forEach(deconstructComponentInternal);\n };\n if (nodes instanceof Array || nodes instanceof NodeList) {\n for (var n = 0; n < nodes.length; n++) {\n downgradeNode(nodes[n]);\n }\n } else if (nodes instanceof Node) {\n downgradeNode(nodes);\n } else {\n throw new Error('Invalid argument provided to downgrade MDL nodes.');\n }\n }\n\n // Now return the functions that should be made public with their publicly\n // facing names...\n return {\n upgradeDom: upgradeDomInternal,\n upgradeElement: upgradeElementInternal,\n upgradeElements: upgradeElementsInternal,\n upgradeAllRegistered: upgradeAllRegisteredInternal,\n registerUpgradedCallback: registerUpgradedCallbackInternal,\n register: registerInternal,\n downgradeElements: downgradeNodesInternal\n };\n})();\n\n/**\n * Describes the type of a registered component type managed by\n * componentHandler. Provided for benefit of the Closure compiler.\n *\n * @typedef {{\n * constructor: Function,\n * classAsString: string,\n * cssClass: string,\n * widget: (string|boolean|undefined)\n * }}\n */\ncomponentHandler.ComponentConfigPublic; // jshint ignore:line\n\n/**\n * Describes the type of a registered component type managed by\n * componentHandler. Provided for benefit of the Closure compiler.\n *\n * @typedef {{\n * constructor: !Function,\n * className: string,\n * cssClass: string,\n * widget: (string|boolean),\n * callbacks: !Array<function(!HTMLElement)>\n * }}\n */\ncomponentHandler.ComponentConfig; // jshint ignore:line\n\n/**\n * Created component (i.e., upgraded element) type as managed by\n * componentHandler. Provided for benefit of the Closure compiler.\n *\n * @typedef {{\n * element_: !HTMLElement,\n * className: string,\n * classAsString: string,\n * cssClass: string,\n * widget: string\n * }}\n */\ncomponentHandler.Component; // jshint ignore:line\n\n// Export all symbols, for the benefit of Closure compiler.\n// No effect on uncompiled code.\ncomponentHandler['upgradeDom'] = componentHandler.upgradeDom;\ncomponentHandler['upgradeElement'] = componentHandler.upgradeElement;\ncomponentHandler['upgradeElements'] = componentHandler.upgradeElements;\ncomponentHandler['upgradeAllRegistered'] =\n componentHandler.upgradeAllRegistered;\ncomponentHandler['registerUpgradedCallback'] =\n componentHandler.registerUpgradedCallback;\ncomponentHandler['register'] = componentHandler.register;\ncomponentHandler['downgradeElements'] = componentHandler.downgradeElements;\nwindow.componentHandler = componentHandler;\nwindow['componentHandler'] = componentHandler;\n\nwindow.addEventListener('load', function() {\n 'use strict';\n\n /**\n * Performs a \"Cutting the mustard\" test. If the browser supports the features\n * tested, adds a mdl-js class to the <html> element. It then upgrades all MDL\n * components requiring JavaScript.\n */\n if ('classList' in document.createElement('div') &&\n 'querySelector' in document &&\n 'addEventListener' in window && Array.prototype.forEach) {\n document.documentElement.classList.add('mdl-js');\n componentHandler.upgradeAllRegistered();\n } else {\n /**\n * Dummy function to avoid JS errors.\n */\n componentHandler.upgradeElement = function() {};\n /**\n * Dummy function to avoid JS errors.\n */\n componentHandler.register = function() {};\n }\n});\n", + "// Source: https://github.com/darius/requestAnimationFrame/blob/master/requestAnimationFrame.js\n// Adapted from https://gist.github.com/paulirish/1579671 which derived from\n// http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating\n// requestAnimationFrame polyfill by Erik Möller.\n// Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon\n// MIT license\nif (!Date.now) {\n /**\n * Date.now polyfill.\n * @return {number} the current Date\n */\n Date.now = function () {\n return new Date().getTime();\n };\n Date['now'] = Date.now;\n}\nvar vendors = [\n 'webkit',\n 'moz'\n];\nfor (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {\n var vp = vendors[i];\n window.requestAnimationFrame = window[vp + 'RequestAnimationFrame'];\n window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame'];\n window['requestAnimationFrame'] = window.requestAnimationFrame;\n window['cancelAnimationFrame'] = window.cancelAnimationFrame;\n}\nif (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) {\n var lastTime = 0;\n /**\n * requestAnimationFrame polyfill.\n * @param {!Function} callback the callback function.\n */\n window.requestAnimationFrame = function (callback) {\n var now = Date.now();\n var nextTime = Math.max(lastTime + 16, now);\n return setTimeout(function () {\n callback(lastTime = nextTime);\n }, nextTime - now);\n };\n window.cancelAnimationFrame = clearTimeout;\n window['requestAnimationFrame'] = window.requestAnimationFrame;\n window['cancelAnimationFrame'] = window.cancelAnimationFrame;\n}", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Button MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialButton = function MaterialButton(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialButton'] = MaterialButton;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialButton.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialButton.prototype.CssClasses_ = {\n RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_CONTAINER: 'mdl-button__ripple-container',\n RIPPLE: 'mdl-ripple'\n};\n/**\n * Handle blur of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialButton.prototype.blurHandler_ = function (event) {\n if (event) {\n this.element_.blur();\n }\n};\n// Public methods.\n/**\n * Disable button.\n *\n * @public\n */\nMaterialButton.prototype.disable = function () {\n this.element_.disabled = true;\n};\nMaterialButton.prototype['disable'] = MaterialButton.prototype.disable;\n/**\n * Enable button.\n *\n * @public\n */\nMaterialButton.prototype.enable = function () {\n this.element_.disabled = false;\n};\nMaterialButton.prototype['enable'] = MaterialButton.prototype.enable;\n/**\n * Initialize element.\n */\nMaterialButton.prototype.init = function () {\n if (this.element_) {\n if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {\n var rippleContainer = document.createElement('span');\n rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);\n this.rippleElement_ = document.createElement('span');\n this.rippleElement_.classList.add(this.CssClasses_.RIPPLE);\n rippleContainer.appendChild(this.rippleElement_);\n this.boundRippleBlurHandler = this.blurHandler_.bind(this);\n this.rippleElement_.addEventListener('mouseup', this.boundRippleBlurHandler);\n this.element_.appendChild(rippleContainer);\n }\n this.boundButtonBlurHandler = this.blurHandler_.bind(this);\n this.element_.addEventListener('mouseup', this.boundButtonBlurHandler);\n this.element_.addEventListener('mouseleave', this.boundButtonBlurHandler);\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialButton,\n classAsString: 'MaterialButton',\n cssClass: 'mdl-js-button',\n widget: true\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Checkbox MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialCheckbox = function MaterialCheckbox(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialCheckbox'] = MaterialCheckbox;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialCheckbox.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialCheckbox.prototype.CssClasses_ = {\n INPUT: 'mdl-checkbox__input',\n BOX_OUTLINE: 'mdl-checkbox__box-outline',\n FOCUS_HELPER: 'mdl-checkbox__focus-helper',\n TICK_OUTLINE: 'mdl-checkbox__tick-outline',\n RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE_CONTAINER: 'mdl-checkbox__ripple-container',\n RIPPLE_CENTER: 'mdl-ripple--center',\n RIPPLE: 'mdl-ripple',\n IS_FOCUSED: 'is-focused',\n IS_DISABLED: 'is-disabled',\n IS_CHECKED: 'is-checked',\n IS_UPGRADED: 'is-upgraded'\n};\n/**\n * Handle change of state.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialCheckbox.prototype.onChange_ = function (event) {\n this.updateClasses_();\n};\n/**\n * Handle focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialCheckbox.prototype.onFocus_ = function (event) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle lost focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialCheckbox.prototype.onBlur_ = function (event) {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle mouseup.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialCheckbox.prototype.onMouseUp_ = function (event) {\n this.blur_();\n};\n/**\n * Handle class updates.\n *\n * @private\n */\nMaterialCheckbox.prototype.updateClasses_ = function () {\n this.checkDisabled();\n this.checkToggleState();\n};\n/**\n * Add blur.\n *\n * @private\n */\nMaterialCheckbox.prototype.blur_ = function () {\n // TODO: figure out why there's a focus event being fired after our blur,\n // so that we can avoid this hack.\n window.setTimeout(function () {\n this.inputElement_.blur();\n }.bind(this), this.Constant_.TINY_TIMEOUT);\n};\n// Public methods.\n/**\n * Check the inputs toggle state and update display.\n *\n * @public\n */\nMaterialCheckbox.prototype.checkToggleState = function () {\n if (this.inputElement_.checked) {\n this.element_.classList.add(this.CssClasses_.IS_CHECKED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_CHECKED);\n }\n};\nMaterialCheckbox.prototype['checkToggleState'] = MaterialCheckbox.prototype.checkToggleState;\n/**\n * Check the inputs disabled state and update display.\n *\n * @public\n */\nMaterialCheckbox.prototype.checkDisabled = function () {\n if (this.inputElement_.disabled) {\n this.element_.classList.add(this.CssClasses_.IS_DISABLED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DISABLED);\n }\n};\nMaterialCheckbox.prototype['checkDisabled'] = MaterialCheckbox.prototype.checkDisabled;\n/**\n * Disable checkbox.\n *\n * @public\n */\nMaterialCheckbox.prototype.disable = function () {\n this.inputElement_.disabled = true;\n this.updateClasses_();\n};\nMaterialCheckbox.prototype['disable'] = MaterialCheckbox.prototype.disable;\n/**\n * Enable checkbox.\n *\n * @public\n */\nMaterialCheckbox.prototype.enable = function () {\n this.inputElement_.disabled = false;\n this.updateClasses_();\n};\nMaterialCheckbox.prototype['enable'] = MaterialCheckbox.prototype.enable;\n/**\n * Check checkbox.\n *\n * @public\n */\nMaterialCheckbox.prototype.check = function () {\n this.inputElement_.checked = true;\n this.updateClasses_();\n};\nMaterialCheckbox.prototype['check'] = MaterialCheckbox.prototype.check;\n/**\n * Uncheck checkbox.\n *\n * @public\n */\nMaterialCheckbox.prototype.uncheck = function () {\n this.inputElement_.checked = false;\n this.updateClasses_();\n};\nMaterialCheckbox.prototype['uncheck'] = MaterialCheckbox.prototype.uncheck;\n/**\n * Initialize element.\n */\nMaterialCheckbox.prototype.init = function () {\n if (this.element_) {\n this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);\n var boxOutline = document.createElement('span');\n boxOutline.classList.add(this.CssClasses_.BOX_OUTLINE);\n var tickContainer = document.createElement('span');\n tickContainer.classList.add(this.CssClasses_.FOCUS_HELPER);\n var tickOutline = document.createElement('span');\n tickOutline.classList.add(this.CssClasses_.TICK_OUTLINE);\n boxOutline.appendChild(tickOutline);\n this.element_.appendChild(tickContainer);\n this.element_.appendChild(boxOutline);\n if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n this.rippleContainerElement_ = document.createElement('span');\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);\n this.boundRippleMouseUp = this.onMouseUp_.bind(this);\n this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);\n var ripple = document.createElement('span');\n ripple.classList.add(this.CssClasses_.RIPPLE);\n this.rippleContainerElement_.appendChild(ripple);\n this.element_.appendChild(this.rippleContainerElement_);\n }\n this.boundInputOnChange = this.onChange_.bind(this);\n this.boundInputOnFocus = this.onFocus_.bind(this);\n this.boundInputOnBlur = this.onBlur_.bind(this);\n this.boundElementMouseUp = this.onMouseUp_.bind(this);\n this.inputElement_.addEventListener('change', this.boundInputOnChange);\n this.inputElement_.addEventListener('focus', this.boundInputOnFocus);\n this.inputElement_.addEventListener('blur', this.boundInputOnBlur);\n this.element_.addEventListener('mouseup', this.boundElementMouseUp);\n this.updateClasses_();\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialCheckbox,\n classAsString: 'MaterialCheckbox',\n cssClass: 'mdl-js-checkbox',\n widget: true\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for icon toggle MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialIconToggle = function MaterialIconToggle(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialIconToggle'] = MaterialIconToggle;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialIconToggle.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialIconToggle.prototype.CssClasses_ = {\n INPUT: 'mdl-icon-toggle__input',\n JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE_CONTAINER: 'mdl-icon-toggle__ripple-container',\n RIPPLE_CENTER: 'mdl-ripple--center',\n RIPPLE: 'mdl-ripple',\n IS_FOCUSED: 'is-focused',\n IS_DISABLED: 'is-disabled',\n IS_CHECKED: 'is-checked'\n};\n/**\n * Handle change of state.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialIconToggle.prototype.onChange_ = function (event) {\n this.updateClasses_();\n};\n/**\n * Handle focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialIconToggle.prototype.onFocus_ = function (event) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle lost focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialIconToggle.prototype.onBlur_ = function (event) {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle mouseup.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialIconToggle.prototype.onMouseUp_ = function (event) {\n this.blur_();\n};\n/**\n * Handle class updates.\n *\n * @private\n */\nMaterialIconToggle.prototype.updateClasses_ = function () {\n this.checkDisabled();\n this.checkToggleState();\n};\n/**\n * Add blur.\n *\n * @private\n */\nMaterialIconToggle.prototype.blur_ = function () {\n // TODO: figure out why there's a focus event being fired after our blur,\n // so that we can avoid this hack.\n window.setTimeout(function () {\n this.inputElement_.blur();\n }.bind(this), this.Constant_.TINY_TIMEOUT);\n};\n// Public methods.\n/**\n * Check the inputs toggle state and update display.\n *\n * @public\n */\nMaterialIconToggle.prototype.checkToggleState = function () {\n if (this.inputElement_.checked) {\n this.element_.classList.add(this.CssClasses_.IS_CHECKED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_CHECKED);\n }\n};\nMaterialIconToggle.prototype['checkToggleState'] = MaterialIconToggle.prototype.checkToggleState;\n/**\n * Check the inputs disabled state and update display.\n *\n * @public\n */\nMaterialIconToggle.prototype.checkDisabled = function () {\n if (this.inputElement_.disabled) {\n this.element_.classList.add(this.CssClasses_.IS_DISABLED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DISABLED);\n }\n};\nMaterialIconToggle.prototype['checkDisabled'] = MaterialIconToggle.prototype.checkDisabled;\n/**\n * Disable icon toggle.\n *\n * @public\n */\nMaterialIconToggle.prototype.disable = function () {\n this.inputElement_.disabled = true;\n this.updateClasses_();\n};\nMaterialIconToggle.prototype['disable'] = MaterialIconToggle.prototype.disable;\n/**\n * Enable icon toggle.\n *\n * @public\n */\nMaterialIconToggle.prototype.enable = function () {\n this.inputElement_.disabled = false;\n this.updateClasses_();\n};\nMaterialIconToggle.prototype['enable'] = MaterialIconToggle.prototype.enable;\n/**\n * Check icon toggle.\n *\n * @public\n */\nMaterialIconToggle.prototype.check = function () {\n this.inputElement_.checked = true;\n this.updateClasses_();\n};\nMaterialIconToggle.prototype['check'] = MaterialIconToggle.prototype.check;\n/**\n * Uncheck icon toggle.\n *\n * @public\n */\nMaterialIconToggle.prototype.uncheck = function () {\n this.inputElement_.checked = false;\n this.updateClasses_();\n};\nMaterialIconToggle.prototype['uncheck'] = MaterialIconToggle.prototype.uncheck;\n/**\n * Initialize element.\n */\nMaterialIconToggle.prototype.init = function () {\n if (this.element_) {\n this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);\n if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n this.rippleContainerElement_ = document.createElement('span');\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);\n this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT);\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);\n this.boundRippleMouseUp = this.onMouseUp_.bind(this);\n this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);\n var ripple = document.createElement('span');\n ripple.classList.add(this.CssClasses_.RIPPLE);\n this.rippleContainerElement_.appendChild(ripple);\n this.element_.appendChild(this.rippleContainerElement_);\n }\n this.boundInputOnChange = this.onChange_.bind(this);\n this.boundInputOnFocus = this.onFocus_.bind(this);\n this.boundInputOnBlur = this.onBlur_.bind(this);\n this.boundElementOnMouseUp = this.onMouseUp_.bind(this);\n this.inputElement_.addEventListener('change', this.boundInputOnChange);\n this.inputElement_.addEventListener('focus', this.boundInputOnFocus);\n this.inputElement_.addEventListener('blur', this.boundInputOnBlur);\n this.element_.addEventListener('mouseup', this.boundElementOnMouseUp);\n this.updateClasses_();\n this.element_.classList.add('is-upgraded');\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialIconToggle,\n classAsString: 'MaterialIconToggle',\n cssClass: 'mdl-js-icon-toggle',\n widget: true\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for dropdown MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialMenu = function MaterialMenu(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialMenu'] = MaterialMenu;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialMenu.prototype.Constant_ = {\n // Total duration of the menu animation.\n TRANSITION_DURATION_SECONDS: 0.3,\n // The fraction of the total duration we want to use for menu item animations.\n TRANSITION_DURATION_FRACTION: 0.8,\n // How long the menu stays open after choosing an option (so the user can see\n // the ripple).\n CLOSE_TIMEOUT: 150\n};\n/**\n * Keycodes, for code readability.\n *\n * @enum {number}\n * @private\n */\nMaterialMenu.prototype.Keycodes_ = {\n ENTER: 13,\n ESCAPE: 27,\n SPACE: 32,\n UP_ARROW: 38,\n DOWN_ARROW: 40\n};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialMenu.prototype.CssClasses_ = {\n CONTAINER: 'mdl-menu__container',\n OUTLINE: 'mdl-menu__outline',\n ITEM: 'mdl-menu__item',\n ITEM_RIPPLE_CONTAINER: 'mdl-menu__item-ripple-container',\n RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE: 'mdl-ripple',\n // Statuses\n IS_UPGRADED: 'is-upgraded',\n IS_VISIBLE: 'is-visible',\n IS_ANIMATING: 'is-animating',\n // Alignment options\n BOTTOM_LEFT: 'mdl-menu--bottom-left',\n // This is the default.\n BOTTOM_RIGHT: 'mdl-menu--bottom-right',\n TOP_LEFT: 'mdl-menu--top-left',\n TOP_RIGHT: 'mdl-menu--top-right',\n UNALIGNED: 'mdl-menu--unaligned'\n};\n/**\n * Initialize element.\n */\nMaterialMenu.prototype.init = function () {\n if (this.element_) {\n // Create container for the menu.\n var container = document.createElement('div');\n container.classList.add(this.CssClasses_.CONTAINER);\n this.element_.parentElement.insertBefore(container, this.element_);\n this.element_.parentElement.removeChild(this.element_);\n container.appendChild(this.element_);\n this.container_ = container;\n // Create outline for the menu (shadow and background).\n var outline = document.createElement('div');\n outline.classList.add(this.CssClasses_.OUTLINE);\n this.outline_ = outline;\n container.insertBefore(outline, this.element_);\n // Find the \"for\" element and bind events to it.\n var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for');\n var forEl = null;\n if (forElId) {\n forEl = document.getElementById(forElId);\n if (forEl) {\n this.forElement_ = forEl;\n forEl.addEventListener('click', this.handleForClick_.bind(this));\n forEl.addEventListener('keydown', this.handleForKeyboardEvent_.bind(this));\n }\n }\n var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);\n this.boundItemKeydown_ = this.handleItemKeyboardEvent_.bind(this);\n this.boundItemClick_ = this.handleItemClick_.bind(this);\n for (var i = 0; i < items.length; i++) {\n // Add a listener to each menu item.\n items[i].addEventListener('click', this.boundItemClick_);\n // Add a tab index to each menu item.\n items[i].tabIndex = '-1';\n // Add a keyboard listener to each menu item.\n items[i].addEventListener('keydown', this.boundItemKeydown_);\n }\n // Add ripple classes to each item, if the user has enabled ripples.\n if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n for (i = 0; i < items.length; i++) {\n var item = items[i];\n var rippleContainer = document.createElement('span');\n rippleContainer.classList.add(this.CssClasses_.ITEM_RIPPLE_CONTAINER);\n var ripple = document.createElement('span');\n ripple.classList.add(this.CssClasses_.RIPPLE);\n rippleContainer.appendChild(ripple);\n item.appendChild(rippleContainer);\n item.classList.add(this.CssClasses_.RIPPLE_EFFECT);\n }\n }\n // Copy alignment classes to the container, so the outline can use them.\n if (this.element_.classList.contains(this.CssClasses_.BOTTOM_LEFT)) {\n this.outline_.classList.add(this.CssClasses_.BOTTOM_LEFT);\n }\n if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {\n this.outline_.classList.add(this.CssClasses_.BOTTOM_RIGHT);\n }\n if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {\n this.outline_.classList.add(this.CssClasses_.TOP_LEFT);\n }\n if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {\n this.outline_.classList.add(this.CssClasses_.TOP_RIGHT);\n }\n if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {\n this.outline_.classList.add(this.CssClasses_.UNALIGNED);\n }\n container.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n};\n/**\n * Handles a click on the \"for\" element, by positioning the menu and then\n * toggling it.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialMenu.prototype.handleForClick_ = function (evt) {\n if (this.element_ && this.forElement_) {\n var rect = this.forElement_.getBoundingClientRect();\n var forRect = this.forElement_.parentElement.getBoundingClientRect();\n if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {\n } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {\n // Position below the \"for\" element, aligned to its right.\n this.container_.style.right = forRect.right - rect.right + 'px';\n this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px';\n } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {\n // Position above the \"for\" element, aligned to its left.\n this.container_.style.left = this.forElement_.offsetLeft + 'px';\n this.container_.style.bottom = forRect.bottom - rect.top + 'px';\n } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {\n // Position above the \"for\" element, aligned to its right.\n this.container_.style.right = forRect.right - rect.right + 'px';\n this.container_.style.bottom = forRect.bottom - rect.top + 'px';\n } else {\n // Default: position below the \"for\" element, aligned to its left.\n this.container_.style.left = this.forElement_.offsetLeft + 'px';\n this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px';\n }\n }\n this.toggle(evt);\n};\n/**\n * Handles a keyboard event on the \"for\" element.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialMenu.prototype.handleForKeyboardEvent_ = function (evt) {\n if (this.element_ && this.container_ && this.forElement_) {\n var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])');\n if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {\n if (evt.keyCode === this.Keycodes_.UP_ARROW) {\n evt.preventDefault();\n items[items.length - 1].focus();\n } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) {\n evt.preventDefault();\n items[0].focus();\n }\n }\n }\n};\n/**\n * Handles a keyboard event on an item.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialMenu.prototype.handleItemKeyboardEvent_ = function (evt) {\n if (this.element_ && this.container_) {\n var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])');\n if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {\n var currentIndex = Array.prototype.slice.call(items).indexOf(evt.target);\n if (evt.keyCode === this.Keycodes_.UP_ARROW) {\n evt.preventDefault();\n if (currentIndex > 0) {\n items[currentIndex - 1].focus();\n } else {\n items[items.length - 1].focus();\n }\n } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) {\n evt.preventDefault();\n if (items.length > currentIndex + 1) {\n items[currentIndex + 1].focus();\n } else {\n items[0].focus();\n }\n } else if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) {\n evt.preventDefault();\n // Send mousedown and mouseup to trigger ripple.\n var e = new MouseEvent('mousedown');\n evt.target.dispatchEvent(e);\n e = new MouseEvent('mouseup');\n evt.target.dispatchEvent(e);\n // Send click.\n evt.target.click();\n } else if (evt.keyCode === this.Keycodes_.ESCAPE) {\n evt.preventDefault();\n this.hide();\n }\n }\n }\n};\n/**\n * Handles a click event on an item.\n *\n * @param {Event} evt The event that fired.\n * @private\n */\nMaterialMenu.prototype.handleItemClick_ = function (evt) {\n if (evt.target.hasAttribute('disabled')) {\n evt.stopPropagation();\n } else {\n // Wait some time before closing menu, so the user can see the ripple.\n this.closing_ = true;\n window.setTimeout(function (evt) {\n this.hide();\n this.closing_ = false;\n }.bind(this), this.Constant_.CLOSE_TIMEOUT);\n }\n};\n/**\n * Calculates the initial clip (for opening the menu) or final clip (for closing\n * it), and applies it. This allows us to animate from or to the correct point,\n * that is, the point it's aligned to in the \"for\" element.\n *\n * @param {number} height Height of the clip rectangle\n * @param {number} width Width of the clip rectangle\n * @private\n */\nMaterialMenu.prototype.applyClip_ = function (height, width) {\n if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {\n // Do not clip.\n this.element_.style.clip = '';\n } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {\n // Clip to the top right corner of the menu.\n this.element_.style.clip = 'rect(0 ' + width + 'px ' + '0 ' + width + 'px)';\n } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {\n // Clip to the bottom left corner of the menu.\n this.element_.style.clip = 'rect(' + height + 'px 0 ' + height + 'px 0)';\n } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {\n // Clip to the bottom right corner of the menu.\n this.element_.style.clip = 'rect(' + height + 'px ' + width + 'px ' + height + 'px ' + width + 'px)';\n } else {\n // Default: do not clip (same as clipping to the top left corner).\n this.element_.style.clip = '';\n }\n};\n/**\n * Cleanup function to remove animation listeners.\n *\n * @param {Event} evt\n * @private\n */\nMaterialMenu.prototype.removeAnimationEndListener_ = function (evt) {\n evt.target.classList.remove(MaterialMenu.prototype.CssClasses_.IS_ANIMATING);\n};\n/**\n * Adds an event listener to clean up after the animation ends.\n *\n * @private\n */\nMaterialMenu.prototype.addAnimationEndListener_ = function () {\n this.element_.addEventListener('transitionend', this.removeAnimationEndListener_);\n this.element_.addEventListener('webkitTransitionEnd', this.removeAnimationEndListener_);\n};\n/**\n * Displays the menu.\n *\n * @public\n */\nMaterialMenu.prototype.show = function (evt) {\n if (this.element_ && this.container_ && this.outline_) {\n // Measure the inner element.\n var height = this.element_.getBoundingClientRect().height;\n var width = this.element_.getBoundingClientRect().width;\n // Apply the inner element's size to the container and outline.\n this.container_.style.width = width + 'px';\n this.container_.style.height = height + 'px';\n this.outline_.style.width = width + 'px';\n this.outline_.style.height = height + 'px';\n var transitionDuration = this.Constant_.TRANSITION_DURATION_SECONDS * this.Constant_.TRANSITION_DURATION_FRACTION;\n // Calculate transition delays for individual menu items, so that they fade\n // in one at a time.\n var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);\n for (var i = 0; i < items.length; i++) {\n var itemDelay = null;\n if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT) || this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {\n itemDelay = (height - items[i].offsetTop - items[i].offsetHeight) / height * transitionDuration + 's';\n } else {\n itemDelay = items[i].offsetTop / height * transitionDuration + 's';\n }\n items[i].style.transitionDelay = itemDelay;\n }\n // Apply the initial clip to the text before we start animating.\n this.applyClip_(height, width);\n // Wait for the next frame, turn on animation, and apply the final clip.\n // Also make it visible. This triggers the transitions.\n window.requestAnimationFrame(function () {\n this.element_.classList.add(this.CssClasses_.IS_ANIMATING);\n this.element_.style.clip = 'rect(0 ' + width + 'px ' + height + 'px 0)';\n this.container_.classList.add(this.CssClasses_.IS_VISIBLE);\n }.bind(this));\n // Clean up after the animation is complete.\n this.addAnimationEndListener_();\n // Add a click listener to the document, to close the menu.\n var callback = function (e) {\n // Check to see if the document is processing the same event that\n // displayed the menu in the first place. If so, do nothing.\n // Also check to see if the menu is in the process of closing itself, and\n // do nothing in that case.\n // Also check if the clicked element is a menu item\n // if so, do nothing.\n if (e !== evt && !this.closing_ && e.target.parentNode !== this.element_) {\n document.removeEventListener('click', callback);\n this.hide();\n }\n }.bind(this);\n document.addEventListener('click', callback);\n }\n};\nMaterialMenu.prototype['show'] = MaterialMenu.prototype.show;\n/**\n * Hides the menu.\n *\n * @public\n */\nMaterialMenu.prototype.hide = function () {\n if (this.element_ && this.container_ && this.outline_) {\n var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);\n // Remove all transition delays; menu items fade out concurrently.\n for (var i = 0; i < items.length; i++) {\n items[i].style.removeProperty('transition-delay');\n }\n // Measure the inner element.\n var rect = this.element_.getBoundingClientRect();\n var height = rect.height;\n var width = rect.width;\n // Turn on animation, and apply the final clip. Also make invisible.\n // This triggers the transitions.\n this.element_.classList.add(this.CssClasses_.IS_ANIMATING);\n this.applyClip_(height, width);\n this.container_.classList.remove(this.CssClasses_.IS_VISIBLE);\n // Clean up after the animation is complete.\n this.addAnimationEndListener_();\n }\n};\nMaterialMenu.prototype['hide'] = MaterialMenu.prototype.hide;\n/**\n * Displays or hides the menu, depending on current state.\n *\n * @public\n */\nMaterialMenu.prototype.toggle = function (evt) {\n if (this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {\n this.hide();\n } else {\n this.show(evt);\n }\n};\nMaterialMenu.prototype['toggle'] = MaterialMenu.prototype.toggle;\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialMenu,\n classAsString: 'MaterialMenu',\n cssClass: 'mdl-js-menu',\n widget: true\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Progress MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialProgress = function MaterialProgress(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialProgress'] = MaterialProgress;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialProgress.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialProgress.prototype.CssClasses_ = { INDETERMINATE_CLASS: 'mdl-progress__indeterminate' };\n/**\n * Set the current progress of the progressbar.\n *\n * @param {number} p Percentage of the progress (0-100)\n * @public\n */\nMaterialProgress.prototype.setProgress = function (p) {\n if (this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)) {\n return;\n }\n this.progressbar_.style.width = p + '%';\n};\nMaterialProgress.prototype['setProgress'] = MaterialProgress.prototype.setProgress;\n/**\n * Set the current progress of the buffer.\n *\n * @param {number} p Percentage of the buffer (0-100)\n * @public\n */\nMaterialProgress.prototype.setBuffer = function (p) {\n this.bufferbar_.style.width = p + '%';\n this.auxbar_.style.width = 100 - p + '%';\n};\nMaterialProgress.prototype['setBuffer'] = MaterialProgress.prototype.setBuffer;\n/**\n * Initialize element.\n */\nMaterialProgress.prototype.init = function () {\n if (this.element_) {\n var el = document.createElement('div');\n el.className = 'progressbar bar bar1';\n this.element_.appendChild(el);\n this.progressbar_ = el;\n el = document.createElement('div');\n el.className = 'bufferbar bar bar2';\n this.element_.appendChild(el);\n this.bufferbar_ = el;\n el = document.createElement('div');\n el.className = 'auxbar bar bar3';\n this.element_.appendChild(el);\n this.auxbar_ = el;\n this.progressbar_.style.width = '0%';\n this.bufferbar_.style.width = '100%';\n this.auxbar_.style.width = '0%';\n this.element_.classList.add('is-upgraded');\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialProgress,\n classAsString: 'MaterialProgress',\n cssClass: 'mdl-js-progress',\n widget: true\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Radio MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialRadio = function MaterialRadio(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialRadio'] = MaterialRadio;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialRadio.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialRadio.prototype.CssClasses_ = {\n IS_FOCUSED: 'is-focused',\n IS_DISABLED: 'is-disabled',\n IS_CHECKED: 'is-checked',\n IS_UPGRADED: 'is-upgraded',\n JS_RADIO: 'mdl-js-radio',\n RADIO_BTN: 'mdl-radio__button',\n RADIO_OUTER_CIRCLE: 'mdl-radio__outer-circle',\n RADIO_INNER_CIRCLE: 'mdl-radio__inner-circle',\n RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE_CONTAINER: 'mdl-radio__ripple-container',\n RIPPLE_CENTER: 'mdl-ripple--center',\n RIPPLE: 'mdl-ripple'\n};\n/**\n * Handle change of state.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRadio.prototype.onChange_ = function (event) {\n // Since other radio buttons don't get change events, we need to look for\n // them to update their classes.\n var radios = document.getElementsByClassName(this.CssClasses_.JS_RADIO);\n for (var i = 0; i < radios.length; i++) {\n var button = radios[i].querySelector('.' + this.CssClasses_.RADIO_BTN);\n // Different name == different group, so no point updating those.\n if (button.getAttribute('name') === this.btnElement_.getAttribute('name')) {\n if (typeof radios[i]['MaterialRadio'] !== 'undefined') {\n radios[i]['MaterialRadio'].updateClasses_();\n }\n }\n }\n};\n/**\n * Handle focus.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRadio.prototype.onFocus_ = function (event) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle lost focus.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRadio.prototype.onBlur_ = function (event) {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle mouseup.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRadio.prototype.onMouseup_ = function (event) {\n this.blur_();\n};\n/**\n * Update classes.\n *\n * @private\n */\nMaterialRadio.prototype.updateClasses_ = function () {\n this.checkDisabled();\n this.checkToggleState();\n};\n/**\n * Add blur.\n *\n * @private\n */\nMaterialRadio.prototype.blur_ = function () {\n // TODO: figure out why there's a focus event being fired after our blur,\n // so that we can avoid this hack.\n window.setTimeout(function () {\n this.btnElement_.blur();\n }.bind(this), this.Constant_.TINY_TIMEOUT);\n};\n// Public methods.\n/**\n * Check the components disabled state.\n *\n * @public\n */\nMaterialRadio.prototype.checkDisabled = function () {\n if (this.btnElement_.disabled) {\n this.element_.classList.add(this.CssClasses_.IS_DISABLED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DISABLED);\n }\n};\nMaterialRadio.prototype['checkDisabled'] = MaterialRadio.prototype.checkDisabled;\n/**\n * Check the components toggled state.\n *\n * @public\n */\nMaterialRadio.prototype.checkToggleState = function () {\n if (this.btnElement_.checked) {\n this.element_.classList.add(this.CssClasses_.IS_CHECKED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_CHECKED);\n }\n};\nMaterialRadio.prototype['checkToggleState'] = MaterialRadio.prototype.checkToggleState;\n/**\n * Disable radio.\n *\n * @public\n */\nMaterialRadio.prototype.disable = function () {\n this.btnElement_.disabled = true;\n this.updateClasses_();\n};\nMaterialRadio.prototype['disable'] = MaterialRadio.prototype.disable;\n/**\n * Enable radio.\n *\n * @public\n */\nMaterialRadio.prototype.enable = function () {\n this.btnElement_.disabled = false;\n this.updateClasses_();\n};\nMaterialRadio.prototype['enable'] = MaterialRadio.prototype.enable;\n/**\n * Check radio.\n *\n * @public\n */\nMaterialRadio.prototype.check = function () {\n this.btnElement_.checked = true;\n this.onChange_(null);\n};\nMaterialRadio.prototype['check'] = MaterialRadio.prototype.check;\n/**\n * Uncheck radio.\n *\n * @public\n */\nMaterialRadio.prototype.uncheck = function () {\n this.btnElement_.checked = false;\n this.onChange_(null);\n};\nMaterialRadio.prototype['uncheck'] = MaterialRadio.prototype.uncheck;\n/**\n * Initialize element.\n */\nMaterialRadio.prototype.init = function () {\n if (this.element_) {\n this.btnElement_ = this.element_.querySelector('.' + this.CssClasses_.RADIO_BTN);\n this.boundChangeHandler_ = this.onChange_.bind(this);\n this.boundFocusHandler_ = this.onChange_.bind(this);\n this.boundBlurHandler_ = this.onBlur_.bind(this);\n this.boundMouseUpHandler_ = this.onMouseup_.bind(this);\n var outerCircle = document.createElement('span');\n outerCircle.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE);\n var innerCircle = document.createElement('span');\n innerCircle.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE);\n this.element_.appendChild(outerCircle);\n this.element_.appendChild(innerCircle);\n var rippleContainer;\n if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n rippleContainer = document.createElement('span');\n rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);\n rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT);\n rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER);\n rippleContainer.addEventListener('mouseup', this.boundMouseUpHandler_);\n var ripple = document.createElement('span');\n ripple.classList.add(this.CssClasses_.RIPPLE);\n rippleContainer.appendChild(ripple);\n this.element_.appendChild(rippleContainer);\n }\n this.btnElement_.addEventListener('change', this.boundChangeHandler_);\n this.btnElement_.addEventListener('focus', this.boundFocusHandler_);\n this.btnElement_.addEventListener('blur', this.boundBlurHandler_);\n this.element_.addEventListener('mouseup', this.boundMouseUpHandler_);\n this.updateClasses_();\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialRadio,\n classAsString: 'MaterialRadio',\n cssClass: 'mdl-js-radio',\n widget: true\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Slider MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialSlider = function MaterialSlider(element) {\n this.element_ = element;\n // Browser feature detection.\n this.isIE_ = window.navigator.msPointerEnabled;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialSlider'] = MaterialSlider;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialSlider.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialSlider.prototype.CssClasses_ = {\n IE_CONTAINER: 'mdl-slider__ie-container',\n SLIDER_CONTAINER: 'mdl-slider__container',\n BACKGROUND_FLEX: 'mdl-slider__background-flex',\n BACKGROUND_LOWER: 'mdl-slider__background-lower',\n BACKGROUND_UPPER: 'mdl-slider__background-upper',\n IS_LOWEST_VALUE: 'is-lowest-value',\n IS_UPGRADED: 'is-upgraded'\n};\n/**\n * Handle input on element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSlider.prototype.onInput_ = function (event) {\n this.updateValueStyles_();\n};\n/**\n * Handle change on element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSlider.prototype.onChange_ = function (event) {\n this.updateValueStyles_();\n};\n/**\n * Handle mouseup on element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSlider.prototype.onMouseUp_ = function (event) {\n event.target.blur();\n};\n/**\n * Handle mousedown on container element.\n * This handler is purpose is to not require the use to click\n * exactly on the 2px slider element, as FireFox seems to be very\n * strict about this.\n *\n * @param {Event} event The event that fired.\n * @private\n * @suppress {missingProperties}\n */\nMaterialSlider.prototype.onContainerMouseDown_ = function (event) {\n // If this click is not on the parent element (but rather some child)\n // ignore. It may still bubble up.\n if (event.target !== this.element_.parentElement) {\n return;\n }\n // Discard the original event and create a new event that\n // is on the slider element.\n event.preventDefault();\n var newEvent = new MouseEvent('mousedown', {\n target: event.target,\n buttons: event.buttons,\n clientX: event.clientX,\n clientY: this.element_.getBoundingClientRect().y\n });\n this.element_.dispatchEvent(newEvent);\n};\n/**\n * Handle updating of values.\n *\n * @private\n */\nMaterialSlider.prototype.updateValueStyles_ = function () {\n // Calculate and apply percentages to div structure behind slider.\n var fraction = (this.element_.value - this.element_.min) / (this.element_.max - this.element_.min);\n if (fraction === 0) {\n this.element_.classList.add(this.CssClasses_.IS_LOWEST_VALUE);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE);\n }\n if (!this.isIE_) {\n this.backgroundLower_.style.flex = fraction;\n this.backgroundLower_.style.webkitFlex = fraction;\n this.backgroundUpper_.style.flex = 1 - fraction;\n this.backgroundUpper_.style.webkitFlex = 1 - fraction;\n }\n};\n// Public methods.\n/**\n * Disable slider.\n *\n * @public\n */\nMaterialSlider.prototype.disable = function () {\n this.element_.disabled = true;\n};\nMaterialSlider.prototype['disable'] = MaterialSlider.prototype.disable;\n/**\n * Enable slider.\n *\n * @public\n */\nMaterialSlider.prototype.enable = function () {\n this.element_.disabled = false;\n};\nMaterialSlider.prototype['enable'] = MaterialSlider.prototype.enable;\n/**\n * Update slider value.\n *\n * @param {number} value The value to which to set the control (optional).\n * @public\n */\nMaterialSlider.prototype.change = function (value) {\n if (typeof value !== 'undefined') {\n this.element_.value = value;\n }\n this.updateValueStyles_();\n};\nMaterialSlider.prototype['change'] = MaterialSlider.prototype.change;\n/**\n * Initialize element.\n */\nMaterialSlider.prototype.init = function () {\n if (this.element_) {\n if (this.isIE_) {\n // Since we need to specify a very large height in IE due to\n // implementation limitations, we add a parent here that trims it down to\n // a reasonable size.\n var containerIE = document.createElement('div');\n containerIE.classList.add(this.CssClasses_.IE_CONTAINER);\n this.element_.parentElement.insertBefore(containerIE, this.element_);\n this.element_.parentElement.removeChild(this.element_);\n containerIE.appendChild(this.element_);\n } else {\n // For non-IE browsers, we need a div structure that sits behind the\n // slider and allows us to style the left and right sides of it with\n // different colors.\n var container = document.createElement('div');\n container.classList.add(this.CssClasses_.SLIDER_CONTAINER);\n this.element_.parentElement.insertBefore(container, this.element_);\n this.element_.parentElement.removeChild(this.element_);\n container.appendChild(this.element_);\n var backgroundFlex = document.createElement('div');\n backgroundFlex.classList.add(this.CssClasses_.BACKGROUND_FLEX);\n container.appendChild(backgroundFlex);\n this.backgroundLower_ = document.createElement('div');\n this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER);\n backgroundFlex.appendChild(this.backgroundLower_);\n this.backgroundUpper_ = document.createElement('div');\n this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER);\n backgroundFlex.appendChild(this.backgroundUpper_);\n }\n this.boundInputHandler = this.onInput_.bind(this);\n this.boundChangeHandler = this.onChange_.bind(this);\n this.boundMouseUpHandler = this.onMouseUp_.bind(this);\n this.boundContainerMouseDownHandler = this.onContainerMouseDown_.bind(this);\n this.element_.addEventListener('input', this.boundInputHandler);\n this.element_.addEventListener('change', this.boundChangeHandler);\n this.element_.addEventListener('mouseup', this.boundMouseUpHandler);\n this.element_.parentElement.addEventListener('mousedown', this.boundContainerMouseDownHandler);\n this.updateValueStyles_();\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialSlider,\n classAsString: 'MaterialSlider',\n cssClass: 'mdl-js-slider',\n widget: true\n});", + "/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Snackbar MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialSnackbar = function MaterialSnackbar(element) {\n this.element_ = element;\n this.textElement_ = this.element_.querySelector('.' + this.cssClasses_.MESSAGE);\n this.actionElement_ = this.element_.querySelector('.' + this.cssClasses_.ACTION);\n if (!this.textElement_) {\n throw new Error('There must be a message element for a snackbar.');\n }\n if (!this.actionElement_) {\n throw new Error('There must be an action element for a snackbar.');\n }\n this.active = false;\n this.actionHandler_ = undefined;\n this.message_ = undefined;\n this.actionText_ = undefined;\n this.queuedNotifications_ = [];\n this.setActionHidden_(true);\n};\nwindow['MaterialSnackbar'] = MaterialSnackbar;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialSnackbar.prototype.Constant_ = {\n // The duration of the snackbar show/hide animation, in ms.\n ANIMATION_LENGTH: 250\n};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialSnackbar.prototype.cssClasses_ = {\n SNACKBAR: 'mdl-snackbar',\n MESSAGE: 'mdl-snackbar__text',\n ACTION: 'mdl-snackbar__action',\n ACTIVE: 'mdl-snackbar--active'\n};\n/**\n * Display the snackbar.\n *\n * @private\n */\nMaterialSnackbar.prototype.displaySnackbar_ = function () {\n this.element_.setAttribute('aria-hidden', 'true');\n if (this.actionHandler_) {\n this.actionElement_.textContent = this.actionText_;\n this.actionElement_.addEventListener('click', this.actionHandler_);\n this.setActionHidden_(false);\n }\n this.textElement_.textContent = this.message_;\n this.element_.classList.add(this.cssClasses_.ACTIVE);\n this.element_.setAttribute('aria-hidden', 'false');\n setTimeout(this.cleanup_.bind(this), this.timeout_);\n};\n/**\n * Show the snackbar.\n *\n * @param {Object} data The data for the notification.\n * @public\n */\nMaterialSnackbar.prototype.showSnackbar = function (data) {\n if (data === undefined) {\n throw new Error('Please provide a data object with at least a message to display.');\n }\n if (data['message'] === undefined) {\n throw new Error('Please provide a message to be displayed.');\n }\n if (data['actionHandler'] && !data['actionText']) {\n throw new Error('Please provide action text with the handler.');\n }\n if (this.active) {\n this.queuedNotifications_.push(data);\n } else {\n this.active = true;\n this.message_ = data['message'];\n if (data['timeout']) {\n this.timeout_ = data['timeout'];\n } else {\n this.timeout_ = 2750;\n }\n if (data['actionHandler']) {\n this.actionHandler_ = data['actionHandler'];\n }\n if (data['actionText']) {\n this.actionText_ = data['actionText'];\n }\n this.displaySnackbar_();\n }\n};\nMaterialSnackbar.prototype['showSnackbar'] = MaterialSnackbar.prototype.showSnackbar;\n/**\n * Check if the queue has items within it.\n * If it does, display the next entry.\n *\n * @private\n */\nMaterialSnackbar.prototype.checkQueue_ = function () {\n if (this.queuedNotifications_.length > 0) {\n this.showSnackbar(this.queuedNotifications_.shift());\n }\n};\n/**\n * Cleanup the snackbar event listeners and accessiblity attributes.\n *\n * @private\n */\nMaterialSnackbar.prototype.cleanup_ = function () {\n this.element_.classList.remove(this.cssClasses_.ACTIVE);\n setTimeout(function () {\n this.element_.setAttribute('aria-hidden', 'true');\n this.textElement_.textContent = '';\n if (!Boolean(this.actionElement_.getAttribute('aria-hidden'))) {\n this.setActionHidden_(true);\n this.actionElement_.textContent = '';\n this.actionElement_.removeEventListener('click', this.actionHandler_);\n }\n this.actionHandler_ = undefined;\n this.message_ = undefined;\n this.actionText_ = undefined;\n this.active = false;\n this.checkQueue_();\n }.bind(this), this.Constant_.ANIMATION_LENGTH);\n};\n/**\n * Set the action handler hidden state.\n *\n * @param {boolean} value\n * @private\n */\nMaterialSnackbar.prototype.setActionHidden_ = function (value) {\n if (value) {\n this.actionElement_.setAttribute('aria-hidden', 'true');\n } else {\n this.actionElement_.removeAttribute('aria-hidden');\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialSnackbar,\n classAsString: 'MaterialSnackbar',\n cssClass: 'mdl-js-snackbar',\n widget: true\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Spinner MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @param {HTMLElement} element The element that will be upgraded.\n * @constructor\n */\nvar MaterialSpinner = function MaterialSpinner(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialSpinner'] = MaterialSpinner;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialSpinner.prototype.Constant_ = { MDL_SPINNER_LAYER_COUNT: 4 };\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialSpinner.prototype.CssClasses_ = {\n MDL_SPINNER_LAYER: 'mdl-spinner__layer',\n MDL_SPINNER_CIRCLE_CLIPPER: 'mdl-spinner__circle-clipper',\n MDL_SPINNER_CIRCLE: 'mdl-spinner__circle',\n MDL_SPINNER_GAP_PATCH: 'mdl-spinner__gap-patch',\n MDL_SPINNER_LEFT: 'mdl-spinner__left',\n MDL_SPINNER_RIGHT: 'mdl-spinner__right'\n};\n/**\n * Auxiliary method to create a spinner layer.\n *\n * @param {number} index Index of the layer to be created.\n * @public\n */\nMaterialSpinner.prototype.createLayer = function (index) {\n var layer = document.createElement('div');\n layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER);\n layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER + '-' + index);\n var leftClipper = document.createElement('div');\n leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER);\n leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_LEFT);\n var gapPatch = document.createElement('div');\n gapPatch.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH);\n var rightClipper = document.createElement('div');\n rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER);\n rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT);\n var circleOwners = [\n leftClipper,\n gapPatch,\n rightClipper\n ];\n for (var i = 0; i < circleOwners.length; i++) {\n var circle = document.createElement('div');\n circle.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE);\n circleOwners[i].appendChild(circle);\n }\n layer.appendChild(leftClipper);\n layer.appendChild(gapPatch);\n layer.appendChild(rightClipper);\n this.element_.appendChild(layer);\n};\nMaterialSpinner.prototype['createLayer'] = MaterialSpinner.prototype.createLayer;\n/**\n * Stops the spinner animation.\n * Public method for users who need to stop the spinner for any reason.\n *\n * @public\n */\nMaterialSpinner.prototype.stop = function () {\n this.element_.classList.remove('is-active');\n};\nMaterialSpinner.prototype['stop'] = MaterialSpinner.prototype.stop;\n/**\n * Starts the spinner animation.\n * Public method for users who need to manually start the spinner for any reason\n * (instead of just adding the 'is-active' class to their markup).\n *\n * @public\n */\nMaterialSpinner.prototype.start = function () {\n this.element_.classList.add('is-active');\n};\nMaterialSpinner.prototype['start'] = MaterialSpinner.prototype.start;\n/**\n * Initialize element.\n */\nMaterialSpinner.prototype.init = function () {\n if (this.element_) {\n for (var i = 1; i <= this.Constant_.MDL_SPINNER_LAYER_COUNT; i++) {\n this.createLayer(i);\n }\n this.element_.classList.add('is-upgraded');\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialSpinner,\n classAsString: 'MaterialSpinner',\n cssClass: 'mdl-js-spinner',\n widget: true\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Checkbox MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialSwitch = function MaterialSwitch(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialSwitch'] = MaterialSwitch;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialSwitch.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialSwitch.prototype.CssClasses_ = {\n INPUT: 'mdl-switch__input',\n TRACK: 'mdl-switch__track',\n THUMB: 'mdl-switch__thumb',\n FOCUS_HELPER: 'mdl-switch__focus-helper',\n RIPPLE_EFFECT: 'mdl-js-ripple-effect',\n RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE_CONTAINER: 'mdl-switch__ripple-container',\n RIPPLE_CENTER: 'mdl-ripple--center',\n RIPPLE: 'mdl-ripple',\n IS_FOCUSED: 'is-focused',\n IS_DISABLED: 'is-disabled',\n IS_CHECKED: 'is-checked'\n};\n/**\n * Handle change of state.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSwitch.prototype.onChange_ = function (event) {\n this.updateClasses_();\n};\n/**\n * Handle focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSwitch.prototype.onFocus_ = function (event) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle lost focus of element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSwitch.prototype.onBlur_ = function (event) {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle mouseup.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialSwitch.prototype.onMouseUp_ = function (event) {\n this.blur_();\n};\n/**\n * Handle class updates.\n *\n * @private\n */\nMaterialSwitch.prototype.updateClasses_ = function () {\n this.checkDisabled();\n this.checkToggleState();\n};\n/**\n * Add blur.\n *\n * @private\n */\nMaterialSwitch.prototype.blur_ = function () {\n // TODO: figure out why there's a focus event being fired after our blur,\n // so that we can avoid this hack.\n window.setTimeout(function () {\n this.inputElement_.blur();\n }.bind(this), this.Constant_.TINY_TIMEOUT);\n};\n// Public methods.\n/**\n * Check the components disabled state.\n *\n * @public\n */\nMaterialSwitch.prototype.checkDisabled = function () {\n if (this.inputElement_.disabled) {\n this.element_.classList.add(this.CssClasses_.IS_DISABLED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DISABLED);\n }\n};\nMaterialSwitch.prototype['checkDisabled'] = MaterialSwitch.prototype.checkDisabled;\n/**\n * Check the components toggled state.\n *\n * @public\n */\nMaterialSwitch.prototype.checkToggleState = function () {\n if (this.inputElement_.checked) {\n this.element_.classList.add(this.CssClasses_.IS_CHECKED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_CHECKED);\n }\n};\nMaterialSwitch.prototype['checkToggleState'] = MaterialSwitch.prototype.checkToggleState;\n/**\n * Disable switch.\n *\n * @public\n */\nMaterialSwitch.prototype.disable = function () {\n this.inputElement_.disabled = true;\n this.updateClasses_();\n};\nMaterialSwitch.prototype['disable'] = MaterialSwitch.prototype.disable;\n/**\n * Enable switch.\n *\n * @public\n */\nMaterialSwitch.prototype.enable = function () {\n this.inputElement_.disabled = false;\n this.updateClasses_();\n};\nMaterialSwitch.prototype['enable'] = MaterialSwitch.prototype.enable;\n/**\n * Activate switch.\n *\n * @public\n */\nMaterialSwitch.prototype.on = function () {\n this.inputElement_.checked = true;\n this.updateClasses_();\n};\nMaterialSwitch.prototype['on'] = MaterialSwitch.prototype.on;\n/**\n * Deactivate switch.\n *\n * @public\n */\nMaterialSwitch.prototype.off = function () {\n this.inputElement_.checked = false;\n this.updateClasses_();\n};\nMaterialSwitch.prototype['off'] = MaterialSwitch.prototype.off;\n/**\n * Initialize element.\n */\nMaterialSwitch.prototype.init = function () {\n if (this.element_) {\n this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);\n var track = document.createElement('div');\n track.classList.add(this.CssClasses_.TRACK);\n var thumb = document.createElement('div');\n thumb.classList.add(this.CssClasses_.THUMB);\n var focusHelper = document.createElement('span');\n focusHelper.classList.add(this.CssClasses_.FOCUS_HELPER);\n thumb.appendChild(focusHelper);\n this.element_.appendChild(track);\n this.element_.appendChild(thumb);\n this.boundMouseUpHandler = this.onMouseUp_.bind(this);\n if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {\n this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);\n this.rippleContainerElement_ = document.createElement('span');\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);\n this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);\n this.rippleContainerElement_.addEventListener('mouseup', this.boundMouseUpHandler);\n var ripple = document.createElement('span');\n ripple.classList.add(this.CssClasses_.RIPPLE);\n this.rippleContainerElement_.appendChild(ripple);\n this.element_.appendChild(this.rippleContainerElement_);\n }\n this.boundChangeHandler = this.onChange_.bind(this);\n this.boundFocusHandler = this.onFocus_.bind(this);\n this.boundBlurHandler = this.onBlur_.bind(this);\n this.inputElement_.addEventListener('change', this.boundChangeHandler);\n this.inputElement_.addEventListener('focus', this.boundFocusHandler);\n this.inputElement_.addEventListener('blur', this.boundBlurHandler);\n this.element_.addEventListener('mouseup', this.boundMouseUpHandler);\n this.updateClasses_();\n this.element_.classList.add('is-upgraded');\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialSwitch,\n classAsString: 'MaterialSwitch',\n cssClass: 'mdl-js-switch',\n widget: true\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Textfield MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialTextfield = function MaterialTextfield(element) {\n this.element_ = element;\n this.maxRows = this.Constant_.NO_MAX_ROWS;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialTextfield'] = MaterialTextfield;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialTextfield.prototype.Constant_ = {\n NO_MAX_ROWS: -1,\n MAX_ROWS_ATTRIBUTE: 'maxrows'\n};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialTextfield.prototype.CssClasses_ = {\n LABEL: 'mdl-textfield__label',\n INPUT: 'mdl-textfield__input',\n IS_DIRTY: 'is-dirty',\n IS_FOCUSED: 'is-focused',\n IS_DISABLED: 'is-disabled',\n IS_INVALID: 'is-invalid',\n IS_UPGRADED: 'is-upgraded',\n HAS_PLACEHOLDER: 'has-placeholder'\n};\n/**\n * Handle input being entered.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialTextfield.prototype.onKeyDown_ = function (event) {\n var currentRowCount = event.target.value.split('\\n').length;\n if (event.keyCode === 13) {\n if (currentRowCount >= this.maxRows) {\n event.preventDefault();\n }\n }\n};\n/**\n * Handle focus.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialTextfield.prototype.onFocus_ = function (event) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle lost focus.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialTextfield.prototype.onBlur_ = function (event) {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n};\n/**\n * Handle reset event from out side.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialTextfield.prototype.onReset_ = function (event) {\n this.updateClasses_();\n};\n/**\n * Handle class updates.\n *\n * @private\n */\nMaterialTextfield.prototype.updateClasses_ = function () {\n this.checkDisabled();\n this.checkValidity();\n this.checkDirty();\n this.checkFocus();\n};\n// Public methods.\n/**\n * Check the disabled state and update field accordingly.\n *\n * @public\n */\nMaterialTextfield.prototype.checkDisabled = function () {\n if (this.input_.disabled) {\n this.element_.classList.add(this.CssClasses_.IS_DISABLED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DISABLED);\n }\n};\nMaterialTextfield.prototype['checkDisabled'] = MaterialTextfield.prototype.checkDisabled;\n/**\n * Check the focus state and update field accordingly.\n *\n * @public\n */\nMaterialTextfield.prototype.checkFocus = function () {\n if (Boolean(this.element_.querySelector(':focus'))) {\n this.element_.classList.add(this.CssClasses_.IS_FOCUSED);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);\n }\n};\nMaterialTextfield.prototype['checkFocus'] = MaterialTextfield.prototype.checkFocus;\n/**\n * Check the validity state and update field accordingly.\n *\n * @public\n */\nMaterialTextfield.prototype.checkValidity = function () {\n if (this.input_.validity) {\n if (this.input_.validity.valid) {\n this.element_.classList.remove(this.CssClasses_.IS_INVALID);\n } else {\n this.element_.classList.add(this.CssClasses_.IS_INVALID);\n }\n }\n};\nMaterialTextfield.prototype['checkValidity'] = MaterialTextfield.prototype.checkValidity;\n/**\n * Check the dirty state and update field accordingly.\n *\n * @public\n */\nMaterialTextfield.prototype.checkDirty = function () {\n if (this.input_.value && this.input_.value.length > 0) {\n this.element_.classList.add(this.CssClasses_.IS_DIRTY);\n } else {\n this.element_.classList.remove(this.CssClasses_.IS_DIRTY);\n }\n};\nMaterialTextfield.prototype['checkDirty'] = MaterialTextfield.prototype.checkDirty;\n/**\n * Disable text field.\n *\n * @public\n */\nMaterialTextfield.prototype.disable = function () {\n this.input_.disabled = true;\n this.updateClasses_();\n};\nMaterialTextfield.prototype['disable'] = MaterialTextfield.prototype.disable;\n/**\n * Enable text field.\n *\n * @public\n */\nMaterialTextfield.prototype.enable = function () {\n this.input_.disabled = false;\n this.updateClasses_();\n};\nMaterialTextfield.prototype['enable'] = MaterialTextfield.prototype.enable;\n/**\n * Update text field value.\n *\n * @param {string} value The value to which to set the control (optional).\n * @public\n */\nMaterialTextfield.prototype.change = function (value) {\n this.input_.value = value || '';\n this.updateClasses_();\n};\nMaterialTextfield.prototype['change'] = MaterialTextfield.prototype.change;\n/**\n * Initialize element.\n */\nMaterialTextfield.prototype.init = function () {\n if (this.element_) {\n this.label_ = this.element_.querySelector('.' + this.CssClasses_.LABEL);\n this.input_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);\n if (this.input_) {\n if (this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)) {\n this.maxRows = parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE), 10);\n if (isNaN(this.maxRows)) {\n this.maxRows = this.Constant_.NO_MAX_ROWS;\n }\n }\n if (this.input_.hasAttribute('placeholder')) {\n this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER);\n }\n this.boundUpdateClassesHandler = this.updateClasses_.bind(this);\n this.boundFocusHandler = this.onFocus_.bind(this);\n this.boundBlurHandler = this.onBlur_.bind(this);\n this.boundResetHandler = this.onReset_.bind(this);\n this.input_.addEventListener('input', this.boundUpdateClassesHandler);\n this.input_.addEventListener('focus', this.boundFocusHandler);\n this.input_.addEventListener('blur', this.boundBlurHandler);\n this.input_.addEventListener('reset', this.boundResetHandler);\n if (this.maxRows !== this.Constant_.NO_MAX_ROWS) {\n // TODO: This should handle pasting multi line text.\n // Currently doesn't.\n this.boundKeyDownHandler = this.onKeyDown_.bind(this);\n this.input_.addEventListener('keydown', this.boundKeyDownHandler);\n }\n var invalid = this.element_.classList.contains(this.CssClasses_.IS_INVALID);\n this.updateClasses_();\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n if (invalid) {\n this.element_.classList.add(this.CssClasses_.IS_INVALID);\n }\n if (this.input_.hasAttribute('autofocus')) {\n this.element_.focus();\n this.checkFocus();\n }\n }\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialTextfield,\n classAsString: 'MaterialTextfield',\n cssClass: 'mdl-js-textfield',\n widget: true\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Tooltip MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialTooltip = function MaterialTooltip(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialTooltip'] = MaterialTooltip;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialTooltip.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialTooltip.prototype.CssClasses_ = {\n IS_ACTIVE: 'is-active',\n BOTTOM: 'mdl-tooltip--bottom',\n LEFT: 'mdl-tooltip--left',\n RIGHT: 'mdl-tooltip--right',\n TOP: 'mdl-tooltip--top'\n};\n/**\n * Handle mouseenter for tooltip.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialTooltip.prototype.handleMouseEnter_ = function (event) {\n var props = event.target.getBoundingClientRect();\n var left = props.left + props.width / 2;\n var top = props.top + props.height / 2;\n var marginLeft = -1 * (this.element_.offsetWidth / 2);\n var marginTop = -1 * (this.element_.offsetHeight / 2);\n if (this.element_.classList.contains(this.CssClasses_.LEFT) || this.element_.classList.contains(this.CssClasses_.RIGHT)) {\n left = props.width / 2;\n if (top + marginTop < 0) {\n this.element_.style.top = '0';\n this.element_.style.marginTop = '0';\n } else {\n this.element_.style.top = top + 'px';\n this.element_.style.marginTop = marginTop + 'px';\n }\n } else {\n if (left + marginLeft < 0) {\n this.element_.style.left = '0';\n this.element_.style.marginLeft = '0';\n } else {\n this.element_.style.left = left + 'px';\n this.element_.style.marginLeft = marginLeft + 'px';\n }\n }\n if (this.element_.classList.contains(this.CssClasses_.TOP)) {\n this.element_.style.top = props.top - this.element_.offsetHeight - 10 + 'px';\n } else if (this.element_.classList.contains(this.CssClasses_.RIGHT)) {\n this.element_.style.left = props.left + props.width + 10 + 'px';\n } else if (this.element_.classList.contains(this.CssClasses_.LEFT)) {\n this.element_.style.left = props.left - this.element_.offsetWidth - 10 + 'px';\n } else {\n this.element_.style.top = props.top + props.height + 10 + 'px';\n }\n this.element_.classList.add(this.CssClasses_.IS_ACTIVE);\n};\n/**\n * Hide tooltip on mouseleave or scroll\n *\n * @private\n */\nMaterialTooltip.prototype.hideTooltip_ = function () {\n this.element_.classList.remove(this.CssClasses_.IS_ACTIVE);\n};\n/**\n * Initialize element.\n */\nMaterialTooltip.prototype.init = function () {\n if (this.element_) {\n var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for');\n if (forElId) {\n this.forElement_ = document.getElementById(forElId);\n }\n if (this.forElement_) {\n // It's left here because it prevents accidental text selection on Android\n if (!this.forElement_.hasAttribute('tabindex')) {\n this.forElement_.setAttribute('tabindex', '0');\n }\n this.boundMouseEnterHandler = this.handleMouseEnter_.bind(this);\n this.boundMouseLeaveAndScrollHandler = this.hideTooltip_.bind(this);\n this.forElement_.addEventListener('mouseenter', this.boundMouseEnterHandler, false);\n this.forElement_.addEventListener('touchend', this.boundMouseEnterHandler, false);\n this.forElement_.addEventListener('mouseleave', this.boundMouseLeaveAndScrollHandler, false);\n window.addEventListener('scroll', this.boundMouseLeaveAndScrollHandler, true);\n window.addEventListener('touchstart', this.boundMouseLeaveAndScrollHandler);\n }\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialTooltip,\n classAsString: 'MaterialTooltip',\n cssClass: 'mdl-tooltip'\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Data Table Card MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {Element} element The element that will be upgraded.\n */\nvar MaterialDataTable = function MaterialDataTable(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialDataTable'] = MaterialDataTable;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialDataTable.prototype.Constant_ = {};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialDataTable.prototype.CssClasses_ = {\n DATA_TABLE: 'mdl-data-table',\n SELECTABLE: 'mdl-data-table--selectable',\n SELECT_ELEMENT: 'mdl-data-table__select',\n IS_SELECTED: 'is-selected',\n IS_UPGRADED: 'is-upgraded'\n};\n/**\n * Generates and returns a function that toggles the selection state of a\n * single row (or multiple rows).\n *\n * @param {Element} checkbox Checkbox that toggles the selection state.\n * @param {Element} row Row to toggle when checkbox changes.\n * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes.\n * @private\n */\nMaterialDataTable.prototype.selectRow_ = function (checkbox, row, opt_rows) {\n if (row) {\n return function () {\n if (checkbox.checked) {\n row.classList.add(this.CssClasses_.IS_SELECTED);\n } else {\n row.classList.remove(this.CssClasses_.IS_SELECTED);\n }\n }.bind(this);\n }\n if (opt_rows) {\n return function () {\n var i;\n var el;\n if (checkbox.checked) {\n for (i = 0; i < opt_rows.length; i++) {\n el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox');\n el['MaterialCheckbox'].check();\n opt_rows[i].classList.add(this.CssClasses_.IS_SELECTED);\n }\n } else {\n for (i = 0; i < opt_rows.length; i++) {\n el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox');\n el['MaterialCheckbox'].uncheck();\n opt_rows[i].classList.remove(this.CssClasses_.IS_SELECTED);\n }\n }\n }.bind(this);\n }\n};\n/**\n * Creates a checkbox for a single or or multiple rows and hooks up the\n * event handling.\n *\n * @param {Element} row Row to toggle when checkbox changes.\n * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes.\n * @private\n */\nMaterialDataTable.prototype.createCheckbox_ = function (row, opt_rows) {\n var label = document.createElement('label');\n var labelClasses = [\n 'mdl-checkbox',\n 'mdl-js-checkbox',\n 'mdl-js-ripple-effect',\n this.CssClasses_.SELECT_ELEMENT\n ];\n label.className = labelClasses.join(' ');\n var checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.classList.add('mdl-checkbox__input');\n if (row) {\n checkbox.checked = row.classList.contains(this.CssClasses_.IS_SELECTED);\n checkbox.addEventListener('change', this.selectRow_(checkbox, row));\n } else if (opt_rows) {\n checkbox.addEventListener('change', this.selectRow_(checkbox, null, opt_rows));\n }\n label.appendChild(checkbox);\n componentHandler.upgradeElement(label, 'MaterialCheckbox');\n return label;\n};\n/**\n * Initialize element.\n */\nMaterialDataTable.prototype.init = function () {\n if (this.element_) {\n var firstHeader = this.element_.querySelector('th');\n var bodyRows = Array.prototype.slice.call(this.element_.querySelectorAll('tbody tr'));\n var footRows = Array.prototype.slice.call(this.element_.querySelectorAll('tfoot tr'));\n var rows = bodyRows.concat(footRows);\n if (this.element_.classList.contains(this.CssClasses_.SELECTABLE)) {\n var th = document.createElement('th');\n var headerCheckbox = this.createCheckbox_(null, rows);\n th.appendChild(headerCheckbox);\n firstHeader.parentElement.insertBefore(th, firstHeader);\n for (var i = 0; i < rows.length; i++) {\n var firstCell = rows[i].querySelector('td');\n if (firstCell) {\n var td = document.createElement('td');\n if (rows[i].parentNode.nodeName.toUpperCase() === 'TBODY') {\n var rowCheckbox = this.createCheckbox_(rows[i]);\n td.appendChild(rowCheckbox);\n }\n rows[i].insertBefore(td, firstCell);\n }\n }\n this.element_.classList.add(this.CssClasses_.IS_UPGRADED);\n }\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialDataTable,\n classAsString: 'MaterialDataTable',\n cssClass: 'mdl-js-data-table'\n});", + "/**\n * @license\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class constructor for Ripple MDL component.\n * Implements MDL component design pattern defined at:\n * https://github.com/jasonmayes/mdl-component-design-pattern\n *\n * @constructor\n * @param {HTMLElement} element The element that will be upgraded.\n */\nvar MaterialRipple = function MaterialRipple(element) {\n this.element_ = element;\n // Initialize instance.\n this.init();\n};\nwindow['MaterialRipple'] = MaterialRipple;\n/**\n * Store constants in one place so they can be updated easily.\n *\n * @enum {string | number}\n * @private\n */\nMaterialRipple.prototype.Constant_ = {\n INITIAL_SCALE: 'scale(0.0001, 0.0001)',\n INITIAL_SIZE: '1px',\n INITIAL_OPACITY: '0.4',\n FINAL_OPACITY: '0',\n FINAL_SCALE: ''\n};\n/**\n * Store strings for class names defined by this component that are used in\n * JavaScript. This allows us to simply change it in one place should we\n * decide to modify at a later date.\n *\n * @enum {string}\n * @private\n */\nMaterialRipple.prototype.CssClasses_ = {\n RIPPLE_CENTER: 'mdl-ripple--center',\n RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',\n RIPPLE: 'mdl-ripple',\n IS_ANIMATING: 'is-animating',\n IS_VISIBLE: 'is-visible'\n};\n/**\n * Handle mouse / finger down on element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRipple.prototype.downHandler_ = function (event) {\n if (!this.rippleElement_.style.width && !this.rippleElement_.style.height) {\n var rect = this.element_.getBoundingClientRect();\n this.boundHeight = rect.height;\n this.boundWidth = rect.width;\n this.rippleSize_ = Math.sqrt(rect.width * rect.width + rect.height * rect.height) * 2 + 2;\n this.rippleElement_.style.width = this.rippleSize_ + 'px';\n this.rippleElement_.style.height = this.rippleSize_ + 'px';\n }\n this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE);\n if (event.type === 'mousedown' && this.ignoringMouseDown_) {\n this.ignoringMouseDown_ = false;\n } else {\n if (event.type === 'touchstart') {\n this.ignoringMouseDown_ = true;\n }\n var frameCount = this.getFrameCount();\n if (frameCount > 0) {\n return;\n }\n this.setFrameCount(1);\n var bound = event.currentTarget.getBoundingClientRect();\n var x;\n var y;\n // Check if we are handling a keyboard click.\n if (event.clientX === 0 && event.clientY === 0) {\n x = Math.round(bound.width / 2);\n y = Math.round(bound.height / 2);\n } else {\n var clientX = event.clientX !== undefined ? event.clientX : event.touches[0].clientX;\n var clientY = event.clientY !== undefined ? event.clientY : event.touches[0].clientY;\n x = Math.round(clientX - bound.left);\n y = Math.round(clientY - bound.top);\n }\n this.setRippleXY(x, y);\n this.setRippleStyles(true);\n window.requestAnimationFrame(this.animFrameHandler.bind(this));\n }\n};\n/**\n * Handle mouse / finger up on element.\n *\n * @param {Event} event The event that fired.\n * @private\n */\nMaterialRipple.prototype.upHandler_ = function (event) {\n // Don't fire for the artificial \"mouseup\" generated by a double-click.\n if (event && event.detail !== 2) {\n // Allow a repaint to occur before removing this class, so the animation\n // shows for tap events, which seem to trigger a mouseup too soon after\n // mousedown.\n window.setTimeout(function () {\n this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE);\n }.bind(this), 0);\n }\n};\n/**\n * Initialize element.\n */\nMaterialRipple.prototype.init = function () {\n if (this.element_) {\n var recentering = this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);\n if (!this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)) {\n this.rippleElement_ = this.element_.querySelector('.' + this.CssClasses_.RIPPLE);\n this.frameCount_ = 0;\n this.rippleSize_ = 0;\n this.x_ = 0;\n this.y_ = 0;\n // Touch start produces a compat mouse down event, which would cause a\n // second ripples. To avoid that, we use this property to ignore the first\n // mouse down after a touch start.\n this.ignoringMouseDown_ = false;\n this.boundDownHandler = this.downHandler_.bind(this);\n this.element_.addEventListener('mousedown', this.boundDownHandler);\n this.element_.addEventListener('touchstart', this.boundDownHandler);\n this.boundUpHandler = this.upHandler_.bind(this);\n this.element_.addEventListener('mouseup', this.boundUpHandler);\n this.element_.addEventListener('mouseleave', this.boundUpHandler);\n this.element_.addEventListener('touchend', this.boundUpHandler);\n this.element_.addEventListener('blur', this.boundUpHandler);\n /**\n * Getter for frameCount_.\n * @return {number} the frame count.\n */\n this.getFrameCount = function () {\n return this.frameCount_;\n };\n /**\n * Setter for frameCount_.\n * @param {number} fC the frame count.\n */\n this.setFrameCount = function (fC) {\n this.frameCount_ = fC;\n };\n /**\n * Getter for rippleElement_.\n * @return {Element} the ripple element.\n */\n this.getRippleElement = function () {\n return this.rippleElement_;\n };\n /**\n * Sets the ripple X and Y coordinates.\n * @param {number} newX the new X coordinate\n * @param {number} newY the new Y coordinate\n */\n this.setRippleXY = function (newX, newY) {\n this.x_ = newX;\n this.y_ = newY;\n };\n /**\n * Sets the ripple styles.\n * @param {boolean} start whether or not this is the start frame.\n */\n this.setRippleStyles = function (start) {\n if (this.rippleElement_ !== null) {\n var transformString;\n var scale;\n var size;\n var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)';\n if (start) {\n scale = this.Constant_.INITIAL_SCALE;\n size = this.Constant_.INITIAL_SIZE;\n } else {\n scale = this.Constant_.FINAL_SCALE;\n size = this.rippleSize_ + 'px';\n if (recentering) {\n offset = 'translate(' + this.boundWidth / 2 + 'px, ' + this.boundHeight / 2 + 'px)';\n }\n }\n transformString = 'translate(-50%, -50%) ' + offset + scale;\n this.rippleElement_.style.webkitTransform = transformString;\n this.rippleElement_.style.msTransform = transformString;\n this.rippleElement_.style.transform = transformString;\n if (start) {\n this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING);\n } else {\n this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING);\n }\n }\n };\n /**\n * Handles an animation frame.\n */\n this.animFrameHandler = function () {\n if (this.frameCount_-- > 0) {\n window.requestAnimationFrame(this.animFrameHandler.bind(this));\n } else {\n this.setRippleStyles(false);\n }\n };\n }\n }\n};\n// The component registers itself. It can assume componentHandler is available\n// in the global scope.\ncomponentHandler.register({\n constructor: MaterialRipple,\n classAsString: 'MaterialRipple',\n cssClass: 'mdl-js-ripple-effect',\n widget: false\n});" + ] +}
\ No newline at end of file diff --git a/src/polyfills.ts b/src/polyfills.ts new file mode 100644 index 0000000..d8f92c1 --- /dev/null +++ b/src/polyfills.ts @@ -0,0 +1,61 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +import 'core-js/es6/symbol'; +import 'core-js/es6/object'; +import 'core-js/es6/function'; +import 'core-js/es6/parse-int'; +import 'core-js/es6/parse-float'; +import 'core-js/es6/number'; +import 'core-js/es6/math'; +import 'core-js/es6/string'; +import 'core-js/es6/date'; +import 'core-js/es6/array'; +import 'core-js/es6/regexp'; +import 'core-js/es6/map'; +import 'core-js/es6/weak-map'; +import 'core-js/es6/set'; +import 'core-js/es6/reflect'; +import 'core-js/es7/reflect'; +import 'zone.js/dist/zone'; // Included with Angular CLI. diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 0000000..57ba1f2 --- /dev/null +++ b/src/styles.css @@ -0,0 +1,591 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ + +input[type=text], +input[type=password], +input[type=email], +input[type=url], +input[type=time], +input[type=date], +input[type=datetime-local], +input[type=tel], +input[type=number], +input[type=search-md], +input[type=search], +textarea.md-textarea { + font-family: 'Roboto'; + background-color: transparent; + border: 1px solid; + border-bottom: 1px solid; + border-color: grey; + border-radius: 5px; + outline: none; + height: 37px; + width: 100%; + font-size: 1rem; + box-shadow: none; + box-sizing: inherit; + padding: 8px; +} + +select.form-control { + border-radius: 5px; + border: 1px solid; + padding-left: 10px; + border-color: grey; + font-family: 'Roboto'; +} + +input[type=text]:disabled { + background: #e0dada; + font-family: 'Roboto'; +} + +body { + background: white; + font-family: 'Roboto'; +} + +body { + margin: 0; +} + +/* Disable ugly boxes around images in IE10 */ + +a img { + border: 0px; +} + +::-moz-selection { + background-color: #6ab344; + color: #fff; +} + +::selection { + background-color: #6ab344; + color: #fff; +} + +.android-search-box .mdl-textfield__input { + color: rgba(0, 0, 0, 0.87); +} + +.android-header .mdl-menu__container { + z-index: 50; + margin: 0 !important; +} + +.mdl-textfield--expandable { + width: auto; +} + +.android-fab { + position: absolute; + right: 20%; + bottom: -26px; + z-index: 3; + background: #64ffda !important; + color: black !important; +} + +.android-mobile-title { + display: none !important; +} + +.android-logo-image { + height: 28px; + width: 140px; +} + +.warningMarker { + position: absolute; + background: orange; + color: red; + z-index: 20 +} + +.col-lg-12-ln { + margin-left: 41px; + margin-top: 2px; + position: centre; +} + +.col-lg-12-ln1 { + margin-left: 30px; + margin-top: 2px; + position: centre; +} + +.col-lg-12-ln2 { + margin-left: 370px; + margin-top: 15px; + position: centre; +} + +.keyedMarker { + position: absolute; + background: green; + z-index: 20 +} + +.noKeyedMarker { + position: absolute; + background: orange; + z-index: 20 +} + +.defaultMarker { + position: absolute; + background: lightgreen; + z-index: 20; +} + +.android-header { + overflow: visible; + background-color: white; +} + +.android-header .material-icons { + color: #767777 !important; +} + +.android-header .mdl-layout__drawer-button { + background: transparent; + color: #767777; +} + +.android-header .mdl-navigation__link { + color: #757575; + font-weight: 700; + font-size: 14px; +} + +.android-navigation-container { + /* Simple hack to make the overflow happen to the left instead... */ + direction: rtl; + -webkit-order: 1; + -ms-flex-order: 1; + order: 1; + width: 500px; + transition: opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1), width 0.2s cubic-bezier(0.4, 0, 0.2, 1); +} + +.android-navigation { + /* ... and now make sure the content is actually LTR */ + direction: ltr; + -webkit-justify-content: flex-end; + -ms-flex-pack: end; + justify-content: flex-end; + width: 800px; +} + +.android-search-box.is-focused + .android-navigation-container { + opacity: 0; + width: 100px; +} + +.android-navigation .mdl-navigation__link { + display: inline-block; + height: 60px; + line-height: 68px; + background-color: transparent !important; + border-bottom: 4px solid transparent; +} + +.android-navigation .mdl-navigation__link:hover { + border-bottom: 4px solid #6ab344; +} + +.android-search-box { + -webkit-order: 2; + -ms-flex-order: 2; + order: 2; + margin-left: 16px; + margin-right: 16px; +} + +.android-more-button { + -webkit-order: 3; + -ms-flex-order: 3; + order: 3; +} + +.android-drawer { + border-right: none; +} + +.android-drawer-separator { + height: 1px; + background-color: #dcdcdc; + margin: 8px 0; +} + +.android-drawer .mdl-navigation__link.mdl-navigation__link { + font-size: 14px; + color: #757575; +} + +.android-drawer span.mdl-navigation__link.mdl-navigation__link { + color: #6ab344; +} + +.android-drawer .mdl-layout-title { + position: relative; + background: #6ab344; + height: 160px; +} + +.android-drawer .android-logo-image { + position: absolute; + bottom: 16px; +} + +.logo-font { + font-family: 'Roboto'; + line-height: 1; + color: #767777; + font-weight: 500; +} + +.android-slogan { + font-size: 60px; + padding-top: 160px; +} + +.android-sub-slogan { + font-size: 21px; + padding-top: 24px; +} + +.android-create-character { + font-size: 21px; + padding-top: 400px; +} + +.android-create-character a { + text-decoration: none; + color: #767777; + font-weight: 300; +} + +.android-screen-section { + position: relative; + padding-top: 60px; + padding-bottom: 80px; +} + +.android-screens { + text-align: right; + width: 100%; + white-space: nowrap; + overflow-x: auto; +} + +.android-screen { + text-align: center; +} + +.android-screen .android-link { + margin-top: 16px; + display: block; + z-index: 2; +} + +.android-image-link { + text-decoration: none; +} + +.android-wear { + display: inline-block; + width: 160px; + margin-right: 32px; +} + +.android-wear .android-screen-image { + width: 40%; + z-index: 1; +} + +.android-phone { + display: inline-block; + width: 64px; + margin-right: 48px; +} + +.android-phone .android-screen-image { + width: 100%; + z-index: 1; +} + +.android-tablet { + display: inline-block; + width: 110px; + margin-right: 64px; +} + +.android-tablet .android-screen-image { + width: 100%; + z-index: 1; +} + +.android-tablet .android-link { + display: block; + z-index: 2; +} + +.android-tv { + display: inline-block; + width: 300px; + margin-right: 80px; +} + +.android-tv .android-screen-image { + width: 100%; + z-index: 1; +} + +.android-auto { + display: inline-block; + width: 300px; + overflow: hidden; +} + +.android-auto .android-screen-image { + display: block; + height: 300px; + z-index: 1; +} + +.android-wear-band-text p { + padding-top: 8px; +} + +.android-link { + text-decoration: none; + color: #6ab344 !important; +} + +.android-link:hover { + color: #6ab344 !important; +} + +.android-link .material-icons { + position: relative; + top: -1px; + vertical-align: middle; +} + +.android-alt-link { + text-decoration: none; + color: #64ffda !important; + font-size: 16px; +} + +.android-alt-link:hover { + color: #00bfa5 !important; +} + +.android-alt-link .material-icons { + position: relative; + top: 6px; +} + +.android-customized-section { + text-align: center; +} + +.android-customized-section-text { + max-width: 500px; + margin-left: auto; + margin-right: auto; + padding: 80px 16px 0 16px; +} + +.android-customized-section-text p { + padding-top: 16px; +} + +.android-more-section { + padding: 80px 0; + max-width: 1044px; + margin-left: auto; + margin-right: auto; +} + +.android-more-section .android-section-title { + margin-left: 12px; + padding-bottom: 24px; +} + +.android-card-container { +} + +.android-card-container .mdl-card__media { + overflow: hidden; + background: transparent; +} + +.android-card-container .mdl-card__media img { + width: 100%; +} + +.android-card-container .mdl-card__title { + background: transparent; + height: auto; +} + +.android-card-container .mdl-card__title-text { + color: black; + height: auto; +} + +.android-card-container .mdl-card__supporting-text { + height: auto; + color: black; + padding-bottom: 56px; +} + +.android-card-container .mdl-card__actions { + position: absolute; + bottom: 0; +} + +.android-card-container .mdl-card__actions a { + border-top: none; + font-size: 16px; +} + +.android-footer { + background-color: #fafafa; + position: relative; +} + +.android-footer a:hover { + color: #8bc34a; +} + +.android-footer .mdl-mega-footer--top-section::after { + border-bottom: none; +} + +.android-footer .mdl-mega-footer--middle-section::after { + border-bottom: none; +} + +.android-footer .mdl-mega-footer--bottom-section { + position: relative; +} + +.android-footer .mdl-mega-footer--bottom-section a { + margin-right: 2em; +} + +.android-footer .mdl-mega-footer--right-section a .material-icons { + position: relative; + top: 6px; +} + +.android-link-menu:hover { + cursor: pointer; +} + +/**** Mobile layout ****/ + +@media (max-width: 900px) { + .android-navigation-container { + display: none; + } + + .android-title { + display: none !important; + } + + .android-mobile-title { + display: block !important; + position: absolute; + left: calc(50% - 70px); + top: 12px; + transition: opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1); + } + + /* WebViews in iOS 9 break the "~" operator, and WebViews in OS X 10.10 break + consecutive "+" operators in some cases. Therefore, we need to use both + here to cover all the bases. */ + .android.android-search-box.is-focused ~ .android-mobile-title, + .android-search-box.is-focused + .android-navigation-container + .android-mobile-title { + opacity: 0; + } + + .android-more-button { + display: none; + } + + .android-search-box.is-focused { + width: calc(100% - 48px); + } + + .android-search-box .mdl-textfield__expandable-holder { + width: 100%; + } + + .android-be-together-section { + height: 350px; + } + + .android-slogan { + font-size: 26px; + margin: 0 16px; + padding-top: 24px; + } + + .android-sub-slogan { + font-size: 16px; + margin: 0 16px; + padding-top: 8px; + } + + .android-create-character { + padding-top: 200px; + font-size: 16px; + } + + .android-create-character img { + height: 12px; + } + + .android-fab { + display: none; + } + + .android-wear-band-text { + margin-left: 0; + padding: 16px; + } + + .android-footer .mdl-mega-footer--bottom-section { + display: none; + } +} + +input[type=text]:readonly { + background: #e0dada; +}
\ No newline at end of file diff --git a/src/test.ts b/src/test.ts new file mode 100644 index 0000000..e5cdb59 --- /dev/null +++ b/src/test.ts @@ -0,0 +1,54 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ +*/ + +import 'zone.js/dist/long-stack-trace-zone'; +import 'zone.js/dist/proxy.js'; +import 'zone.js/dist/sync-test'; +import 'zone.js/dist/jasmine-patch'; +import 'zone.js/dist/async-test'; +import 'zone.js/dist/fake-async-test'; + +import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing'; + +import {getTestBed} from '@angular/core/testing'; + +// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. +declare const __karma__: any; +declare const require: any; + +// Prevent Karma from running prematurely. +__karma__.loaded = function () { +}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./app', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); +// Finally, start Karma to run the tests. +__karma__.start(); diff --git a/src/test/java/org/openecom/appc/cdt/cdt/AppTest.java b/src/test/java/org/openecom/appc/cdt/cdt/AppTest.java new file mode 100644 index 0000000..bdf1f4b --- /dev/null +++ b/src/test/java/org/openecom/appc/cdt/cdt/AppTest.java @@ -0,0 +1,59 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ +package org.openecom.appc.cdt.cdt; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/src/tsconfig.app.json b/src/tsconfig.app.json new file mode 100644 index 0000000..4993ee1 --- /dev/null +++ b/src/tsconfig.app.json @@ -0,0 +1,18 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "baseUrl": "./", + "module": "es2015", + "types": [ + "node" + ], + "typeRoots": [ + "../node_modules/@types" + ] + }, + "exclude": [ + "test.ts", + "**/*.spec.ts" + ] +}
\ No newline at end of file diff --git a/src/tsconfig.spec.json b/src/tsconfig.spec.json new file mode 100644 index 0000000..f32f968 --- /dev/null +++ b/src/tsconfig.spec.json @@ -0,0 +1,20 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/spec", + "baseUrl": "./", + "module": "commonjs", + "target": "es5", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "test.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +}
\ No newline at end of file diff --git a/src/typings.d.ts b/src/typings.d.ts new file mode 100644 index 0000000..c681441 --- /dev/null +++ b/src/typings.d.ts @@ -0,0 +1,28 @@ +/* +============LICENSE_START========================================== +=================================================================== +Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. +=================================================================== + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the License); +you may not use this software 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. + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +============LICENSE_END============================================ */ + +/* SystemJS module definition */ +declare var module: NodeModule; + +interface NodeModule { + id: string; +} |