Merge branch 'DEVELOP' of ssh://git.eclipse.org:29418/openk-usermodules/org.eclipse.openk-usermodules.gridFailureInformation.frontend into SI-723-meldung-beenden
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-api-client.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-api-client.ts
index cf8a52d..6c42a93 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-api-client.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-api-client.ts
@@ -238,4 +238,10 @@
   ): Observable<PublicationChannel> {
     return null;
   }
+
+  @GET('/failure-reminder')
+  @Adapter(GridFailureService.reminderAdapter)
+  public getFailureReminder(): Observable<boolean> {
+    return null;
+  }
 }
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list.component.spec.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list.component.spec.ts
index 3fdace4..2772c12 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list.component.spec.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list.component.spec.ts
@@ -17,8 +17,6 @@
 import { Subscription, of } from 'rxjs';
 import { UtilService } from '@grid-failure-information-app/shared/utility';
 import { RolesEnum } from '@grid-failure-information-app/shared/constants/enums';
-import { async } from '@angular/core/testing';
-import { GridApi } from 'ag-grid-community';
 
 describe('GridFailureListComponent ', () => {
   let component: GridFailureListComponent;
@@ -130,7 +128,7 @@
     expect(spy3).toHaveBeenCalled();
   });
 
-  it('should call and check if onGridReady(params) works fine', async(() => {
+  it('should call and check if onGridReady(params) works fine', () => {
     const mockGridApi = {
       setFilterModel() {},
     } as any;
@@ -145,7 +143,7 @@
     component.sandbox.qualifierFilterIsActive = true;
     component.initGridFilter({ api: mockGridApi });
     expect(spy2).toHaveBeenCalledTimes(2);
-  }));
+  });
 
   it('should call and check if changeToSelectionMode() works fine', () => {
     const spy: any = spyOn(component.events$, 'next');
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure.sandbox.spec.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure.sandbox.spec.ts
index a05a0a0..25d0689 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure.sandbox.spec.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure.sandbox.spec.ts
@@ -94,4 +94,11 @@
     service.setFilteredGridFailureMapList([girdFailure]);
     expect(service.filteredGridFailureMapList[0]).toBe(girdFailure);
   });
+
+  it('should dispatch a "loadFailureReminder"-action', () => {
+    (service as any)._startPolling();
+    (service as any)._timer.subscribe(() => {
+      expect(appState.dispatch).toHaveBeenCalled();
+    });
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure.sandbox.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure.sandbox.ts
index 5d9e805..6d4250e 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure.sandbox.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure.sandbox.ts
@@ -24,6 +24,9 @@
 import { ofType } from '@ngrx/effects';
 import { map, take, filter } from 'rxjs/operators';
 import { StateEnum, RolesEnum } from '@grid-failure-information-app/shared/constants/enums';
+import { Subscription } from 'rxjs/Subscription';
+import { TimerObservable } from 'rxjs/observable/TimerObservable';
+import { Globals } from '@grid-failure-information-app/shared/constants/globals';
 
 @Injectable()
 export class GridFailureSandbox extends BaseSandbox {
@@ -40,10 +43,15 @@
   public condenseId: string = null;
   public StateEnum = StateEnum;
   public RolesEnum = RolesEnum;
+  public isReminderActive$: Observable<boolean> = this.appState$.select(store.getGridFailureReminderData);
+
+  private _timer;
+  private _subscription: Subscription;
 
   constructor(protected appState$: Store<store.State>, private _router: Router, private actionsSubject: ActionsSubject) {
     super(appState$);
     this._registerEvents();
+    this._startPolling();
   }
 
   public loadGridFailures(): void {
@@ -130,4 +138,9 @@
     }
     return ret;
   }
+
+  private _startPolling() {
+    this._timer = TimerObservable.create(Globals.REMINDER_JOB_POLLING_START_DELAY, Globals.REMINDER_JOB_POLLING_INTERVALL);
+    this._subscription = this._timer.subscribe(() => this.appState$.dispatch(gridFailureActions.loadFailureReminder()));
+  }
 }
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.service.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.service.ts
index f428f45..33601d3 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.service.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.service.ts
@@ -91,4 +91,8 @@
   static publicationChannelAdapter(response: any): PublicationChannel {
     return new PublicationChannel(response);
   }
+
+  static reminderAdapter(response: any): boolean {
+    return response;
+  }
 }
