diff --git a/package.json b/package.json
index 39ec4150376324c4716d6d4ad396926450ff4ea2..f458233cbde6e933180626125c130f1f3dcbe33f 100644
--- a/package.json
+++ b/package.json
@@ -25,10 +25,9 @@
   "devDependencies": {
     "@angular/animations": "^9.0.0",
     "@angular/cdk": "^9.0.0",
-    "@angular/cdk-experimental": "^7.3.7",
     "@angular/common": "^9.0.0",
     "@angular/compiler": "^9.0.0",
-    "@angular/compiler-cli": "^9.0.0",
+    "@angular/compiler-cli": "^9.1.4",
     "@angular/core": "^9.0.0",
     "@angular/elements": "^9.0.0",
     "@angular/forms": "^9.0.0",
@@ -36,10 +35,7 @@
     "@angular/material": "^9.0.0",
     "@angular/platform-browser": "^9.0.0",
     "@angular/platform-browser-dynamic": "^9.0.0",
-    "@angular/router": "^9.0.0",
     "@material/dialog": "^4.0.0",
-    "@ngrx/effects": "^7.4.0",
-    "@ngrx/store": "^7.4.0",
     "@ngtools/webpack": "^9.0.1",
     "@types/jasmine": "^3.5.0",
     "@types/node": "^12.0.0",
@@ -47,7 +43,6 @@
     "@typescript-eslint/eslint-plugin": "^2.12.0",
     "@typescript-eslint/parser": "^2.12.0",
     "angular2-template-loader": "^0.6.2",
-    "bootstrap": "^4.4.1",
     "codelyzer": "^5.0.1",
     "core-js": "^3.0.1",
     "css-loader": "^3.2.0",
@@ -71,13 +66,14 @@
     "karma-webpack": "^3.0.0",
     "lodash.merge": "^4.6.2",
     "mini-css-extract-plugin": "^0.8.0",
-    "node-sass": "^4.12.0",
+    "node-sass": "^4.14.1",
     "protractor": "^6.0.0",
     "raw-loader": "^0.5.1",
     "reflect-metadata": "^0.1.12",
     "rxjs": "6.5.4",
     "sass-loader": "^7.2.0",
     "showdown": "^1.9.1",
+    "terser-webpack-plugin": "^3.0.1",
     "ts-loader": "^4.3.0",
     "ts-node": "^8.1.0",
     "typescript": "~3.7.5",
@@ -90,6 +86,8 @@
     "zone.js": "^0.10.2"
   },
   "dependencies": {
+    "@ngrx/effects": "^9.1.1",
+    "@ngrx/store": "^9.1.1",
     "hbp-connectivity-component": "^0.1.0"
   }
 }
diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts
index aacddc60b77f47538c7861b4aab2657e1c0edd44..9f816d2e307e48fb25af4cc21bf7bb1fdd3dae00 100644
--- a/src/atlasViewer/atlasViewer.component.ts
+++ b/src/atlasViewer/atlasViewer.component.ts
@@ -47,6 +47,8 @@ import { ARIA_LABELS } from 'common/constants'
 
 export const NEHUBA_CLICK_OVERRIDE = 'NEHUBA_CLICK_OVERRIDE'
 
