diff --git a/angular.json b/angular.json index f2ff4b21..f0912c14 100644 --- a/angular.json +++ b/angular.json @@ -1308,6 +1308,111 @@ } } } + }, + "ucap-webmessenger-ui-group": { + "projectType": "library", + "root": "projects/ucap-webmessenger-ui-group", + "sourceRoot": "projects/ucap-webmessenger-ui-group/src", + "prefix": "ucap-group", + "architect": { + "build": { + "builder": "@angular-devkit/build-ng-packagr:build", + "options": { + "tsConfig": "projects/ucap-webmessenger-ui-group/tsconfig.lib.json", + "project": "projects/ucap-webmessenger-ui-group/ng-package.json" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "projects/ucap-webmessenger-ui-group/src/test.ts", + "tsConfig": "projects/ucap-webmessenger-ui-group/tsconfig.spec.json", + "karmaConfig": "projects/ucap-webmessenger-ui-group/karma.conf.js" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "projects/ucap-webmessenger-ui-group/tsconfig.lib.json", + "projects/ucap-webmessenger-ui-group/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + }, + "ucap-webmessenger-util-translate": { + "projectType": "library", + "root": "projects/ucap-webmessenger-util-translate", + "sourceRoot": "projects/ucap-webmessenger-util-translate/src", + "prefix": "ucap-util-translate", + "architect": { + "build": { + "builder": "@angular-devkit/build-ng-packagr:build", + "options": { + "tsConfig": "projects/ucap-webmessenger-util-translate/tsconfig.lib.json", + "project": "projects/ucap-webmessenger-util-translate/ng-package.json" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "projects/ucap-webmessenger-util-translate/src/test.ts", + "tsConfig": "projects/ucap-webmessenger-util-translate/tsconfig.spec.json", + "karmaConfig": "projects/ucap-webmessenger-util-translate/karma.conf.js" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "projects/ucap-webmessenger-util-translate/tsconfig.lib.json", + "projects/ucap-webmessenger-util-translate/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + }, + "ucap-webmessenger-native-browser": { + "projectType": "library", + "root": "projects/ucap-webmessenger-native-browser", + "sourceRoot": "projects/ucap-webmessenger-native-browser/src", + "prefix": "ucap-native-browser", + "architect": { + "build": { + "builder": "@angular-devkit/build-ng-packagr:build", + "options": { + "tsConfig": "projects/ucap-webmessenger-native-browser/tsconfig.lib.json", + "project": "projects/ucap-webmessenger-native-browser/ng-package.json" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "projects/ucap-webmessenger-native-browser/src/test.ts", + "tsConfig": "projects/ucap-webmessenger-native-browser/tsconfig.spec.json", + "karmaConfig": "projects/ucap-webmessenger-native-browser/karma.conf.js" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "projects/ucap-webmessenger-native-browser/tsconfig.lib.json", + "projects/ucap-webmessenger-native-browser/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } } }, "defaultProject": "ucap-webmessenger-app" diff --git a/main/src/index.ts b/main/src/index.ts index fc6c6724..5e7255cd 100644 --- a/main/src/index.ts +++ b/main/src/index.ts @@ -1,11 +1,13 @@ import { app, ipcMain, IpcMainEvent } from 'electron'; import * as path from 'path'; import * as url from 'url'; +import * as fse from 'fs-extra'; import { AppWindow } from './app/AppWindow'; import { now } from './util/now'; import { showUncaughtException } from './crash/show-uncaught-exception'; import { Channel } from '@ucap-webmessenger/native-electron'; +import { root } from './util/root'; let appWindow: AppWindow | null = null; @@ -168,3 +170,21 @@ function onDidLoad(fn: OnDidLoadFn) { ipcMain.on(Channel.checkForUpdates, (event: IpcMainEvent, ...args: any[]) => { event.returnValue = false; }); + +ipcMain.on(Channel.readFile, (event: IpcMainEvent, ...args: any[]) => { + try { + const rBuf = fse.readFileSync(root(args[0])); + event.returnValue = rBuf.buffer; + } catch (error) { + event.returnValue = null; + } +}); + +ipcMain.on(Channel.saveFile, (event: IpcMainEvent, ...args: any[]) => { + try { + fse.writeFileSync(root(args[0]), args[1]); + event.returnValue = true; + } catch (error) { + event.returnValue = false; + } +}); diff --git a/main/src/util/root.ts b/main/src/util/root.ts new file mode 100644 index 00000000..f5611558 --- /dev/null +++ b/main/src/util/root.ts @@ -0,0 +1,11 @@ +import * as path from 'path'; + +// tslint:disable-next-line: variable-name +const _root = __DEV__ + ? path.resolve(__dirname, '..', '..') + : path.resolve(__dirname); + +export function root(...paths: string[]) { + const args = Array.prototype.slice.call(paths, 0); + return path.join.apply(path, [_root].concat(args)); +} diff --git a/package-lock.json b/package-lock.json index 1a59786f..7edf556a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2208,6 +2208,15 @@ "integrity": "sha512-cGnXW1YH24LI6iCWFjaJ9nVX/WX3d1XzIjJuniZWMD+hpGBWDECCeh8H4MwTg17IMKRU1pfjwfI8crok7b2fEA==", "dev": true }, + "@types/fs-extra": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.0.0.tgz", + "integrity": "sha512-bCtL5v9zdbQW86yexOlXWTEGvLNqWxMFyi7gQA7Gcthbezr2cPSOb8SkESVKA937QD5cIwOFLDFt0MQoXOEr9Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", @@ -5543,6 +5552,17 @@ "ms": "^2.1.1" } }, + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -6660,12 +6680,12 @@ } }, "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } diff --git a/package.json b/package.json index b2a02e66..a44b8913 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@types/crypto-js": "^3.1.43", "@types/detect-browser": "^4.0.0", "@types/extract-text-webpack-plugin": "^3.0.4", + "@types/fs-extra": "^8.0.0", "@types/filesize": "^4.1.0", "@types/jasmine": "~3.3.8", "@types/jasminewd2": "~2.0.3", @@ -70,6 +71,7 @@ "electron-reload": "^1.5.0", "electron-store": "^4.0.0", "electron-window-state": "^5.0.3", + "fs-extra": "^8.1.0", "filesize": "^4.1.2", "hammerjs": "^2.0.8", "jasmine-core": "~3.4.0", diff --git a/projects/ucap-webmessenger-app/src/app/app-translate.module.ts b/projects/ucap-webmessenger-app/src/app/app-translate.module.ts index e8e1836b..5faaf634 100644 --- a/projects/ucap-webmessenger-app/src/app/app-translate.module.ts +++ b/projects/ucap-webmessenger-app/src/app/app-translate.module.ts @@ -2,8 +2,32 @@ import { NgModule } from '@angular/core'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native'; + +export async function createTranslateLoader(nativeService: NativeService) { + // tslint:disable-next-line: variable-name + let _TranslateLoader; + _TranslateLoader = await import('@ucap-webmessenger/native-browser').then( + m => m.TranslateBrowserLoader + ); + _TranslateLoader = await import('@ucap-webmessenger/native-electron').then( + m => m.TranslateElectronLoader + ); + + // return new TranslateBrowserLoader(nativeService, './assets/i18n/', '.json'); + return new _TranslateLoader(nativeService, './assets/i18n/', '.json'); +} + @NgModule({ - imports: [TranslateModule.forRoot({})], + imports: [ + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: createTranslateLoader, + deps: [UCAP_NATIVE_SERVICE] + } + }) + ], exports: [] }) export class AppTranslateModule {} diff --git a/projects/ucap-webmessenger-app/src/app/layouts/chat/chat.layout.module.ts b/projects/ucap-webmessenger-app/src/app/layouts/chat/chat.layout.module.ts index 6250f4e9..58c05972 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/chat/chat.layout.module.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/chat/chat.layout.module.ts @@ -7,6 +7,8 @@ import { MatTabsModule } from '@angular/material/tabs'; import { MatToolbarModule } from '@angular/material/toolbar'; import { UCapUiChatModule } from '@ucap-webmessenger/ui-chat'; +import { UCapUiGroupModule } from '@ucap-webmessenger/ui-group'; +import { UCapUiOrganizationModule } from '@ucap-webmessenger/ui-organization'; import { COMPONENTS } from './components'; @@ -17,7 +19,9 @@ import { COMPONENTS } from './components'; MatMenuModule, MatTabsModule, MatToolbarModule, - UCapUiChatModule + UCapUiChatModule, + UCapUiGroupModule, + UCapUiOrganizationModule ], exports: [...COMPONENTS], declarations: [...COMPONENTS], diff --git a/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav.component.html b/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav.component.html index ff7eb089..e17b30db 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav.component.html @@ -1,7 +1,7 @@ - + - + group @@ -9,7 +9,7 @@ - + chat @@ -17,7 +17,7 @@ - thumb_up + device_hub @@ -25,7 +25,7 @@ - thumb_up + phone diff --git a/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav/group.component.html b/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav/group.component.html index e5664964..f7b88494 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav/group.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav/group.component.html @@ -1 +1 @@ -Group + diff --git a/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav/organization.component.html b/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav/organization.component.html index 21cac3c7..ca34a27d 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav/organization.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/chat/components/left-sidenav/organization.component.html @@ -1 +1 @@ -Organization + diff --git a/projects/ucap-webmessenger-app/src/app/pages/account/components/login.page.component.ts b/projects/ucap-webmessenger-app/src/app/pages/account/components/login.page.component.ts index 2c15bd2d..24aafddd 100644 --- a/projects/ucap-webmessenger-app/src/app/pages/account/components/login.page.component.ts +++ b/projects/ucap-webmessenger-app/src/app/pages/account/components/login.page.component.ts @@ -45,7 +45,7 @@ export class LoginPageComponent implements OnInit { notValid: () => void; }) { this.store.dispatch( - AuthenticationStore.login({ + AuthenticationStore.webLogin({ loginInfo: { companyCode: value.companyCode, loginId: value.loginId, diff --git a/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.html b/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.html index dfcaaad8..bdab3e9e 100644 --- a/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.html +++ b/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.html @@ -1,4 +1,4 @@ -
+
@@ -10,7 +10,7 @@ - + diff --git a/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.scss b/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.scss index 2f5aeea7..15f62344 100644 --- a/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.scss +++ b/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.scss @@ -1,6 +1,12 @@ -#chat { +#messenger { + position: absolute; + left: 0; + right: 0; + bottom: 0; + top: 0; + height: auto !important; + .center { - padding: 32px !important; max-width: 1400px; margin: 0 auto; @@ -15,11 +21,20 @@ flex: 1; width: 100%; + .left-sidenav { + width: 300px; + } + + .right-sidenav { + width: 70px; + } + > .mat-sidenav-content, > .mat-drawer-content { display: flex; flex: 1 1 auto; min-height: 100%; + width: auto; height: auto; } diff --git a/projects/ucap-webmessenger-app/src/app/resolvers/messenger.resolver.ts b/projects/ucap-webmessenger-app/src/app/resolvers/messenger.resolver.ts index 248bc6b2..f3b5cd4c 100644 --- a/projects/ucap-webmessenger-app/src/app/resolvers/messenger.resolver.ts +++ b/projects/ucap-webmessenger-app/src/app/resolvers/messenger.resolver.ts @@ -4,8 +4,8 @@ import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; -import { Observable } from 'rxjs'; -import { take, map } from 'rxjs/operators'; +import { Observable, of } from 'rxjs'; +import { take, map, catchError } from 'rxjs/operators'; import { Store, select } from '@ngrx/store'; @@ -22,6 +22,7 @@ import { SSOMode } from '@ucap-webmessenger/protocol-authentication'; import { LocaleCode } from '@ucap-webmessenger/core'; +import * as AuthenticationStore from '@app/store/account/authentication'; @Injectable() export class AppMessengerResolver implements Resolve { @@ -59,6 +60,7 @@ export class AppMessengerResolver implements Resolve { .pipe( take(1), map(connRes => { + console.log('connRes', connRes); this.authenticationProtocolService .login({ loginId: loginInfo.loginId, @@ -82,7 +84,16 @@ export class AppMessengerResolver implements Resolve { .pipe( take(1), map(loginRes => { - console.log('loginRes', loginRes); + this.store.dispatch( + AuthenticationStore.loginSuccess({ + loginInfo: loginRes + }) + ); + }), + catchError(err => { + return of( + AuthenticationStore.loginFailure({ error: err }) + ); }) ) .subscribe(); diff --git a/projects/ucap-webmessenger-app/src/app/store/account/authentication/actions.ts b/projects/ucap-webmessenger-app/src/app/store/account/authentication/actions.ts index 28b5bcc0..1e10669f 100644 --- a/projects/ucap-webmessenger-app/src/app/store/account/authentication/actions.ts +++ b/projects/ucap-webmessenger-app/src/app/store/account/authentication/actions.ts @@ -1,19 +1,20 @@ import { createAction, props } from '@ngrx/store'; import { Login2Response } from '@ucap-webmessenger/pi'; +import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { LoginInfo } from '../../../types'; -export const login = createAction( - '[Account::Authentication] Login', +export const webLogin = createAction( + '[Account::Authentication] Web Login', props<{ loginInfo: LoginInfo; rememberMe: boolean; }>() ); -export const loginSuccess = createAction( - '[Account::Authentication] Login Success', +export const webLoginSuccess = createAction( + '[Account::Authentication] Web Login Success', props<{ loginInfo: LoginInfo; rememberMe: boolean; @@ -21,6 +22,18 @@ export const loginSuccess = createAction( }>() ); +export const webLoginFailure = createAction( + '[Account::Authentication] Web Login Failure', + props<{ error: any }>() +); + +export const loginSuccess = createAction( + '[Account::Authentication] Login Success', + props<{ + loginInfo: LoginResponse; + }>() +); + export const loginFailure = createAction( '[Account::Authentication] Login Failure', props<{ error: any }>() diff --git a/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts b/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts index b3d81cea..818aa464 100644 --- a/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts +++ b/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts @@ -20,22 +20,24 @@ import { } from '@ucap-webmessenger/ui'; import { - login, loginSuccess, loginFailure, loginRedirect, logout, logoutConfirmation, - logoutConfirmationDismiss + logoutConfirmationDismiss, + webLogin, + webLoginSuccess, + webLoginFailure } from './actions'; import { LoginInfo } from '../../../types'; import { AppAuthenticationService } from '../../../services/authentication.service'; @Injectable() export class Effects { - login$ = createEffect(() => + webLogin$ = createEffect(() => this.actions$.pipe( - ofType(login), + ofType(webLogin), map(action => action), exhaustMap((params: { loginInfo: LoginInfo; rememberMe: boolean }) => this.piService @@ -47,25 +49,25 @@ export class Effects { .pipe( map((res: Login2Response) => { if (res.status === ResponseStatus.Fail) { - return loginFailure({ error: 'Failed' }); + return webLoginFailure({ error: 'Failed' }); } else { - return loginSuccess({ + return webLoginSuccess({ loginInfo: params.loginInfo, rememberMe: params.rememberMe, login2Response: res }); } }), - catchError(error => of(loginFailure({ error }))) + catchError(error => of(webLoginFailure({ error }))) ) ) ) ); - loginSuccess$ = createEffect( + webLoginSuccess$ = createEffect( () => this.actions$.pipe( - ofType(loginSuccess), + ofType(webLoginSuccess), tap(params => { this.nativeService .checkForUpdates() diff --git a/projects/ucap-webmessenger-app/src/app/store/account/authentication/reducers.ts b/projects/ucap-webmessenger-app/src/app/store/account/authentication/reducers.ts index 28e58c6f..c67608e3 100644 --- a/projects/ucap-webmessenger-app/src/app/store/account/authentication/reducers.ts +++ b/projects/ucap-webmessenger-app/src/app/store/account/authentication/reducers.ts @@ -1,6 +1,13 @@ -import { Action, combineReducers } from '@ngrx/store'; -import { State } from './state'; +import { Action, combineReducers, createReducer, on } from '@ngrx/store'; +import { State, initialState } from './state'; +import { loginSuccess } from './actions'; -export function reducers(state: State | undefined, action: Action) { - return combineReducers({})(state, action); -} +export const reducer = createReducer( + initialState, + on(loginSuccess, (state, action) => { + return { + ...state, + loginInfo: action.loginInfo + }; + }) +); diff --git a/projects/ucap-webmessenger-app/src/app/store/account/authentication/state.ts b/projects/ucap-webmessenger-app/src/app/store/account/authentication/state.ts index aacfe4f7..579cad2a 100644 --- a/projects/ucap-webmessenger-app/src/app/store/account/authentication/state.ts +++ b/projects/ucap-webmessenger-app/src/app/store/account/authentication/state.ts @@ -1,10 +1,20 @@ -import { Selector } from '@ngrx/store'; +import { Selector, createSelector } from '@ngrx/store'; +import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; // tslint:disable-next-line: no-empty-interface -export interface State {} +export interface State { + loginInfo: LoginResponse | null; +} -export const initialState: State = {}; +export const initialState: State = { + loginInfo: null +}; export function selectors(selector: Selector) { - return {}; + return { + loginInfo: createSelector( + selector, + (state: State) => state.loginInfo + ) + }; } diff --git a/projects/ucap-webmessenger-app/src/app/store/account/index.ts b/projects/ucap-webmessenger-app/src/app/store/account/index.ts index 5cdac23a..13adc103 100644 --- a/projects/ucap-webmessenger-app/src/app/store/account/index.ts +++ b/projects/ucap-webmessenger-app/src/app/store/account/index.ts @@ -11,7 +11,7 @@ export const effects: Type[] = [AuthenticationStore.Effects]; export function reducers(state: State | undefined, action: Action) { return combineReducers({ - authentication: AuthenticationStore.reducers + authentication: AuthenticationStore.reducer })(state, action); } diff --git a/projects/ucap-webmessenger-app/src/assets/images/icons/material/style.css b/projects/ucap-webmessenger-app/src/assets/images/icons/material/style.css new file mode 100644 index 00000000..54b2004d --- /dev/null +++ b/projects/ucap-webmessenger-app/src/assets/images/icons/material/style.css @@ -0,0 +1,3074 @@ +@font-face { + font-family: 'material-outline-icons'; + src: + url('material-outline-icons.ttf?8ot508') format('truetype'), + url('material-outline-icons.woff?8ot508') format('woff'), + url('material-outline-icons.svg?8ot508#material-outline-icons') format('svg'); + font-weight: normal; + font-style: normal; +} + +i, .icomoon-liga, .material-icons { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'material-outline-icons' !important; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Enable Ligatures ================ */ + letter-spacing: 0; + -webkit-font-feature-settings: "liga"; + -moz-font-feature-settings: "liga=1"; + -moz-font-feature-settings: "liga"; + -ms-font-feature-settings: "liga" 1; + font-feature-settings: "liga"; + -webkit-font-variant-ligatures: discretionary-ligatures; + font-variant-ligatures: discretionary-ligatures; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-3d_rotation:before { + content: "\e900"; +} +.icon-4k:before { + content: "\e901"; +} +.icon-360:before { + content: "\e902"; +} +.icon-ac_unit:before { + content: "\e903"; +} +.icon-access_alarm:before { + content: "\e904"; +} +.icon-access_alarms:before { + content: "\e905"; +} +.icon-access_time:before { + content: "\e906"; +} +.icon-accessibility_new:before { + content: "\e907"; +} +.icon-accessibility:before { + content: "\e908"; +} +.icon-accessible_forward:before { + content: "\e909"; +} +.icon-accessible:before { + content: "\e90a"; +} +.icon-account_balance_wallet:before { + content: "\e90b"; +} +.icon-account_balance:before { + content: "\e90c"; +} +.icon-account_box:before { + content: "\e90d"; +} +.icon-account_circle:before { + content: "\e90e"; +} +.icon-adb:before { + content: "\e90f"; +} +.icon-add_a_photo:before { + content: "\e910"; +} +.icon-add_alarm:before { + content: "\e911"; +} +.icon-add_alert:before { + content: "\e912"; +} +.icon-add_box:before { + content: "\e913"; +} +.icon-add_circle_outline:before { + content: "\e914"; +} +.icon-add_circle:before { + content: "\e915"; +} +.icon-add_comment:before { + content: "\e916"; +} +.icon-add_location:before { + content: "\e917"; +} +.icon-add_photo_alternate:before { + content: "\e918"; +} +.icon-add_shopping_cart:before { + content: "\e919"; +} +.icon-add_to_home_screen:before { + content: "\e91a"; +} +.icon-add_to_photos:before { + content: "\e91b"; +} +.icon-add_to_queue:before { + content: "\e91c"; +} +.icon-add:before { + content: "\e91d"; +} +.icon-adjust:before { + content: "\e91e"; +} +.icon-airline_seat_flat_angled:before { + content: "\e91f"; +} +.icon-airline_seat_flat:before { + content: "\e920"; +} +.icon-airline_seat_individual_suite:before { + content: "\e921"; +} +.icon-airline_seat_legroom_extra:before { + content: "\e922"; +} +.icon-airline_seat_legroom_normal:before { + content: "\e923"; +} +.icon-airline_seat_legroom_reduced:before { + content: "\e924"; +} +.icon-airline_seat_recline_extra:before { + content: "\e925"; +} +.icon-airline_seat_recline_normal:before { + content: "\e926"; +} +.icon-airplanemode_active:before { + content: "\e927"; +} +.icon-airplanemode_inactive:before { + content: "\e928"; +} +.icon-airplay:before { + content: "\e929"; +} +.icon-airport_shuttle:before { + content: "\e92a"; +} +.icon-alarm_add:before { + content: "\e92b"; +} +.icon-alarm_off:before { + content: "\e92c"; +} +.icon-alarm_on:before { + content: "\e92d"; +} +.icon-alarm:before { + content: "\e92e"; +} +.icon-album:before { + content: "\e92f"; +} +.icon-all_inbox:before { + content: "\e930"; +} +.icon-all_inclusive:before { + content: "\e931"; +} +.icon-all_out:before { + content: "\e932"; +} +.icon-alternate_email:before { + content: "\e933"; +} +.icon-android:before { + content: "\e934"; +} +.icon-announcement:before { + content: "\e935"; +} +.icon-apps:before { + content: "\e936"; +} +.icon-archive:before { + content: "\e937"; +} +.icon-arrow_back_ios:before { + content: "\e938"; +} +.icon-arrow_back:before { + content: "\e939"; +} +.icon-arrow_downward:before { + content: "\e93a"; +} +.icon-arrow_drop_down_circle:before { + content: "\e93b"; +} +.icon-arrow_drop_down:before { + content: "\e93c"; +} +.icon-arrow_drop_up:before { + content: "\e93d"; +} +.icon-arrow_forward_ios:before { + content: "\e93e"; +} +.icon-arrow_forward:before { + content: "\e93f"; +} +.icon-arrow_left:before { + content: "\e940"; +} +.icon-arrow_right_alt:before { + content: "\e941"; +} +.icon-arrow_right:before { + content: "\e942"; +} +.icon-arrow_upward:before { + content: "\e943"; +} +.icon-art_track:before { + content: "\e944"; +} +.icon-aspect_ratio:before { + content: "\e945"; +} +.icon-assessment:before { + content: "\e946"; +} +.icon-assignment_ind:before { + content: "\e947"; +} +.icon-assignment_late:before { + content: "\e948"; +} +.icon-assignment_return:before { + content: "\e949"; +} +.icon-assignment_returned:before { + content: "\e94a"; +} +.icon-assignment_turned_in:before { + content: "\e94b"; +} +.icon-assignment:before { + content: "\e94c"; +} +.icon-assistant_photo:before { + content: "\e94d"; +} +.icon-assistant:before { + content: "\e94e"; +} +.icon-atm:before { + content: "\e94f"; +} +.icon-attach_file:before { + content: "\e950"; +} +.icon-attach_money:before { + content: "\e951"; +} +.icon-attachment:before { + content: "\e952"; +} +.icon-audiotrack:before { + content: "\e953"; +} +.icon-autorenew:before { + content: "\e954"; +} +.icon-av_timer:before { + content: "\e955"; +} +.icon-backspace:before { + content: "\e956"; +} +.icon-backup:before { + content: "\e957"; +} +.icon-ballot:before { + content: "\e958"; +} +.icon-bar_chart:before { + content: "\e959"; +} +.icon-battery_alert:before { + content: "\e95a"; +} +.icon-battery_charging_full:before { + content: "\e95b"; +} +.icon-battery_full:before { + content: "\e95c"; +} +.icon-battery_std:before { + content: "\e95d"; +} +.icon-battery_unknown:before { + content: "\e95e"; +} +.icon-beach_access:before { + content: "\e95f"; +} +.icon-beenhere:before { + content: "\e960"; +} +.icon-block:before { + content: "\e961"; +} +.icon-bluetooth_audio:before { + content: "\e962"; +} +.icon-bluetooth_connected:before { + content: "\e963"; +} +.icon-bluetooth_disabled:before { + content: "\e964"; +} +.icon-bluetooth_searching:before { + content: "\e965"; +} +.icon-bluetooth:before { + content: "\e966"; +} +.icon-blur_circular:before { + content: "\e967"; +} +.icon-blur_linear:before { + content: "\e968"; +} +.icon-blur_off:before { + content: "\e969"; +} +.icon-blur_on:before { + content: "\e96a"; +} +.icon-book:before { + content: "\e96b"; +} +.icon-bookmark_border:before { + content: "\e96c"; +} +.icon-bookmark:before { + content: "\e96d"; +} +.icon-bookmarks:before { + content: "\e96e"; +} +.icon-border_all:before { + content: "\e96f"; +} +.icon-border_bottom:before { + content: "\e970"; +} +.icon-border_clear:before { + content: "\e971"; +} +.icon-border_horizontal:before { + content: "\e972"; +} +.icon-border_inner:before { + content: "\e973"; +} +.icon-border_left:before { + content: "\e974"; +} +.icon-border_outer:before { + content: "\e975"; +} +.icon-border_right:before { + content: "\e976"; +} +.icon-border_style:before { + content: "\e977"; +} +.icon-border_top:before { + content: "\e978"; +} +.icon-border_vertical:before { + content: "\e979"; +} +.icon-branding_watermark:before { + content: "\e97a"; +} +.icon-brightness_1:before { + content: "\e97b"; +} +.icon-brightness_2:before { + content: "\e97c"; +} +.icon-brightness_3:before { + content: "\e97d"; +} +.icon-brightness_4:before { + content: "\e97e"; +} +.icon-brightness_5:before { + content: "\e97f"; +} +.icon-brightness_6:before { + content: "\e980"; +} +.icon-brightness_7:before { + content: "\e981"; +} +.icon-brightness_auto:before { + content: "\e982"; +} +.icon-brightness_high:before { + content: "\e983"; +} +.icon-brightness_low:before { + content: "\e984"; +} +.icon-brightness_medium:before { + content: "\e985"; +} +.icon-broken_image:before { + content: "\e986"; +} +.icon-brush:before { + content: "\e987"; +} +.icon-bubble_chart:before { + content: "\e988"; +} +.icon-bug_report:before { + content: "\e989"; +} +.icon-build:before { + content: "\e98a"; +} +.icon-burst_mode:before { + content: "\e98b"; +} +.icon-business_center:before { + content: "\e98c"; +} +.icon-business:before { + content: "\e98d"; +} +.icon-cached:before { + content: "\e98e"; +} +.icon-cake:before { + content: "\e98f"; +} +.icon-calendar_today:before { + content: "\e990"; +} +.icon-calendar_view_day:before { + content: "\e991"; +} +.icon-call_end:before { + content: "\e992"; +} +.icon-call_made:before { + content: "\e993"; +} +.icon-call_merge:before { + content: "\e994"; +} +.icon-call_missed_outgoing:before { + content: "\e995"; +} +.icon-call_missed:before { + content: "\e996"; +} +.icon-call_received:before { + content: "\e997"; +} +.icon-call_split:before { + content: "\e998"; +} +.icon-call_to_action:before { + content: "\e999"; +} +.icon-call:before { + content: "\e99a"; +} +.icon-camera_alt:before { + content: "\e99b"; +} +.icon-camera_enhance:before { + content: "\e99c"; +} +.icon-camera_front:before { + content: "\e99d"; +} +.icon-camera_rear:before { + content: "\e99e"; +} +.icon-camera_roll:before { + content: "\e99f"; +} +.icon-camera:before { + content: "\e9a0"; +} +.icon-cancel_presentation:before { + content: "\e9a1"; +} +.icon-cancel:before { + content: "\e9a2"; +} +.icon-card_giftcard:before { + content: "\e9a3"; +} +.icon-card_membership:before { + content: "\e9a4"; +} +.icon-card_travel:before { + content: "\e9a5"; +} +.icon-casino:before { + content: "\e9a6"; +} +.icon-cast_connected:before { + content: "\e9a7"; +} +.icon-cast_for_education:before { + content: "\e9a8"; +} +.icon-cast:before { + content: "\e9a9"; +} +.icon-category:before { + content: "\e9aa"; +} +.icon-center_focus_strong:before { + content: "\e9ab"; +} +.icon-center_focus_weak:before { + content: "\e9ac"; +} +.icon-change_history:before { + content: "\e9ad"; +} +.icon-chat_bubble_outline:before { + content: "\e9ae"; +} +.icon-chat_bubble:before { + content: "\e9af"; +} +.icon-chat:before { + content: "\e9b0"; +} +.icon-check_box_outline_blank:before { + content: "\e9b1"; +} +.icon-check_box:before { + content: "\e9b2"; +} +.icon-check_circle_outline:before { + content: "\e9b3"; +} +.icon-check_circle:before { + content: "\e9b4"; +} +.icon-check:before { + content: "\e9b5"; +} +.icon-chevron_left:before { + content: "\e9b6"; +} +.icon-chevron_right:before { + content: "\e9b7"; +} +.icon-child_care:before { + content: "\e9b8"; +} +.icon-child_friendly:before { + content: "\e9b9"; +} +.icon-chrome_reader_mode:before { + content: "\e9ba"; +} +.icon-class:before { + content: "\e9bb"; +} +.icon-clear_all:before { + content: "\e9bc"; +} +.icon-clear:before { + content: "\e9bd"; +} +.icon-close:before { + content: "\e9be"; +} +.icon-closed_caption:before { + content: "\e9bf"; +} +.icon-cloud_circle:before { + content: "\e9c0"; +} +.icon-cloud_done:before { + content: "\e9c1"; +} +.icon-cloud_download:before { + content: "\e9c2"; +} +.icon-cloud_off:before { + content: "\e9c3"; +} +.icon-cloud_queue:before { + content: "\e9c4"; +} +.icon-cloud_upload:before { + content: "\e9c5"; +} +.icon-cloud:before { + content: "\e9c6"; +} +.icon-code:before { + content: "\e9c7"; +} +.icon-collections_bookmark:before { + content: "\e9c8"; +} +.icon-collections:before { + content: "\e9c9"; +} +.icon-color_lens:before { + content: "\e9ca"; +} +.icon-colorize:before { + content: "\e9cb"; +} +.icon-comment:before { + content: "\e9cc"; +} +.icon-commute:before { + content: "\e9cd"; +} +.icon-compare_arrows:before { + content: "\e9ce"; +} +.icon-compare:before { + content: "\e9cf"; +} +.icon-compass_calibration:before { + content: "\e9d0"; +} +.icon-computer:before { + content: "\e9d1"; +} +.icon-confirmation_number:before { + content: "\e9d2"; +} +.icon-contact_mail:before { + content: "\e9d3"; +} +.icon-contact_phone:before { + content: "\e9d4"; +} +.icon-contact_support:before { + content: "\e9d5"; +} +.icon-contacts:before { + content: "\e9d6"; +} +.icon-control_camera:before { + content: "\e9d7"; +} +.icon-control_point_duplicate:before { + content: "\e9d8"; +} +.icon-control_point:before { + content: "\e9d9"; +} +.icon-copyright:before { + content: "\e9da"; +} +.icon-create_new_folder:before { + content: "\e9db"; +} +.icon-create:before { + content: "\e9dc"; +} +.icon-credit_card:before { + content: "\e9dd"; +} +.icon-crop_3_2:before { + content: "\e9de"; +} +.icon-crop_5_4:before { + content: "\e9df"; +} +.icon-crop_7_5:before { + content: "\e9e0"; +} +.icon-crop_16_9:before { + content: "\e9e1"; +} +.icon-crop_din:before { + content: "\e9e2"; +} +.icon-crop_free:before { + content: "\e9e3"; +} +.icon-crop_landscape:before { + content: "\e9e4"; +} +.icon-crop_original:before { + content: "\e9e5"; +} +.icon-crop_portrait:before { + content: "\e9e6"; +} +.icon-crop_rotate:before { + content: "\e9e7"; +} +.icon-crop_square:before { + content: "\e9e8"; +} +.icon-crop:before { + content: "\e9e9"; +} +.icon-dashboard:before { + content: "\e9ea"; +} +.icon-data_usage:before { + content: "\e9eb"; +} +.icon-date_range:before { + content: "\e9ec"; +} +.icon-dehaze:before { + content: "\e9ed"; +} +.icon-delete_forever:before { + content: "\e9ee"; +} +.icon-delete_outline:before { + content: "\e9ef"; +} +.icon-delete_sweep:before { + content: "\e9f0"; +} +.icon-delete:before { + content: "\e9f1"; +} +.icon-departure_board:before { + content: "\e9f2"; +} +.icon-description:before { + content: "\e9f3"; +} +.icon-desktop_access_disabled:before { + content: "\e9f4"; +} +.icon-desktop_mac:before { + content: "\e9f5"; +} +.icon-desktop_windows:before { + content: "\e9f6"; +} +.icon-details:before { + content: "\e9f7"; +} +.icon-developer_board:before { + content: "\e9f8"; +} +.icon-developer_mode:before { + content: "\e9f9"; +} +.icon-device_hub:before { + content: "\e9fa"; +} +.icon-device_unknown:before { + content: "\e9fb"; +} +.icon-devices_other:before { + content: "\e9fc"; +} +.icon-devices:before { + content: "\e9fd"; +} +.icon-dialer_sip:before { + content: "\e9fe"; +} +.icon-dialpad:before { + content: "\e9ff"; +} +.icon-directions_bike:before { + content: "\ea00"; +} +.icon-directions_boat:before { + content: "\ea01"; +} +.icon-directions_bus:before { + content: "\ea02"; +} +.icon-directions_car:before { + content: "\ea03"; +} +.icon-directions_railway:before { + content: "\ea04"; +} +.icon-directions_run:before { + content: "\ea05"; +} +.icon-directions_subway:before { + content: "\ea06"; +} +.icon-directions_transit:before { + content: "\ea07"; +} +.icon-directions_walk:before { + content: "\ea08"; +} +.icon-directions:before { + content: "\ea09"; +} +.icon-disc_full:before { + content: "\ea0a"; +} +.icon-dns:before { + content: "\ea0b"; +} +.icon-dock:before { + content: "\ea0c"; +} +.icon-domain_disabled:before { + content: "\ea0d"; +} +.icon-domain:before { + content: "\ea0e"; +} +.icon-done_all:before { + content: "\ea0f"; +} +.icon-done_outline:before { + content: "\ea10"; +} +.icon-done:before { + content: "\ea11"; +} +.icon-donut_large:before { + content: "\ea12"; +} +.icon-donut_small:before { + content: "\ea13"; +} +.icon-drafts:before { + content: "\ea14"; +} +.icon-drag_handle:before { + content: "\ea15"; +} +.icon-drag_indicator:before { + content: "\ea16"; +} +.icon-drive_eta:before { + content: "\ea17"; +} +.icon-duo:before { + content: "\ea18"; +} +.icon-dvr:before { + content: "\ea19"; +} +.icon-edit_attributes:before { + content: "\ea1a"; +} +.icon-edit_location:before { + content: "\ea1b"; +} +.icon-edit:before { + content: "\ea1c"; +} +.icon-eject:before { + content: "\ea1d"; +} +.icon-email:before { + content: "\ea1e"; +} +.icon-enhanced_encryption:before { + content: "\ea1f"; +} +.icon-equalizer:before { + content: "\ea20"; +} +.icon-error_outline:before { + content: "\ea21"; +} +.icon-error:before { + content: "\ea22"; +} +.icon-euro_symbol:before { + content: "\ea23"; +} +.icon-ev_station:before { + content: "\ea24"; +} +.icon-event_available:before { + content: "\ea25"; +} +.icon-event_busy:before { + content: "\ea26"; +} +.icon-event_note:before { + content: "\ea27"; +} +.icon-event_seat:before { + content: "\ea28"; +} +.icon-event:before { + content: "\ea29"; +} +.icon-exit_to_app:before { + content: "\ea2a"; +} +.icon-expand_less:before { + content: "\ea2b"; +} +.icon-expand_more:before { + content: "\ea2c"; +} +.icon-explicit:before { + content: "\ea2d"; +} +.icon-explore_off:before { + content: "\ea2e"; +} +.icon-explore:before { + content: "\ea2f"; +} +.icon-exposure_neg_1:before { + content: "\ea30"; +} +.icon-exposure_neg_2:before { + content: "\ea31"; +} +.icon-exposure_plus_1:before { + content: "\ea32"; +} +.icon-exposure_plus_2:before { + content: "\ea33"; +} +.icon-exposure_zero:before { + content: "\ea34"; +} +.icon-exposure:before { + content: "\ea35"; +} +.icon-extension:before { + content: "\ea36"; +} +.icon-face:before { + content: "\ea37"; +} +.icon-fast_forward:before { + content: "\ea38"; +} +.icon-fast_rewind:before { + content: "\ea39"; +} +.icon-fastfood:before { + content: "\ea3a"; +} +.icon-favorite_border:before { + content: "\ea3b"; +} +.icon-favorite:before { + content: "\ea3c"; +} +.icon-featured_play_list:before { + content: "\ea3d"; +} +.icon-featured_video:before { + content: "\ea3e"; +} +.icon-feedback:before { + content: "\ea3f"; +} +.icon-fiber_dvr:before { + content: "\ea40"; +} +.icon-fiber_manual_record:before { + content: "\ea41"; +} +.icon-fiber_new:before { + content: "\ea42"; +} +.icon-fiber_pin:before { + content: "\ea43"; +} +.icon-fiber_smart_record:before { + content: "\ea44"; +} +.icon-file_copy:before { + content: "\ea45"; +} +.icon-filter_1:before { + content: "\ea46"; +} +.icon-filter_2:before { + content: "\ea47"; +} +.icon-filter_3:before { + content: "\ea48"; +} +.icon-filter_4:before { + content: "\ea49"; +} +.icon-filter_5:before { + content: "\ea4a"; +} +.icon-filter_6:before { + content: "\ea4b"; +} +.icon-filter_7:before { + content: "\ea4c"; +} +.icon-filter_8:before { + content: "\ea4d"; +} +.icon-filter_9_plus:before { + content: "\ea4e"; +} +.icon-filter_9:before { + content: "\ea4f"; +} +.icon-filter_b_and_w:before { + content: "\ea50"; +} +.icon-filter_center_focus:before { + content: "\ea51"; +} +.icon-filter_drama:before { + content: "\ea52"; +} +.icon-filter_frames:before { + content: "\ea53"; +} +.icon-filter_hdr:before { + content: "\ea54"; +} +.icon-filter_list:before { + content: "\ea55"; +} +.icon-filter_none:before { + content: "\ea56"; +} +.icon-filter_tilt_shift:before { + content: "\ea57"; +} +.icon-filter_vintage:before { + content: "\ea58"; +} +.icon-filter:before { + content: "\ea59"; +} +.icon-find_in_page:before { + content: "\ea5a"; +} +.icon-find_replace:before { + content: "\ea5b"; +} +.icon-fingerprint:before { + content: "\ea5c"; +} +.icon-first_page:before { + content: "\ea5d"; +} +.icon-fitness_center:before { + content: "\ea5e"; +} +.icon-flag:before { + content: "\ea5f"; +} +.icon-flare:before { + content: "\ea60"; +} +.icon-flash_auto:before { + content: "\ea61"; +} +.icon-flash_off:before { + content: "\ea62"; +} +.icon-flash_on:before { + content: "\ea63"; +} +.icon-flight_land:before { + content: "\ea64"; +} +.icon-flight_takeoff:before { + content: "\ea65"; +} +.icon-flight:before { + content: "\ea66"; +} +.icon-flip_to_back:before { + content: "\ea67"; +} +.icon-flip_to_front:before { + content: "\ea68"; +} +.icon-flip:before { + content: "\ea69"; +} +.icon-folder_open:before { + content: "\ea6a"; +} +.icon-folder_shared:before { + content: "\ea6b"; +} +.icon-folder_special:before { + content: "\ea6c"; +} +.icon-folder:before { + content: "\ea6d"; +} +.icon-font_download:before { + content: "\ea6e"; +} +.icon-format_align_center:before { + content: "\ea6f"; +} +.icon-format_align_justify:before { + content: "\ea70"; +} +.icon-format_align_left:before { + content: "\ea71"; +} +.icon-format_align_right:before { + content: "\ea72"; +} +.icon-format_bold:before { + content: "\ea73"; +} +.icon-format_clear:before { + content: "\ea74"; +} +.icon-format_color_reset:before { + content: "\ea75"; +} +.icon-format_indent_decrease:before { + content: "\ea76"; +} +.icon-format_indent_increase:before { + content: "\ea77"; +} +.icon-format_italic:before { + content: "\ea78"; +} +.icon-format_line_spacing:before { + content: "\ea79"; +} +.icon-format_list_bulleted:before { + content: "\ea7a"; +} +.icon-format_list_numbered_rtl:before { + content: "\ea7b"; +} +.icon-format_list_numbered:before { + content: "\ea7c"; +} +.icon-format_paint:before { + content: "\ea7d"; +} +.icon-format_quote:before { + content: "\ea7e"; +} +.icon-format_shapes:before { + content: "\ea7f"; +} +.icon-format_size:before { + content: "\ea80"; +} +.icon-format_strikethrough:before { + content: "\ea81"; +} +.icon-format_textdirection_l_to_r:before { + content: "\ea82"; +} +.icon-format_textdirection_r_to_l:before { + content: "\ea83"; +} +.icon-format_underlined:before { + content: "\ea84"; +} +.icon-forum:before { + content: "\ea85"; +} +.icon-forward_5:before { + content: "\ea86"; +} +.icon-forward_10:before { + content: "\ea87"; +} +.icon-forward_30:before { + content: "\ea88"; +} +.icon-forward:before { + content: "\ea89"; +} +.icon-free_breakfast:before { + content: "\ea8a"; +} +.icon-fullscreen_exit:before { + content: "\ea8b"; +} +.icon-fullscreen:before { + content: "\ea8c"; +} +.icon-functions:before { + content: "\ea8d"; +} +.icon-g_translate:before { + content: "\ea8e"; +} +.icon-gamepad:before { + content: "\ea8f"; +} +.icon-games:before { + content: "\ea90"; +} +.icon-gavel:before { + content: "\ea91"; +} +.icon-gesture:before { + content: "\ea92"; +} +.icon-get_app:before { + content: "\ea93"; +} +.icon-gif:before { + content: "\ea94"; +} +.icon-golf_course:before { + content: "\ea95"; +} +.icon-gps_fixed:before { + content: "\ea96"; +} +.icon-gps_not_fixed:before { + content: "\ea97"; +} +.icon-gps_off:before { + content: "\ea98"; +} +.icon-grade:before { + content: "\ea99"; +} +.icon-gradient:before { + content: "\ea9a"; +} +.icon-grain:before { + content: "\ea9b"; +} +.icon-graphic_eq:before { + content: "\ea9c"; +} +.icon-grid_off:before { + content: "\ea9d"; +} +.icon-grid_on:before { + content: "\ea9e"; +} +.icon-group_add:before { + content: "\ea9f"; +} +.icon-group_work:before { + content: "\eaa0"; +} +.icon-group:before { + content: "\eaa1"; +} +.icon-hd:before { + content: "\eaa2"; +} +.icon-hdr_off:before { + content: "\eaa3"; +} +.icon-hdr_on:before { + content: "\eaa4"; +} +.icon-hdr_strong:before { + content: "\eaa5"; +} +.icon-hdr_weak:before { + content: "\eaa6"; +} +.icon-headset_mic:before { + content: "\eaa7"; +} +.icon-headset:before { + content: "\eaa8"; +} +.icon-healing:before { + content: "\eaa9"; +} +.icon-hearing:before { + content: "\eaaa"; +} +.icon-help_outline:before { + content: "\eaab"; +} +.icon-help:before { + content: "\eaac"; +} +.icon-high_quality:before { + content: "\eaad"; +} +.icon-highlight_off:before { + content: "\eaae"; +} +.icon-highlight:before { + content: "\eaaf"; +} +.icon-history:before { + content: "\eab0"; +} +.icon-home:before { + content: "\eab1"; +} +.icon-horizontal_split:before { + content: "\eab2"; +} +.icon-hot_tub:before { + content: "\eab3"; +} +.icon-hotel:before { + content: "\eab4"; +} +.icon-hourglass_empty:before { + content: "\eab5"; +} +.icon-hourglass_full:before { + content: "\eab6"; +} +.icon-how_to_reg:before { + content: "\eab7"; +} +.icon-how_to_vote:before { + content: "\eab8"; +} +.icon-http:before { + content: "\eab9"; +} +.icon-https:before { + content: "\eaba"; +} +.icon-image_aspect_ratio:before { + content: "\eabb"; +} +.icon-image_search:before { + content: "\eabc"; +} +.icon-image:before { + content: "\eabd"; +} +.icon-import_contacts:before { + content: "\eabe"; +} +.icon-import_export:before { + content: "\eabf"; +} +.icon-important_devices:before { + content: "\eac0"; +} +.icon-inbox:before { + content: "\eac1"; +} +.icon-indeterminate_check_box:before { + content: "\eac2"; +} +.icon-info:before { + content: "\eac3"; +} +.icon-input:before { + content: "\eac4"; +} +.icon-insert_chart_outlined:before { + content: "\eac5"; +} +.icon-insert_chart:before { + content: "\eac6"; +} +.icon-insert_comment:before { + content: "\eac7"; +} +.icon-insert_drive_file:before { + content: "\eac8"; +} +.icon-insert_emoticon:before { + content: "\eac9"; +} +.icon-insert_invitation:before { + content: "\eaca"; +} +.icon-insert_link:before { + content: "\eacb"; +} +.icon-insert_photo:before { + content: "\eacc"; +} +.icon-invert_colors_off:before { + content: "\eacd"; +} +.icon-invert_colors:before { + content: "\eace"; +} +.icon-iso:before { + content: "\eacf"; +} +.icon-keyboard_arrow_down:before { + content: "\ead0"; +} +.icon-keyboard_arrow_left:before { + content: "\ead1"; +} +.icon-keyboard_arrow_right:before { + content: "\ead2"; +} +.icon-keyboard_arrow_up:before { + content: "\ead3"; +} +.icon-keyboard_backspace:before { + content: "\ead4"; +} +.icon-keyboard_capslock:before { + content: "\ead5"; +} +.icon-keyboard_hide:before { + content: "\ead6"; +} +.icon-keyboard_return:before { + content: "\ead7"; +} +.icon-keyboard_tab:before { + content: "\ead8"; +} +.icon-keyboard_voice:before { + content: "\ead9"; +} +.icon-keyboard:before { + content: "\eada"; +} +.icon-kitchen:before { + content: "\eadb"; +} +.icon-label_important:before { + content: "\eadc"; +} +.icon-label_off:before { + content: "\eadd"; +} +.icon-label:before { + content: "\eade"; +} +.icon-landscape:before { + content: "\eadf"; +} +.icon-language:before { + content: "\eae0"; +} +.icon-laptop_chromebook:before { + content: "\eae1"; +} +.icon-laptop_mac:before { + content: "\eae2"; +} +.icon-laptop_windows:before { + content: "\eae3"; +} +.icon-laptop:before { + content: "\eae4"; +} +.icon-last_page:before { + content: "\eae5"; +} +.icon-launch:before { + content: "\eae6"; +} +.icon-layers_clear:before { + content: "\eae7"; +} +.icon-layers:before { + content: "\eae8"; +} +.icon-leak_add:before { + content: "\eae9"; +} +.icon-leak_remove:before { + content: "\eaea"; +} +.icon-lens:before { + content: "\eaeb"; +} +.icon-library_add:before { + content: "\eaec"; +} +.icon-library_books:before { + content: "\eaed"; +} +.icon-library_music:before { + content: "\eaee"; +} +.icon-line_style:before { + content: "\eaef"; +} +.icon-line_weight:before { + content: "\eaf0"; +} +.icon-linear_scale:before { + content: "\eaf1"; +} +.icon-link_off:before { + content: "\eaf2"; +} +.icon-link:before { + content: "\eaf3"; +} +.icon-linked_camera:before { + content: "\eaf4"; +} +.icon-list_alt:before { + content: "\eaf5"; +} +.icon-list:before { + content: "\eaf6"; +} +.icon-live_help:before { + content: "\eaf7"; +} +.icon-live_tv:before { + content: "\eaf8"; +} +.icon-local_activity:before { + content: "\eaf9"; +} +.icon-local_airport:before { + content: "\eafa"; +} +.icon-local_atm:before { + content: "\eafb"; +} +.icon-local_bar:before { + content: "\eafc"; +} +.icon-local_cafe:before { + content: "\eafd"; +} +.icon-local_car_wash:before { + content: "\eafe"; +} +.icon-local_convenience_store:before { + content: "\eaff"; +} +.icon-local_dining:before { + content: "\eb00"; +} +.icon-local_drink:before { + content: "\eb01"; +} +.icon-local_florist:before { + content: "\eb02"; +} +.icon-local_gas_station:before { + content: "\eb03"; +} +.icon-local_grocery_store:before { + content: "\eb04"; +} +.icon-local_hospital:before { + content: "\eb05"; +} +.icon-local_hotel:before { + content: "\eb06"; +} +.icon-local_laundry_service:before { + content: "\eb07"; +} +.icon-local_library:before { + content: "\eb08"; +} +.icon-local_mall:before { + content: "\eb09"; +} +.icon-local_movies:before { + content: "\eb0a"; +} +.icon-local_offer:before { + content: "\eb0b"; +} +.icon-local_parking:before { + content: "\eb0c"; +} +.icon-local_pharmacy:before { + content: "\eb0d"; +} +.icon-local_phone:before { + content: "\eb0e"; +} +.icon-local_pizza:before { + content: "\eb0f"; +} +.icon-local_play:before { + content: "\eb10"; +} +.icon-local_post_office:before { + content: "\eb11"; +} +.icon-local_printshop:before { + content: "\eb12"; +} +.icon-local_see:before { + content: "\eb13"; +} +.icon-local_shipping:before { + content: "\eb14"; +} +.icon-local_taxi:before { + content: "\eb15"; +} +.icon-location_city:before { + content: "\eb16"; +} +.icon-location_disabled:before { + content: "\eb17"; +} +.icon-location_off:before { + content: "\eb18"; +} +.icon-location_on:before { + content: "\eb19"; +} +.icon-location_searching:before { + content: "\eb1a"; +} +.icon-lock_open:before { + content: "\eb1b"; +} +.icon-lock:before { + content: "\eb1c"; +} +.icon-looks_3:before { + content: "\eb1d"; +} +.icon-looks_4:before { + content: "\eb1e"; +} +.icon-looks_5:before { + content: "\eb1f"; +} +.icon-looks_6:before { + content: "\eb20"; +} +.icon-looks_one:before { + content: "\eb21"; +} +.icon-looks_two:before { + content: "\eb22"; +} +.icon-looks:before { + content: "\eb23"; +} +.icon-loop:before { + content: "\eb24"; +} +.icon-loupe:before { + content: "\eb25"; +} +.icon-low_priority:before { + content: "\eb26"; +} +.icon-loyalty:before { + content: "\eb27"; +} +.icon-mail_outline:before { + content: "\eb28"; +} +.icon-mail:before { + content: "\eb29"; +} +.icon-map:before { + content: "\eb2a"; +} +.icon-markunread_mailbox:before { + content: "\eb2b"; +} +.icon-markunread:before { + content: "\eb2c"; +} +.icon-maximize:before { + content: "\eb2d"; +} +.icon-meeting_room:before { + content: "\eb2e"; +} +.icon-memory:before { + content: "\eb2f"; +} +.icon-menu:before { + content: "\eb30"; +} +.icon-merge_type:before { + content: "\eb31"; +} +.icon-message:before { + content: "\eb32"; +} +.icon-mic_none:before { + content: "\eb33"; +} +.icon-mic_off:before { + content: "\eb34"; +} +.icon-mic:before { + content: "\eb35"; +} +.icon-minimize:before { + content: "\eb36"; +} +.icon-missed_video_call:before { + content: "\eb37"; +} +.icon-mms:before { + content: "\eb38"; +} +.icon-mobile_friendly:before { + content: "\eb39"; +} +.icon-mobile_off:before { + content: "\eb3a"; +} +.icon-mobile_screen_share:before { + content: "\eb3b"; +} +.icon-mode_comment:before { + content: "\eb3c"; +} +.icon-monetization_on:before { + content: "\eb3d"; +} +.icon-money_off:before { + content: "\eb3e"; +} +.icon-money:before { + content: "\eb3f"; +} +.icon-monochrome_photos:before { + content: "\eb40"; +} +.icon-mood_bad:before { + content: "\eb41"; +} +.icon-mood:before { + content: "\eb42"; +} +.icon-more_horiz:before { + content: "\eb43"; +} +.icon-more_vert:before { + content: "\eb44"; +} +.icon-more:before { + content: "\eb45"; +} +.icon-motorcycle:before { + content: "\eb46"; +} +.icon-mouse:before { + content: "\eb47"; +} +.icon-move_to_inbox:before { + content: "\eb48"; +} +.icon-movie_creation:before { + content: "\eb49"; +} +.icon-movie_filter:before { + content: "\eb4a"; +} +.icon-movie:before { + content: "\eb4b"; +} +.icon-multiline_chart:before { + content: "\eb4c"; +} +.icon-music_note:before { + content: "\eb4d"; +} +.icon-music_off:before { + content: "\eb4e"; +} +.icon-music_video:before { + content: "\eb4f"; +} +.icon-my_location:before { + content: "\eb50"; +} +.icon-nature_people:before { + content: "\eb51"; +} +.icon-nature:before { + content: "\eb52"; +} +.icon-navigate_before:before { + content: "\eb53"; +} +.icon-navigate_next:before { + content: "\eb54"; +} +.icon-navigation:before { + content: "\eb55"; +} +.icon-near_me:before { + content: "\eb56"; +} +.icon-network_check:before { + content: "\eb57"; +} +.icon-network_locked:before { + content: "\eb58"; +} +.icon-new_releases:before { + content: "\eb59"; +} +.icon-next_week:before { + content: "\eb5a"; +} +.icon-nfc:before { + content: "\eb5b"; +} +.icon-no_encryption:before { + content: "\eb5c"; +} +.icon-no_meeting_room:before { + content: "\eb5d"; +} +.icon-no_sim:before { + content: "\eb5e"; +} +.icon-not_interested:before { + content: "\eb5f"; +} +.icon-not_listed_location:before { + content: "\eb60"; +} +.icon-note_add:before { + content: "\eb61"; +} +.icon-note:before { + content: "\eb62"; +} +.icon-notes:before { + content: "\eb63"; +} +.icon-notification_important:before { + content: "\eb64"; +} +.icon-notifications_active:before { + content: "\eb65"; +} +.icon-notifications_none:before { + content: "\eb66"; +} +.icon-notifications_off:before { + content: "\eb67"; +} +.icon-notifications_paused:before { + content: "\eb68"; +} +.icon-notifications:before { + content: "\eb69"; +} +.icon-offline_bolt:before { + content: "\eb6a"; +} +.icon-offline_pin:before { + content: "\eb6b"; +} +.icon-ondemand_video:before { + content: "\eb6c"; +} +.icon-opacity:before { + content: "\eb6d"; +} +.icon-open_in_browser:before { + content: "\eb6e"; +} +.icon-open_in_new:before { + content: "\eb6f"; +} +.icon-open_with:before { + content: "\eb70"; +} +.icon-outlined_flag:before { + content: "\eb71"; +} +.icon-pages:before { + content: "\eb72"; +} +.icon-pageview:before { + content: "\eb73"; +} +.icon-palette:before { + content: "\eb74"; +} +.icon-pan_tool:before { + content: "\eb75"; +} +.icon-panorama_fish_eye:before { + content: "\eb76"; +} +.icon-panorama_horizontal:before { + content: "\eb77"; +} +.icon-panorama_vertical:before { + content: "\eb78"; +} +.icon-panorama_wide_angle:before { + content: "\eb79"; +} +.icon-panorama:before { + content: "\eb7a"; +} +.icon-party_mode:before { + content: "\eb7b"; +} +.icon-pause_circle_filled:before { + content: "\eb7c"; +} +.icon-pause_circle_outline:before { + content: "\eb7d"; +} +.icon-pause_presentation:before { + content: "\eb7e"; +} +.icon-pause:before { + content: "\eb7f"; +} +.icon-payment:before { + content: "\eb80"; +} +.icon-people_outline:before { + content: "\eb81"; +} +.icon-people:before { + content: "\eb82"; +} +.icon-perm_camera_mic:before { + content: "\eb83"; +} +.icon-perm_contact_calendar:before { + content: "\eb84"; +} +.icon-perm_data_setting:before { + content: "\eb85"; +} +.icon-perm_device_information:before { + content: "\eb86"; +} +.icon-perm_identity:before { + content: "\eb87"; +} +.icon-perm_media:before { + content: "\eb88"; +} +.icon-perm_phone_msg:before { + content: "\eb89"; +} +.icon-perm_scan_wifi:before { + content: "\eb8a"; +} +.icon-person_add_disabled:before { + content: "\eb8b"; +} +.icon-person_add:before { + content: "\eb8c"; +} +.icon-person_outline:before { + content: "\eb8d"; +} +.icon-person_pin_circle:before { + content: "\eb8e"; +} +.icon-person_pin:before { + content: "\eb8f"; +} +.icon-person:before { + content: "\eb90"; +} +.icon-personal_video:before { + content: "\eb91"; +} +.icon-pets:before { + content: "\eb92"; +} +.icon-phone_android:before { + content: "\eb93"; +} +.icon-phone_bluetooth_speaker:before { + content: "\eb94"; +} +.icon-phone_callback:before { + content: "\eb95"; +} +.icon-phone_forwarded:before { + content: "\eb96"; +} +.icon-phone_in_talk:before { + content: "\eb97"; +} +.icon-phone_iphone:before { + content: "\eb98"; +} +.icon-phone_locked:before { + content: "\eb99"; +} +.icon-phone_missed:before { + content: "\eb9a"; +} +.icon-phone_paused:before { + content: "\eb9b"; +} +.icon-phone:before { + content: "\eb9c"; +} +.icon-phonelink_erase:before { + content: "\eb9d"; +} +.icon-phonelink_lock:before { + content: "\eb9e"; +} +.icon-phonelink_off:before { + content: "\eb9f"; +} +.icon-phonelink_ring:before { + content: "\eba0"; +} +.icon-phonelink_setup:before { + content: "\eba1"; +} +.icon-phonelink:before { + content: "\eba2"; +} +.icon-photo_album:before { + content: "\eba3"; +} +.icon-photo_camera:before { + content: "\eba4"; +} +.icon-photo_filter:before { + content: "\eba5"; +} +.icon-photo_library:before { + content: "\eba6"; +} +.icon-photo_size_select_actual:before { + content: "\eba7"; +} +.icon-photo_size_select_large:before { + content: "\eba8"; +} +.icon-photo_size_select_small:before { + content: "\eba9"; +} +.icon-photo:before { + content: "\ebaa"; +} +.icon-picture_as_pdf:before { + content: "\ebab"; +} +.icon-picture_in_picture_alt:before { + content: "\ebac"; +} +.icon-picture_in_picture:before { + content: "\ebad"; +} +.icon-pie_chart:before { + content: "\ebae"; +} +.icon-pin_drop:before { + content: "\ebaf"; +} +.icon-place:before { + content: "\ebb0"; +} +.icon-play_arrow:before { + content: "\ebb1"; +} +.icon-play_circle_filled_white:before { + content: "\ebb2"; +} +.icon-play_circle_filled:before { + content: "\ebb3"; +} +.icon-play_circle_outline:before { + content: "\ebb4"; +} +.icon-play_for_work:before { + content: "\ebb5"; +} +.icon-playlist_add_check:before { + content: "\ebb6"; +} +.icon-playlist_add:before { + content: "\ebb7"; +} +.icon-playlist_play:before { + content: "\ebb8"; +} +.icon-plus_one:before { + content: "\ebb9"; +} +.icon-poll:before { + content: "\ebba"; +} +.icon-polymer:before { + content: "\ebbb"; +} +.icon-pool:before { + content: "\ebbc"; +} +.icon-portable_wifi_off:before { + content: "\ebbd"; +} +.icon-portrait:before { + content: "\ebbe"; +} +.icon-power_input:before { + content: "\ebbf"; +} +.icon-power_off:before { + content: "\ebc0"; +} +.icon-power_settings_new:before { + content: "\ebc1"; +} +.icon-power:before { + content: "\ebc2"; +} +.icon-pregnant_woman:before { + content: "\ebc3"; +} +.icon-present_to_all:before { + content: "\ebc4"; +} +.icon-print_disabled:before { + content: "\ebc5"; +} +.icon-print:before { + content: "\ebc6"; +} +.icon-priority_high:before { + content: "\ebc7"; +} +.icon-public:before { + content: "\ebc8"; +} +.icon-publish:before { + content: "\ebc9"; +} +.icon-query_builder:before { + content: "\ebca"; +} +.icon-question_answer:before { + content: "\ebcb"; +} +.icon-queue_music:before { + content: "\ebcc"; +} +.icon-queue_play_next:before { + content: "\ebcd"; +} +.icon-queue:before { + content: "\ebce"; +} +.icon-radio_button_checked:before { + content: "\ebcf"; +} +.icon-radio_button_unchecked:before { + content: "\ebd0"; +} +.icon-radio:before { + content: "\ebd1"; +} +.icon-rate_review:before { + content: "\ebd2"; +} +.icon-receipt:before { + content: "\ebd3"; +} +.icon-recent_actors:before { + content: "\ebd4"; +} +.icon-record_voice_over:before { + content: "\ebd5"; +} +.icon-redeem:before { + content: "\ebd6"; +} +.icon-redo:before { + content: "\ebd7"; +} +.icon-refresh:before { + content: "\ebd8"; +} +.icon-remove_circle_outline:before { + content: "\ebd9"; +} +.icon-remove_circle:before { + content: "\ebda"; +} +.icon-remove_from_queue:before { + content: "\ebdb"; +} +.icon-remove_red_eye:before { + content: "\ebdc"; +} +.icon-remove_shopping_cart:before { + content: "\ebdd"; +} +.icon-remove:before { + content: "\ebde"; +} +.icon-reorder:before { + content: "\ebdf"; +} +.icon-repeat_one:before { + content: "\ebe0"; +} +.icon-repeat:before { + content: "\ebe1"; +} +.icon-replay_5:before { + content: "\ebe2"; +} +.icon-replay_10:before { + content: "\ebe3"; +} +.icon-replay_30:before { + content: "\ebe4"; +} +.icon-replay:before { + content: "\ebe5"; +} +.icon-reply_all:before { + content: "\ebe6"; +} +.icon-reply:before { + content: "\ebe7"; +} +.icon-report_off:before { + content: "\ebe8"; +} +.icon-report_problem:before { + content: "\ebe9"; +} +.icon-report:before { + content: "\ebea"; +} +.icon-restaurant_menu:before { + content: "\ebeb"; +} +.icon-restaurant:before { + content: "\ebec"; +} +.icon-restore_from_trash:before { + content: "\ebed"; +} +.icon-restore_page:before { + content: "\ebee"; +} +.icon-restore:before { + content: "\ebef"; +} +.icon-ring_volume:before { + content: "\ebf0"; +} +.icon-room_service:before { + content: "\ebf1"; +} +.icon-room:before { + content: "\ebf2"; +} +.icon-rotate_90_degrees_ccw:before { + content: "\ebf3"; +} +.icon-rotate_left:before { + content: "\ebf4"; +} +.icon-rotate_right:before { + content: "\ebf5"; +} +.icon-rounded_corner:before { + content: "\ebf6"; +} +.icon-router:before { + content: "\ebf7"; +} +.icon-rowing:before { + content: "\ebf8"; +} +.icon-rss_feed:before { + content: "\ebf9"; +} +.icon-rv_hookup:before { + content: "\ebfa"; +} +.icon-satellite:before { + content: "\ebfb"; +} +.icon-save_alt:before { + content: "\ebfc"; +} +.icon-save:before { + content: "\ebfd"; +} +.icon-scanner:before { + content: "\ebfe"; +} +.icon-scatter_plot:before { + content: "\ebff"; +} +.icon-schedule:before { + content: "\ec00"; +} +.icon-school:before { + content: "\ec01"; +} +.icon-score:before { + content: "\ec02"; +} +.icon-screen_lock_landscape:before { + content: "\ec03"; +} +.icon-screen_lock_portrait:before { + content: "\ec04"; +} +.icon-screen_lock_rotation:before { + content: "\ec05"; +} +.icon-screen_rotation:before { + content: "\ec06"; +} +.icon-screen_share:before { + content: "\ec07"; +} +.icon-sd_card:before { + content: "\ec08"; +} +.icon-sd_storage:before { + content: "\ec09"; +} +.icon-search:before { + content: "\ec0a"; +} +.icon-security:before { + content: "\ec0b"; +} +.icon-select_all:before { + content: "\ec0c"; +} +.icon-send:before { + content: "\ec0d"; +} +.icon-sentiment_dissatisfied:before { + content: "\ec0e"; +} +.icon-sentiment_satisfied_alt:before { + content: "\ec0f"; +} +.icon-sentiment_satisfied:before { + content: "\ec10"; +} +.icon-sentiment_very_dissatisfied:before { + content: "\ec11"; +} +.icon-sentiment_very_satisfied:before { + content: "\ec12"; +} +.icon-settings_applications:before { + content: "\ec13"; +} +.icon-settings_backup_restore:before { + content: "\ec14"; +} +.icon-settings_bluetooth:before { + content: "\ec15"; +} +.icon-settings_brightness:before { + content: "\ec16"; +} +.icon-settings_cell:before { + content: "\ec17"; +} +.icon-settings_ethernet:before { + content: "\ec18"; +} +.icon-settings_input_antenna:before { + content: "\ec19"; +} +.icon-settings_input_component:before { + content: "\ec1a"; +} +.icon-settings_input_composite:before { + content: "\ec1b"; +} +.icon-settings_input_hdmi:before { + content: "\ec1c"; +} +.icon-settings_input_svideo:before { + content: "\ec1d"; +} +.icon-settings_overscan:before { + content: "\ec1e"; +} +.icon-settings_phone:before { + content: "\ec1f"; +} +.icon-settings_power:before { + content: "\ec20"; +} +.icon-settings_remote:before { + content: "\ec21"; +} +.icon-settings_system_daydream:before { + content: "\ec22"; +} +.icon-settings_voice:before { + content: "\ec23"; +} +.icon-settings:before { + content: "\ec24"; +} +.icon-share:before { + content: "\ec25"; +} +.icon-shop_two:before { + content: "\ec26"; +} +.icon-shop:before { + content: "\ec27"; +} +.icon-shopping_basket:before { + content: "\ec28"; +} +.icon-shopping_cart:before { + content: "\ec29"; +} +.icon-short_text:before { + content: "\ec2a"; +} +.icon-show_chart:before { + content: "\ec2b"; +} +.icon-shuffle:before { + content: "\ec2c"; +} +.icon-shutter_speed:before { + content: "\ec2d"; +} +.icon-signal_cellular_0_bar:before { + content: "\ec2e"; +} +.icon-signal_cellular_4_bar:before { + content: "\ec2f"; +} +.icon-signal_cellular_alt:before { + content: "\ec30"; +} +.icon-signal_cellular_connected_no_internet_4_bar:before { + content: "\ec31"; +} +.icon-signal_cellular_no_sim:before { + content: "\ec32"; +} +.icon-signal_cellular_null:before { + content: "\ec33"; +} +.icon-signal_cellular_off:before { + content: "\ec34"; +} +.icon-signal_wifi_0_bar:before { + content: "\ec35"; +} +.icon-signal_wifi_4_bar_lock:before { + content: "\ec36"; +} +.icon-signal_wifi_4_bar:before { + content: "\ec37"; +} +.icon-signal_wifi_off:before { + content: "\ec38"; +} +.icon-sim_card:before { + content: "\ec39"; +} +.icon-skip_next:before { + content: "\ec3a"; +} +.icon-skip_previous:before { + content: "\ec3b"; +} +.icon-slideshow:before { + content: "\ec3c"; +} +.icon-slow_motion_video:before { + content: "\ec3d"; +} +.icon-smartphone:before { + content: "\ec3e"; +} +.icon-smoke_free:before { + content: "\ec3f"; +} +.icon-smoking_rooms:before { + content: "\ec40"; +} +.icon-sms_failed:before { + content: "\ec41"; +} +.icon-sms:before { + content: "\ec42"; +} +.icon-snooze:before { + content: "\ec43"; +} +.icon-sort_by_alpha:before { + content: "\ec44"; +} +.icon-sort:before { + content: "\ec45"; +} +.icon-spa:before { + content: "\ec46"; +} +.icon-space_bar:before { + content: "\ec47"; +} +.icon-speaker_group:before { + content: "\ec48"; +} +.icon-speaker_notes_off:before { + content: "\ec49"; +} +.icon-speaker_notes:before { + content: "\ec4a"; +} +.icon-speaker_phone:before { + content: "\ec4b"; +} +.icon-speaker:before { + content: "\ec4c"; +} +.icon-spellcheck:before { + content: "\ec4d"; +} +.icon-star_border:before { + content: "\ec4e"; +} +.icon-star_half:before { + content: "\ec4f"; +} +.icon-star_rate:before { + content: "\ec50"; +} +.icon-star:before { + content: "\ec51"; +} +.icon-stars:before { + content: "\ec52"; +} +.icon-stay_current_landscape:before { + content: "\ec53"; +} +.icon-stay_current_portrait:before { + content: "\ec54"; +} +.icon-stay_primary_landscape:before { + content: "\ec55"; +} +.icon-stay_primary_portrait:before { + content: "\ec56"; +} +.icon-stop_screen_share:before { + content: "\ec57"; +} +.icon-stop:before { + content: "\ec58"; +} +.icon-storage:before { + content: "\ec59"; +} +.icon-store_mall_directory:before { + content: "\ec5a"; +} +.icon-store:before { + content: "\ec5b"; +} +.icon-straighten:before { + content: "\ec5c"; +} +.icon-streetview:before { + content: "\ec5d"; +} +.icon-strikethrough_s:before { + content: "\ec5e"; +} +.icon-style:before { + content: "\ec5f"; +} +.icon-subdirectory_arrow_left:before { + content: "\ec60"; +} +.icon-subdirectory_arrow_right:before { + content: "\ec61"; +} +.icon-subject:before { + content: "\ec62"; +} +.icon-subscriptions:before { + content: "\ec63"; +} +.icon-subtitles:before { + content: "\ec64"; +} +.icon-subway:before { + content: "\ec65"; +} +.icon-supervised_user_circle:before { + content: "\ec66"; +} +.icon-supervisor_account:before { + content: "\ec67"; +} +.icon-surround_sound:before { + content: "\ec68"; +} +.icon-swap_calls:before { + content: "\ec69"; +} +.icon-swap_horiz:before { + content: "\ec6a"; +} +.icon-swap_horizontal_circle:before { + content: "\ec6b"; +} +.icon-swap_vert:before { + content: "\ec6c"; +} +.icon-swap_vertical_circle:before { + content: "\ec6d"; +} +.icon-switch_camera:before { + content: "\ec6e"; +} +.icon-switch_video:before { + content: "\ec6f"; +} +.icon-sync_disabled:before { + content: "\ec70"; +} +.icon-sync_problem:before { + content: "\ec71"; +} +.icon-sync:before { + content: "\ec72"; +} +.icon-system_update:before { + content: "\ec73"; +} +.icon-tab_unselected:before { + content: "\ec74"; +} +.icon-tab:before { + content: "\ec75"; +} +.icon-table_chart:before { + content: "\ec76"; +} +.icon-tablet_android:before { + content: "\ec77"; +} +.icon-tablet_mac:before { + content: "\ec78"; +} +.icon-tablet:before { + content: "\ec79"; +} +.icon-tag_faces:before { + content: "\ec7a"; +} +.icon-tap_and_play:before { + content: "\ec7b"; +} +.icon-terrain:before { + content: "\ec7c"; +} +.icon-text_fields:before { + content: "\ec7d"; +} +.icon-text_format:before { + content: "\ec7e"; +} +.icon-text_rotate_up:before { + content: "\ec7f"; +} +.icon-text_rotate_vertical:before { + content: "\ec80"; +} +.icon-text_rotation_down:before { + content: "\ec81"; +} +.icon-text_rotation_none:before { + content: "\ec82"; +} +.icon-textsms:before { + content: "\ec83"; +} +.icon-texture:before { + content: "\ec84"; +} +.icon-theaters:before { + content: "\ec85"; +} +.icon-thumb_down_alt:before { + content: "\ec86"; +} +.icon-thumb_down:before { + content: "\ec87"; +} +.icon-thumb_up_alt:before { + content: "\ec88"; +} +.icon-thumb_up:before { + content: "\ec89"; +} +.icon-thumbs_up_down:before { + content: "\ec8a"; +} +.icon-time_to_leave:before { + content: "\ec8b"; +} +.icon-timelapse:before { + content: "\ec8c"; +} +.icon-timeline:before { + content: "\ec8d"; +} +.icon-timer_3:before { + content: "\ec8e"; +} +.icon-timer_10:before { + content: "\ec8f"; +} +.icon-timer_off:before { + content: "\ec90"; +} +.icon-timer:before { + content: "\ec91"; +} +.icon-title:before { + content: "\ec92"; +} +.icon-toc:before { + content: "\ec93"; +} +.icon-today:before { + content: "\ec94"; +} +.icon-toggle_off:before { + content: "\ec95"; +} +.icon-toggle_on:before { + content: "\ec96"; +} +.icon-toll:before { + content: "\ec97"; +} +.icon-tonality:before { + content: "\ec98"; +} +.icon-touch_app:before { + content: "\ec99"; +} +.icon-toys:before { + content: "\ec9a"; +} +.icon-track_changes:before { + content: "\ec9b"; +} +.icon-traffic:before { + content: "\ec9c"; +} +.icon-train:before { + content: "\ec9d"; +} +.icon-tram:before { + content: "\ec9e"; +} +.icon-transfer_within_a_station:before { + content: "\ec9f"; +} +.icon-transform:before { + content: "\eca0"; +} +.icon-transit_enterexit:before { + content: "\eca1"; +} +.icon-translate:before { + content: "\eca2"; +} +.icon-trending_down:before { + content: "\eca3"; +} +.icon-trending_flat:before { + content: "\eca4"; +} +.icon-trending_up:before { + content: "\eca5"; +} +.icon-trip_origin:before { + content: "\eca6"; +} +.icon-tune:before { + content: "\eca7"; +} +.icon-turned_in_not:before { + content: "\eca8"; +} +.icon-turned_in:before { + content: "\eca9"; +} +.icon-tv_off:before { + content: "\ecaa"; +} +.icon-tv:before { + content: "\ecab"; +} +.icon-unarchive:before { + content: "\ecac"; +} +.icon-undo:before { + content: "\ecad"; +} +.icon-unfold_less:before { + content: "\ecae"; +} +.icon-unfold_more:before { + content: "\ecaf"; +} +.icon-unsubscribe:before { + content: "\ecb0"; +} +.icon-update:before { + content: "\ecb1"; +} +.icon-usb:before { + content: "\ecb2"; +} +.icon-verified_user:before { + content: "\ecb3"; +} +.icon-vertical_align_bottom:before { + content: "\ecb4"; +} +.icon-vertical_align_center:before { + content: "\ecb5"; +} +.icon-vertical_align_top:before { + content: "\ecb6"; +} +.icon-vertical_split:before { + content: "\ecb7"; +} +.icon-vibration:before { + content: "\ecb8"; +} +.icon-video_call:before { + content: "\ecb9"; +} +.icon-video_label:before { + content: "\ecba"; +} +.icon-video_library:before { + content: "\ecbb"; +} +.icon-videocam_off:before { + content: "\ecbc"; +} +.icon-videocam:before { + content: "\ecbd"; +} +.icon-videogame_asset:before { + content: "\ecbe"; +} +.icon-view_agenda:before { + content: "\ecbf"; +} +.icon-view_array:before { + content: "\ecc0"; +} +.icon-view_carousel:before { + content: "\ecc1"; +} +.icon-view_column:before { + content: "\ecc2"; +} +.icon-view_comfy:before { + content: "\ecc3"; +} +.icon-view_compact:before { + content: "\ecc4"; +} +.icon-view_day:before { + content: "\ecc5"; +} +.icon-view_headline:before { + content: "\ecc6"; +} +.icon-view_list:before { + content: "\ecc7"; +} +.icon-view_module:before { + content: "\ecc8"; +} +.icon-view_quilt:before { + content: "\ecc9"; +} +.icon-view_stream:before { + content: "\ecca"; +} +.icon-view_week:before { + content: "\eccb"; +} +.icon-vignette:before { + content: "\eccc"; +} +.icon-visibility_off:before { + content: "\eccd"; +} +.icon-visibility:before { + content: "\ecce"; +} +.icon-voice_chat:before { + content: "\eccf"; +} +.icon-voice_over_off:before { + content: "\ecd0"; +} +.icon-voicemail:before { + content: "\ecd1"; +} +.icon-volume_down:before { + content: "\ecd2"; +} +.icon-volume_mute:before { + content: "\ecd3"; +} +.icon-volume_off:before { + content: "\ecd4"; +} +.icon-volume_up:before { + content: "\ecd5"; +} +.icon-vpn_key:before { + content: "\ecd6"; +} +.icon-vpn_lock:before { + content: "\ecd7"; +} +.icon-wallpaper:before { + content: "\ecd8"; +} +.icon-warning:before { + content: "\ecd9"; +} +.icon-watch_later:before { + content: "\ecda"; +} +.icon-watch:before { + content: "\ecdb"; +} +.icon-waves:before { + content: "\ecdc"; +} +.icon-wb_auto:before { + content: "\ecdd"; +} +.icon-wb_cloudy:before { + content: "\ecde"; +} +.icon-wb_incandescent:before { + content: "\ecdf"; +} +.icon-wb_iridescent:before { + content: "\ece0"; +} +.icon-wb_sunny:before { + content: "\ece1"; +} +.icon-wc:before { + content: "\ece2"; +} +.icon-web_asset:before { + content: "\ece3"; +} +.icon-web:before { + content: "\ece4"; +} +.icon-weekend:before { + content: "\ece5"; +} +.icon-whatshot:before { + content: "\ece6"; +} +.icon-where_to_vote:before { + content: "\ece7"; +} +.icon-widgets:before { + content: "\ece8"; +} +.icon-wifi_lock:before { + content: "\ece9"; +} +.icon-wifi_off:before { + content: "\ecea"; +} +.icon-wifi_tethering:before { + content: "\eceb"; +} +.icon-wifi:before { + content: "\ecec"; +} +.icon-work_off:before { + content: "\eced"; +} +.icon-work_outline:before { + content: "\ecee"; +} +.icon-work:before { + content: "\ecef"; +} +.icon-wrap_text:before { + content: "\ecf0"; +} +.icon-youtube_searched_for:before { + content: "\ecf1"; +} +.icon-zoom_in:before { + content: "\ecf2"; +} +.icon-zoom_out_map:before { + content: "\ecf3"; +} +.icon-zoom_out:before { + content: "\ecf4"; +} diff --git a/projects/ucap-webmessenger-app/src/index.html b/projects/ucap-webmessenger-app/src/index.html index 4d98163a..9b059414 100644 --- a/projects/ucap-webmessenger-app/src/index.html +++ b/projects/ucap-webmessenger-app/src/index.html @@ -6,6 +6,7 @@ + diff --git a/projects/ucap-webmessenger-native-browser/README.md b/projects/ucap-webmessenger-native-browser/README.md new file mode 100644 index 00000000..b53cff21 --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/README.md @@ -0,0 +1,24 @@ +# UcapWebmessengerNativeBrowser + +This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.5. + +## Code scaffolding + +Run `ng generate component component-name --project ucap-webmessenger-native-browser` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ucap-webmessenger-native-browser`. +> Note: Don't forget to add `--project ucap-webmessenger-native-browser` or else it will be added to the default project in your `angular.json` file. + +## Build + +Run `ng build ucap-webmessenger-native-browser` to build the project. The build artifacts will be stored in the `dist/` directory. + +## Publishing + +After building your library with `ng build ucap-webmessenger-native-browser`, go to the dist folder `cd dist/ucap-webmessenger-native-browser` and run `npm publish`. + +## Running unit tests + +Run `ng test ucap-webmessenger-native-browser` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). diff --git a/projects/ucap-webmessenger-native-browser/karma.conf.js b/projects/ucap-webmessenger-native-browser/karma.conf.js new file mode 100644 index 00000000..d45cd1c2 --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/karma.conf.js @@ -0,0 +1,32 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageIstanbulReporter: { + dir: require('path').join(__dirname, '../../coverage/ucap-webmessenger-native-browser'), + reports: ['html', 'lcovonly', 'text-summary'], + fixWebpackSourcePaths: true + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true + }); +}; diff --git a/projects/ucap-webmessenger-native-browser/ng-package.json b/projects/ucap-webmessenger-native-browser/ng-package.json new file mode 100644 index 00000000..bfd5e851 --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/ng-package.json @@ -0,0 +1,7 @@ +{ + "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../dist/ucap-webmessenger-native-browser", + "lib": { + "entryFile": "src/public-api.ts" + } +} \ No newline at end of file diff --git a/projects/ucap-webmessenger-native-browser/package.json b/projects/ucap-webmessenger-native-browser/package.json new file mode 100644 index 00000000..13b5a16b --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/package.json @@ -0,0 +1,8 @@ +{ + "name": "@ucap-webmessenger/native-browser", + "version": "0.0.1", + "peerDependencies": { + "@angular/common": "^8.2.5", + "@angular/core": "^8.2.5" + } +} diff --git a/projects/ucap-webmessenger-native-browser/src/lib/services/browser-native.service.spec.ts b/projects/ucap-webmessenger-native-browser/src/lib/services/browser-native.service.spec.ts new file mode 100644 index 00000000..2fc66828 --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/src/lib/services/browser-native.service.spec.ts @@ -0,0 +1,3 @@ +import { BrowserNativeService } from './browser-native.service'; + +describe('BrowserNativeService', () => {}); diff --git a/projects/ucap-webmessenger-native-browser/src/lib/services/browser-native.service.ts b/projects/ucap-webmessenger-native-browser/src/lib/services/browser-native.service.ts new file mode 100644 index 00000000..faac9400 --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/src/lib/services/browser-native.service.ts @@ -0,0 +1,39 @@ +import { Observable } from 'rxjs'; + +import { NativeService } from '@ucap-webmessenger/native'; +import { HttpClient } from '@angular/common/http'; +import { map } from 'rxjs/operators'; + +export class BrowserNativeService implements NativeService { + showNotify( + roomSeq: number, + title: string, + contents: string, + image: string, + useSound: boolean + ): void {} + + checkForUpdates(): Observable { + return new Observable(subscriber => { + try { + subscriber.next(false); + } catch (error) { + subscriber.error(error); + } finally { + subscriber.complete(); + } + }); + } + + showImageViewer(): void {} + + readFile(path: string): Observable { + return this.httpClient.get(path, { responseType: 'arraybuffer' }); + } + + saveFile(path: string, buf: ArrayBuffer): Observable { + return this.httpClient.post(path, buf, {}); + } + + constructor(private httpClient: HttpClient) {} +} diff --git a/projects/ucap-webmessenger-native-browser/src/lib/translate/browser-loader.ts b/projects/ucap-webmessenger-native-browser/src/lib/translate/browser-loader.ts new file mode 100644 index 00000000..d927e114 --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/src/lib/translate/browser-loader.ts @@ -0,0 +1,26 @@ +import { TranslateLoader } from '@ngx-translate/core'; +import { Observable } from 'rxjs'; +import { NativeService } from '@ucap-webmessenger/native'; +import { take, map } from 'rxjs/operators'; + +export class TranslateBrowserLoader implements TranslateLoader { + constructor( + private nativeService: NativeService, + private prefix: string = '/assets/i18n/', + private suffix: string = '.json' + ) {} + + /** + * Gets the translations from the server + */ + public getTranslation(lang: string): Observable { + return this.nativeService + .readFile(`${this.prefix}${lang}.${this.suffix}`) + .pipe( + take(1), + map(buf => { + return JSON.parse(Buffer.from(buf).toString('utf8')); + }) + ); + } +} diff --git a/projects/ucap-webmessenger-native-browser/src/public-api.ts b/projects/ucap-webmessenger-native-browser/src/public-api.ts new file mode 100644 index 00000000..46578228 --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/src/public-api.ts @@ -0,0 +1,7 @@ +/* + * Public API Surface of ucap-webmessenger-native-browser + */ + +export * from './lib/services/browser-native.service'; + +export * from './lib/translate/browser-loader'; diff --git a/projects/ucap-webmessenger-native-browser/src/test.ts b/projects/ucap-webmessenger-native-browser/src/test.ts new file mode 100644 index 00000000..978c64fb --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/src/test.ts @@ -0,0 +1,21 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/zone'; +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: any; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/projects/ucap-webmessenger-native-browser/tsconfig.lib.json b/projects/ucap-webmessenger-native-browser/tsconfig.lib.json new file mode 100644 index 00000000..bd23948e --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/tsconfig.lib.json @@ -0,0 +1,26 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/lib", + "target": "es2015", + "declaration": true, + "inlineSources": true, + "types": [], + "lib": [ + "dom", + "es2018" + ] + }, + "angularCompilerOptions": { + "annotateForClosureCompiler": true, + "skipTemplateCodegen": true, + "strictMetadataEmit": true, + "fullTemplateTypeCheck": true, + "strictInjectionParameters": true, + "enableResourceInlining": true + }, + "exclude": [ + "src/test.ts", + "**/*.spec.ts" + ] +} diff --git a/projects/ucap-webmessenger-native-browser/tsconfig.spec.json b/projects/ucap-webmessenger-native-browser/tsconfig.spec.json new file mode 100644 index 00000000..16da33db --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "src/test.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/projects/ucap-webmessenger-native-browser/tslint.json b/projects/ucap-webmessenger-native-browser/tslint.json new file mode 100644 index 00000000..3c621804 --- /dev/null +++ b/projects/ucap-webmessenger-native-browser/tslint.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tslint.json", + "rules": { + "directive-selector": [ + true, + "attribute", + "ucapNativeBrowser", + "camelCase" + ], + "component-selector": [ + true, + "element", + "ucap-native-browser", + "kebab-case" + ] + } +} diff --git a/projects/ucap-webmessenger-native-electron/src/lib/services/electron-native.service.ts b/projects/ucap-webmessenger-native-electron/src/lib/services/electron-native.service.ts index a94f79c5..39466845 100644 --- a/projects/ucap-webmessenger-native-electron/src/lib/services/electron-native.service.ts +++ b/projects/ucap-webmessenger-native-electron/src/lib/services/electron-native.service.ts @@ -1,5 +1,3 @@ -import { Injectable } from '@angular/core'; - import { ipcRenderer } from 'electron'; import { Observable } from 'rxjs'; @@ -41,8 +39,29 @@ export class ElectronNativeService implements NativeService { ipcRenderer.send(Channel.showImageViewer); } - saveFile(blob: Blob): void { - ipcRenderer.send(Channel.saveFile, blob); + readFile(path: string): Observable { + return new Observable(subscriber => { + try { + subscriber.next(ipcRenderer.sendSync(Channel.readFile, path)); + } catch (error) { + subscriber.error(error); + } finally { + subscriber.complete(); + } + }); } + + saveFile(path: string, buf: ArrayBuffer): Observable { + return new Observable(subscriber => { + try { + subscriber.next(ipcRenderer.sendSync(Channel.saveFile, path, buf)); + } catch (error) { + subscriber.error(error); + } finally { + subscriber.complete(); + } + }); + } + constructor() {} } diff --git a/projects/ucap-webmessenger-native-electron/src/lib/translate/electron-loader.ts b/projects/ucap-webmessenger-native-electron/src/lib/translate/electron-loader.ts new file mode 100644 index 00000000..5ec354ea --- /dev/null +++ b/projects/ucap-webmessenger-native-electron/src/lib/translate/electron-loader.ts @@ -0,0 +1,26 @@ +import { TranslateLoader } from '@ngx-translate/core'; +import { Observable } from 'rxjs'; +import { NativeService } from '@ucap-webmessenger/native'; +import { take, map } from 'rxjs/operators'; + +export class TranslateElectronLoader implements TranslateLoader { + constructor( + private nativeService: NativeService, + private prefix: string = '/assets/i18n/', + private suffix: string = '.json' + ) {} + + /** + * Gets the translations from the server + */ + public getTranslation(lang: string): Observable { + return this.nativeService + .readFile(`${this.prefix}${lang}.${this.suffix}`) + .pipe( + take(1), + map(buf => { + return JSON.parse(buf.toString()); + }) + ); + } +} diff --git a/projects/ucap-webmessenger-native-electron/src/lib/types/channel.type.ts b/projects/ucap-webmessenger-native-electron/src/lib/types/channel.type.ts index 72230cbe..efd46d98 100644 --- a/projects/ucap-webmessenger-native-electron/src/lib/types/channel.type.ts +++ b/projects/ucap-webmessenger-native-electron/src/lib/types/channel.type.ts @@ -2,5 +2,6 @@ export enum Channel { showNotify = 'UCAP::showNotify', checkForUpdates = 'UCAP::checkForUpdates', showImageViewer = 'UCAP::showImageViewer', - saveFile = 'UCAP::saveFile' + saveFile = 'UCAP::saveFile', + readFile = 'UCAP::readFile' } diff --git a/projects/ucap-webmessenger-native-electron/src/public-api.ts b/projects/ucap-webmessenger-native-electron/src/public-api.ts index 20f1dddf..689efae4 100644 --- a/projects/ucap-webmessenger-native-electron/src/public-api.ts +++ b/projects/ucap-webmessenger-native-electron/src/public-api.ts @@ -4,4 +4,6 @@ export * from './lib/services/electron-native.service'; +export * from './lib/translate/electron-loader'; + export * from './lib/types/channel.type'; diff --git a/projects/ucap-webmessenger-native/src/lib/services/native.service.ts b/projects/ucap-webmessenger-native/src/lib/services/native.service.ts index 7ffe2c4b..3e106c71 100644 --- a/projects/ucap-webmessenger-native/src/lib/services/native.service.ts +++ b/projects/ucap-webmessenger-native/src/lib/services/native.service.ts @@ -13,5 +13,6 @@ export interface NativeService { showImageViewer(): void; - saveFile(blob: Blob): void; + saveFile(path: string, buf: ArrayBuffer): Observable; + readFile(path: string): Observable; } diff --git a/projects/ucap-webmessenger-protocol/src/lib/services/protocol.service.ts b/projects/ucap-webmessenger-protocol/src/lib/services/protocol.service.ts index 1fa02eb8..3540aa98 100644 --- a/projects/ucap-webmessenger-protocol/src/lib/services/protocol.service.ts +++ b/projects/ucap-webmessenger-protocol/src/lib/services/protocol.service.ts @@ -194,7 +194,7 @@ export class ProtocolService { this._requestId = this.moduleConfig.requestId.min; } - return this._requestId; + return this._requestId++; } private decodePacket( diff --git a/projects/ucap-webmessenger-ui-group/README.md b/projects/ucap-webmessenger-ui-group/README.md new file mode 100644 index 00000000..0248dd59 --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/README.md @@ -0,0 +1,24 @@ +# UcapWebmessengerUiGroup + +This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.5. + +## Code scaffolding + +Run `ng generate component component-name --project ucap-webmessenger-ui-group` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ucap-webmessenger-ui-group`. +> Note: Don't forget to add `--project ucap-webmessenger-ui-group` or else it will be added to the default project in your `angular.json` file. + +## Build + +Run `ng build ucap-webmessenger-ui-group` to build the project. The build artifacts will be stored in the `dist/` directory. + +## Publishing + +After building your library with `ng build ucap-webmessenger-ui-group`, go to the dist folder `cd dist/ucap-webmessenger-ui-group` and run `npm publish`. + +## Running unit tests + +Run `ng test ucap-webmessenger-ui-group` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). diff --git a/projects/ucap-webmessenger-ui-group/karma.conf.js b/projects/ucap-webmessenger-ui-group/karma.conf.js new file mode 100644 index 00000000..99f6884b --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/karma.conf.js @@ -0,0 +1,32 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageIstanbulReporter: { + dir: require('path').join(__dirname, '../../coverage/ucap-webmessenger-ui-group'), + reports: ['html', 'lcovonly', 'text-summary'], + fixWebpackSourcePaths: true + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true + }); +}; diff --git a/projects/ucap-webmessenger-ui-group/ng-package.json b/projects/ucap-webmessenger-ui-group/ng-package.json new file mode 100644 index 00000000..c684c08e --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/ng-package.json @@ -0,0 +1,7 @@ +{ + "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../dist/ucap-webmessenger-ui-group", + "lib": { + "entryFile": "src/public-api.ts" + } +} \ No newline at end of file diff --git a/projects/ucap-webmessenger-ui-group/package.json b/projects/ucap-webmessenger-ui-group/package.json new file mode 100644 index 00000000..ca8d8c69 --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/package.json @@ -0,0 +1,8 @@ +{ + "name": "@ucap-webmessenger/ui-group", + "version": "0.0.1", + "peerDependencies": { + "@angular/common": "^8.2.5", + "@angular/core": "^8.2.5" + } +} diff --git a/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.html b/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.html new file mode 100644 index 00000000..5a7d12b4 --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.scss b/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.spec.ts b/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.spec.ts new file mode 100644 index 00000000..748e039c --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.spec.ts @@ -0,0 +1,24 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ExpansionPanelComponent } from './expansion-panel.component'; + +describe('Organization::ExpansionPanelComponent', () => { + let component: ExpansionPanelComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ExpansionPanelComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ExpansionPanelComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.ts b/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.ts new file mode 100644 index 00000000..0a69487e --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/src/lib/components/expansion-panel.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit, Input } from '@angular/core'; + +@Component({ + selector: 'ucap-group-expansion-panel', + templateUrl: './expansion-panel.component.html', + styleUrls: ['./expansion-panel.component.scss'] +}) +export class ExpansionPanelComponent implements OnInit { + @Input() + groupList: any[]; + + constructor() {} + + ngOnInit() {} +} diff --git a/projects/ucap-webmessenger-ui-group/src/lib/ucap-ui-group.module.ts b/projects/ucap-webmessenger-ui-group/src/lib/ucap-ui-group.module.ts new file mode 100644 index 00000000..eb55f826 --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/src/lib/ucap-ui-group.module.ts @@ -0,0 +1,24 @@ +import { NgModule, ModuleWithProviders } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; + +import { MatExpansionModule } from '@angular/material/expansion'; + +import { ExpansionPanelComponent } from './components/expansion-panel.component'; + +const COMPONENTS = [ExpansionPanelComponent]; +const SERVICES = []; + +@NgModule({ + imports: [CommonModule, ReactiveFormsModule, MatExpansionModule], + exports: [...COMPONENTS], + declarations: [...COMPONENTS] +}) +export class UCapUiGroupModule { + public static forRoot(): ModuleWithProviders { + return { + ngModule: UCapUiGroupModule, + providers: [...SERVICES] + }; + } +} diff --git a/projects/ucap-webmessenger-ui-group/src/public-api.ts b/projects/ucap-webmessenger-ui-group/src/public-api.ts new file mode 100644 index 00000000..af7c2271 --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/src/public-api.ts @@ -0,0 +1,7 @@ +/* + * Public API Surface of ucap-webmessenger-ui-group + */ + +export * from './lib/components/expansion-panel.component'; + +export * from './lib/ucap-ui-group.module'; diff --git a/projects/ucap-webmessenger-ui-group/src/test.ts b/projects/ucap-webmessenger-ui-group/src/test.ts new file mode 100644 index 00000000..978c64fb --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/src/test.ts @@ -0,0 +1,21 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/zone'; +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: any; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/projects/ucap-webmessenger-ui-group/tsconfig.lib.json b/projects/ucap-webmessenger-ui-group/tsconfig.lib.json new file mode 100644 index 00000000..bd23948e --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/tsconfig.lib.json @@ -0,0 +1,26 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/lib", + "target": "es2015", + "declaration": true, + "inlineSources": true, + "types": [], + "lib": [ + "dom", + "es2018" + ] + }, + "angularCompilerOptions": { + "annotateForClosureCompiler": true, + "skipTemplateCodegen": true, + "strictMetadataEmit": true, + "fullTemplateTypeCheck": true, + "strictInjectionParameters": true, + "enableResourceInlining": true + }, + "exclude": [ + "src/test.ts", + "**/*.spec.ts" + ] +} diff --git a/projects/ucap-webmessenger-ui-group/tsconfig.spec.json b/projects/ucap-webmessenger-ui-group/tsconfig.spec.json new file mode 100644 index 00000000..16da33db --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "src/test.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/projects/ucap-webmessenger-ui-group/tslint.json b/projects/ucap-webmessenger-ui-group/tslint.json new file mode 100644 index 00000000..cc851681 --- /dev/null +++ b/projects/ucap-webmessenger-ui-group/tslint.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tslint.json", + "rules": { + "directive-selector": [ + true, + "attribute", + "ucapGroup", + "camelCase" + ], + "component-selector": [ + true, + "element", + "ucap-group", + "kebab-case" + ] + } +} diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.html b/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.html new file mode 100644 index 00000000..e8738470 --- /dev/null +++ b/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.scss b/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.spec.ts b/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.spec.ts new file mode 100644 index 00000000..748e039c --- /dev/null +++ b/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.spec.ts @@ -0,0 +1,24 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ExpansionPanelComponent } from './expansion-panel.component'; + +describe('Organization::ExpansionPanelComponent', () => { + let component: ExpansionPanelComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ExpansionPanelComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ExpansionPanelComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.ts b/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.ts new file mode 100644 index 00000000..72103902 --- /dev/null +++ b/projects/ucap-webmessenger-ui-organization/src/lib/components/expansion-panel.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit, Input } from '@angular/core'; + +@Component({ + selector: 'ucap-organization-expansion-panel', + templateUrl: './expansion-panel.component.html', + styleUrls: ['./expansion-panel.component.scss'] +}) +export class ExpansionPanelComponent implements OnInit { + @Input() + organizationList: any[]; + + constructor() {} + + ngOnInit() {} +} diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/ucap-ui-organization.module.ts b/projects/ucap-webmessenger-ui-organization/src/lib/ucap-ui-organization.module.ts index 3d270e20..4bf445e3 100644 --- a/projects/ucap-webmessenger-ui-organization/src/lib/ucap-ui-organization.module.ts +++ b/projects/ucap-webmessenger-ui-organization/src/lib/ucap-ui-organization.module.ts @@ -2,11 +2,15 @@ import { NgModule, ModuleWithProviders } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ReactiveFormsModule } from '@angular/forms'; -const COMPONENTS = []; +import { MatExpansionModule } from '@angular/material/expansion'; + +import { ExpansionPanelComponent } from './components/expansion-panel.component'; + +const COMPONENTS = [ExpansionPanelComponent]; const SERVICES = []; @NgModule({ - imports: [CommonModule, ReactiveFormsModule], + imports: [CommonModule, ReactiveFormsModule, MatExpansionModule], exports: [...COMPONENTS], declarations: [...COMPONENTS] }) diff --git a/projects/ucap-webmessenger-ui-organization/src/public-api.ts b/projects/ucap-webmessenger-ui-organization/src/public-api.ts index f9b0a086..d6bb500c 100644 --- a/projects/ucap-webmessenger-ui-organization/src/public-api.ts +++ b/projects/ucap-webmessenger-ui-organization/src/public-api.ts @@ -1,5 +1,6 @@ /* * Public API Surface of ucap-webmessenger-ui-organization */ +export * from './lib/components/expansion-panel.component'; export * from './lib/ucap-ui-organization.module'; diff --git a/tsconfig.json b/tsconfig.json index 89c8c0e9..ee295a3c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,7 +16,6 @@ "lib": ["es2018", "dom"], "paths": { "@app/*": ["projects/ucap-webmessenger-app/src/app/*"], - "@ucap-webmessenger/core": [ "projects/ucap-webmessenger-core/src/public-api" ], @@ -40,6 +39,9 @@ "@ucap-webmessenger/ui-chat": [ "projects/ucap-webmessenger-ui-chat/src/public-api" ], + "@ucap-webmessenger/ui-group": [ + "projects/ucap-webmessenger-ui-group/src/public-api" + ], "@ucap-webmessenger/ui-messenger": [ "projects/ucap-webmessenger-ui-messenger/src/public-api" ], @@ -106,6 +108,9 @@ "@ucap-webmessenger/native": [ "projects/ucap-webmessenger-native/src/public-api" ], + "@ucap-webmessenger/native-browser": [ + "projects/ucap-webmessenger-native-browser/src/public-api" + ], "@ucap-webmessenger/native-electron": [ "projects/ucap-webmessenger-native-electron/src/public-api" ],