diff --git a/projects/grid-failure-information-app/src/app/shared/components/header/header.component.html b/projects/grid-failure-information-app/src/app/shared/components/header/header.component.html
index 600b642..34c4473 100644
--- a/projects/grid-failure-information-app/src/app/shared/components/header/header.component.html
+++ b/projects/grid-failure-information-app/src/app/shared/components/header/header.component.html
@@ -19,6 +19,7 @@
       </a>
     </div>
     <div class="navbar-right" style="display: inline-flex;">
+      <fa id="bell" title="Erinnerung" name="bell" [style.color]="!!(failureSandbox.isReminderActive$ | async) ? 'red' : '#003a5f'"></fa>
       <button type="button" class="btn btn-link navbar-btn" title="Startseite" (click)="navigateHome()">
         <fa name="home"></fa>
       </button>
diff --git a/projects/grid-failure-information-app/src/app/shared/components/header/header.component.scss b/projects/grid-failure-information-app/src/app/shared/components/header/header.component.scss
index 55da100..dd9204b 100644
--- a/projects/grid-failure-information-app/src/app/shared/components/header/header.component.scss
+++ b/projects/grid-failure-information-app/src/app/shared/components/header/header.component.scss
@@ -42,7 +42,7 @@
 }
 
 #bell {
-  font-size: 130%;
+  padding: 8px 12px;
 }
 
 #bell:hover {
diff --git a/projects/grid-failure-information-app/src/app/shared/components/header/header.component.spec.ts b/projects/grid-failure-information-app/src/app/shared/components/header/header.component.spec.ts
index 05138f5..868b7a6 100644
--- a/projects/grid-failure-information-app/src/app/shared/components/header/header.component.spec.ts
+++ b/projects/grid-failure-information-app/src/app/shared/components/header/header.component.spec.ts
@@ -11,15 +11,17 @@
  * SPDX-License-Identifier: EPL-2.0
  ********************************************************************************/
 import { HeaderComponent } from '@grid-failure-information-app/shared/components/header/header.component';