+import { MIN_REQ_EXPLAINER } from 'src/util/constants'
+
 /**
  * TODO
  * check against auxlillary mesh indicies, to only filter out aux indicies
@@ -123,6 +125,8 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
 
   public onhoverSegmentsForFixed$: Observable<string[]>
 
+  public MIN_REQ_EXPLAINER = MIN_REQ_EXPLAINER
+
   constructor(
     private store: Store<IavRootStoreInterface>,
     private widgetServices: WidgetServices,
@@ -191,9 +195,9 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
     // TODO deprecate
     this.dedicatedView$ = this.store.pipe(
       select('viewerState'),
-      filter(state => isDefined(state) && typeof state.dedicatedView !== 'undefined'),
-      map(state => state.dedicatedView),
+      select('dedicatedView'),
       distinctUntilChanged(),
+      map(v => v[v.length -1])
     )
 
     // TODO temporary hack. even though the front octant is hidden, it seems if a mesh is present, hover will select the said mesh
@@ -241,7 +245,7 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
   }
 
   private selectedParcellation$: Observable<any>
-  private selectedParcellation: any
+  public selectedParcellation: any
 
   private cookieDialogRef: MatDialogRef<any>
   private kgTosDialogRef: MatDialogRef<any>
diff --git a/src/atlasViewer/atlasViewer.constantService.service.ts b/src/atlasViewer/atlasViewer.constantService.service.ts
index 56057d3be8df33a05ce589edb85a9a54b1b5cb27..867dd0c334ad86a061cd081c73e2183083e56468 100644
--- a/src/atlasViewer/atlasViewer.constantService.service.ts
+++ b/src/atlasViewer/atlasViewer.constantService.service.ts
@@ -180,12 +180,6 @@ export class AtlasViewerConstantsServices implements OnDestroy {
     pointHitRadius : 0,
   }
 
-  public minReqExplaner = `
-  - Interactive atlas viewer requires **webgl2.0**, and the \`EXT_color_buffer_float\` extension enabled.
-  - You can check browsers' support of webgl2.0 by visiting <https://caniuse.com/#feat=webgl2>
-  - Unfortunately, Safari and iOS devices currently do not support **webgl2.0**: <https://webkit.org/status/#specification-webgl-2>
-  `
-
   public minReqMD = `
 # Hmm... it seems like we hit a snag
 It seems your browser has trouble loading interactive atlas viewer.
diff --git a/src/atlasViewer/atlasViewer.template.html b/src/atlasViewer/atlasViewer.template.html
index 0dc97ab18a8e00a1bc18f9796aaa494d4e1243cb..cd35f9386379a17a7910d54bbe8179b961d89cce 100644
--- a/src/atlasViewer/atlasViewer.template.html
+++ b/src/atlasViewer/atlasViewer.template.html
@@ -119,8 +119,8 @@
 
     <div class="d-flex flex-row justify-content-end z-index-10 position-absolute pe-none w-100 h-100">
       <signin-banner
-          signinWrapper
-          [parcellationIsSelected]="selectedParcellation? true : false">
+        signinWrapper
+        [parcellationIsSelected]="!!selectedParcellation">
       </signin-banner>
     </div>
 
@@ -136,14 +136,14 @@
 
       <div floatingMouseContextualContainerDirective>
 
-        <div *ngIf="!ismobile && !presentDatasetDialogRef"
+        <div *ngIf="!ismobile"
           class="d-inline-block"
           iav-mouse-hover
           #iavMouseHoverContextualBlock="iavMouseHover"
           contextualBlock>
 
           <ng-container
-            *ngFor="let labelText of iavMouseHoverContextualBlock.currentOnHoverObs$ | async | mouseOverTextPipe : selectedParcellation">
+            *ngFor="let labelText of iavMouseHoverContextualBlock.currentOnHoverObs$ | async | mouseOverTextPipe">
 
             <mat-list dense>
 
@@ -180,9 +180,7 @@
                 class="pe-all"
                 [region]="onHoverRegion"
                 [isSelected]="selectedRegions$ | async | includes : onHoverRegion : compareFn"
-                [hasConnectivity]="selectedParcellation
-                  && selectedParcellation.hasAdditionalViewMode
-                  && selectedParcellation.hasAdditionalViewMode.includes('connectivity')"
+                [hasConnectivity]="selectedParcellation?.hasAdditionalViewMode?.includes('connectivity')"
                 (closeRegionMenu)="rClContextualMenu.hide()">
               </region-menu>
             </div>
@@ -227,7 +225,7 @@
         </p>
         <div class="col-6 d-inline-block text-left">
           <readmore-component [collapsedHeight]="0">
-            <markdown-dom [markdown]="constantsService.minReqExplaner">
+            <markdown-dom [markdown]="MIN_REQ_EXPLAINER">
 
             </markdown-dom>
           </readmore-component>
@@ -252,8 +250,3 @@
 <ng-template #logoTmpl>
   <logo-container></logo-container>
 </ng-template>
-
-<ng-template #persistentStateNotifierTemplate>
-  {{persistentStateNotifierMessage$ | async}}
-</ng-template>
-
diff --git a/src/services/state/uiState.store.ts b/src/services/state/uiState.store.ts
index b2403dd86aa4385d979fd2d9bd013358995e94c5..199cbf3c3c8e21040a31bbfda4f13d464078a11c 100644
--- a/src/services/state/uiState.store.ts
+++ b/src/services/state/uiState.store.ts
@@ -159,7 +159,7 @@ export interface StateInterface {
 
   focusedSidePanel: string | null
 
-  snackbarMessage: symbol
+  snackbarMessage: string
 
   agreedCookies: boolean
   agreedKgTos: boolean
diff --git a/src/ui/connectivityBrowser/connectivityBrowser.component.ts b/src/ui/connectivityBrowser/connectivityBrowser.component.ts
index d40fee0933041d63a08b9dad2e5617839721db44..dd6ca5d115b626146e375f10176f82e25a8694aa 100644
--- a/src/ui/connectivityBrowser/connectivityBrowser.component.ts
+++ b/src/ui/connectivityBrowser/connectivityBrowser.component.ts
@@ -23,7 +23,7 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy, A
     public region: string
     public datasetList: any[] = []
     public selectedDataset: any
-    private connectedAreas = []
+    public connectedAreas = []
     public componentHeight: any
 
     private connectivityRegion$: Observable<any>
diff --git a/src/ui/databrowserModule/bulkDownload/bulkDownloadBtn.component.ts b/src/ui/databrowserModule/bulkDownload/bulkDownloadBtn.component.ts
index 28dbf168600ae2902fba295f54b8d0672319237d..0291a5d31e790f0b6aca0303ca144db7817b9994 100644
--- a/src/ui/databrowserModule/bulkDownload/bulkDownloadBtn.component.ts
+++ b/src/ui/databrowserModule/bulkDownload/bulkDownloadBtn.component.ts
@@ -39,11 +39,12 @@ export class BulkDownloadBtn implements OnChanges{
 }
 
 @Pipe({
-  name: 'iavDatamoduleTransformDsToIdPipe'
+  name: 'iavDatamoduleTransformDsToIdPipe',
+  pure: true
 })
 
 export class TransformDatasetToIdPipe implements PipeTransform{
-  public transform(datasets: IDataEntry[]): string[]{
+  public transform(datasets: Partial<IDataEntry>[]): string[]{
     return datasets.map(({ fullId }) => {
       const re = getKgSchemaIdFromFullId(fullId)
       if (re) return re[1]
diff --git a/src/ui/databrowserModule/databrowser.service.ts b/src/ui/databrowserModule/databrowser.service.ts
index 2bb4c828b61241c778a4014834f2390766afc428..b0d6bc256f9f0bd652aa35afca04bdcec4b44c58 100644
--- a/src/ui/databrowserModule/databrowser.service.ts
+++ b/src/ui/databrowserModule/databrowser.service.ts
@@ -47,7 +47,7 @@ function generateToken() {
 export class DatabrowserService implements OnDestroy {
 
   public kgTos$: Observable<any>
-  public favedDataentries$: Observable<IDataEntry[]>
+  public favedDataentries$: Observable<Partial<IDataEntry>[]>
   public darktheme: boolean = false
 
   public instantiatedWidgetUnits: WidgetUnit[] = []
diff --git a/src/ui/databrowserModule/databrowser.useEffect.ts b/src/ui/databrowserModule/databrowser.useEffect.ts
index cfacc89069999af348764dc599f16acfddc5f69c..7a55fe649643910505bf5c09e541e1740f6137ab 100644
--- a/src/ui/databrowserModule/databrowser.useEffect.ts
+++ b/src/ui/databrowserModule/databrowser.useEffect.ts
@@ -425,7 +425,7 @@ export class DataBrowserUseEffect implements OnDestroy {
 
   private savedFav$: Observable<Array<{id: string, name: string}> | null>
 
-  private favDataEntries$: Observable<IDataEntry[]>
+  private favDataEntries$: Observable<Partial<IDataEntry>[]>
 
   @Effect()
   public favDataset$: Observable<any>
diff --git a/src/ui/databrowserModule/databrowser/databrowser.component.ts b/src/ui/databrowserModule/databrowser/databrowser.component.ts
index 39cfcff1dcc554485cb3d8ee267af93de7ac69f1..94167944cb254ca6b13435a0b23bcddf2bfcf9af 100644
--- a/src/ui/databrowserModule/databrowser/databrowser.component.ts
+++ b/src/ui/databrowserModule/databrowser/databrowser.component.ts
@@ -43,7 +43,7 @@ export class DataBrowser implements OnChanges, OnDestroy, OnInit {
   @ViewChild(ModalityPicker)
   public modalityPicker: ModalityPicker
 
-  public favDataentries$: Observable<IDataEntry[]>
+  public favDataentries$: Observable<Partial<IDataEntry>[]>
 
   /**
    * TODO
diff --git a/src/ui/databrowserModule/databrowser/databrowser.template.html b/src/ui/databrowserModule/databrowser/databrowser.template.html
index 9e0c3bd02a2db9bc6217186a3beb0092dd366c74..04e6637f81601377837f048ab8862e77c94d55ae 100644
--- a/src/ui/databrowserModule/databrowser/databrowser.template.html
+++ b/src/ui/databrowserModule/databrowser/databrowser.template.html
@@ -146,12 +146,3 @@
   </mat-accordion>
 
 </ng-template>
-
-<!-- currently unused -->
-<ng-template #history>
-  <mat-list>
-    <mat-list-item *ngFor="let item of (history$ | async)">
-      Viewed {{ item.file.name }}
-    </mat-list-item>
-  </mat-list>
-</ng-template>
\ No newline at end of file
diff --git a/src/ui/databrowserModule/singleDataset/singleDataset.base.ts b/src/ui/databrowserModule/singleDataset/singleDataset.base.ts
index 0caa4d51c49573510fe0a937b730145647b031f4..e856f8bc90afe07ea26f11034754abc7f9731ab6 100644
--- a/src/ui/databrowserModule/singleDataset/singleDataset.base.ts
+++ b/src/ui/databrowserModule/singleDataset/singleDataset.base.ts
@@ -67,7 +67,7 @@ export class SingleDatasetBase implements OnInit, OnChanges {
 
   public selectedTemplateSpace$: Observable<any>
 
-  public favedDataentries$: Observable<IDataEntry[]>
+  public favedDataentries$: Observable<Partial<IDataEntry>[]>
   constructor(
     private dbService: DatabrowserService,
     private singleDatasetService: KgSingleDatasetService,
diff --git a/src/ui/databrowserModule/util/datasetIsFaved.pipe.ts b/src/ui/databrowserModule/util/datasetIsFaved.pipe.ts
index dcb578417f01260b7cd00fbcbd6f6930e6ebc247..2c6c0f8eb0e3a5cbcbaa3d4c65ae83f23cb0df49 100644
--- a/src/ui/databrowserModule/util/datasetIsFaved.pipe.ts
+++ b/src/ui/databrowserModule/util/datasetIsFaved.pipe.ts
@@ -6,7 +6,7 @@ import { getKgSchemaIdFromFullId } from "./getKgSchemaIdFromFullId.pipe";
   name: 'datasetIsFaved',
 })
 export class DatasetIsFavedPipe implements PipeTransform {
-  public transform(favedDataEntry: IDataEntry[], dataentry: IDataEntry): boolean {
+  public transform(favedDataEntry: Partial<IDataEntry>[], dataentry: IDataEntry): boolean {
     if (!dataentry) { return false }
     const re2 = getKgSchemaIdFromFullId(dataentry.fullId)
     if (!re2) return false
diff --git a/src/ui/kgEntryViewer/kgentry.template.html b/src/ui/kgEntryViewer/kgentry.template.html
index 42e95d0156320d1e8e703bcd09364ea95121bc72..cb309ebd9a5bc6fc307968557c3e7357ef8b0faf 100644
--- a/src/ui/kgEntryViewer/kgentry.template.html
+++ b/src/ui/kgEntryViewer/kgentry.template.html
@@ -50,7 +50,7 @@
       License
     </div>
     <div body>
-      <div *ngFor="let l of dataset.licence">
+      <div *ngFor="let l of dataset.license">
         {{ l }}
       </div>
       <div *ngFor="let l of dataset.licenseInfo">
diff --git a/src/ui/layerbrowser/layerbrowser.component.ts b/src/ui/layerbrowser/layerbrowser.component.ts
index f72381f1347697e037d92331f89d5cb7277df383..91121d8f27731c516768eadbc6dc62de728a2c8b 100644
--- a/src/ui/layerbrowser/layerbrowser.component.ts
+++ b/src/ui/layerbrowser/layerbrowser.component.ts
@@ -7,7 +7,7 @@ import { LoggingService } from "src/logging";
 import { NG_VIEWER_ACTION_TYPES } from "src/services/state/ngViewerState.store";
 import { getViewer } from "src/util/fn";
 import { INgLayerInterface } from "../../atlasViewer/atlasViewer.component";
-import { FORCE_SHOW_SEGMENT, getNgIds, isDefined, REMOVE_NG_LAYER, safeFilter, ViewerStateInterface } from "../../services/stateStore.service";
+import { FORCE_SHOW_SEGMENT, getNgIds, isDefined, REMOVE_NG_LAYER, safeFilter, ViewerStateInterface, IavRootStoreInterface } from "../../services/stateStore.service";
 import { MatSliderChange } from "@angular/material/slider";
 
 @Component({
@@ -51,7 +51,7 @@ export class LayerBrowser implements OnInit, OnDestroy {
   private customNgLayers: string[] = ['spatial landmark layer']
 
   constructor(
-    private store: Store<ViewerStateInterface>,
+    private store: Store<IavRootStoreInterface>,
     private constantsService: AtlasViewerConstantsServices,
     private log: LoggingService,
   ) {
diff --git a/src/ui/nehubaContainer/nehubaContainer.component.ts b/src/ui/nehubaContainer/nehubaContainer.component.ts
index dc97e053c908a8cd4f19b470c15d3d383408a894..33ab824dcefec59da1d5b6728d30a3cdad38d94c 100644
--- a/src/ui/nehubaContainer/nehubaContainer.component.ts
+++ b/src/ui/nehubaContainer/nehubaContainer.component.ts
@@ -22,7 +22,7 @@ import {
 import { LoggingService } from "src/logging";
 import { FOUR_PANEL, H_ONE_THREE, NEHUBA_READY, NG_VIEWER_ACTION_TYPES, SINGLE_PANEL, V_ONE_THREE } from "src/services/state/ngViewerState.store";
 import { SELECT_REGIONS_WITH_ID, VIEWERSTATE_ACTION_TYPES } from "src/services/state/viewerState.store";
-import { ADD_NG_LAYER, generateLabelIndexId, getMultiNgIdsRegionsLabelIndexMap, getNgIds, ILandmark, IOtherLandmarkGeometry, IPlaneLandmarkGeometry, IPointLandmarkGeometry, isDefined, MOUSE_OVER_LANDMARK, NgViewerStateInterface, REMOVE_NG_LAYER, safeFilter, ViewerStateInterface } from "src/services/stateStore.service";
+import { ADD_NG_LAYER, generateLabelIndexId, getMultiNgIdsRegionsLabelIndexMap, getNgIds, ILandmark, IOtherLandmarkGeometry, IPlaneLandmarkGeometry, IPointLandmarkGeometry, isDefined, MOUSE_OVER_LANDMARK, NgViewerStateInterface, REMOVE_NG_LAYER, safeFilter, ViewerStateInterface, IavRootStoreInterface } from "src/services/stateStore.service";
 import { getExportNehuba, isSame } from "src/util/fn";
 import { AtlasViewerAPIServices, IUserLandmark } from "src/atlasViewer/atlasViewer.apiService.service";
 import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service";
@@ -113,10 +113,7 @@ export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
 
   public onHoverSegments$: Observable<any[]>
 
-  public spatialResultsVisible$: Observable<boolean>
-  private spatialResultsVisible: boolean = false
-
-  private selectedTemplate: any | null
+  public selectedTemplate: any | null
   private selectedRegionIndexSet: Set<string> = new Set()
   public fetchedSpatialData: ILandmark[] = []
 
@@ -146,7 +143,7 @@ export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
   constructor(
     private constantService: AtlasViewerConstantsServices,
     private apiService: AtlasViewerAPIServices,
-    private store: Store<ViewerStateInterface>,
+    private store: Store<IavRootStoreInterface>,
     private elementRef: ElementRef,
     private log: LoggingService,
     private cdr: ChangeDetectorRef
@@ -221,16 +218,6 @@ export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
       debounceTime(300),
     )
 
-    this.spatialResultsVisible$ = this.store.pipe(
-      select('spatialSearchState'),
-      map(state => isDefined(state) ?
-        isDefined(state.spatialDataVisible) ?
-          state.spatialDataVisible :
-          true :
-        true),
-      distinctUntilChanged(),
-    )
-
     this.userLandmarks$ = this.store.pipe(
       select('viewerState'),
       select('userLandmarks'),
@@ -408,11 +395,10 @@ export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
     this.subscriptions.push(
       combineLatest(
         this.fetchedSpatialDatasets$,
-        this.spatialResultsVisible$,
-      ).subscribe(([fetchedSpatialData, visible]) => {
+      ).subscribe(([fetchedSpatialData]) => {
         this.fetchedSpatialData = fetchedSpatialData
 
-        if (visible && this.fetchedSpatialData && this.fetchedSpatialData.length > 0) {
+        if (this.fetchedSpatialData && this.fetchedSpatialData.length > 0) {
           this.nehubaViewer.addSpatialSearch3DLandmarks(
             this.fetchedSpatialData
               .map(data => data.geometry.type === 'point'
@@ -445,10 +431,6 @@ export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
       }),
     )
 
-    this.subscriptions.push(
-      this.spatialResultsVisible$.subscribe(visible => this.spatialResultsVisible = visible),
-    )
-
     this.subscriptions.push(
       this.newViewer$.pipe(
         skip(1),
diff --git a/src/ui/nehubaContainer/splashScreen/splashScreen.component.ts b/src/ui/nehubaContainer/splashScreen/splashScreen.component.ts
index 8681248e788a5476e5d0b28abea58b32570b1d29..89c0178b74dc61c3351da5832bb5280630161996 100644
--- a/src/ui/nehubaContainer/splashScreen/splashScreen.component.ts
+++ b/src/ui/nehubaContainer/splashScreen/splashScreen.component.ts
@@ -3,7 +3,7 @@ import { select, Store } from "@ngrx/store";
 import { fromEvent, Observable, Subject, Subscription, combineLatest } from "rxjs";
 import { bufferTime, filter, map, switchMap, take, withLatestFrom, shareReplay, startWith } from 'rxjs/operators'
 import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service";
-import { NEWVIEWER, ViewerStateInterface } from "src/services/stateStore.service";
+import { NEWVIEWER, ViewerStateInterface, IavRootStoreInterface } from "src/services/stateStore.service";
 
 @Component({
   selector : 'ui-splashscreen',
@@ -19,12 +19,12 @@ export class SplashScreen implements AfterViewInit {
   public loadedTemplate$: Observable<any[]>
   @ViewChild('parentContainer', {read: ElementRef})
   private parentContainer: ElementRef
-  private activatedTemplate$: Subject<any> = new Subject()
+  public activatedTemplate$: Subject<any> = new Subject()
 
   private subscriptions: Subscription[] = []
 
   constructor(
-    private store: Store<ViewerStateInterface>,
+    private store: Store<IavRootStoreInterface>,
     private constanceService: AtlasViewerConstantsServices,
   ) {
     this.loadedTemplate$ = this.store.pipe(
diff --git a/src/ui/parcellationRegion/regionMenu/regionMenu.template.html b/src/ui/parcellationRegion/regionMenu/regionMenu.template.html
index 29daefc54deed588985927adf6e890805299d96b..587ec84ba6197faad01abf697bacadf553a846cc 100644
--- a/src/ui/parcellationRegion/regionMenu/regionMenu.template.html
+++ b/src/ui/parcellationRegion/regionMenu/regionMenu.template.html
@@ -50,7 +50,7 @@
               class="h-100 w-100"
               mat-ripple>
               <i class="far fa-eye" iav-v-button-icon></i>
-              <span iav-v-button-text [class]="(previewDirective.active | async) ? 'iv-custom-comp primary' : ''">Probability Map {{ previewDirective.active | async }}</span>
+              <span iav-v-button-text [class]="previewDirective.active ? 'iv-custom-comp primary' : ''">Probability Map {{ previewDirective.active }}</span>
             </iav-v-button>
           </mat-grid-tile>
         </ng-container> 
diff --git a/src/ui/sharedModules/angularMaterial.module.ts b/src/ui/sharedModules/angularMaterial.module.ts
index 0455c50b110e7ed3dc425acf169a8f7815e3c20f..d5384113b07877cc3d0c0a726387c2c38d5e64bf 100644
--- a/src/ui/sharedModules/angularMaterial.module.ts
+++ b/src/ui/sharedModules/angularMaterial.module.ts
@@ -13,7 +13,7 @@ import {MatSelectModule} from "@angular/material/select";
 import {MatChipsModule} from "@angular/material/chips";
 import {MatAutocompleteModule} from "@angular/material/autocomplete";
 
-import { ScrollingModule as ExperimentalScrollingModule } from '@angular/cdk-experimental/scrolling'
+import { ScrollingModule } from '@angular/cdk/scrolling'
 import {MatInputModule} from "@angular/material/input";
 import {MatSlideToggleModule} from "@angular/material/slide-toggle";
 import {MatListModule} from "@angular/material/list";
@@ -57,7 +57,7 @@ const defaultDialogOption: MatDialogConfig = new MatDialogConfig()
     MatGridListModule,
     MatIconModule,
     MatMenuModule,
-    ExperimentalScrollingModule,
+    ScrollingModule,
     MatToolbarModule,
     ClipboardModule,
   ],
@@ -86,7 +86,7 @@ const defaultDialogOption: MatDialogConfig = new MatDialogConfig()
     MatGridListModule,
     MatIconModule,
     MatMenuModule,
-    ExperimentalScrollingModule,
+    ScrollingModule,
     MatToolbarModule,
     ClipboardModule,
   ],
diff --git a/src/ui/signinBanner/signinBanner.components.ts b/src/ui/signinBanner/signinBanner.components.ts
index c5036ae52bfb8fbffb6c78dcfb8d9dcb190ddfd3..adeed41ba2cdf8b868397fe5194174889e2a68d4 100644
--- a/src/ui/signinBanner/signinBanner.components.ts
+++ b/src/ui/signinBanner/signinBanner.components.ts
@@ -34,7 +34,7 @@ export class SigninBanner {
 
   public user$: Observable<any>
   public userBtnTooltip$: Observable<string>
-  public favDataEntries$: Observable<IDataEntry[]>
+  public favDataEntries$: Observable<Partial<IDataEntry>[]>
 
   public pluginTooltipText: string = `Plugins and Tools`
   public screenshotTooltipText: string = 'Take screenshot'
diff --git a/src/ui/templateParcellationCitations/templateParcellationCitations.component.ts b/src/ui/templateParcellationCitations/templateParcellationCitations.component.ts
index 3a04ab1b33c42badecdcf0dac78e32605ea145e2..c97715d798fbf1345ee5832cd890d2ebcb0ef477 100644
--- a/src/ui/templateParcellationCitations/templateParcellationCitations.component.ts
+++ b/src/ui/templateParcellationCitations/templateParcellationCitations.component.ts
@@ -2,7 +2,7 @@ import { Component } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { Observable } from "rxjs";
 import { map, switchMap } from "rxjs/operators";
-import { safeFilter, ViewerStateInterface } from "../../services/stateStore.service";
+import { safeFilter, IavRootStoreInterface } from "../../services/stateStore.service";
 
 @Component({
   selector : 'template-parcellation-citation-container',
@@ -16,7 +16,7 @@ export class TemplateParcellationCitationsContainer {
   public selectedTemplate$: Observable<any>
   public selectedParcellation$: Observable<any>
 
-  constructor(private store: Store<ViewerStateInterface>) {
+  constructor(private store: Store<IavRootStoreInterface>) {
     this.selectedTemplate$ = this.store.pipe(
       select('viewerState'),
       safeFilter('templateSelected'),
diff --git a/src/util/constants.ts b/src/util/constants.ts
index a5776463a1751861ffc1946db557f3ff35c9bbb9..af922497ebe53f2d7c309a58a8fc4d61fbdace1e 100644
--- a/src/util/constants.ts
+++ b/src/util/constants.ts
@@ -13,3 +13,9 @@ export const COOKIE_VERSION = '0.3.0'
 export const KG_TOS_VERSION = '0.3.0'
 export const DS_PREVIEW_URL = DATASET_PREVIEW_URL
 export const BACKENDURL = BACKEND_URL || 'http://localhost:3000/'
+
+export const MIN_REQ_EXPLAINER = `
+- Interactive atlas viewer requires **webgl2.0**, and the \`EXT_color_buffer_float\` extension enabled.
+- You can check browsers' support of webgl2.0 by visiting <https://caniuse.com/#feat=webgl2>
+- Unfortunately, Safari and iOS devices currently do not support **webgl2.0**: <https://webkit.org/status/#specification-webgl-2>
+`
\ No newline at end of file
diff --git a/tsconfig-aot.json b/tsconfig-aot.json
index 7e541551de2f10d6e188764fe44de55db26581f5..15a0003e484369a70d602ca95fa1c95174849205 100644
--- a/tsconfig-aot.json
+++ b/tsconfig-aot.json
@@ -3,6 +3,7 @@
     "experimentalDecorators": true,
     "emitDecoratorMetadata": true,
     "moduleResolution": "node",
+    "module": "esnext",
     "target": "es2015",
     "sourceMap": false,
     "baseUrl": ".",
@@ -13,6 +14,8 @@
     }
   },
   "angularCompilerOptions":{
+    "fullTemplateTypeCheck": true,
+    "strictInjectionParameters": true,
     "annotateForClosureCompiler" : true
   }
 }
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index 59ee73b188970995b9fc4b12331823aa5ffef17c..1833901f2db9f5097d430a3b428314d13b8cb904 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,6 +3,7 @@
     "experimentalDecorators": true,
     "emitDecoratorMetadata": true,
     "moduleResolution": "node",
+    "module": "esnext",
     "target": "es2015",
     "sourceMap": true,
     "baseUrl": ".",
diff --git a/webpack.aot.js b/webpack.aot.js
index 8c815798d118033bf6a7662bbf4e32980cbd74d1..d6788dd3eb58747941a4a317d07e660051f856a9 100644
--- a/webpack.aot.js
+++ b/webpack.aot.js
@@ -6,9 +6,11 @@ const AngularCompilerPlugin = ngtools.AngularCompilerPlugin
 const ClosureCompilerPlugin = require('webpack-closure-compiler')
 const merge = require('webpack-merge')
 const staticAssets = require('./webpack.staticassets')
+const TerserPlugin = require('terser-webpack-plugin')
+const webpack = require('webpack')
 
 module.exports = merge(staticAssets, {
-
+  mode: 'production',
   entry : {
     main : './src/main-aot.ts'
   },
@@ -56,9 +58,21 @@ module.exports = merge(staticAssets, {
     }),
     new AngularCompilerPlugin({
       tsConfigPath: 'tsconfig-aot.json',
-      entryModule: 'src/main.module#MainModule'
+      entryModule: 'src/main.module#MainModule',
+      directTemplateLoading: true
+    }),
+    new webpack.DefinePlugin({
+      // TODO have to figure out how to set this properly
+      // needed to avoid inline eval
+      // shouldn't mode: 'production' do that already?
+      ngDevMode: false
     })
   ],
+  optimization: {
+    minimizer: [
+      new TerserPlugin()
+    ]
+  },
   resolve : {
     extensions : [
       '.ts',