diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts
index 59d7751b8340a5bfa5004369d4f3adeebadfae4a..014c570dc56d6da85efc41d9d315c8eca5e79925 100644
--- a/src/atlasViewer/atlasViewer.component.ts
+++ b/src/atlasViewer/atlasViewer.component.ts
@@ -33,6 +33,7 @@ export class AtlasViewer implements OnDestroy, OnInit {
   @ViewChild('databrowser', { read: ElementRef }) databrowser: ElementRef
   @ViewChild('floatingMouseContextualContainer', { read: ViewContainerRef }) floatingMouseContextualContainer: ViewContainerRef
   @ViewChild('helpComponent', {read: TemplateRef}) helpComponent : TemplateRef<any>
+  @ViewChild('viewerConfigComponent', {read: TemplateRef}) viewerConfigComponent : TemplateRef<any>
   @ViewChild(LayoutMainSide) layoutMainSide: LayoutMainSide
 
   @ViewChild(NehubaContainer) nehubaContainer: NehubaContainer
@@ -49,7 +50,8 @@ export class AtlasViewer implements OnDestroy, OnInit {
   private newViewer$: Observable<any>
 
   public selectedPOI$ : Observable<any[]>
-  public showHelp$: Observable<any>
+  private showHelp$: Observable<any>
+  private showConfig$: Observable<any>
 
   public dedicatedView$: Observable<string | null>
   public onhoverSegment$: Observable<string>
@@ -95,6 +97,10 @@ export class AtlasViewer implements OnDestroy, OnInit {
       debounceTime(170)
     )
 
+    this.showConfig$ = this.constantsService.showConfigSubject$.pipe(
+      debounceTime(170)
+    )
+
     this.selectedPOI$ = combineLatest(
       this.store.pipe(
         select('viewerState'),
@@ -182,6 +188,17 @@ export class AtlasViewer implements OnDestroy, OnInit {
       )
     )
 
+    this.subscriptions.push(
+      this.showConfig$.subscribe(() => {
+        this.modalService.show(ModalUnit, {
+          initialState: {
+            title: this.constantsService.showConfigTitle,
+            template: this.viewerConfigComponent
+          }
+        })
+      })
+    )
+
     this.subscriptions.push(
       this.ngLayerNames$.pipe(
         concatMap(data => this.constantsService.loadExportNehubaPromise.then(data))
diff --git a/src/atlasViewer/atlasViewer.constantService.service.ts b/src/atlasViewer/atlasViewer.constantService.service.ts
index cc1e6b0bf5c315b7b927c2caf49ec45cbbc3a2a0..ead53d9e364375cbea6786064a70614751f329ae 100644
--- a/src/atlasViewer/atlasViewer.constantService.service.ts
+++ b/src/atlasViewer/atlasViewer.constantService.service.ts
@@ -2,7 +2,7 @@ import { Injectable } from "@angular/core";
 import { Store } from "@ngrx/store";
 import { ViewerStateInterface, Property, FETCHED_METADATA } from "../services/stateStore.service";
 import { Subject } from "rxjs";
-
+import { ACTION_TYPES, ViewerConfiguration, viewerConfigState } from 'src/services/state/viewerConfig.store'
 
 @Injectable({
   providedIn : 'root'
@@ -137,6 +137,11 @@ Interactive atlas viewer requires **webgl2.0**, and the \`EXT_color_buffer_float
    */
   public toggleMessage: string = 'double click to toggle select'
 
+  /**
+   * Observable for showing config modal
+   */
+  public showConfigSubject$: Subject<null> = new Subject()
+  public showConfigTitle: String = 'Settings'
   /**
    * Observable for showing help modal
    */
@@ -210,6 +215,18 @@ Interactive atlas viewer requires **webgl2.0**, and the \`EXT_color_buffer_float
     /* https://stackoverflow.com/a/25394023/6059235 */
     this.mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i.test(ua)
 
+    /**
+     * set gpu limit if user is on mobile
+     */
+    if (this.mobile) {
+      this.store.dispatch({
+        type: ACTION_TYPES.UPDATE_CONFIG,
+        config: {
+          gpuLimit: 2e8
+        } as Partial<ViewerConfiguration>
+      })  
+    }
+
     const meta = 'res/json/allAggregatedData.json'
   
     fetch(meta)
diff --git a/src/atlasViewer/atlasViewer.pluginService.service.ts b/src/atlasViewer/atlasViewer.pluginService.service.ts
index 390fd9156c82ba4864244d6cd1f71c13cea9fa8f..8bf27a5f3a7dee3cbcda9be7ba4a62b1acee0ee2 100644
--- a/src/atlasViewer/atlasViewer.pluginService.service.ts
+++ b/src/atlasViewer/atlasViewer.pluginService.service.ts
@@ -1,6 +1,7 @@
 import { Injectable, ViewContainerRef, ComponentFactoryResolver, ComponentFactory } from "@angular/core";
 import { AtlasViewerDataService } from "./atlasViewer.dataService.service";
-import { isDefined, PluginInitManifestInterface, SET_INIT_PLUGIN } from "../services/stateStore.service";
+import { PluginInitManifestInterface, ACTION_TYPES } from "src/services/state/pluginState.store";
+import { isDefined } from 'src/services/stateStore.service'
 import { AtlasViewerAPIServices } from "./atlasViewer.apiService.service";
 import { PluginUnit } from "./pluginUnit/pluginUnit.component";
 import { WidgetServices } from "./widgetUnit/widgetService.service";
@@ -87,7 +88,7 @@ export class PluginServices{
           : null
 
         handler.setInitManifestUrl = (url) => this.store.dispatch({
-          type : SET_INIT_PLUGIN,
+          type : ACTION_TYPES.SET_INIT_PLUGIN,
           manifest : {
             name : plugin.name,
             initManifestUrl : url
diff --git a/src/atlasViewer/atlasViewer.template.html b/src/atlasViewer/atlasViewer.template.html
index 85b14f2aff0545c8f5551cb6eb73fa4733dc5da0..fbdb2f07935e84a824861b7b6adcc8ff22b0d2ce 100644
--- a/src/atlasViewer/atlasViewer.template.html
+++ b/src/atlasViewer/atlasViewer.template.html
@@ -179,7 +179,12 @@
 </div>
 
 <ng-template #helpComponent>
-  <help-component></help-component>
+  <help-component>
+  </help-component>
+</ng-template>
+<ng-template #viewerConfigComponent>
+  <config-component>
+  </config-component>
 </ng-template>
 
 <markdown-dom minReqMd *ngIf = "!meetsRequirement" [markdown] = "constantsService.minReqMD" >
diff --git a/src/atlasViewer/atlasViewer.urlService.service.ts b/src/atlasViewer/atlasViewer.urlService.service.ts
index 5aa63426f2d52de25b01b7bcf3d5a2a226d8eec6..52408d9c10662c60503d7c5474475c556bf27728 100644
--- a/src/atlasViewer/atlasViewer.urlService.service.ts
+++ b/src/atlasViewer/atlasViewer.urlService.service.ts
@@ -1,6 +1,7 @@
 import { Injectable } from "@angular/core";
 import { Store, select } from "@ngrx/store";
-import { ViewerStateInterface, isDefined, NEWVIEWER, getLabelIndexMap, SELECT_REGIONS, CHANGE_NAVIGATION, LOAD_DEDICATED_LAYER, ADD_NG_LAYER, PluginInitManifestInterface } from "../services/stateStore.service";
+import { ViewerStateInterface, isDefined, NEWVIEWER, getLabelIndexMap, SELECT_REGIONS, CHANGE_NAVIGATION, ADD_NG_LAYER } from "../services/stateStore.service";
+import { PluginInitManifestInterface } from 'src/services/state/pluginState.store'
 import { Observable,combineLatest } from "rxjs";
 import { filter, map, scan, distinctUntilChanged, skipWhile, take } from "rxjs/operators";
 import { getActiveColorMapFragmentMain } from "../ui/nehubaContainer/nehubaContainer.component";
diff --git a/src/main.module.ts b/src/main.module.ts
index e04add7c374f89020a29e6d011139fd397433b64..65c41e5591377a13780af5e1d0555b8dae0d2939 100644
--- a/src/main.module.ts
+++ b/src/main.module.ts
@@ -4,7 +4,7 @@ import { UIModule } from "./ui/ui.module";
 import { LayoutModule } from "./layouts/layout.module";
 import { AtlasViewer } from "./atlasViewer/atlasViewer.component";
 import { StoreModule } from "@ngrx/store";
-import { viewerState, dataStore,spatialSearchState,uiState, ngViewerState, pluginState } from "./services/stateStore.service";
+import { viewerState, dataStore,spatialSearchState,uiState, ngViewerState, states } from "./services/stateStore.service";
 import { GetNamesPipe } from "./util/pipes/getNames.pipe";
 import { CommonModule } from "@angular/common";
 import { GetNamePipe } from "./util/pipes/getName.pipe";
@@ -49,7 +49,7 @@ import { FloatingMouseContextualContainerDirective } from "./util/directives/flo
       spatialSearchState,
       uiState,
       ngViewerState,
-      pluginState
+      ...states
     })
   ],
   declarations : [
diff --git a/src/services/state/pluginState.store.ts b/src/services/state/pluginState.store.ts
new file mode 100644
index 0000000000000000000000000000000000000000..35cc5dd1dcdfadda1493a7d6edd87e6f8bc7436a
--- /dev/null
+++ b/src/services/state/pluginState.store.ts
@@ -0,0 +1,30 @@
+import { Action } from '@ngrx/store'
+
+
+export interface PluginInitManifestInterface{
+  initManifests : Map<string,string|null>
+}
+
+export interface PluginInitManifestActionInterface extends Action{
+  manifest: {
+    name : string,
+    initManifestUrl : string | null
+  }
+}
+
+export const ACTION_TYPES = {
+  SET_INIT_PLUGIN: `SET_INIT_PLUGIN`
+}
+
+export function pluginState(prevState:PluginInitManifestInterface = {initManifests : new Map()}, action:PluginInitManifestActionInterface):PluginInitManifestInterface{
+  switch(action.type){
+    case ACTION_TYPES.SET_INIT_PLUGIN:
+      const newMap = new Map(prevState.initManifests)
+      return {
+        ...prevState,
+        initManifests: newMap.set(action.manifest.name, action.manifest.initManifestUrl)
+      }
+    default:
+      return prevState
+  }
+}
diff --git a/src/services/state/viewerConfig.store.ts b/src/services/state/viewerConfig.store.ts
new file mode 100644
index 0000000000000000000000000000000000000000..631def221573e6bfad560dce0f6d08cb830c99b0
--- /dev/null
+++ b/src/services/state/viewerConfig.store.ts
@@ -0,0 +1,48 @@
+import { Action } from "@ngrx/store";
+
+export interface ViewerConfiguration{
+  gpuLimit: number
+  animation: boolean
+}
+
+interface ViewerConfigurationAction extends Action{
+  config: Partial<ViewerConfiguration>,
+  payload: any
+}
+
+export const CONFIG_CONSTANTS = {
+  /**
+   * byets
+   */
+  gpuLimitMin: 1e8, 
+  gpuLimitMax: 1e9
+}
+
+export const ACTION_TYPES = {
+  UPDATE_CONFIG: `UPDATE_CONFIG`,
+  CHANGE_GPU_LIMIT: `CHANGE_GPU_LIMIT`
+}
+
+export function viewerConfigState(prevState:ViewerConfiguration = {gpuLimit: 1e9, animation: true}, action:ViewerConfigurationAction) {
+  switch (action.type) {
+    case ACTION_TYPES.UPDATE_CONFIG:
+      return {
+        ...prevState,
+        ...action.config
+      }
+    case ACTION_TYPES.CHANGE_GPU_LIMIT:
+      const newGpuLimit = Math.min(
+        CONFIG_CONSTANTS.gpuLimitMax,
+        Math.max(
+          prevState.gpuLimit + action.payload.delta,
+          CONFIG_CONSTANTS.gpuLimitMin
+        ))
+
+      return {
+        ...prevState,
+        gpuLimit: newGpuLimit
+      }
+    default:
+      return prevState
+  }
+}
\ No newline at end of file
diff --git a/src/services/stateStore.service.ts b/src/services/stateStore.service.ts
index 52e4df7e6c6db7039ac980ddde421e4a8af56e44..d33ea4df51702ed06d6187db37cd00e15e3f8883 100644
--- a/src/services/stateStore.service.ts
+++ b/src/services/stateStore.service.ts
@@ -1,6 +1,13 @@
 import { Action } from '@ngrx/store'
 import { filter } from 'rxjs/operators';
 import { UserLandmark } from '../atlasViewer/atlasViewer.apiService.service';
+import { pluginState } from './state/pluginState.store'
+import { viewerConfigState } from './state/viewerConfig.store'
+
+export const states = {
+  pluginState,
+  viewerConfigState
+}
 
 export const NEWVIEWER = 'NEWVIEWER'
 
@@ -32,20 +39,10 @@ export const OPEN_SIDE_PANEL = `OPEN_SIDE_PANEL`
 export const MOUSE_OVER_SEGMENT = `MOUSE_OVER_SEGMENT`
 export const MOUSE_OVER_LANDMARK = `MOUSE_OVER_LANDMARK`
 
-export const SET_INIT_PLUGIN = `SET_INIT_PLUGIN`
 export const FETCHED_PLUGIN_MANIFESTS = `FETCHED_PLUGIN_MANIFESTS`
 export const LAUNCH_PLUGIN = `LAUNCH_PLUGIN`
 
-export interface PluginInitManifestInterface{
-  initManifests : Map<string,string|null>
-}
 
-export interface PluginInitManifestActionInterface extends Action{
-  manifest: {
-    name : string,
-    initManifestUrl : string | null
-  }
-}
 
 export interface ViewerStateInterface{
   fetchedTemplates : any[]
@@ -121,39 +118,6 @@ export interface NgViewerAction extends Action{
   forceShowSegment : boolean
 }
 
-
-/**
- * TODO unused function, remove
- */
-const mapLayer = (existingLayer:NgLayerInterface, incomingLayer:NgLayerInterface):NgLayerInterface => {
-  return incomingLayer.mixability === 'base'
-    ? existingLayer
-    : incomingLayer.mixability === 'mixable'
-      ? existingLayer.mixability === 'nonmixable'
-        ? Object.assign({}, existingLayer, {
-            visible : false
-          } as NgLayerInterface)
-        : existingLayer
-      /* incomingLayer.mixability === 'nonmixable' */
-      : existingLayer.mixability === 'base'
-        ? existingLayer
-        : Object.assign({}, existingLayer, {
-            visible : false
-          } as NgLayerInterface)
-}
-
-export function pluginState(prevState:PluginInitManifestInterface = {initManifests : new Map()}, action:PluginInitManifestActionInterface):PluginInitManifestInterface{
-  switch(action.type){
-    case SET_INIT_PLUGIN:
-      const newMap = new Map(prevState.initManifests)
-      return Object.assign({}, prevState, {
-        initManifests : newMap.set(action.manifest.name, action.manifest.initManifestUrl)
-      } as PluginInitManifestInterface)
-    default:
-      return prevState
-  }
-}
-
 export function ngViewerState(prevState:NgViewerStateInterface = {layers:[], forceShowSegment:null}, action:NgViewerAction):NgViewerStateInterface{
   switch(action.type){
     case ADD_NG_LAYER:
diff --git a/src/ui/banner/banner.component.ts b/src/ui/banner/banner.component.ts
index fc75046e2c26bedc769d8f8624e20543b3bf48f5..fde833e0f2aad51685d1d13db292a67ad33bb916 100644
--- a/src/ui/banner/banner.component.ts
+++ b/src/ui/banner/banner.component.ts
@@ -288,6 +288,10 @@ export class AtlasBanner implements OnDestroy, OnInit {
     this.constantService.showHelpSubject$.next()
   }
 
+  showConfig() {
+    this.constantService.showConfigSubject$.next()
+  }
+
   get toastDuration() {
     return this.constantService.citationToastDuration
   }
diff --git a/src/ui/banner/banner.template.html b/src/ui/banner/banner.template.html
index 7dfc5fb9b87bd2092053e5ab6c5fc170f1aad457..7028ad6406b541413ff62a852eaa928f77a8b478 100644
--- a/src/ui/banner/banner.template.html
+++ b/src/ui/banner/banner.template.html
@@ -1,15 +1,15 @@
 <dropdown-component
-  (itemSelected) = "selectTemplate($event)"
-  [activeDisplay] = "displayActiveTemplate"
-  [selectedItem] = "selectedTemplate"
-  [inputArray] = "loadedTemplates$ | async | filterNull">
+  (itemSelected)="selectTemplate($event)"
+  [activeDisplay]="displayActiveTemplate"
+  [selectedItem]="selectedTemplate"
+  [inputArray]="loadedTemplates$ | async | filterNull">
 
 </dropdown-component>
 
 <i 
-  *ngIf = "citationExists(selectedTemplate) && !isMobile" 
-  [toastLength] = "toastDuration"
-  [showToast] = "citation"
+  *ngIf="citationExists(selectedTemplate) && !isMobile" 
+  [toastLength]="toastDuration"
+  [showToast]="citation"
   class="glyphicon glyphicon-info-sign"
   #templateCitationAnchor>
 
@@ -18,24 +18,24 @@
       Citations for {{ selectedTemplate ? selectedTemplate.name : '' }} 
     </h4>
     <citations-component
-      [properties] = "selectedTemplate.properties">
+      [properties]="selectedTemplate.properties">
     </citations-component>
   </ng-template>
 
 </i>
 
 <dropdown-component
-  *ngIf = "selectedTemplate"
-  (itemSelected) = "selectParcellation($event)"
-  [activeDisplay] = "displayActiveParcellation"
-  [selectedItem] = "selectedParcellation"
-  [inputArray] = "selectedTemplate.parcellations">
+  *ngIf="selectedTemplate"
+  (itemSelected)="selectParcellation($event)"
+  [activeDisplay]="displayActiveParcellation"
+  [selectedItem]="selectedParcellation"
+  [inputArray]="selectedTemplate.parcellations">
 </dropdown-component>
 
 <i 
-  *ngIf = "citationExists(selectedParcellation) && !isMobile" 
-  [toastLength] = "toastDuration"
-  [showToast] = "citation"
+  *ngIf="citationExists(selectedParcellation) && !isMobile" 
+  [toastLength]="toastDuration"
+  [showToast]="citation"
   class="glyphicon glyphicon-info-sign"
   #parcellationCitationAnchor>
   <ng-template #citation>
@@ -43,49 +43,56 @@
       Citations for {{ selectedParcellation ? selectedParcellation.name : '' }} 
     </h4>
     <citations-component
-      [properties] = "selectedParcellation.properties">
+      [properties]="selectedParcellation.properties">
     </citations-component>
   </ng-template>
 </i>
 
 <div 
-  *ngIf = "selectedTemplate"
+  *ngIf="selectedTemplate"
   #searchRegionPopover
   searchRegionPopover>
 
   <input 
-    (keydown.esc) = "showRegionTree = false; $event.target.blur(); searchTerm = ''"
-    (focus) = "showRegionTree = true"
-    [value] = "searchTerm"
-    (input) = "changeSearchTerm($event)"
-    class = "form-control" 
+    (keydown.esc)="showRegionTree=false; $event.target.blur(); searchTerm=''"
+    (focus)="showRegionTree=true"
+    [value]="searchTerm"
+    (input)="changeSearchTerm($event)"
+    class="form-control" 
     type="text" 
     placeholder="Regions"/>
     
   <div 
     [@showState]
-    *ngIf = "showRegionTree" 
+    *ngIf="showRegionTree" 
     hideScrollbarContainer>
 
     <div treeContainer #treeContainer>
       <div treeHeader>
         <span>{{ selectedRegions.length }} {{ selectedRegions.length > 1 ? 'regions' : 'region' }} selected</span> 
-        <span (click) = "clearRegions($event)" *ngIf = "selectedRegions.length > 0" class = "btn btn-link">clear all</span>
+        <span (click)="clearRegions($event)" *ngIf="selectedRegions.length > 0" class="btn btn-link">clear all</span>
       </div>
       
       <flat-tree-component 
-        [flatTreeViewPort] = "treeContainer"
-        (treeNodeClick) = "handleClickRegion($event)"
-        [inputItem] = "aggregatedRegionTree"
-        [renderNode] = "displayTreeNode.bind(this)"
-        [searchFilter] = "filterTreeBySearch.bind(this)">
+        [flatTreeViewPort]="treeContainer"
+        (treeNodeClick)="handleClickRegion($event)"
+        [inputItem]="aggregatedRegionTree"
+        [renderNode]="displayTreeNode.bind(this)"
+        [searchFilter]="filterTreeBySearch.bind(this)">
         
       </flat-tree-component>
     </div>
   </div>
 </div>
 
-<div *ngIf = "isMobile" class = "help-container">
-  <i (click) = "showHelp()" class="glyphicon glyphicon-question-sign"></i>
+<!-- help btn -->
+<div *ngIf="isMobile" class="help-container">
+  <i (click)="showHelp()" class="glyphicon glyphicon-question-sign"></i>
 </div>
-<i *ngIf = "!isMobile" (click) = "showHelp()" class="glyphicon glyphicon-question-sign"></i>
+<i *ngIf="!isMobile" (click)="showHelp()" class="glyphicon glyphicon-question-sign"></i>
+
+<!-- config btn -->
+<div *ngIf="isMobile" class="help-container">
+  <i (click)="showConfig()" class="glyphicon glyphicon-cog"></i>
+</div>
+<i *ngIf="!isMobile" (click)="showConfig()" class="glyphicon glyphicon-cog"></i>
diff --git a/src/ui/config/config.component.ts b/src/ui/config/config.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..51769165babb28cb9a41a0e3451df81633b3add1
--- /dev/null
+++ b/src/ui/config/config.component.ts
@@ -0,0 +1,47 @@
+import { Component } from '@angular/core'
+import { Store, select } from '@ngrx/store';
+import { ViewerConfiguration, ACTION_TYPES } from 'src/services/state/viewerConfig.store'
+import { Observable } from 'rxjs';
+import { map, distinctUntilChanged } from 'rxjs/operators';
+
+@Component({
+  selector: 'config-component',
+  templateUrl: './config.template.html',
+  styleUrls: [
+    './config.style.css'
+  ]
+})
+
+export class ConfigComponent{
+
+  /**
+   * in MB
+   */
+  public gpuLimit$: Observable<number>
+  
+  constructor(private store: Store<ViewerConfiguration>) {
+    this.gpuLimit$ = this.store.pipe(
+      select('viewerConfigState'),
+      map((config:ViewerConfiguration) => config.gpuLimit),
+      distinctUntilChanged(),
+      map(v => v / 1e6)
+    )
+  }
+
+  public wheelEvent(ev:WheelEvent) {
+    const delta = ev.deltaY * -1e5
+    this.store.dispatch({
+      type: ACTION_TYPES.CHANGE_GPU_LIMIT,
+      payload: { delta }
+    })
+  }
+
+  public setGpuPreset({value}: {value: number}) {
+    this.store.dispatch({
+      type: ACTION_TYPES.UPDATE_CONFIG,
+      config: {
+        gpuLimit: value * 1e6
+      }
+    })
+  }
+}
\ No newline at end of file
diff --git a/src/ui/config/config.style.css b/src/ui/config/config.style.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/ui/config/config.template.html b/src/ui/config/config.template.html
new file mode 100644
index 0000000000000000000000000000000000000000..34b6ef179db65e509e67e9cb300cebd14344e450
--- /dev/null
+++ b/src/ui/config/config.template.html
@@ -0,0 +1,24 @@
+<div class="input-group">
+  <span class="input-group-addon">
+    GPU Limit
+  </span>
+  <input
+    (wheel)="wheelEvent($event)"
+    type="number"
+    class="form-control"
+    [value]="gpuLimit$ | async ">
+  <div class="input-group-btn">
+    <div (click)="setGpuPreset({ value: 100 })" class="btn btn-default">
+      100
+    </div>
+    <div (click)="setGpuPreset({ value: 500 })" class="btn btn-default">
+      500
+    </div>
+    <div (click)="setGpuPreset({ value: 1000 })" class="btn btn-default">
+      1000
+    </div>
+  </div>
+  <span class="input-group-addon">
+    MB
+  </span>
+</div>
\ No newline at end of file
diff --git a/src/ui/nehubaContainer/nehubaContainer.component.ts b/src/ui/nehubaContainer/nehubaContainer.component.ts
index f97f445181d8f8f357c72bbcaabf86b5d5310072..8f46c8c7ee11c09a61e2ea9fb8a4f9a81bdc0fc1 100644
--- a/src/ui/nehubaContainer/nehubaContainer.component.ts
+++ b/src/ui/nehubaContainer/nehubaContainer.component.ts
@@ -8,6 +8,7 @@ import { AtlasViewerAPIServices, UserLandmark } from "../../atlasViewer/atlasVie
 import { timedValues } from "../../util/generator";
 import { AtlasViewerDataService } from "../../atlasViewer/atlasViewer.dataService.service";
 import { AtlasViewerConstantsServices } from "../../atlasViewer/atlasViewer.constantService.service";
+import { ViewerConfiguration } from "src/services/state/viewerConfig.store";
 
 @Component({
   selector : 'ui-nehuba-container',
@@ -29,6 +30,8 @@ export class NehubaContainer implements OnInit, OnDestroy{
 
   public viewerLoaded : boolean = false
 
+  private viewerPerformanceConfig$: Observable<ViewerConfiguration>
+
   public sliceViewLoading0$: Observable<boolean>
   public sliceViewLoading1$: Observable<boolean>
   public sliceViewLoading2$: Observable<boolean>
@@ -81,6 +84,17 @@ export class NehubaContainer implements OnInit, OnDestroy{
     private store : Store<ViewerStateInterface>,
     private elementRef : ElementRef
   ){
+    this.viewerPerformanceConfig$ = this.store.pipe(
+      select('viewerConfigState'),
+      /**
+       * TODO: this is only a bandaid fix. Technically, we should also implement
+       * logic to take the previously set config to apply oninit
+       */
+      filter(() => isDefined(this.nehubaViewer) && isDefined(this.nehubaViewer.nehubaViewer)),
+      distinctUntilChanged(),
+      debounceTime(200)
+    )
+
     this.nehubaViewerFactory = this.csf.resolveComponentFactory(NehubaViewerUnit)
 
     this.newViewer$ = this.store.pipe(
@@ -274,6 +288,12 @@ export class NehubaContainer implements OnInit, OnDestroy{
 
   ngOnInit(){
 
+    this.subscriptions.push(
+      this.viewerPerformanceConfig$.subscribe(config => {
+        this.nehubaViewer.applyPerformanceConfig(config)
+      })
+    )
+
     this.subscriptions.push(
       this.fetchedSpatialDatasets$.subscribe(datasets => {
         this.landmarksLabelIndexMap = new Map(datasets.map((v,idx) => [idx, v]) as [number, any][])
@@ -882,6 +902,11 @@ export class NehubaContainer implements OnInit, OnDestroy{
     /* extract the animation object */
     const { animation, ..._navigation } = navigation
 
+    /**
+     * remove keys that are falsy
+     */
+    Object.keys(_navigation).forEach(key => (!_navigation[key]) && delete _navigation[key])
+    
     if( animation ){
       /* animated */
 
@@ -981,28 +1006,28 @@ export class NehubaContainer implements OnInit, OnDestroy{
     return this.selectedTemplate && this.selectedTemplate.properties && this.selectedTemplate.properties.publications && this.selectedTemplate.properties.publications.constructor === Array
   }
 
-  resetNavigation(){
+  resetNavigation({rotation: rotationFlag = false, position: positionFlag = false, zoom : zoomFlag = false} : {rotation: boolean, position: boolean, zoom: boolean}){
     const initialNgState = this.selectedTemplate.nehubaConfig.dataset.initialNgState
     
     const perspectiveZoom = initialNgState ? initialNgState.perspectiveZoom : undefined
     const perspectiveOrientation = initialNgState ? initialNgState.perspectiveOrientation : undefined
-    const zoom = initialNgState ? 
-      initialNgState.navigation ?
-        initialNgState.navigation.zoomFactor :
-        undefined :
-      undefined
-
-    const position = initialNgState ? 
-      initialNgState.navigation ?
-        initialNgState.navigation.pose ?
-          initialNgState.navigation.pose.position.voxelCoordinates ?
-            initialNgState.navigation.pose.position.voxelCoordinates :
-            undefined :
-          undefined :
-        undefined :
-      undefined
-
-    const orientation = [0,0,0,1]
+    const zoom = (zoomFlag
+      && initialNgState
+      && initialNgState.navigation
+      && initialNgState.navigation.zoomFactor)
+      || undefined
+
+    const position = (positionFlag
+      && initialNgState
+      && initialNgState.navigation
+      && initialNgState.navigation.pose
+      && initialNgState.navigation.pose.position.voxelCoordinates
+      && initialNgState.navigation.pose.position.voxelCoordinates)
+      || undefined
+
+    const orientation = rotationFlag
+      ? [0,0,0,1]
+      : undefined
 
     this.store.dispatch({
       type : CHANGE_NAVIGATION,
diff --git a/src/ui/nehubaContainer/nehubaContainer.template.html b/src/ui/nehubaContainer/nehubaContainer.template.html
index 7c945595b5357e1568941e801dd52b10de5d1cd7..3334c087fa64293a2acbfd78fc9bd8994e67ff94 100644
--- a/src/ui/nehubaContainer/nehubaContainer.template.html
+++ b/src/ui/nehubaContainer/nehubaContainer.template.html
@@ -1,7 +1,7 @@
 <ng-template #container>
 </ng-template>
 
-<ui-splashscreen *ngIf = "!viewerLoaded">
+<ui-splashscreen *ngIf="!viewerLoaded">
 </ui-splashscreen>
 
 <div landmarkMasterContainer>
@@ -11,18 +11,18 @@
       pos00 
       landmarkContainer>
       <nehuba-2dlandmark-unit 
-        *ngFor = "let spatialData of (selectedPtLandmarks$ | async)"
-        (mouseenter) = "handleMouseEnterLandmark(spatialData)"
-        (mouseleave) = "handleMouseLeaveLandmark(spatialData)"
-        [highlight] = "spatialData.highlight ? spatialData.highlight : false"
-        [glyphiconClass] = "spatialData.type === 'userLandmark' ? 'glyphicon-chevron-down' : 'glyphicon-map-marker'"
-        [positionX] = "getPositionX(0,spatialData)"
-        [positionY] = "getPositionY(0,spatialData)"
-        [positionZ] = "getPositionZ(0,spatialData)">
+        *ngFor="let spatialData of (selectedPtLandmarks$ | async)"
+        (mouseenter)="handleMouseEnterLandmark(spatialData)"
+        (mouseleave)="handleMouseLeaveLandmark(spatialData)"
+        [highlight]="spatialData.highlight ? spatialData.highlight : false"
+        [glyphiconClass]="spatialData.type === 'userLandmark' ? 'glyphicon-chevron-down' : 'glyphicon-map-marker'"
+        [positionX]="getPositionX(0,spatialData)"
+        [positionY]="getPositionY(0,spatialData)"
+        [positionZ]="getPositionZ(0,spatialData)">
       </nehuba-2dlandmark-unit>
 
-      <div *ngIf = "sliceViewLoading0$ | async" class = "loadingIndicator">
-        <div class = "spinnerAnimationCircle">
+      <div *ngIf="sliceViewLoading0$ | async" class="loadingIndicator">
+        <div class="spinnerAnimationCircle">
 
         </div>
       </div>
@@ -33,18 +33,18 @@
       pos01 
       landmarkContainer>
       <nehuba-2dlandmark-unit 
-        *ngFor = "let spatialData of (selectedPtLandmarks$ | async)"
-        (mouseenter) = "handleMouseEnterLandmark(spatialData)"
-        (mouseleave) = "handleMouseLeaveLandmark(spatialData)"
-        [highlight] = "spatialData.highlight ? spatialData.highlight : false"
-        [glyphiconClass] = "spatialData.type === 'userLandmark' ? 'glyphicon-chevron-down' : 'glyphicon-map-marker'"
-        [positionX] = "getPositionX(1,spatialData)"
-        [positionY] = "getPositionY(1,spatialData)"
-        [positionZ] = "getPositionZ(1,spatialData)">
+        *ngFor="let spatialData of (selectedPtLandmarks$ | async)"
+        (mouseenter)="handleMouseEnterLandmark(spatialData)"
+        (mouseleave)="handleMouseLeaveLandmark(spatialData)"
+        [highlight]="spatialData.highlight ? spatialData.highlight : false"
+        [glyphiconClass]="spatialData.type === 'userLandmark' ? 'glyphicon-chevron-down' : 'glyphicon-map-marker'"
+        [positionX]="getPositionX(1,spatialData)"
+        [positionY]="getPositionY(1,spatialData)"
+        [positionZ]="getPositionZ(1,spatialData)">
       </nehuba-2dlandmark-unit>
       
-      <div *ngIf = "sliceViewLoading1$ | async" class = "loadingIndicator">
-        <div class = "spinnerAnimationCircle">
+      <div *ngIf="sliceViewLoading1$ | async" class="loadingIndicator">
+        <div class="spinnerAnimationCircle">
 
         </div>
       </div>
@@ -55,18 +55,18 @@
       pos10 
       landmarkContainer>
       <nehuba-2dlandmark-unit 
-        *ngFor = "let spatialData of (selectedPtLandmarks$ | async)"
-        (mouseenter) = "handleMouseEnterLandmark(spatialData)"
-        (mouseleave) = "handleMouseLeaveLandmark(spatialData)"
-        [highlight] = "spatialData.highlight ? spatialData.highlight : false"
-        [glyphiconClass] = "spatialData.type === 'userLandmark' ? 'glyphicon-chevron-down' : 'glyphicon-map-marker'"
-        [positionX] = "getPositionX(2,spatialData)"
-        [positionY] = "getPositionY(2,spatialData)"
-        [positionZ] = "getPositionZ(2,spatialData)">
+        *ngFor="let spatialData of (selectedPtLandmarks$ | async)"
+        (mouseenter)="handleMouseEnterLandmark(spatialData)"
+        (mouseleave)="handleMouseLeaveLandmark(spatialData)"
+        [highlight]="spatialData.highlight ? spatialData.highlight : false"
+        [glyphiconClass]="spatialData.type === 'userLandmark' ? 'glyphicon-chevron-down' : 'glyphicon-map-marker'"
+        [positionX]="getPositionX(2,spatialData)"
+        [positionY]="getPositionY(2,spatialData)"
+        [positionZ]="getPositionZ(2,spatialData)">
       </nehuba-2dlandmark-unit>
       
-      <div *ngIf = "sliceViewLoading2$ | async" class = "loadingIndicator">
-        <div class = "spinnerAnimationCircle">
+      <div *ngIf="sliceViewLoading2$ | async" class="loadingIndicator">
+        <div class="spinnerAnimationCircle">
 
         </div>
       </div>
@@ -76,8 +76,8 @@
     <layout-floating-container  
       pos11 
       landmarkContainer>
-      <div *ngIf = "perspectiveViewLoading$ | async" class = "loadingIndicator">
-        <div class = "spinnerAnimationCircle"></div>
+      <div *ngIf="perspectiveViewLoading$ | async" class="loadingIndicator">
+        <div class="spinnerAnimationCircle"></div>
         <div perspectiveLoadingText>
           {{ perspectiveViewLoading$ | async }}
         </div>
@@ -86,40 +86,63 @@
   </div>
 </div>
 
-<layout-floating-container *ngIf = "viewerLoaded">
+<layout-floating-container *ngIf="viewerLoaded">
 
   <!-- TODO export status card to its own container -->
   <div statusCard>
 
-    <hr *ngIf = "showCitation && !isMobile" />
+    <hr *ngIf="showCitation && !isMobile" />
 
     <div linksContainer>
-      <a href = "#" (click)="$event.preventDefault();statusPanelRealSpace = !statusPanelRealSpace">
-        {{statusPanelRealSpace ? 'real space' : 'voxel space'}}
+      <span>
+        reset: 
+      </span>
+      <a
+        href="#"
+        (click)="$event.preventDefault();resetNavigation({position:true})">
+        position
       </a>
-  
-      <a href = "#" (click) = "$event.preventDefault();resetNavigation()">
-        reset navigation
+
+      <a
+        href="#"
+        (click)="$event.preventDefault();resetNavigation({rotation:true})">
+        rotation
       </a>
+
+      <a
+        href="#"
+        (click)="$event.preventDefault();resetNavigation({zoom:true})">
+        zoom
+      </a>
+
+      <br />
+      <span>
+        space:
+      </span>
+      
+      <a href="#" (click)="$event.preventDefault();statusPanelRealSpace=!statusPanelRealSpace">
+        {{statusPanelRealSpace ? 'physical' : 'voxel'}}
+      </a>
+  
     </div>
   
     <br />
     <div textContainer>
       <small>Navigation: </small>
         <input 
-          (keydown.enter) = "textNavigateTo(navigateInput.value)"
-          (keydown.tab) = "textNavigateTo(navigateInput.value)"
-          [ngModel] = "navigationValue()" 
-          spellcheck = "false"
+          (keydown.enter)="textNavigateTo(navigateInput.value)"
+          (keydown.tab)="textNavigateTo(navigateInput.value)"
+          [ngModel]="navigationValue()" 
+          spellcheck="false"
           #navigateInput
           navigateInput/>
     
       <br />
-      <small *ngIf = "!isMobile">Mouse: </small>
-      <small *ngIf = "!isMobile">
+      <small *ngIf="!isMobile">Mouse: </small>
+      <small *ngIf="!isMobile">
         {{ mouseCoord }}
       </small> 
-      <br *ngIf = "!isMobile" />
+      <br *ngIf="!isMobile" />
       <small onHoverSegment>
         {{ onHoverSegmentName$ | async }}
       </small>
@@ -132,9 +155,9 @@
 </div>
 
 <mobile-overlay 
-  *ngIf = "isMobile && viewerLoaded" 
-  [tunableProperties] = "tunableMobileProperties" 
-  (deltaValue) = "handleMobileOverlayEvent($event)">
+  *ngIf="isMobile && viewerLoaded" 
+  [tunableProperties]="tunableMobileProperties" 
+  (deltaValue)="handleMobileOverlayEvent($event)">
   <div mobileObliqueGuide guide>
     <div>
       <i class="glyphicon glyphicon-resize-vertical"></i> oblique mode 
diff --git a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
index b20c2edb87a12a326546cb1258408859e0dca424..518cf2516ad16a335c1d404385627f4af89153df 100644
--- a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
+++ b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
@@ -6,6 +6,7 @@ import { AtlasWorkerService } from "../../../atlasViewer/atlasViewer.workerServi
 import { buffer, map, filter, debounceTime, take, takeUntil, scan, switchMap, takeWhile } from "rxjs/operators";
 import { AtlasViewerConstantsServices } from "../../../atlasViewer/atlasViewer.constantService.service";
 import { takeOnePipe, identifySrcElement } from "../nehubaContainer.component";
+import { ViewerConfiguration } from "src/services/state/viewerConfig.store";
 
 @Component({
   templateUrl : './nehubaViewer.template.html',
@@ -232,6 +233,15 @@ export class NehubaViewerUnit implements OnDestroy{
       : 0
   }
 
+  public applyPerformanceConfig ({ gpuLimit }: Partial<ViewerConfiguration>) {
+    if (gpuLimit && this.nehubaViewer) {
+      const limit = this.nehubaViewer.ngviewer.state.children.get('gpuMemoryLimit')
+      if (limit && limit.restoreState) {
+        limit.restoreState(gpuLimit)
+      }
+    }
+  }
+
   /* required to check if correct landmarks are loaded */
   private _templateId : string
   get templateId(){
diff --git a/src/ui/ui.module.ts b/src/ui/ui.module.ts
index 0d8dc8b6cc986088ce7ad1420f68d46772452c57..e744af52480e14be9a7e051cc199042cb7568482 100644
--- a/src/ui/ui.module.ts
+++ b/src/ui/ui.module.ts
@@ -40,6 +40,7 @@ import { MobileOverlay } from "./nehubaContainer/mobileOverlay/mobileOverlay.com
 import { FilterNullPipe } from "../util/pipes/filterNull.pipe";
 import { ShowToastDirective } from "../util/directives/showToast.directive";
 import { HelpComponent } from "./help/help.component";
+import { ConfigComponent } from './config/config.component'
 
 
 @NgModule({
@@ -73,6 +74,7 @@ import { HelpComponent } from "./help/help.component";
     TemplateParcellationCitationsContainer,
     MobileOverlay,
     HelpComponent,
+    ConfigComponent,
 
     /* pipes */
     GroupDatasetByRegion,
@@ -114,7 +116,8 @@ import { HelpComponent } from "./help/help.component";
     DatasetViewerComponent,
     TemplateParcellationCitationsContainer,
     MobileOverlay,
-    HelpComponent
+    HelpComponent,
+    ConfigComponent
   ]
 })