+import { GridFailureSandbox } from '@grid-failure-information-app/pages/grid-failure/grid-failure-list/grid-failure.sandbox';
 import { of } from 'rxjs';
 
 describe('HeaderComponent', () => {
   let component: HeaderComponent;
   let router: any;
+  let sandbox: GridFailureSandbox;
 
   beforeEach(() => {
     router = { navigateByUrl() {} } as any;
-    component = new HeaderComponent(router);
+    component = new HeaderComponent(router, sandbox);
   });
 
   it('should create', () => {
diff --git a/projects/grid-failure-information-app/src/app/shared/components/header/header.component.ts b/projects/grid-failure-information-app/src/app/shared/components/header/header.component.ts
index 5453067..b962e20 100644
--- a/projects/grid-failure-information-app/src/app/shared/components/header/header.component.ts
+++ b/projects/grid-failure-information-app/src/app/shared/components/header/header.component.ts
@@ -15,6 +15,7 @@
 import { navigateHome } from '@grid-failure-information-app/shared/utility';
 import { Globals } from '@grid-failure-information-app/shared/constants/globals';
 import { RolesEnum } from '@grid-failure-information-app/shared/constants/enums';
+import { GridFailureSandbox } from '@grid-failure-information-app/pages/grid-failure/grid-failure-list/grid-failure.sandbox';
 
 @Component({
   selector: 'app-header',
@@ -30,7 +31,7 @@
   public helpUrl = Globals.HELP_URL;
   public RolesEnum = RolesEnum;
 
-  constructor(public router: Router) {}
+  constructor(public router: Router, public failureSandbox: GridFailureSandbox) {}
 
   public navigateHome(): void {
     navigateHome(this.router).then(this._winLocReload);
diff --git a/projects/grid-failure-information-app/src/app/shared/constants/globals.ts b/projects/grid-failure-information-app/src/app/shared/constants/globals.ts
index 31e6c4e..69e5ee9 100644
--- a/projects/grid-failure-information-app/src/app/shared/constants/globals.ts
+++ b/projects/grid-failure-information-app/src/app/shared/constants/globals.ts
@@ -21,6 +21,8 @@
   public static FAILURE_LOCATION_NS: string = 'NS';
   public static FAILURE_LOCATION_MS: string = 'MS';
   public static FAILURE_LOCATION_MAP: string = 'map';
+  public static REMINDER_JOB_POLLING_INTERVALL = 60000; //60 seconds
+  public static REMINDER_JOB_POLLING_START_DELAY = 2000; // 2 seconds
 
   public static LOCALE_TEXT: any = {
     equals: 'ist gleich',
diff --git a/projects/grid-failure-information-app/src/app/shared/store/actions/grid-failures.action.ts b/projects/grid-failure-information-app/src/app/shared/store/actions/grid-failures.action.ts
index 4bd4dbc..7c478f3 100644
--- a/projects/grid-failure-information-app/src/app/shared/store/actions/grid-failures.action.ts
+++ b/projects/grid-failure-information-app/src/app/shared/store/actions/grid-failures.action.ts
@@ -172,3 +172,7 @@
 export const deletePublicationChannelAssignment = createAction('[PublicationGroupAssignment] Delete', props<{ gridFailureId: string; channel: string }>());
 export const deletePublicationChannelAssignmentSuccess = createAction('[PublicationChannelAssignment] Delete Success');
 export const deletePublicationChannelAssignmentFail = createAction('[PublicationChannelAssignment] Delete Fail', props<{ payload: string }>());
+
+export const loadFailureReminder = createAction('[GridFailureReminder] Load');
+export const loadFailureReminderSuccess = createAction('[GridFailureReminder] Load Success', props<{ payload: boolean }>());
+export const loadFailureReminderFail = createAction('[GridFailureReminder] Load Fail', props<{ payload: string }>());
diff --git a/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.spec.ts b/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.spec.ts
index 71f575f..332bf24 100644
--- a/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.spec.ts
+++ b/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.spec.ts
@@ -68,6 +68,7 @@
       postGridFailureStation() {},
       deleteGridFailureStation() {},
       getGridFailurePolygon() {},
+      getFailureReminder() {},
     } as any;
     store = {
       dispatch() {},
@@ -659,7 +660,7 @@
     actions$.next(gridFailureActions.deletePublicationChannelAssignment({ gridFailureId: '1', channel: 'SMS' }));
   });
 
-  it('should equal loadGridFailurePolygon in response to getGridFailurePolygon', done => {
+  it('should equal loadGridFailurePolygonSuccess in response to getGridFailurePolygon', done => {
     apiResponse = [
       [1, 1],
       [5, 5],
@@ -680,4 +681,23 @@
     done();
     actions$.next(gridFailureActions.loadGridFailurePolygon({ payload: ['xx', 'xx'] }));
   });
+
+  it('should equal loadFailureReminderSuccess in response to loadFailureReminder', done => {
+    apiResponse = true;
+    spyOn(apiClient, 'getFailureReminder').and.returnValue(of(apiResponse));
+    effects.getFailureReminder$.pipe(take(1)).subscribe(result => {
+      expect(result).toEqual(gridFailureActions.loadFailureReminderSuccess({ payload: apiResponse }));
+    });
+    done();
+    actions$.next(gridFailureActions.loadFailureReminder());
+  });
+
+  it('should equal loadFailureReminder Fail after loadFailureReminder Error', done => {
+    spyOn(apiClient, 'getFailureReminder').and.returnValue(throwError('x'));
+    effects.getFailureReminder$.pipe(take(1)).subscribe(result => {
+      expect(result).toEqual(gridFailureActions.loadFailureReminderFail({ payload: 'x' }));
+    });
+    done();
+    actions$.next(gridFailureActions.loadFailureReminder());
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.ts b/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.ts
index 15e1c52..cbfb53e 100644
--- a/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.ts
+++ b/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.ts
@@ -96,7 +96,11 @@
       switchMap(action => {
         return this._apiClient
           .getGridFailureVersion(action.gridFailureId, action.versionNumber)
-          .map((gridFailureVersion: GridFailure) => gridFailureActions.loadGridFailureVersionSuccess({ payload: gridFailureVersion }))
+          .map((gridFailureVersion: GridFailure) => {
+            console.log(gridFailureVersion);
+            return gridFailureActions.loadGridFailureVersionSuccess({ payload: gridFailureVersion });
+          })
+
           .catch(error => of(gridFailureActions.loadGridFailureVersionFail({ payload: error })));
       })
     )
@@ -429,5 +433,17 @@
     )
   );
 
+  getFailureReminder$: any = createEffect(() =>
+    this._actions$.pipe(
+      ofType(gridFailureActions.loadFailureReminder),
+      switchMap(action => {
+        return this._apiClient
+          .getFailureReminder()
+          .map((isReminderActive: boolean) => gridFailureActions.loadFailureReminderSuccess({ payload: isReminderActive }))
+          .catch(error => of(gridFailureActions.loadFailureReminderFail({ payload: error })));
+      })
+    )
+  );
+
   constructor(private _actions$: Actions, private _apiClient: GridFailureApiClient, private _store: Store<any>) {}
 }
diff --git a/projects/grid-failure-information-app/src/app/shared/store/index.ts b/projects/grid-failure-information-app/src/app/shared/store/index.ts
index eb9b659..f1d789b 100644
--- a/projects/grid-failure-information-app/src/app/shared/store/index.ts
+++ b/projects/grid-failure-information-app/src/app/shared/store/index.ts
@@ -31,6 +31,7 @@
 import * as fromGridFailuresDetailForm from '@grid-failure-information-app/shared/store/reducers/grid-failures/grid-failure-details-form.reducer';
 import * as fromCondensedGridFailures from '@grid-failure-information-app/shared/store/reducers/grid-failures/condensed-grid-failures.reducer';
 import * as fromDistributionGroups from '@grid-failure-information-app/shared/store/reducers/distribution-groups/distribution-groups.reducer';
+import * as fromGridFailureReminder from '@grid-failure-information-app/shared/store/reducers/grid-failures/grid-failure-reminder.reducer';
 import * as fromDistributionGroupsDetailForm from '@grid-failure-information-app/shared/store/reducers/distribution-groups/distribution-group-details-form.reducer';
 import * as fromDistributionGroupMembers from '@grid-failure-information-app/shared/store/reducers/distribution-groups/distribution-group-members.reducer';
 import * as fromGridFailureDistributionGroups from '@grid-failure-information-app/shared/store/reducers/grid-failures/grid-failure-distribution-groups.reducer';
@@ -61,6 +62,7 @@
   stations: fromStations.State;
   condensedGridFailures: fromCondensedGridFailures.State;
   gridFailureDistributionGroups: fromGridFailureDistributionGroups.State;
+  gridFailureReminder: fromGridFailureReminder.State;
 }
 
 export interface DistributionGroupState {
@@ -94,6 +96,7 @@
   stations: fromStations.reducer,
   condensedGridFailures: fromCondensedGridFailures.reducer,
   gridFailureDistributionGroups: fromGridFailureDistributionGroups.reducer,
+  gridFailureReminder: fromGridFailureReminder.reducer,
 };
 
 export const distributionGroupReducers = {
@@ -205,6 +208,13 @@
 export const getCondensedGridFailuresFailed = createSelector(selectCondensedGridFailures, fromCondensedGridFailures.getFailed);
 export const getCondensedGridFailuresData = createSelector(selectCondensedGridFailures, fromCondensedGridFailures.getData);
 
+// GridFailure reminder
+export const selectGridFailureReminder = createSelector(selectGridFailuresState, (state: GridFailureState) => state.gridFailureReminder);
+export const getGridFailureReminderLoaded = createSelector(selectGridFailureReminder, fromGridFailureReminder.getLoaded);
+export const getGridFailureReminderLoading = createSelector(selectGridFailureReminder, fromGridFailureReminder.getLoading);
+export const getGridFailureReminderFailed = createSelector(selectGridFailureReminder, fromGridFailureReminder.getFailed);
+export const getGridFailureReminderData = createSelector(selectGridFailureReminder, fromGridFailureReminder.getData);
+
 // GridFailureDistributionGroups
 export const selectGridFailureDistributionGroups = createSelector(selectGridFailuresState, (state: GridFailureState) => state.gridFailureDistributionGroups);
 export const getGridFailureDistributionGroupsLoaded = createSelector(selectGridFailureDistributionGroups, fromGridFailureDistributionGroups.getLoaded);
diff --git a/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-reminder.reducer.spec.ts b/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-reminder.reducer.spec.ts
new file mode 100644
index 0000000..4f18dae
--- /dev/null
+++ b/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-reminder.reducer.spec.ts
@@ -0,0 +1,85 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import {
+  GridFailureReminderReducer,
+  INITIAL_STATE,
+  getData,
+  getLoading,
+  getLoaded,
+  getFailed,
+  reducer,
+} from '@grid-failure-information-app/shared/store/reducers/grid-failures/grid-failure-reminder.reducer';
+import * as gridFailureActions from '@grid-failure-information-app/shared/store/actions/grid-failures.action';
+import { DistributionGroup } from '@grid-failure-information-app/shared/models';
+
+describe('GridFailureReminderReducer reducer', () => {
+  it('should return the initial state', () => {
+    const action = { type: 'NOOP' } as any;
+    const result = reducer(undefined, action);
+
+    expect(result).toBe(INITIAL_STATE);
+  });
+
+  it('should trigger loading state', () => {
+    const action = gridFailureActions.loadFailureReminder();
+    const result = GridFailureReminderReducer(INITIAL_STATE, action);
+
+    expect(result).toEqual({
+      ...INITIAL_STATE,
+      loading: true,
+    });
+  });
+
+  it('should trigger loaded state', () => {
+    const items = { payload: true };
+    const action = gridFailureActions.loadFailureReminderSuccess(items);
+    const result = GridFailureReminderReducer(INITIAL_STATE, action);
+
+    expect(result.loaded).toBe(true);
+  });
+
+  it('should trigger failed state', () => {
+    const error = { payload: 'err_msg' };
+    const action = gridFailureActions.loadFailureReminderFail(error);
+    const result = GridFailureReminderReducer(INITIAL_STATE, action);
+
+    expect(result).toEqual({
+      ...INITIAL_STATE,
+      failed: true,
+    });
+  });
+
+  it('getData return state.data', () => {
+    const state = { ...INITIAL_STATE };
+    const result = getData(state);
+    expect(result).toBe(state.data);
+  });
+
+  it('getLoading return state.loading', () => {
+    const state = { ...INITIAL_STATE };
+    const result = getLoading(state);
+    expect(result).toBe(state.loading);
+  });
+
+  it('getLoaded return state.loaded', () => {
+    const state = { ...INITIAL_STATE };
+    const result = getLoaded(state);
+    expect(result).toBe(state.loaded);
+  });
+
+  it('getFailed return state.failed', () => {
+    const state = { ...INITIAL_STATE };
+    const result = getFailed(state);
+    expect(result).toBe(state.failed);
+  });
+});
diff --git a/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-reminder.reducer.ts b/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-reminder.reducer.ts
new file mode 100644
index 0000000..e80aba1
--- /dev/null
+++ b/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-reminder.reducer.ts
@@ -0,0 +1,68 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+import * as gridFailureActions from '@grid-failure-information-app/shared/store/actions/grid-failures.action';
+import { DistributionGroup } from '@grid-failure-information-app/shared/models';
+import { createReducer, on } from '@ngrx/store';
+
+export interface State {
+  loading: boolean;
+  loaded: boolean;
+  failed: boolean;
+  data: boolean;
+}
+
+export const INITIAL_STATE: State = {
+  loading: false,
+  loaded: false,
+  failed: false,
+  data: false,
+};
+
+export const GridFailureReminderReducer = createReducer(
+  INITIAL_STATE,
+  on(gridFailureActions.loadFailureReminder, (state: any, action: any) => {
+    return {
+      ...state,
+      loading: true,
+      loaded: false,
+      failed: false,
+    };
+  }),
+  on(gridFailureActions.loadFailureReminderSuccess, (state: any, action: any) => {
+    return {
+      ...state,
+      loading: false,
+      loaded: true,
+      failed: false,
+      data: action['payload'],
+    };
+  }),
+  on(gridFailureActions.loadFailureReminderFail, (state: any, action: any) => {
+    return {
+      ...state,
+      loaded: false,
+      loading: false,
+      failed: true,
+      data: false,
+    };
+  })
+);
+
+export function reducer(state = INITIAL_STATE, action: any): State {
+  return GridFailureReminderReducer(state, action);
+}
+
+export const getData = (state: State) => state.data;
+export const getLoading = (state: State) => state.loading;
+export const getLoaded = (state: State) => state.loaded;
+export const getFailed = (state: State) => state.failed;