From 5ea4996addfe0fee8f2f4bdb62d793ba55dfcd86 Mon Sep 17 00:00:00 2001
From: Xiao Gui <xgui3783@gmail.com>
Date: Fri, 8 Jan 2021 18:40:30 +0100
Subject: [PATCH] chore: add touch contrl

---
 .../nehubaContainer.component.ts              | 1181 -----------------
 .../nehubaContainer/nehubaContainer.style.css |  182 ---
 .../nehubaContainer.template.html             |  844 ------------
 src/viewerModule/module.ts                    |  305 -----
 .../nehubaViewerGlue.component.ts             |    4 +-
 .../nehubaViewerGlue.template.html            |   18 +-
 6 files changed, 16 insertions(+), 2518 deletions(-)
 delete mode 100644 src/ui/nehubaContainer/nehubaContainer.component.ts
 delete mode 100644 src/ui/nehubaContainer/nehubaContainer.style.css
 delete mode 100644 src/ui/nehubaContainer/nehubaContainer.template.html

diff --git a/src/ui/nehubaContainer/nehubaContainer.component.ts b/src/ui/nehubaContainer/nehubaContainer.component.ts
deleted file mode 100644
index 3582fc984..000000000
--- a/src/ui/nehubaContainer/nehubaContainer.component.ts
+++ /dev/null
@@ -1,1181 +0,0 @@
-// import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, ViewChild, ChangeDetectorRef, Output, EventEmitter, Inject, Optional } from "@angular/core";
-// import { select, Store } from "@ngrx/store";
-// import { combineLatest, fromEvent, merge, Observable, of, Subscription, timer, asyncScheduler, BehaviorSubject, Subject } from "rxjs";
-// import { buffer, debounceTime, distinctUntilChanged, filter, map, mapTo, scan, shareReplay, skip, startWith, switchMap, switchMapTo, take, tap, withLatestFrom, delayWhen, throttleTime } from "rxjs/operators";
-// import { trigger, state, style, animate, transition } from '@angular/animations'
-// import { MatDrawer } from "@angular/material/sidenav";
-
-// import { LoggingService } from "src/logging";
-// import {
-//   CHANGE_NAVIGATION,
-//   getMultiNgIdsRegionsLabelIndexMap,
-//   getNgIds,
-//   ILandmark,
-//   IOtherLandmarkGeometry,
-//   IPlaneLandmarkGeometry,
-//   IPointLandmarkGeometry,
-//   isDefined,
-//   MOUSE_OVER_LANDMARK,
-//   NgViewerStateInterface
-// } from "src/services/stateStore.service";
-
-// import { getExportNehuba, isSame } from "src/util/fn";
-// import { API_SERVICE_SET_VIEWER_HANDLE_TOKEN, IUserLandmark } from "src/atlasViewer/atlasViewer.apiService.service";
-// import { NehubaViewerUnit } from "./nehubaViewer/nehubaViewer.component";
-// import { compareLandmarksChanged } from "src/util/constants";
-// import { PureContantService } from "src/util";
-// import { ARIA_LABELS, IDS, CONST } from 'common/constants'
-// import { serialiseParcellationRegion } from "common/util"
-// import { ngViewerActionSetPerspOctantRemoval, PANELS, ngViewerActionToggleMax, ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer } from "src/services/state/ngViewerState.store.helper";
-// import { viewerStateSelectRegionWithIdDeprecated, viewerStateAddUserLandmarks, viewreStateRemoveUserLandmarks, viewerStateCustomLandmarkSelector, viewerStateSelectedParcellationSelector, viewerStateSelectedTemplateSelector, viewerStateSelectedRegionsSelector } from 'src/services/state/viewerState.store.helper'
-// import { SwitchDirective } from "src/util/directives/switch.directive";
-// import {
-//   viewerStateDblClickOnViewer,
-// } from "src/services/state/viewerState.store.helper";
-
-// import { getFourPanel, getHorizontalOneThree, getSinglePanel, getVerticalOneThree, calculateSliceZoomFactor, scanSliceViewRenderFn as scanFn, takeOnePipe } from "./util";
-// import { NehubaViewerContainerDirective } from "./nehubaViewerInterface/nehubaViewerInterface.directive";
-// import { ITunableProp } from "./mobileOverlay/mobileOverlay.component";
-// import { viewerStateMouseOverCustomLandmark } from "src/services/state/viewerState/actions";
-// import { ngViewerSelectorNehubaReady, ngViewerSelectorOctantRemoval, ngViewerSelectorPanelMode, ngViewerSelectorPanelOrder } from "src/services/state/ngViewerState/selectors";
-// import { REGION_OF_INTEREST } from "src/util/interfaces";
-// import { uiActionHideAllDatasets, uiActionHideDatasetWithId } from "src/services/state/uiState/actions";
-
-// const { MESH_LOADING_STATUS } = IDS
-
-// const sortByFreshness: (acc: any[], curr: any[]) => any[] = (acc, curr) => {
-
-//   const getLayerName = ({layer} = {layer: {}}) => {
-//     const { name } = layer as any
-//     return name
-//   }
-
-//   const newEntries = (curr && curr.filter(entry => {
-//     const name = getLayerName(entry)
-//     return acc.map(getLayerName).indexOf(name) < 0
-//   })) || []
-
-//   const entryChanged: (itemPrevState, newArr) => boolean = (itemPrevState, newArr) => {
-//     const layerName = getLayerName(itemPrevState)
-//     const { segment } = itemPrevState
-//     const foundItem = newArr?.find((_item) =>
-//       getLayerName(_item) === layerName)
-
-//     if (foundItem) {
-//       const { segment: foundSegment } = foundItem
-//       return segment !== foundSegment
-//     } else {
-//       /**
-//        * if item was not found in the new array, meaning hovering nothing
-//        */
-//       return segment !== null
-//     }
-//   }
-
-//   const getItemFromLayerName = (item, arr) => {
-//     const foundItem = arr?.find(i => getLayerName(i) === getLayerName(item))
-//     return foundItem
-//       ? foundItem
-//       : {
-//         layer: item.layer,
-//         segment: null,
-//       }
-//   }
-
-//   const getReduceExistingLayers = (newArr) => ([changed, unchanged], _curr) => {
-//     const changedFlag = entryChanged(_curr, newArr)
-//     return changedFlag
-//       ? [ changed.concat( getItemFromLayerName(_curr, newArr) ), unchanged ]
-//       : [ changed, unchanged.concat(_curr) ]
-//   }
-
-//   /**
-//    * now, for all the previous layers, separate into changed and unchanged layers
-//    */
-//   const [changed, unchanged] = acc.reduce(getReduceExistingLayers(curr), [[], []])
-//   return [...newEntries, ...changed, ...unchanged]
-// }
-
-// const {
-//   ZOOM_IN,
-//   ZOOM_OUT,
-//   TOGGLE_FRONTAL_OCTANT,
-//   TOGGLE_SIDE_PANEL,
-//   EXPAND,
-//   COLLAPSE,
-//   ADDITIONAL_VOLUME_CONTROL,
-// } = ARIA_LABELS
-
-// @Component({
-//   selector : 'ui-nehuba-container',
-//   templateUrl : './nehubaContainer.template.html',
-//   styleUrls : [
-//     `./nehubaContainer.style.css`,
-//   ],
-//   animations: [
-//     trigger('openClose', [
-//       state('open', style({
-//         transform: 'translateY(0)',
-//         opacity: 1
-//       })),
-//       state('closed', style({
-//         transform: 'translateY(-100vh)',
-//         opacity: 0
-//       })),
-//       transition('open => closed', [
-//         animate('200ms cubic-bezier(0.35, 0, 0.25, 1)')
-//       ]),
-//       transition('closed => open', [
-//         animate('200ms cubic-bezier(0.35, 0, 0.25, 1)')
-//       ])
-//     ]),
-//     trigger('openCloseAnchor', [
-//       state('open', style({
-//         transform: 'translateY(0)'
-//       })),
-//       state('closed', style({
-//         transform: 'translateY(100vh)'
-//       })),
-//       transition('open => closed', [
-//         animate('200ms cubic-bezier(0.35, 0, 0.25, 1)')
-//       ]),
-//       transition('closed => open', [
-//         animate('200ms cubic-bezier(0.35, 0, 0.25, 1)')
-//       ])
-//     ]),
-//   ],
-//   exportAs: 'uiNehubaContainer',
-//   providers: [
-//     {
-//       provide: REGION_OF_INTEREST,
-//       useFactory: (store: Store<any>) => store.pipe(
-//         select(viewerStateSelectedRegionsSelector),
-//         map(rs => rs[0] || null)
-//       ),
-//       deps: [
-//         Store
-//       ]
-//     }
-//   ]
-// })
-
-// export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
-
-//   public CONST = CONST
-//   public ARIA_LABEL_ZOOM_IN = ZOOM_IN
-//   public ARIA_LABEL_ZOOM_OUT = ZOOM_OUT
-//   public ARIA_LABEL_TOGGLE_FRONTAL_OCTANT = TOGGLE_FRONTAL_OCTANT
-//   public ARIA_LABEL_TOGGLE_SIDE_PANEL = TOGGLE_SIDE_PANEL
-//   public ARIA_LABEL_EXPAND = EXPAND
-//   public ARIA_LABEL_COLLAPSE = COLLAPSE
-//   public ARIA_LABEL_ADDITIONAL_VOLUME_CONTROL = ADDITIONAL_VOLUME_CONTROL
-  
-//   public ID_MESH_LOADING_STATUS = MESH_LOADING_STATUS
-
-//   @ViewChild(NehubaViewerContainerDirective,{static: true})
-//   public nehubaContainerDirective: NehubaViewerContainerDirective
-
-//   // @ViewChild('sideNavMasterSwitch', { static: true })
-//   // public navSideDrawerMainSwitch: SwitchDirective
-//   // @ViewChild('sideNavSwitch', { static: true })
-//   // public navSideDrawerMinorSwitch: SwitchDirective
-
-//   @ViewChild('matDrawerMaster', {static: true})
-//   public matDrawerMain: MatDrawer
-//   @ViewChild('matDrawerMinor', { static: true })
-//   public matDrawerMinor: MatDrawer
-
-//   @Output()
-//   public nehubaViewerLoaded: EventEmitter<boolean> = new EventEmitter()
-
-//   @Output()
-//   public forceUI$: Observable<{ target: 'perspective:octantRemoval', mode: boolean,  message?: string }>
-
-//   public disableOctantRemoval$: Observable<{ message?: string, mode: boolean }>
-
-//   public handleViewerLoadedEvent(flag: boolean){
-//     this.viewerLoaded = flag
-//     this.nehubaViewerLoaded.emit(flag)
-//   }
-
-//   public viewerLoaded: boolean = false
-
-//   private sliceRenderEvent$: Observable<CustomEvent>
-//   public sliceViewLoadingMain$: Observable<[boolean, boolean, boolean]>
-//   public perspectiveViewLoading$: Observable<string|null>
-//   public showPerpsectiveScreen$: Observable<string>
-
-//   public templateSelected$: Observable<any> = this.store.pipe(
-//     select(viewerStateSelectedTemplateSelector),
-//     distinctUntilChanged(isSame),
-//   )
-
-//   private newViewer$: Observable<any> = this.templateSelected$.pipe(
-//     filter(v => !!v),
-//   )
-
-//   private selectedParcellation$: Observable<any> = this.store.pipe(
-//     select(viewerStateSelectedParcellationSelector),
-//     distinctUntilChanged(),
-//     filter(v => !!v)
-//   )
-//   public selectedRegions: any[] = []
-//   public selectedRegions$: Observable<any[]> = this.store.pipe(
-//     select(viewerStateSelectedRegionsSelector),
-//     filter(rs => !!rs),
-//   )
-
-//   public selectedLandmarks$: Observable<any[]>
-//   public selectedPtLandmarks$: Observable<any[]>
-//   public customLandmarks$: Observable<any> = this.store.pipe(
-//     select(viewerStateCustomLandmarkSelector),
-//     map(lms => lms.map(lm => ({
-//       ...lm,
-//       geometry: {
-//         position: lm.position
-//       }
-//     })))
-//   )
-//   private hideSegmentations$: Observable<boolean>
-
-//   private fetchedSpatialDatasets$: Observable<ILandmark[]>
-//   private userLandmarks$: Observable<IUserLandmark[]>
-
-//   public nehubaViewerPerspectiveOctantRemoval$: Observable<boolean>
-
-//   @Input()
-//   private currentOnHover: {segments: any, landmark: any, userLandmark: any}
-
-//   @Input()
-//   currentOnHoverObs$: Observable<{segments: any, landmark: any, userLandmark: any}>
-
-//   public iavAdditionalLayers$ = new Subject<any[]>()
-
-//   // public alwaysHideMinorPanel$: Observable<boolean> = combineLatest(
-//   //   this.selectedRegions$,
-//   //   this.iavAdditionalLayers$.pipe(
-//   //     startWith([])
-//   //   )
-//   // ).pipe(
-//   //   map(([ regions, layers ]) => regions.length === 0 && layers.length === 0)
-//   // )
-
-//   public onHoverSegments$: BehaviorSubject<any[]> = new BehaviorSubject([])
-//   public onHoverSegment$: Observable<any> = this.onHoverSegments$.pipe(
-//     scan(sortByFreshness, []),
-//     /**
-//      * take the first element after sort by freshness
-//      */
-//     map(arr => arr[0]),
-//     /**
-//      * map to the older interface
-//      */
-//     filter(v => !!v),
-//     map(({ segment }) => {
-//       return {
-//         labelIndex: (isNaN(segment) && Number(segment.labelIndex)) || null,
-//         foundRegion: (isNaN(segment) && segment) || null,
-//       }
-//     }),
-//   )
-
-//   public selectedTemplate: any | null
-//   private selectedRegionIndexSet: Set<string> = new Set()
-//   public fetchedSpatialData: ILandmark[] = []
-
-//   private ngLayersRegister: Partial<NgViewerStateInterface> = {layers : [], forceShowSegment: null}
-//   private ngLayers$: Observable<NgViewerStateInterface>
-
-//   public selectedParcellation: any | null
-
-//   public nehubaViewer: NehubaViewerUnit = null
-//   private multiNgIdsRegionsLabelIndexMap: Map<string, Map<number, any>> = new Map()
-//   private landmarksLabelIndexMap: Map<number, any> = new Map()
-//   private landmarksNameMap: Map<string, number> = new Map()
-
-//   private subscriptions: Subscription[] = []
-
-//   public nanometersToOffsetPixelsFn: Array<(...arg) => any> = []
-
-//   public viewPanels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement] = [null, null, null, null]
-//   public panelMode$: Observable<string>
-
-//   public panelOrder$: Observable<string>
-//   private redrawLayout$: Observable<[string, string]>
-
-//   public hoveredPanelIndices$: Observable<number>
-
-//   public connectivityNumber: string
-
-//   constructor(
-//     private pureConstantService: PureContantService,
-//     @Optional() @Inject(API_SERVICE_SET_VIEWER_HANDLE_TOKEN) private setViewerHandle: (arg) => void,
-//     private store: Store<any>,
-//     private elementRef: ElementRef,
-//     private log: LoggingService,
-//     private cdr: ChangeDetectorRef,
-//     @Optional() @Inject(REGION_OF_INTEREST) public regionOfInterest$: Observable<any>
-//   ) {
-
-//     this.useMobileUI$ = this.pureConstantService.useTouchUI$
-
-//     // this.nehubaViewerPerspectiveOctantRemoval$ = this.store.pipe(
-//     //   select(ngViewerSelectorOctantRemoval),
-//     // )
-
-//     // this.panelMode$ = this.store.pipe(
-//     //   select(ngViewerSelectorPanelMode),
-//     //   distinctUntilChanged(),
-//     //   shareReplay(1),
-//     // )
-
-//     // this.panelOrder$ = this.store.pipe(
-//     //   select(ngViewerSelectorPanelOrder),
-//     //   distinctUntilChanged(),
-//     //   shareReplay(1),
-//     // )
-
-//     // this.redrawLayout$ = this.store.pipe(
-//     //   select(ngViewerSelectorNehubaReady),
-//     //   distinctUntilChanged(),
-//     //   filter(v => !!v),
-//     //   switchMapTo(combineLatest([
-//     //     this.panelMode$,
-//     //     this.panelOrder$,
-//     //   ])),
-//     // )
-
-//     this.selectedLandmarks$ = this.store.pipe(
-//       select('viewerState'),
-//       select('landmarksSelected'),
-//     )
-
-//     this.selectedPtLandmarks$ = this.selectedLandmarks$.pipe(
-//       map(lms => lms.filter(lm => lm.geometry.type === 'point')),
-//     )
-
-//     this.fetchedSpatialDatasets$ = this.store.pipe(
-//       select('dataStore'),
-//       select('fetchedSpatialData'),
-//       distinctUntilChanged(compareLandmarksChanged),
-//       filter(v => !!v),
-//       startWith([]),
-//       debounceTime(300),
-//     )
-
-//     // this.userLandmarks$ = this.store.pipe(
-//     //   select(viewerStateCustomLandmarkSelector),
-//     //   distinctUntilChanged(),
-//     // )
-
-//     /**
-//      * in future, perhaps add other force UI optinos here
-//      */
-//     // this.forceUI$ = this.userLandmarks$.pipe(
-//     //   map(lm => {
-//     //     if (lm.length > 0) {
-//     //       return {
-//     //         target: 'perspective:octantRemoval',
-//     //         mode: false,
-//     //         message: `octant control disabled: showing landmarks.`
-//     //       }
-//     //     } else {
-//     //       return {
-//     //         target: 'perspective:octantRemoval',
-//     //         mode: null
-//     //       }
-//     //     }
-//     //   })
-//     // )
-
-//     // this.disableOctantRemoval$ = this.forceUI$.pipe(
-//     //   filter(({ target }) => target === 'perspective:octantRemoval'),
-//     // )
-
-//     // this.sliceRenderEvent$ = fromEvent(this.elementRef.nativeElement, 'sliceRenderEvent').pipe(
-//     //   map(ev => ev as CustomEvent)
-//     // )
-
-//     // this.sliceViewLoadingMain$ = this.sliceRenderEvent$.pipe(
-//     //   scan(scanFn, [null, null, null]),
-//     //   startWith([true, true, true] as [boolean, boolean, boolean]),
-//     //   shareReplay(1),
-//     // )
-
-//     // this.showPerpsectiveScreen$ = this.newViewer$.pipe(
-//     //   switchMapTo(this.sliceRenderEvent$.pipe(
-//     //     scan((acc, curr) => {
-
-//     //       /**
-//     //        * if at any point, all chunks have been loaded, always return loaded state
-//     //        */
-//     //       if (acc.every(v => v === 0)) return [0, 0, 0]
-//     //       const { detail = {}, target } = curr || {}
-//     //       const { missingChunks = -1, missingImageChunks = -1 } = detail
-//     //       const idx = this.findPanelIndex(target as HTMLElement)
-//     //       const returnAcc = [...acc]
-//     //       if (idx >= 0) {
-//     //         returnAcc[idx] = missingChunks + missingImageChunks
-//     //       }
-//     //       return returnAcc
-//     //     }, [-1, -1, -1]),
-//     //     map(arr => {
-//     //       let sum = 0
-//     //       let uncertain = false
-//     //       for (const num of arr) {
-//     //         if (num < 0) {
-//     //           uncertain = true
-//     //         } else {
-//     //           sum += num
-//     //         }
-//     //       }
-//     //       return sum > 0
-//     //         ? `Loading ${sum}${uncertain ? '+' : ''} chunks ...`
-//     //         : null
-//     //     }),
-//     //     distinctUntilChanged(),
-//     //     startWith('Loading ...'),
-//     //     throttleTime(100, asyncScheduler, { leading: true, trailing: true }),
-//     //     shareReplay(1),
-//     //   ))
-//     // )
-
-//     /* missing chunk perspective view */
-//     // this.perspectiveViewLoading$ = fromEvent(this.elementRef.nativeElement, 'perpspectiveRenderEvent')
-//     //   .pipe(
-//     //     filter(event => isDefined(event) && isDefined((event as any).detail) && isDefined((event as any).detail.lastLoadedMeshId) ),
-//     //     map(event => {
-
-//     //       /**
-//     //        * TODO dig into event detail to see if the exact mesh loaded
-//     //        */
-//     //       const { meshesLoaded, meshFragmentsLoaded, lastLoadedMeshId } = (event as any).detail
-//     //       return meshesLoaded >= this.nehubaViewer.numMeshesToBeLoaded
-//     //         ? null
-//     //         : 'Loading meshes ...'
-//     //     }),
-//     //     distinctUntilChanged()
-//     //   )
-
-//     this.ngLayers$ = this.store.pipe(
-//       select('ngViewerState'),
-//     )
-
-//     this.hideSegmentations$ = this.ngLayers$.pipe(
-//       map(state => isDefined(state)
-//         ? state.layers?.findIndex(l => l.mixability === 'nonmixable') >= 0
-//         : false),
-//     )
-
-//     /**
-//      * fixes 
-//      * https://github.com/HumanBrainProject/interactive-viewer/issues/800
-//      */
-//     this.subscriptions.push(
-//       this.nehubaViewerLoaded.pipe(
-//         debounceTime(500),
-//         filter(v => !v),
-//       ).subscribe(() => {
-//         this.matDrawerMain.close()
-//         this.matDrawerMinor.close()
-//       })
-//     )
-//   }
-
-//   public useMobileUI$: Observable<boolean>
-
-//   // private removeExistingPanels() {
-//   //   const element = this.nehubaViewer.nehubaViewer.ngviewer.layout.container.componentValue.element as HTMLElement
-//   //   while (element.childElementCount > 0) {
-//   //     element.removeChild(element.firstElementChild)
-//   //   }
-//   //   return element
-//   // }
-
-//   // private findPanelIndex = (panel: HTMLElement) => this.viewPanels?.findIndex(p => p === panel)
-
-//   private _exportNehuba: any
-//   get exportNehuba() {
-//     if (!this._exportNehuba) {
-//       this._exportNehuba = getExportNehuba()
-//     }
-//     return this._exportNehuba
-//   }
-
-//   public ngOnInit() {
-//     // this.hoveredPanelIndices$ = fromEvent(this.elementRef.nativeElement, 'mouseover').pipe(
-//     //   switchMap((ev: MouseEvent) => merge(
-//     //     of(this.findPanelIndex(ev.target as HTMLElement)),
-//     //     fromEvent(this.elementRef.nativeElement, 'mouseout').pipe(
-//     //       mapTo(null),
-//     //     ),
-//     //   )),
-//     //   debounceTime(20),
-//     //   shareReplay(1),
-//     // )
-
-//     // TODO deprecate
-//     /* each time a new viewer is initialised, take the first event to get the translation function */
-//     // this.subscriptions.push(
-//     //   this.newViewer$.pipe(
-//     //     switchMapTo(this.sliceRenderEvent$.pipe(
-//     //       takeOnePipe()
-//     //     ))
-//     //   ).subscribe((events) => {
-//     //     for (const idx in [0, 1, 2]) {
-//     //       const ev = events[idx] as CustomEvent
-//     //       this.viewPanels[idx] = ev.target as HTMLElement
-//     //       this.nanometersToOffsetPixelsFn[idx] = ev.detail.nanometersToOffsetPixels
-//     //     }
-//     //   }),
-//     // )
-
-//     // this.subscriptions.push(
-//     //   this.newViewer$.pipe(
-//     //     switchMapTo(fromEvent(this.elementRef.nativeElement, 'perpspectiveRenderEvent').pipe(
-//     //       take(1),
-//     //     )),
-//     //   ).subscribe(ev => this.viewPanels[3] = ((ev as CustomEvent).target) as HTMLElement),
-//     // )
-
-//     // this.subscriptions.push(
-//     //   this.redrawLayout$.subscribe(([mode, panelOrder]) => {
-//     //     const viewPanels = panelOrder.split('').map(v => Number(v)).map(idx => this.viewPanels[idx]) as [HTMLElement, HTMLElement, HTMLElement, HTMLElement]
-//     //     /**
-//     //      * TODO be smarter with event stream
-//     //      */
-//     //     if (!this.nehubaViewer) { return }
-
-//     //     /**
-//     //      * TODO smarter with event stream
-//     //      */
-//     //     if (!viewPanels.every(v => !!v)) { return }
-
-//     //     switch (mode) {
-//     //     case PANELS.H_ONE_THREE: {
-//     //       const element = this.removeExistingPanels()
-//     //       const newEl = getHorizontalOneThree(viewPanels)
-//     //       element.appendChild(newEl)
-//     //       break;
-//     //     }
-//     //     case PANELS.V_ONE_THREE: {
-//     //       const element = this.removeExistingPanels()
-//     //       const newEl = getVerticalOneThree(viewPanels)
-//     //       element.appendChild(newEl)
-//     //       break;
-//     //     }
-//     //     case PANELS.FOUR_PANEL: {
-//     //       const element = this.removeExistingPanels()
-//     //       const newEl = getFourPanel(viewPanels)
-//     //       element.appendChild(newEl)
-//     //       break;
-//     //     }
-//     //     case PANELS.SINGLE_PANEL: {
-//     //       const element = this.removeExistingPanels()
-//     //       const newEl = getSinglePanel(viewPanels)
-//     //       element.appendChild(newEl)
-//     //       break;
-//     //     }
-//     //     default:
-//     //     }
-//     //     for (const panel of viewPanels) {
-//     //       (panel as HTMLElement).classList.add('neuroglancer-panel')
-//     //     }
-
-//     //     // TODO needed to redraw?
-//     //     // see https://trello.com/c/oJOnlc6v/60-enlarge-panel-allow-user-rearrange-panel-position
-//     //     // further investigaation required
-//     //     this.nehubaViewer.redraw()
-//     //   }),
-//     // )
-
-//     this.subscriptions.push(
-//       this.fetchedSpatialDatasets$.subscribe(datasets => {
-//         this.landmarksLabelIndexMap = new Map(datasets.map((v, idx) => [idx, v]) as Array<[number, any]>)
-//         this.landmarksNameMap = new Map(datasets.map((v, idx) => [v.name, idx] as [string, number]))
-//       }),
-//     )
-
-//     /**
-//      * TODO deprecate, but document the method
-//      */
-//     this.subscriptions.push(
-//       combineLatest(
-//         this.fetchedSpatialDatasets$,
-//       ).subscribe(([fetchedSpatialData]) => {
-//         this.fetchedSpatialData = fetchedSpatialData
-
-//         if (this.fetchedSpatialData?.length > 0) {
-//           this.nehubaViewer.addSpatialSearch3DLandmarks(
-//             this.fetchedSpatialData
-//               .map(data => data.geometry.type === 'point'
-//                 ? (data.geometry as IPointLandmarkGeometry).position
-//                 : data.geometry.type === 'plane'
-//                   ? [
-//                     (data.geometry as IPlaneLandmarkGeometry).corners,
-//                     [[0, 1, 2], [0, 2, 3]],
-//                   ]
-//                   : data.geometry.type === 'mesh'
-//                     ? [
-//                       (data.geometry as IOtherLandmarkGeometry).vertices,
-//                       (data.geometry as IOtherLandmarkGeometry).meshIdx,
-//                     ]
-//                     : null),
-//           )
-//         } else {
-//           if (this.nehubaViewer && this.nehubaViewer.removeSpatialSearch3DLandmarks instanceof Function) {
-//             this.nehubaViewer.removeSpatialSearch3DLandmarks()
-//           }
-//         }
-//       }),
-//     )
-
-//     // this.subscriptions.push(
-//     //   this.userLandmarks$.pipe(
-//     //     withLatestFrom(
-//     //       this.nehubaViewerPerspectiveOctantRemoval$
-//     //     )
-//     //   ).subscribe(([landmarks, flag]) => {
-//     //     if (this.nehubaContainerDirective) {
-//     //       this.nehubaContainerDirective.toggleOctantRemoval(
-//     //         landmarks.length > 0 ? false : flag
-//     //       )
-//     //     }
-//     //     if (this.nehubaViewer) {
-//     //       this.nehubaViewer.updateUserLandmarks(landmarks)
-//     //     }
-//     //   }),
-//     // )
-
-//     // this.subscriptions.push(
-//     //   this.newViewer$.pipe(
-//     //     skip(1),
-//     //   ).subscribe(() => {
-
-//     //     /* on selecting of new template, remove additional nglayers */
-//     //     const baseLayerNames = Object.keys(this.selectedTemplate.nehubaConfig.dataset.initialNgState.layers)
-//     //     this.ngLayersRegister.layers
-//     //       .filter(layer => baseLayerNames?.findIndex(l => l === layer.name) < 0)
-//     //       .map(l => l.name)
-//     //       .forEach(layerName => {
-//     //         this.store.dispatch(ngViewerActionRemoveNgLayer({
-//     //           layer: {
-//     //             name: layerName
-//     //           }
-//     //         }))
-//     //       })
-//     //   }),
-//     // )
-
-//     this.subscriptions.push(
-//       this.templateSelected$.subscribe(() => this.destroynehuba()),
-//     )
-
-//     /* order of subscription will determine the order of execution */
-//     // this.subscriptions.push(
-//     //   this.newViewer$.pipe(
-//     //     map(templateSelected => {
-//     //       const deepCopiedState = JSON.parse(JSON.stringify(templateSelected))
-//     //       const navigation = deepCopiedState.nehubaConfig.dataset.initialNgState.navigation
-//     //       if (!navigation) {
-//     //         return deepCopiedState
-//     //       }
-//     //       navigation.zoomFactor = calculateSliceZoomFactor(navigation.zoomFactor)
-//     //       deepCopiedState.nehubaConfig.dataset.initialNgState.navigation = navigation
-//     //       return deepCopiedState
-//     //     }),
-//     //     withLatestFrom(
-//     //       this.selectedParcellation$.pipe(
-//     //         startWith(null),
-//     //       )
-//     //     ),
-//     //   ).subscribe(([templateSelected, parcellationSelected]) => {
-
-//     //     this.selectedTemplate = templateSelected
-//     //     this.createNewNehuba(templateSelected)
-//     //     const foundParcellation = parcellationSelected
-//     //       && templateSelected?.parcellations?.find(parcellation => parcellationSelected.name === parcellation.name)
-//     //     this.handleParcellation(foundParcellation || templateSelected.parcellations[0])
-
-//     //     const nehubaConfig = templateSelected.nehubaConfig
-//     //     const initialSpec = nehubaConfig.dataset.initialNgState
-//     //     const {layers} = initialSpec
-
-//     //     const dispatchLayers = Object.keys(layers).map(key => {
-//     //       const layer = {
-//     //         name : key,
-//     //         source : layers[key].source,
-//     //         mixability : layers[key].type === 'image'
-//     //           ? 'base'
-//     //           : 'mixable',
-//     //         visible : typeof layers[key].visible === 'undefined'
-//     //           ? true
-//     //           : layers[key].visible,
-//     //         transform : typeof layers[key].transform === 'undefined'
-//     //           ? null
-//     //           : layers[key].transform,
-//     //       }
-//     //       this.ngLayersRegister.layers.push(layer)
-//     //       return layer
-//     //     })
-
-//     //     this.store.dispatch(ngViewerActionAddNgLayer({
-//     //       layer: dispatchLayers
-//     //     }))
-//     //   })
-//     // )
-
-//     let prevParcellation = null
-
-//     // this.subscriptions.push(
-
-//     //   combineLatest([
-//     //     this.selectedRegions$.pipe(
-//     //       distinctUntilChanged(),
-//     //     ),
-//     //     this.hideSegmentations$.pipe(
-//     //       distinctUntilChanged(),
-//     //     ),
-//     //     this.ngLayers$.pipe(
-//     //       map(state => state.forceShowSegment),
-//     //       distinctUntilChanged(),
-//     //     ),
-//     //     this.selectedParcellation$,
-//     //     this.store.pipe(
-//     //       select('viewerState'),
-//     //       select('overwrittenColorMap'),
-//     //       distinctUntilChanged()
-//     //     )
-//     //   ]).pipe(
-//     //     delayWhen(() => timer())
-//     //   ).subscribe(([regions, hideSegmentFlag, forceShowSegment, selectedParcellation, overwrittenColorMap]) => {
-//     //     if (!this.nehubaViewer) { return }
-
-//     //     const { ngId: defaultNgId } = selectedParcellation
-
-//     //     /* selectedregionindexset needs to be updated regardless of forceshowsegment */
-//     //     this.selectedRegionIndexSet = !prevParcellation || prevParcellation === selectedParcellation?
-//     //       new Set(regions.map(({ngId = defaultNgId, labelIndex}) => serialiseParcellationRegion({ ngId, labelIndex }))) : new Set()
-
-//     //     if ( forceShowSegment === false || (forceShowSegment === null && hideSegmentFlag) ) {
-//     //       this.nehubaViewer.hideAllSeg()
-//     //       return
-//     //     }
-
-//     //     this.selectedRegionIndexSet.size > 0 && !overwrittenColorMap
-//     //       ? this.nehubaViewer.showSegs([...this.selectedRegionIndexSet])
-//     //       : this.nehubaViewer.showAllSeg()
-
-//     //     prevParcellation = selectedParcellation
-//     //   }),
-//     // )
-
-//     // this.subscriptions.push(
-//     //   this.ngLayers$.subscribe(ngLayersInterface => {
-//     //     if (!this.nehubaViewer) { return }
-
-//     //     const newLayers = ngLayersInterface.layers.filter(l => this.ngLayersRegister.layers?.findIndex(ol => ol.name === l.name) < 0)
-//     //     const removeLayers = this.ngLayersRegister.layers.filter(l => ngLayersInterface.layers?.findIndex(nl => nl.name === l.name) < 0)
-
-//     //     if (newLayers?.length > 0) {
-//     //       const newLayersObj: any = {}
-//     //       newLayers.forEach(({ name, source, ...rest }) => newLayersObj[name] = {
-//     //         ...rest,
-//     //         source,
-//     //         // source: getProxyUrl(source),
-//     //         // ...getProxyOther({source})
-//     //       })
-
-//     //       if (!this.nehubaViewer.nehubaViewer || !this.nehubaViewer.nehubaViewer.ngviewer) {
-//     //         this.nehubaViewer.initNiftiLayers.push(newLayersObj)
-//     //       } else {
-//     //         this.nehubaViewer.loadLayer(newLayersObj)
-//     //       }
-//     //       this.ngLayersRegister.layers = this.ngLayersRegister.layers.concat(newLayers)
-//     //     }
-
-//     //     if (removeLayers?.length > 0) {
-//     //       removeLayers.forEach(l => {
-//     //         if (this.nehubaViewer.removeLayer({
-//     //           name : l.name,
-//     //         })) {
-//     //           this.ngLayersRegister.layers = this.ngLayersRegister.layers.filter(rl => rl.name !== l.name)
-//     //         }
-//     //       })
-//     //     }
-//     //   }),
-//     // )
-
-//     this.subscriptions.push(
-//       this.selectedParcellation$.subscribe(this.handleParcellation.bind(this))
-//     )
-
-//     /* setup init view state */
-
-//     this.subscriptions.push(
-//       this.selectedRegions$.pipe(
-//         filter(() => !!this.nehubaViewer),
-//       ).subscribe(regions => {
-//         this.nehubaViewer.initRegions = regions.map(({ ngId, labelIndex }) => serialiseParcellationRegion({ ngId, labelIndex }))
-//       })
-//     )
-
-//     this.subscriptions.push(this.selectedRegions$.subscribe(sr => {
-//       this.selectedRegions = sr
-//     }))
-
-//     /** switch side nav */
-//     // this.subscriptions.push(
-//     //   this.alwaysHideMinorPanel$.pipe(
-//     //     distinctUntilChanged()
-//     //   ).subscribe(flag => {
-//     //     if (!flag) {
-//     //       this.matDrawerMinor && this.matDrawerMinor.open()
-//     //       this.navSideDrawerMainSwitch && this.navSideDrawerMainSwitch.open()
-//     //     }
-//     //   })
-//     // )
-
-//     this.subscriptions.push(
-//       this.selectedRegions$.subscribe(regions => {
-//         this.selectedRegions = regions
-//       })
-//     )
-
-//     /* handler to open/select landmark */
-//     const clickObs$ = fromEvent(this.elementRef.nativeElement, 'click')
-
-//     this.subscriptions.push(
-//       clickObs$.pipe(
-//         buffer(
-//           clickObs$.pipe(
-//             debounceTime(200),
-//           ),
-//         ),
-//         filter(arr => arr?.length >= 2),
-//       )
-//         .subscribe(() => {
-//           const { currentOnHover } = this
-//           this.store.dispatch(viewerStateDblClickOnViewer({
-//             payload: { ...currentOnHover }
-//           }))
-//         }),
-//     )
-
-//     // this.subscriptions.push(
-//     //   this.selectedLandmarks$.pipe(
-//     //     map(lms => lms.map(lm => this.landmarksNameMap.get(lm.name))),
-//     //     debounceTime(16),
-//     //   ).subscribe(indices => {
-//     //     const filteredIndices = indices.filter(v => typeof v !== 'undefined' && v !== null)
-//     //     if (this.nehubaViewer) {
-//     //       this.nehubaViewer.spatialLandmarkSelectionChanged(filteredIndices)
-//     //     }
-//     //   }),
-//     // )
-//   }
-
-//   // datasetViewerRegistry : Set<string> = new Set()
-//   public showObliqueScreen$: Observable<boolean>
-//   public showObliqueSelection$: Observable<boolean>
-//   public showObliqueRotate$: Observable<boolean>
-
-//   private currOnHoverObsSub: Subscription
-//   public ngOnChanges() {
-//     this.currOnHoverObsSub && this.currOnHoverObsSub.unsubscribe()
-//     if (this.currentOnHoverObs$) {
-//       this.currOnHoverObsSub = this.currentOnHoverObs$.subscribe(({ segments }) => this.onHoverSegments$.next(segments))
-//     }
-//   }
-
-//   public ngOnDestroy() {
-//     this.subscriptions.forEach(s => s.unsubscribe())
-//   }
-
-//   // public toggleMaximiseMinimise(index: number) {
-//   //   this.store.dispatch(ngViewerActionToggleMax({
-//   //     payload: { index }
-//   //   }))
-//   // }
-
-//   public tunableMobileProperties: ITunableProp[] = []
-
-
-//   public selectedProp = null
-
-//   // public returnTruePos(quadrant: number, data: any) {
-//   //   const pos = quadrant > 2
-//   //     ? [0, 0, 0]
-//   //     : this.nanometersToOffsetPixelsFn && this.nanometersToOffsetPixelsFn[quadrant]
-//   //       ? this.nanometersToOffsetPixelsFn[quadrant](data.geometry.position.map(n => n * 1e6))
-//   //       : [0, 0, 0]
-//   //   return pos
-//   // }
-
-//   // public getPositionX(quadrant: number, data: any) {
-//   //   return this.returnTruePos(quadrant, data)[0]
-//   // }
-//   // public getPositionY(quadrant: number, data: any) {
-//   //   return this.returnTruePos(quadrant, data)[1]
-//   // }
-//   // public getPositionZ(quadrant: number, data: any) {
-//   //   return this.returnTruePos(quadrant, data)[2]
-//   // }
-
-//   // public handleMouseEnterCustomLandmark(lm) {
-//   //   this.store.dispatch(
-//   //     viewerStateMouseOverCustomLandmark({
-//   //       payload: { userLandmark: lm }
-//   //     })
-//   //   )
-//   // }
-
-//   // public handleMouseLeaveCustomLandmark(lm) {
-//   //   this.store.dispatch(
-//   //     viewerStateMouseOverCustomLandmark({
-//   //       payload: { userLandmark: null }
-//   //     })
-//   //   )
-//   // }
-
-//   // handles mouse enter/leave landmarks in 2D
-//   public handleMouseEnterLandmark(spatialData: any) {
-//     spatialData.highlight = true
-//     this.store.dispatch({
-//       type : MOUSE_OVER_LANDMARK,
-//       landmark : spatialData._label,
-//     })
-//   }
-
-//   public handleMouseLeaveLandmark(spatialData: any) {
-//     spatialData.highlight = false
-//     this.store.dispatch({
-//       type : MOUSE_OVER_LANDMARK,
-//       landmark : null,
-//     })
-//   }
-
-//   // private handleParcellation(parcellation: any) {
-//   //   /**
-//   //    * parcellaiton may be undefined
-//   //    */
-//   //   if ( !(parcellation && parcellation.regions)) {
-//   //     return
-//   //   }
-
-//   //   /**
-//   //    * first, get all all the ngIds, including parent id from parcellation (if defined)
-//   //    */
-//   //   const ngIds = getNgIds(parcellation.regions).concat( parcellation.ngId ? parcellation.ngId : [])
-
-//   //   this.multiNgIdsRegionsLabelIndexMap = getMultiNgIdsRegionsLabelIndexMap(parcellation)
-
-//   //   this.nehubaViewer.multiNgIdsLabelIndexMap = this.multiNgIdsRegionsLabelIndexMap
-//   //   this.nehubaViewer.auxilaryMeshIndices = parcellation.auxillaryMeshIndices || []
-
-//   //   /* TODO replace with proper KG id */
-//   //   /**
-//   //    * need to set unique array of ngIds, or else workers will be overworked
-//   //    */
-//   //   this.nehubaViewer.ngIds = Array.from(new Set(ngIds))
-//   //   this.selectedParcellation = parcellation
-//   // }
-
-//   /* related spatial search */
-//   public spatialSearchPagination: number = 0
-
-//   private destroynehuba() {
-//     /**
-//      * TODO if plugin subscribes to viewerHandle, and then new template is selected, changes willl not be be sent
-//      * could be considered as a bug.
-//      */
-//     this.setViewerHandle && this.setViewerHandle(null)
-//     this.nehubaContainerDirective.clear()
-
-//     this.nehubaViewer = null
-
-//     this.cdr.detectChanges()
-//   }
-
-//   private createNewNehuba(template: any) {
-
-//     this.nehubaContainerDirective.createNehubaInstance(template)
-//     this.nehubaViewer = this.nehubaContainerDirective.nehubaViewerInstance
-
-//     this.setupViewerHandleApi()
-//   }
-
-//   private setupViewerHandleApi() {
-//     const viewerHandle = {
-//       setNavigationLoc : (coord, realSpace?) => this.nehubaViewer.setNavigationState({
-//         position : coord,
-//         positionReal : typeof realSpace !== 'undefined' ? realSpace : true,
-//       }),
-//       /* TODO introduce animation */
-//       moveToNavigationLoc : (coord, realSpace?) => {
-//         this.store.dispatch({
-//           type: CHANGE_NAVIGATION,
-//           navigation: {
-//             position: coord,
-//             animation: {},
-//           },
-//         })
-//       },
-//       setNavigationOri : (quat) => this.nehubaViewer.setNavigationState({
-//         orientation : quat,
-//       }),
-//       /* TODO introduce animation */
-//       moveToNavigationOri : (quat) => this.nehubaViewer.setNavigationState({
-//         orientation : quat,
-//       }),
-//       showSegment : (_labelIndex) => {
-//         /**
-//          * TODO reenable with updated select_regions api
-//          */
-//         this.log.warn(`showSegment is temporarily disabled`)
-
-//         // if(!this.selectedRegionIndexSet.has(labelIndex))
-//         //   this.store.dispatch({
-//         //     type : SELECT_REGIONS,
-//         //     selectRegions :  [labelIndex, ...this.selectedRegionIndexSet]
-//         //   })
-//       },
-//       add3DLandmarks : landmarks => {
-//         // TODO check uniqueness of ID
-//         if (!landmarks.every(l => isDefined(l.id))) {
-//           throw new Error('every landmarks needs to be identified with the id field')
-//         }
-//         if (!landmarks.every(l => isDefined(l.position))) {
-//           throw new Error('every landmarks needs to have position defined')
-//         }
-//         if (!landmarks.every(l => l.position.constructor === Array) || !landmarks.every(l => l.position.every(v => !isNaN(v))) || !landmarks.every(l => l.position.length == 3)) {
-//           throw new Error('position needs to be a length 3 tuple of numbers ')
-//         }
-
-//         this.store.dispatch(viewerStateAddUserLandmarks({
-//           landmarks
-//         }))
-//       },
-//       remove3DLandmarks : landmarkIds => {
-//         this.store.dispatch(viewreStateRemoveUserLandmarks({
-//           payload: { landmarkIds }
-//         }))
-//       },
-//       hideSegment : (_labelIndex) => {
-//         /**
-//          * TODO reenable with updated select_regions api
-//          */
-//         this.log.warn(`hideSegment is temporarily disabled`)
-
-//         // if(this.selectedRegionIndexSet.has(labelIndex)){
-//         //   this.store.dispatch({
-//         //     type :SELECT_REGIONS,
-//         //     selectRegions : [...this.selectedRegionIndexSet].filter(num=>num!==labelIndex)
-//         //   })
-//         // }
-//       },
-//       showAllSegments : () => {
-//         const selectRegionIds = []
-//         this.multiNgIdsRegionsLabelIndexMap.forEach((map, ngId) => {
-//           Array.from(map.keys()).forEach(labelIndex => {
-//             selectRegionIds.push(serialiseParcellationRegion({ ngId, labelIndex }))
-//           })
-//         })
-//         this.store.dispatch(viewerStateSelectRegionWithIdDeprecated({
-//           selectRegionIds
-//         }))
-//       },
-//       hideAllSegments : () => {
-//         this.store.dispatch(viewerStateSelectRegionWithIdDeprecated({
-//           selectRegionIds: []
-//         }))
-//       },
-//       segmentColourMap : new Map(),
-//       getLayersSegmentColourMap: () => {
-//         const newMainMap = new Map()
-//         for (const [key, colormap] of this.nehubaViewer.multiNgIdColorMap.entries()) {
-//           const newColormap = new Map()
-//           newMainMap.set(key, newColormap)
-
-//           for (const [lableIndex, entry] of colormap.entries()) {
-//             newColormap.set(lableIndex, JSON.parse(JSON.stringify(entry)))
-//           }
-//         }
-//         return newMainMap
-//       },
-//       applyColourMap : (_map) => {
-//         throw new Error(`apply color map has been deprecated. use applyLayersColourMap instead`)
-//       },
-//       applyLayersColourMap: (map) => {
-//         this.nehubaViewer.setColorMap(map)
-//       },
-//       loadLayer : (layerObj) => this.nehubaViewer.loadLayer(layerObj),
-//       removeLayer : (condition) => this.nehubaViewer.removeLayer(condition),
-//       setLayerVisibility : (condition, visible) => this.nehubaViewer.setLayerVisibility(condition, visible),
-//       mouseEvent : merge(
-//         fromEvent(this.elementRef.nativeElement, 'click').pipe(
-//           map((ev: MouseEvent) => ({eventName : 'click', event: ev})),
-//         ),
-//         fromEvent(this.elementRef.nativeElement, 'mousemove').pipe(
-//           map((ev: MouseEvent) => ({eventName : 'mousemove', event: ev})),
-//         ),
-//         /**
-//          * neuroglancer prevents propagation, so use capture instead
-//          */
-//         Observable.create(observer => {
-//           this.elementRef.nativeElement.addEventListener('mousedown', event => observer.next({eventName: 'mousedown', event}), true)
-//         }) as Observable<{eventName: string, event: MouseEvent}>,
-//         fromEvent(this.elementRef.nativeElement, 'mouseup').pipe(
-//           map((ev: MouseEvent) => ({eventName : 'mouseup', event: ev})),
-//         ),
-//       ) ,
-//       mouseOverNehuba : this.onHoverSegment$.pipe(
-//         tap(() => console.warn('mouseOverNehuba observable is becoming deprecated. use mouseOverNehubaLayers instead.')),
-//       ),
-//       mouseOverNehubaLayers: this.onHoverSegments$,
-//       mouseOverNehubaUI: this.currentOnHoverObs$.pipe(
-//         map(({ landmark, segments, userLandmark: customLandmark }) => ({ segments, landmark, customLandmark })),
-//         shareReplay(1),
-//       ),
-//       getNgHash : this.nehubaViewer.getNgHash,
-//     }
-
-//     this.setViewerHandle && this.setViewerHandle(viewerHandle)
-//   }
-
-//   // public setOctantRemoval(octantRemovalFlag: boolean) {
-//   //   this.store.dispatch(
-//   //     ngViewerActionSetPerspOctantRemoval({
-//   //       octantRemovalFlag
-//   //     })
-//   //   )
-//   // }
-
-//   // public zoomNgView(panelIndex: number, factor: number) {
-//   //   const ngviewer = this.nehubaViewer?.nehubaViewer?.ngviewer
-//   //   if (!ngviewer) throw new Error(`ngviewer not defined!`)
-
-//   //   /**
-//   //    * panelIndex < 3 === slice view
-//   //    */
-//   //   if (panelIndex < 3) {
-//   //     /**
-//   //      * factor > 1 === zoom out
-//   //      */
-//   //     ngviewer.navigationState.zoomBy(factor)
-//   //   } else {
-//   //     ngviewer.perspectiveNavigationState.zoomBy(factor)
-//   //   }
-//   // }
-
-//   // public clearPreviewingDataset(id: string){
-//   //   /**
-//   //    * clear all preview
-//   //    */
-//   //   this.store.dispatch(
-//   //     id
-//   //       ? uiActionHideDatasetWithId({ id })
-//   //       : uiActionHideAllDatasets()
-//   //   )
-//   // }
-// }
diff --git a/src/ui/nehubaContainer/nehubaContainer.style.css b/src/ui/nehubaContainer/nehubaContainer.style.css
deleted file mode 100644
index 956ab1237..000000000
--- a/src/ui/nehubaContainer/nehubaContainer.style.css
+++ /dev/null
@@ -1,182 +0,0 @@
-:host
-{
-  width:100%;
-  height:100%;
-  position:relative;
-}
-
-atlas-layer-container
-{
-  margin-bottom: 1em;
-  margin-left: 1em;
-  width: 30em;
-  height: 50em;
-}
-
-current-layout
-{
-  top: 0;
-  left: 0;
-  /** z index of current layout has to be higher than that of layout-floating-container, or status container will cover panel control */
-  /** TODO decide which behaviour is more nature */
-  z-index: 6;
-}
-
-div.loadingIndicator
-{
-  left: auto;
-  top: auto;
-  right: 0;
-  bottom: 0;
-  margin-right: 0.2em;
-  margin-bottom: 0.2em;
-  width: 100%;
-  position:absolute;
-  height:2em;
-  display: flex;
-  flex-direction: row-reverse;
-}
-
-div.loadingIndicator >>> div.spinnerAnimationCircle
-{
-  font-size:150%;
-}
-
-[perspectiveLoadingText]
-{
-  margin-right: 1em;
-}
-
-:host-context([darktheme="true"]) [perspectiveLoadingText]
-{
-  color:rgba(255,255,255,0.8);
-}
-
-div#scratch-pad
-{
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  pointer-events: none;
-}
-
-.overlay-btn-container
-{
-  position: absolute;
-  bottom: 0;
-  right: 0;
-}
-
-/* if not mobile, then show on hover */
-
-.opacity-crossfade
-{
-  transition: opacity 170ms ease-in-out,
-    transform 250ms ease-in-out;
-}
-
-.opacity-crossfade
-{
-
-  opacity: 0.0;
-  pointer-events: none;
-}
-
-.opacity-crossfade.onHover,
-.opacity-crossfade:hover,
-:host-context([ismobile="true"]) .opacity-crossfade.always-show-touchdevice
-{
-  opacity: 1.0 !important;
-  pointer-events: all !important;
-}
-
-.screen-overlay
-{
-  background-color: rgba(255, 255, 255, 0.7);
-}
-
-:host-context([darktheme="true"]) .screen-overlay
-{
-  background-color: rgba(0, 0, 0, 0.7);
-}
-
-.feature-card
-{
-
-  height: 20em;
-  max-height: 20em;
-  flex: 0 0 20em;
-  align-items: flex-start;
-}
-
-.region-populated .feature-card
-{
-  height: 25em;
-  max-height: 25em;
-  flex: 0 0 25em;
-  align-items: flex-start;
-}
-
-.region-text-search-autocomplete-position
-{
-  z-index: 10;
-  position: sticky;
-  top: 0.5rem;
-}
-
-.collapse-position
-{
-  z-index: 10;
-  position: sticky;
-  bottom: 0.5rem;
-}
-
-.placeholder-region-detail
-{
-  padding: 6rem 1rem 1rem 1rem;
-}
-
-.explore-btn
-{
-  margin-top: 4.5rem;
-  width: 100%;
-}
-
-.modality-card-container
-{
-  overflow-x: scroll;
-}
-
-.modality-card
-{
-  width: 10em;
-}
-
-.spacer
-{
-  height: 6rem;
-}
-
-.content-transclusion-top-left
-{
-  margin-left: 3.5rem;
-}
-
-.tab-toggle
-{
-  margin-left: -2rem;
-  padding-right: 0.75rem;
-  margin-right: 1rem;
-  text-align: right;
-}
-
-.accordion-icon
-{
-  width:1.5rem;
-}
-.tab-toggle-container
-{
-  margin-top: 1.5rem;
-}
diff --git a/src/ui/nehubaContainer/nehubaContainer.template.html b/src/ui/nehubaContainer/nehubaContainer.template.html
deleted file mode 100644
index 921151abb..000000000
--- a/src/ui/nehubaContainer/nehubaContainer.template.html
+++ /dev/null
@@ -1,844 +0,0 @@
-<div class="position-absolute h-100 w-100"
-  (touchmove)="$event.preventDefault()"
-  iav-viewer-touch-interface
-  [iav-viewer-touch-interface-v-panels]="viewPanels"
-  [iav-viewer-touch-interface-vp-to-data]="iavContainer?.viewportToDatas"
-  [iav-viewer-touch-interface-ngviewer]="nehubaViewer?.nehubaViewer?.ngviewer"
-  [iav-viewer-touch-interface-nehuba-config]="selectedTemplate?.nehubaConfig">
-  <div
-    iav-nehuba-viewer-container
-    (iavNehubaViewerContainerViewerLoading)="handleViewerLoadedEvent($event)"
-    #iavContainer="iavNehubaViewerContainer">
-  </div>
-</div>
-
-<ui-splashscreen iav-stop="mousedown mouseup touchstart touchmove touchend" *ngIf="!viewerLoaded">
-</ui-splashscreen>
-
-<!-- spatial landmarks overlay -->
-<!-- loading indicator -->
-
-<current-layout *ngIf="viewerLoaded" class="position-absolute w-100 h-100 d-block pe-none">
-  <div class="w-100 h-100 position-relative" cell-i>
-    <ng-content *ngTemplateOutlet="ngPanelOverlayTmpl; context: { panelIndex: panelOrder$ | async | getNthElement : 0 | parseAsNumber }"></ng-content>
-  </div>
-  <div class="w-100 h-100 position-relative" cell-ii>
-    <ng-content *ngTemplateOutlet="ngPanelOverlayTmpl; context: { panelIndex: panelOrder$ | async | getNthElement : 1 | parseAsNumber }"></ng-content>
-  </div>
-  <div class="w-100 h-100 position-relative" cell-iii>
-    <ng-content *ngTemplateOutlet="ngPanelOverlayTmpl; context: { panelIndex: panelOrder$ | async | getNthElement : 2 | parseAsNumber }"></ng-content>
-  </div>
-  <div class="w-100 h-100 position-relative" cell-iv>
-    <ng-content *ngTemplateOutlet="ngPanelOverlayTmpl; context: { panelIndex: panelOrder$ | async | getNthElement : 3 | parseAsNumber }"></ng-content>
-  </div>
-</current-layout>
-
-<layout-floating-container
-  class="overflow-hidden w-100 h-100"
-  [zIndex]="10">
-
-  <!-- drawer #1 -->
-  <mat-drawer-container
-    [iav-switch-initstate]="false"
-    iav-switch
-    #sideNavMasterSwitch="iavSwitch"
-    class="mat-drawer-content-overflow-visible w-100 h-100 position-absolute invisible"
-    [hasBackdrop]="false">
-
-    <!-- sidenav-content -->
-    <mat-drawer class="box-shadow-none border-0 pe-none bg-none col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2"
-      mode="side"
-      [attr.data-mat-drawer-primary-open]="matDrawerMaster.opened"
-      [opened]="sideNavMasterSwitch.switchState"
-      [autoFocus]="false"
-      (closedStart)="sideNavSwitch.switchState && matDrawerMinor.close()"
-      (openedStart)="sideNavSwitch.switchState && matDrawerMinor.open()"
-      [disableClose]="true"
-      #matDrawerMaster="matDrawer">
-
-      <div class="h-0 w-100 region-text-search-autocomplete-position">
-        <ng-container *ngTemplateOutlet="autocompleteTmpl">
-        </ng-container>
-      </div>
-
-      <button mat-raised-button
-        *ngIf="!(alwaysHideMinorPanel$ | async)"
-        [attr.aria-label]="ARIA_LABEL_EXPAND"
-        (click)="matDrawerMinor.open()"
-        class="explore-btn pe-all"
-        [ngClass]="{
-          'darktheme': iavRegion.rgbDarkmode === true,
-          'lighttheme': iavRegion.rgbDarkmode === false
-        }"
-        [style.backgroundColor]="iavRegion?.rgbString || 'accent'">
-        <span class="text iv-custom-comp">
-          Explore
-        </span>
-
-        <div class="hidden"
-          iav-region
-          [region]="(selectedRegions$ | async) && (selectedRegions$ | async)[0]"
-          #iavRegion="iavRegion">
-        </div>
-
-      </button>
-    </mat-drawer>
-    <mat-drawer-content class="visible position-relative">
-
-      <!-- top left overlay -->
-      <div class="content-transclusion-top-left position-absolute top-0 left-0 w-100 d-inline-block pe-none">
-        <ng-content select="[ui-nehuba-container-overlay-top-left]">
-        </ng-content>
-      </div>
-
-      <!-- top right overlay -->
-      <div class="position-absolute top-0 right-0 w-100 d-inline-block pe-none">
-        <ng-content select="[ui-nehuba-container-overlay-top-right]">
-        </ng-content>
-      </div>
-
-      <div *ngIf="viewerLoaded" class="position-absolute z-index-6 top-0 left-0 pe-none tab-toggle-container">
-        <ng-container *ngTemplateOutlet="tabTmpl; context: {
-          isOpen: sideNavMasterSwitch.switchState,
-          regionSelected: selectedRegions$ | async,
-          iavAdditionallayers: iavAdditionalLayers$ | async
-        }">
-
-        </ng-container>
-      </div>
-
-    </mat-drawer-content>
-  </mat-drawer-container>
-
-  <!-- drawer #2 -->
-  <mat-drawer-container
-    [iav-switch-initstate]="!(alwaysHideMinorPanel$ | async)"
-    iav-switch
-    #sideNavSwitch="iavSwitch"
-    class="mat-drawer-content-overflow-visible w-100 h-100 position-absolute invisible"
-    [hasBackdrop]="false">
-
-    <!-- sidenav-content -->
-    <mat-drawer class="darker-bg iv-custom-comp visible col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2 d-flex flex-column pe-all"
-      mode="push"
-      [attr.data-mat-drawer-secondary-open]="matDrawerMinor.opened"
-      [autoFocus]="false"
-      #matDrawerMinor="matDrawer"
-      (openedChange)="$event && sideNavSwitch.open()"
-      [disableClose]="true"
-      [@openClose]="sideNavMasterSwitch.switchState && sideNavSwitch.switchState ? 'open' : 'closed'"
-      (@openClose.done)="$event.toState === 'closed' && matDrawerMinor.close()">
-
-      <div class="position-relative d-flex flex-column h-100">
-
-        <!-- TODO dataset preview will become deprecated in the future.
-        Regional feature/data feature will replace it -->
-
-        <div class="hidden"
-          iav-shown-dataset
-          #iavShownDataset="iavShownDataset">
-        </div>
-      
-        <div class="hidden"
-          iav-shown-previews
-          (emitter)="iavAdditionalLayers$.next($event)"
-          #previews="iavShownPreviews">
-        </div>
-
-        <!-- sidenav datasets -->
-        <ng-container *ngIf="iavShownDataset.shownDatasetId$ | async as shownDatasetId">
-          <ng-template [ngIf]="shownDatasetId.length > 0" [ngIfElse]="sideNavVolumePreview">
-            
-            <!-- single dataset side nav panel -->
-            <single-dataset-sidenav-view *ngFor="let id of shownDatasetId"
-              (clear)="clearPreviewingDataset(id)"
-              [fullId]="id"
-              class="bs-border-box ml-15px-n mr-15px-n">
-              <mat-chip *ngIf="regionOfInterest$ && regionOfInterest$ | async as region"
-                region-of-interest
-                iav-region
-                [region]="region"
-                [ngClass]="{
-                  'darktheme':regionDirective.rgbDarkmode === true,
-                  'lighttheme': regionDirective.rgbDarkmode === false
-                }"
-                [style.backgroundColor]="regionDirective.rgbString"
-                #regionDirective="iavRegion">
-                <span class="iv-custom-comp text text-truncate d-inline">
-                  {{ region.name }}
-                </span>
-              </mat-chip>
-            </single-dataset-sidenav-view>
-          </ng-template>
-        </ng-container>
-
-        <!-- preview volumes -->
-        <ng-template #sideNavVolumePreview>
-          <ng-container *ngIf="previews.iavAdditionalLayers$ | async | filterPreviewByType : [previews.FILETYPES.VOLUMES] as volumePreviews">
-            <ng-template [ngIf]="volumePreviews.length > 0" [ngIfElse]="sidenavRegionTmpl">
-              <ng-container *ngFor="let vPreview of volumePreviews">
-                <ng-container *ngTemplateOutlet="sidenavDsPreviewTmpl; context: vPreview">
-  
-                </ng-container>
-              </ng-container>
-            </ng-template>
-          </ng-container>
-        </ng-template>
-
-      </div>
-    </mat-drawer>
-
-    <!-- main-content -->
-    <mat-drawer-content class="visible position-relative">
-
-      <!-- bottom left overlay -->
-      <div class="position-absolute bottom-0 left-0 w-100 d-inline-block pe-none">
-        <ng-content select="[ui-nehuba-container-overlay-bottom-left]">
-        </ng-content>
-      </div>
-
-    </mat-drawer-content>
-  </mat-drawer-container>
-
-</layout-floating-container>
-
-<!-- collapse btn -->
-<ng-template #collapseBtn>
-
-  <div class="h-0 w-100 collapse-position d-flex flex-column justify-content-end align-items-center">
-    <button mat-raised-button class="mat-elevation-z8"
-      [attr.aria-label]="ARIA_LABEL_COLLAPSE"
-      (click)="sideNavSwitch.close()"
-      color="basic">
-      <i class="fas fa-chevron-up"></i>
-      <span>
-        collapse
-      </span>
-    </button>
-  </div>
-</ng-template>
-
-<!-- region sidenav tmpl -->
-<ng-template #sidenavRegionTmpl>
-
-  <!-- region search autocomplete  -->
-
-  <div class="h-0 w-100 region-text-search-autocomplete-position"
-    [@openCloseAnchor]="sideNavSwitch.switchState ? 'open' : 'closed'">
-    <ng-container *ngTemplateOutlet="autocompleteTmpl">
-    </ng-container>
-  </div>
-
-  <div class="flex-shrink-1 flex-grow-1 d-flex flex-column"
-    [ngClass]="{'region-populated': (selectedRegions$ | async).length > 0 }">
-    <!-- region detail -->
-    <ng-container *ngIf="selectedRegions$ | async as selectedRegions; else selectRegionErrorTmpl">
-
-      <!-- single-region-wrapper -->
-      <ng-template [ngIf]="selectedRegions.length === 1" [ngIfElse]="multiRegionWrapperTmpl">
-        <!-- a series of bugs result in requiring this hacky -->
-        <!-- see https://github.com/HumanBrainProject/interactive-viewer/issues/698 -->
-        <ng-container *ngFor="let region of selectedRegions">
-          <ng-container *ngTemplateOutlet="singleRegionTmpl; context: { region: region }">
-          </ng-container>
-        </ng-container>
-      </ng-template>
-      
-      <!-- multi region wrapper -->
-      <ng-template #multiRegionWrapperTmpl>
-        <ng-container *ngTemplateOutlet="multiRegionTmpl; context: {
-          regions: selectedRegions
-        }">
-        </ng-container>
-        <!-- This is a wrapper for multiregion consisting of {{ selectedRegions.length }} regions -->
-      </ng-template>
-
-      <!-- place holder if length === 0 -->
-      <ng-container *ngIf="selectedRegions.length === 0">
-        <ng-container *ngTemplateOutlet="singleRegionTmpl; context: { region: false }">
-        </ng-container>
-      </ng-container>
-    </ng-container>
-
-    <div class="spacer">
-    </div>
-  </div>
-
-  <!-- collapse btn -->
-  <ng-container *ngTemplateOutlet="collapseBtn">
-  </ng-container>
-</ng-template>
-
-<ng-template #sidenavDsPreviewTmpl let-file="file" let-filename="filename" let-datasetId="datasetId">
-  <div class="w-100 flex-grow-1 d-flex flex-column">
-
-    <preview-card class="d-block bs-border-box ml-15px-n mr-15px-n flex-grow-1"
-      [attr.aria-label]="ARIA_LABEL_ADDITIONAL_VOLUME_CONTROL"
-      [datasetId]="datasetId"
-      [filename]="filename">
-    </preview-card>
-
-    <!-- collapse btn -->
-    <ng-container *ngTemplateOutlet="collapseBtn">
-    </ng-container>
-  </div>
-</ng-template>
-
-<ng-template #empty>
-</ng-template>
-
-<ng-template #autocompleteTmpl>
-  <div class="iv-custom-comp bg card w-100 mat-elevation-z8 pe-all">
-    <region-text-search-autocomplete class="w-100 pt-2 flex-shrink-0 flex-grow-0">
-    </region-text-search-autocomplete>
-  </div>
-</ng-template>
-
-<ng-template #selectRegionErrorTmpl>
-  SELECT REGION ERROR
-</ng-template>
-
-<!-- single region template -->
-<div id="scratch-pad">
-</div>
-
-<!-- mobile nub. may be required when more advanced control is required on mobile. for now, disabled -->
-<mobile-overlay
-  *ngIf="false && (useMobileUI$ | async) && viewerLoaded"
-  [iav-mobile-overlay-guide-tmpl]="mobileOverlayGuide"
-  [tunableProperties]="tunableMobileProperties"
-  [iav-mobile-overlay-hide-ctrl-btn]="(panelMode$ | async) !== 'SINGLE_PANEL'"
-  [iav-mobile-overlay-ctrl-btn-pos]="panelMode$ | async | mobileControlNubStylePipe">
-
-</mobile-overlay>
-
-<ng-template #mobileOverlayGuide>
-  <div>
-    <i class="fas fa-arrows-alt-v"></i>
-    <span>
-      Select item
-    </span>
-  </div>
-  <div>
-    <i class="fas fa-arrows-alt-h"></i>
-    <span>
-      Modify item value
-    </span>
-  </div>
-</ng-template>
-
-<!-- region tmpl placeholder -->
-<ng-template #regionPlaceholderTmpl>
-  <div class="placeholder-region-detail bs-border-box ml-15px-n mr-15px-n mat-elevation-z4">
-    <span class="text-muted">
-      Select a region by clicking on the viewer or search from above
-    </span>
-  </div>
-</ng-template>
-
-<!-- expansion tmpl -->
-<ng-template #ngMatAccordionTmpl
-  let-title="title"
-  let-desc="desc"
-  let-iconClass="iconClass"
-  let-iconTooltip="iconTooltip"
-  let-iavNgIf="iavNgIf"
-  let-content="content">
-  <mat-expansion-panel
-    [attr.data-opened]="expansionPanel.expanded"
-    [attr.data-mat-expansion-title]="title"
-    hideToggle
-    *ngIf="iavNgIf"
-    #expansionPanel="matExpansionPanel">
-
-    <mat-expansion-panel-header>
-
-      <!-- title -->
-      <mat-panel-title>
-        {{ title }}
-      </mat-panel-title>
-
-      <!-- desc + icon -->
-      <mat-panel-description class="d-flex align-items-center justify-content-end"
-        [matTooltip]="iconTooltip">
-        <span class="mr-3">{{ desc }}</span>
-        <span class="accordion-icon d-inline-flex justify-content-center">
-          <i [class]="iconClass"></i>
-        </span>
-      </mat-panel-description>
-
-    </mat-expansion-panel-header>
-
-    <!-- content -->
-    <ng-container *ngTemplateOutlet="content; context: { expansionPanel: expansionPanel }">
-    </ng-container>
-  </mat-expansion-panel>
-</ng-template>
-
-
-<!-- multi region tmpl -->
-<ng-template #multiRegionTmpl let-regions="regions">
-  <ng-template [ngIf]="regions.length > 0" [ngIfElse]="regionPlaceholderTmpl">
-    <region-menu
-      [showRegionInOtherTmpl]="false"
-      [region]="{
-        name: CONST.MULTI_REGION_SELECTION
-      }"
-      class="bs-border-box ml-15px-n mr-15px-n mat-elevation-z4">
-    </region-menu>
-
-    <!-- other regions detail accordion -->
-    <mat-accordion class="bs-border-box ml-15px-n mr-15px-n mt-2">
-
-      <!--  regional features-->
-      <ng-template #regionalFeaturesTmpl>
-        <data-browser
-          [disableVirtualScroll]="true"
-          [regions]="regions">
-        </data-browser>
-      </ng-template>
-
-      <div class="hidden"
-        iav-databrowser-directive
-        [regions]="regions"
-        #iavDbDirective="iavDatabrowserDirective">
-      </div>
-  
-      <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
-        title: CONST.REGIONAL_FEATURES,
-        desc: iavDbDirective?.dataentries?.length,
-        iconClass: 'fas fa-database',
-        iconTooltip: iavDbDirective?.dataentries?.length | regionAccordionTooltipTextPipe : 'regionalFeatures',
-        iavNgIf: iavDbDirective?.dataentries?.length,
-        content: regionalFeaturesTmpl
-      }">
-      </ng-container>
-
-      <!-- Multi regions include -->
-      <ng-template #multiRegionInclTmpl>
-        <mat-chip-list>
-          <mat-chip *ngFor="let r of regions"
-            iav-region
-            [region]="r"
-            [ngClass]="{
-              'darktheme':regionDirective.rgbDarkmode === true,
-              'lighttheme': regionDirective.rgbDarkmode === false
-            }"
-            [style.backgroundColor]="regionDirective.rgbString"
-            #regionDirective="iavRegion">
-            <span class="iv-custom-comp text text-truncate d-inline pl-4">
-              {{ r.name }}
-            </span>
-          </mat-chip>
-        </mat-chip-list>
-      </ng-template>
-      
-      <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
-        title: 'Brain regions',
-        desc: regions.length,
-        iconClass: 'fas fa-brain',
-        iavNgIf: true,
-        content: multiRegionInclTmpl
-      }">
-      </ng-container>
-
-    </mat-accordion>
-  </ng-template>
-</ng-template>
-
-
-<!-- single region tmpl -->
-<ng-template #singleRegionTmpl let-region="region">
-  <!-- region detail -->
-  <ng-container *ngIf="region; else regionPlaceholderTmpl">
-    <region-menu
-      [showRegionInOtherTmpl]="false"
-      [region]="region"
-      class="bs-border-box ml-15px-n mr-15px-n mat-elevation-z4">
-    </region-menu>
-  </ng-container>
-
-  <!-- other region detail accordion -->
-  <mat-accordion *ngIf="region"
-    class="bs-border-box ml-15px-n mr-15px-n mt-2"
-    iav-region
-    [region]="region"
-    #iavRegion="iavRegion">
-
-    <!-- desc -->
-    <ng-container *ngFor="let ods of (region.originDatasets || [])">
-      <ng-template #regionDescTmpl>
-        <single-dataset-view
-          [hideTitle]="true"
-          [hideExplore]="true"
-          [hidePreview]="true"
-          [hidePinBtn]="true"
-          [hideDownloadBtn]="true"
-          [kgSchema]="ods.kgSchema"
-          [kgId]="ods.kgId">
-
-        </single-dataset-view>
-      </ng-template>
-      <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
-        title: 'Description',
-        iconClass: 'fas fa-info',
-        iavNgIf: true,
-        content: regionDescTmpl
-      }">
-
-      </ng-container>
-    </ng-container>
-
-    <!-- Explore in other template -->
-    <ng-container *ngIf="iavRegion.regionInOtherTemplates$ | async as regionInOtherTemplates">
-
-      <ng-template #exploreInOtherTmpl>
-        <mat-card *ngFor="let sameRegion of regionInOtherTemplates"
-          class="p-0 border-0 box-shadow-none mt-1 tb-1 cursor-pointer" 
-          (click)="iavRegion.changeView(sameRegion)"
-          [matTooltip]="sameRegion.template.name + (sameRegion.hemisphere ? (' - ' + sameRegion.hemisphere) : '')"
-          mat-ripple>
-          <small>
-            {{ sameRegion.template.name + (sameRegion.hemisphere ? (' - ' + sameRegion.hemisphere) : '') }}
-          </small>
-        </mat-card>
-      </ng-template>
-
-      <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
-        title: 'Explore in other templates',
-        desc: regionInOtherTemplates.length,
-        iconClass: 'fas fa-brain',
-        iconTooltip: regionInOtherTemplates.length | regionAccordionTooltipTextPipe : 'regionInOtherTmpl',
-        iavNgIf: regionInOtherTemplates.length,
-        content: exploreInOtherTmpl
-      }">
-
-
-      </ng-container>
-    </ng-container>
-
-    <!--  regional features-->
-    <ng-template #regionalFeaturesTmpl let-expansionPanel="expansionPanel">
-
-      <data-browser
-        *ngIf="expansionPanel.expanded" 
-        [disableVirtualScroll]="true"
-        [regions]="[region]">
-      </data-browser>
-    </ng-template>
-
-    <div class="hidden" iav-databrowser-directive
-      [regions]="[region]"
-      #iavDbDirective="iavDatabrowserDirective">
-    </div>
-
-    <!-- if dataset is loading -->
-    <ng-template [ngIf]="iavDbDirective?.fetchingFlag" [ngIfElse]="featureLoadedTmpl">
-      <div class="d-flex justify-content-center">
-        <spinner-cmp></spinner-cmp>
-      </div>
-    </ng-template>
-
-    <ng-template #featureLoadedTmpl>
-
-      <!-- place holder content, if no regional features or connectivity or change ref space options are available -->
-      <ng-template [ngIf]="iavDbDirective?.dataentries?.length === 0
-        && !(selectedParcellation?.hasAdditionalViewMode?.includes('connectivity'))">
-        <div class="p-4">
-          {{ CONST.NO_ADDIONTAL_INFO_AVAIL }}
-        </div>
-      </ng-template>
-
-    </ng-template>
-
-
-    <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
-      title: CONST.REGIONAL_FEATURES,
-      desc: iavDbDirective?.dataentries?.length,
-      iconClass: 'fas fa-database',
-      iconTooltip: iavDbDirective?.dataentries?.length | regionAccordionTooltipTextPipe : 'regionalFeatures',
-      iavNgIf: iavDbDirective?.dataentries?.length,
-      content: regionalFeaturesTmpl
-    }">
-    </ng-container>
-
-    <!-- Connectivity -->
-    <ng-template #connectivityContentTmpl let-expansionPanel="expansionPanel">
-      <mat-card-content class="flex-grow-1 flex-shrink-1 w-100">
-        <ng-container *ngFor="let region of selectedRegions$ | async">
-          <connectivity-browser class="pe-all flex-shrink-1"
-            [region]="region"
-            [parcellationId]="selectedParcellation['@id']"
-            (setOpenState)="expansionPanel.expanded = $event"
-            (connectivityNumberReceived)="connectivityNumber = $event"
-            [accordionExpanded]="expansionPanel.expanded">
-          </connectivity-browser>
-        </ng-container>
-      </mat-card-content>
-    </ng-template>
-
-    <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
-      title: 'Connectivity',
-      desc: connectivityNumber? connectivityNumber : connectedCounterDir.value,
-      iconClass: 'fas fa-braille',
-      iconTooltip: connectedCounterDir.value | regionAccordionTooltipTextPipe : 'connectivity',
-      iavNgIf: selectedParcellation?.hasAdditionalViewMode?.includes('connectivity'),
-      content: connectivityContentTmpl
-    }">
-    </ng-container>
-
-    <div class="w-0 h-0"
-      iav-counter
-      #connectedCounterDir="iavCounter">
-      <!-- TODO figure out why conn browser does not work here -->
-      <!-- @fsdavid, can you take a look why this component is not emitting connectivityNumberReceived event? -->
-      <connectivity-browser *ngIf="region && region.name"
-        class="d-block h-0 w-0 overflow-hidden"
-        [region]="region"
-        [parcellationId]="selectedParcellation['@id']"
-        [accordionExpanded]="true"
-        (connectivityNumberReceived)="connectedCounterDir.value = $event">
-        
-      </connectivity-browser>
-    </div>
-  </mat-accordion>
-</ng-template>
-
-<!-- overlay templates -->
-
-<!-- slice view overlay tmpl -->
-<ng-template #ngPanelOverlayTmpl let-panelIndex="panelIndex">
-
-  <!-- perspective view tmpl -->
-  <ng-template #overlayPerspectiveTmpl>
-    <layout-floating-container class="tmp" landmarkContainer>
-
-      <div class="d-flex flex-column justify-content-center align-items-center w-100 h-100 position-absolute opacity-crossfade screen-overlay pe-none"
-        [ngClass]="{onHover: !!(showPerpsectiveScreen$ | async)}"
-        [attr.id]="ID_MESH_LOADING_STATUS"
-        role="status">
-
-        <spinner-cmp *ngIf="showPerpsectiveScreen$ | async">
-        </spinner-cmp>
-        
-        <mat-list>
-          <mat-list-item>
-            {{ showPerpsectiveScreen$ | async }}
-          </mat-list-item>
-        </mat-list>
-      </div>
-
-      <!-- maximise/minimise button -->
-      <ng-container *ngTemplateOutlet="panelCtrlTmpl; context: {
-        panelIndex: panelIndex,
-        visible: (hoveredPanelIndices$ | async) === panelIndex
-      }">
-      </ng-container>
-
-      <!-- mesh loading is still weird -->
-      <!-- if the precomputed server does not have the necessary fragment file, then the numberws will not collate -->
-      <div *ngIf="false && (perspectiveViewLoading$ | async)" class="loadingIndicator">
-        <spinner-cmp></spinner-cmp>
-
-        <div *ngIf="false" perspectiveLoadingText>
-          {{ perspectiveViewLoading$ | async }}
-        </div>
-      </div>
-    </layout-floating-container>
-  </ng-template>
-
-  <!-- nb this slice view is not suitable for perspective view! -->
-  <layout-floating-container *ngIf="panelIndex < 3; else overlayPerspectiveTmpl"
-    landmarkContainer
-    class="overflow-hidden">
-
-    <!-- customLandmarks -->
-    <landmark-2d-flat-cmp *ngFor="let lm of (customLandmarks$ | async | filterByProperty : 'showInSliceView')"
-      (mouseenter)="handleMouseEnterCustomLandmark(lm)"
-      (mouseleave)="handleMouseLeaveCustomLandmark(lm)"
-      [color]="lm.color || [255, 255, 255]"
-      [positionX]="getPositionX(panelIndex, lm)"
-      [positionY]="getPositionY(panelIndex, lm)"
-      [positionZ]="getPositionZ(panelIndex, lm)">
-
-    </landmark-2d-flat-cmp>
-
-    <!-- only show landmarks in slice views -->
-
-    <landmark-2d-flat-cmp *ngFor="let spatialData of (selectedPtLandmarks$ | async)"
-      (mouseenter)="handleMouseEnterLandmark(spatialData)"
-      (mouseleave)="handleMouseLeaveLandmark(spatialData)"
-      [color]="spatialData.highlight ? [255, 0, 0] : [255, 255, 255]"
-      [positionX]="getPositionX(panelIndex, spatialData)"
-      [positionY]="getPositionY(panelIndex, spatialData)"
-      [positionZ]="getPositionZ(panelIndex, spatialData)">
-    </landmark-2d-flat-cmp>
-
-    <!-- maximise/minimise button -->
-    <ng-container *ngTemplateOutlet="panelCtrlTmpl; context: {
-      panelIndex: panelIndex,
-      visible: (hoveredPanelIndices$ | async) === panelIndex
-    }">
-    </ng-container>
-
-    <div *ngIf="(sliceViewLoadingMain$ | async)[panelIndex]" class="loadingIndicator">
-      <spinner-cmp></spinner-cmp>
-    </div>
-  </layout-floating-container>
-
-</ng-template>
-
-<!-- panel control template -->
-<ng-template
-  #panelCtrlTmpl
-  let-panelIndex="panelIndex"
-  let-visible="visible">
-
-  <div class="opacity-crossfade always-show-touchdevice pe-all overlay-btn-container"
-    [ngClass]="{ onHover: visible }"
-    [attr.data-viewer-controller-visible]="visible"
-    [attr.data-viewer-controller-index]="panelIndex">
-
-    <!-- perspective specific control -->
-    <ng-container *ngIf="panelIndex === 3">
-      <ng-container *ngTemplateOutlet="perspectiveOctantRemovalTmpl; context: {
-        state: (nehubaViewerPerspectiveOctantRemoval$ | async),
-        disableOctantRemoval: disableOctantRemoval$ | async
-      }">
-
-      </ng-container>
-    </ng-container>
-
-    <!-- factor < 1.0 === zoom in -->
-    <button mat-icon-button color="primary"
-      (click)="zoomNgView(panelIndex, 0.9)"
-      [attr.aria-label]="ARIA_LABEL_ZOOM_IN">
-      <i class="fas fa-search-plus"></i>
-    </button>
-
-    <!-- factor > 1.0 === zoom out -->
-    <button mat-icon-button color="primary"
-      (click)="zoomNgView(panelIndex, 1.1)"
-      [attr.aria-label]="ARIA_LABEL_ZOOM_OUT">
-      <i class="fas fa-search-minus"></i>
-    </button>
-
-    <maximise-panel-button
-      (click)="toggleMaximiseMinimise(panelIndex)"
-      [touch-side-class]="panelIndex">
-    </maximise-panel-button>
-  </div>
-
-</ng-template>
-
-
-<ng-template #perspectiveOctantRemovalTmpl let-state="state" let-disableOctantRemoval="disableOctantRemoval">
-  <div class="d-inline-block"
-    [matTooltip]="disableOctantRemoval?.mode !== null ? disableOctantRemoval.message : null">
-    <button
-      (click)="setOctantRemoval(!state)"
-      mat-icon-button
-      [disabled]="disableOctantRemoval?.mode !== null"
-      [attr.aria-label]="ARIA_LABEL_TOGGLE_FRONTAL_OCTANT"
-      color="primary">
-
-      <!-- octant removal is true -->
-      <ng-template [ngIf]="disableOctantRemoval?.mode !== null ? disableOctantRemoval.mode : state" [ngIfElse]="octantRemovalOffTmpl">
-        <i class="fas fa-eye-slash"></i>
-      </ng-template>
-
-      <!-- octant removal is false -->
-      <ng-template #octantRemovalOffTmpl>
-        <i class="fas fa-eye"></i>
-      </ng-template>
-    </button>
-  </div>
-</ng-template>
-
-
-<!-- template for rendering tab -->
-<ng-template #tabTmpl
-  let-isOpen="isOpen"
-  let-regionSelected="regionSelected"
-  let-iavAdditionallayers="iavAdditionallayers">
-
-  <!-- if mat drawer is open -->
-  <ng-template [ngIf]="isOpen" [ngIfElse]="tabTmpl_closedTmpl">
-    <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
-      matColor: 'basic',
-      fontIcon: 'fa-chevron-left'
-    }">
-    </ng-container>
-  </ng-template>
-
-  <!-- if matdrawer is closed -->
-  <ng-template #tabTmpl_closedTmpl>
-
-    <!-- if additional layers are being shown -->
-    <ng-template [ngIf]="iavAdditionallayers?.length > 0" [ngIfElse]="tabTmpl_noAdditionalLayers">
-      <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
-        matColor: 'accent',
-        fontIcon: 'fa-database',
-        tooltip: 'Explore dataset preview'
-      }">
-      </ng-container>
-    </ng-template>
-
-    <!-- if additional layers not not being shown -->
-    <ng-template #tabTmpl_noAdditionalLayers>
-
-      <!-- if region selected > 0 -->
-      <ng-template [ngIf]="regionSelected?.length > 0" [ngIfElse]="tabTmpl_nothingSelected">
-        <div class="hidden"
-          iav-region
-          [region]="regionSelected[0]"
-          #tabTmpl_iavRegion="iavRegion">
-        </div>
-
-        <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
-          matColor: 'accent',
-          customColor: tabTmpl_iavRegion.rgbString,
-          customColorDarkmode: tabTmpl_iavRegion.rgbDarkmode,
-          fontIcon: 'fa-brain',
-          tooltip: 'Explore ' + tabTmpl_iavRegion.region.name
-        }">
-
-        </ng-container>
-      </ng-template>
-
-      <!-- nothing is selected -->
-      <ng-template #tabTmpl_nothingSelected>
-        <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
-          matColor: 'primary',
-          fontIcon: 'fa-sitemap',
-          tooltip: 'Explore regions'
-        }">
-        </ng-container>
-      </ng-template>
-    </ng-template>
-  </ng-template>
-
-  <ng-template #tabTmpl_defaultTmpl
-    let-matColor="matColor"
-    let-fontIcon="fontIcon"
-    let-customColor="customColor"
-    let-customColorDarkmode="customColorDarkmode"
-    let-tooltip="tooltip">
-    <button mat-raised-button
-      [attr.aria-label]="ARIA_LABEL_TOGGLE_SIDE_PANEL"
-      [matTooltip]="tooltip"
-      class="pe-all tab-toggle"
-      [ngClass]="{
-        'darktheme': customColorDarkmode === true,
-        'lighttheme': customColorDarkmode === false
-      }"
-      [style.backgroundColor]="customColor"
-      (click)="sideNavMasterSwitch.toggle()"
-      [color]="(!customColor && matColor) ? matColor : null">
-
-      <span [ngClass]="{'iv-custom-comp  text': !!customColor}">
-        <i class="fas" [ngClass]="fontIcon || 'fa-question'"></i>
-      </span>
-    </button>
-  </ng-template>
-</ng-template>
diff --git a/src/viewerModule/module.ts b/src/viewerModule/module.ts
index b9359cbf6..60663cff4 100644
--- a/src/viewerModule/module.ts
+++ b/src/viewerModule/module.ts
@@ -42,308 +42,3 @@ import { ViewerCmp } from "./viewerCmp/viewerCmp.component";
 })
 
 export class ViewerModule{}
-
-/**
-    <ui-nehuba-container
-      class="z-index-10"
-      #uiNehubaContainer="uiNehubaContainer"
-      iav-mouse-hover
-      #iavMouseHoverEl="iavMouseHover"
-      [currentOnHoverObs$]="iavMouseHoverEl.currentOnHoverObs$"
-      [currentOnHover]="iavMouseHoverEl.currentOnHoverObs$ | async"
-      iav-captureClickListenerDirective
-      [iav-captureClickListenerDirective-captureDocument]="true"
-      (iav-captureClickListenerDirective-onUnmovedClick)="mouseClickDocument($event)"
-      (drag-drop)="localFileService.handleFileDrop($event)">
-
-      <!-- top right content transclusion -->
-      <div ui-nehuba-container-overlay-top-right class="d-inline-flex flex-row justify-content-end align-items-start z-index-6 position-absolute pe-none w-100 h-100">
-
-        <top-menu-cmp
-          class="mt-3 mr-2"
-          [parcellationIsSelected]="!!selectedParcellation"
-          [ismobile]="(media.mediaBreakPoint$ | async) > 3">
-        </top-menu-cmp>
-
-        <!-- atlas selector -->
-        <div *ngIf="uiNehubaContainer.viewerLoaded"
-          class="iv-custom-comp bg card m-2 mat-elevation-z2">
-          <atlas-dropdown-selector class="pe-all mt-2">
-          </atlas-dropdown-selector>
-        </div>
-
-      </div>
-
-      <!-- bottom left content transclusion -->
-      <div ui-nehuba-container-overlay-bottom-left class="d-inline-flex pe-none w-100 align-items-end m-2 mb-4">
-
-        <!-- only load atlas layer selector and chips if viewer is loaded -->
-        <ng-template [ngIf]="uiNehubaContainer.viewerLoaded  && !(isStandaloneVolumes$ | async)">
-
-          <!-- Viewer Selector Container-->
-          <atlas-layer-selector
-            #alSelector="atlasLayerSelector"
-            class="pe-all"
-            (iav-outsideClick)="alSelector.selectorExpanded = false">
-          </atlas-layer-selector>
-          <mat-chip-list class="mb-2">
-            <!-- additional layer -->
-
-            <ng-container>
-              <ng-container *ngTemplateOutlet="currParcellationTmpl; context: { addParc: (selectedAdditionalLayers$ | async), parc: selectedParcellation }">
-              </ng-container>
-            </ng-container>
-
-            <!-- any selected region(s) -->
-            <ng-container>
-              <ng-container *ngTemplateOutlet="selectedRegionTmpl">
-              </ng-container>
-            </ng-container>
-
-            <!-- controls for iav volumes -->
-            <div class="hidden" iav-shown-previews #previews="iavShownPreviews"></div>
-            <ng-container *ngTemplateOutlet="selectedDatasetPreview; context: { layers: previews.iavAdditionalLayers$ | async | filterPreviewByType : [previews.FILETYPES.VOLUMES] }">
-            </ng-container>
-
-          </mat-chip-list>
-
-          <!-- current layer tmpl -->
-
-          <ng-template #currParcellationTmpl let-parc="parc" let-addParc="addParc">
-
-            <div [matMenuTriggerFor]="layerVersionMenu"
-              [matMenuTriggerData]="{ layerVersionMenuTrigger: layerVersionMenuTrigger }"
-              #layerVersionMenuTrigger="matMenuTrigger">
-
-              <ng-template [ngIf]="addParc.length > 0" [ngIfElse]="defaultParcTmpl">
-                <ng-container *ngFor="let p of addParc">
-                  <ng-container *ngTemplateOutlet="chipTmpl; context: {
-                    parcel: p,
-                    selected: true,
-                    dismissable: true,
-                    onclick: layerVersionMenuTrigger.toggleMenu.bind(layerVersionMenuTrigger)
-                  }">
-                  </ng-container>
-                </ng-container>
-              </ng-template>
-              <ng-template #defaultParcTmpl>
-                <ng-container *ngTemplateOutlet="chipTmpl; context: {
-                  parcel: parc,
-                  selected: false,
-                  dismissable: false,
-                  onclick: layerVersionMenuTrigger.toggleMenu.bind(layerVersionMenuTrigger)
-                }">
-                </ng-container>
-              </ng-template>
-            </div>
-          </ng-template>
-
-          <!-- render parc templ -->
-          <ng-template #chipTmpl
-            let-parcel="parcel"
-            let-selected="selected"
-            let-dismissable="dismissable"
-            let-chipClass="class"
-            let-onclick="onclick">
-            <mat-chip class="pe-all position-relative z-index-2 d-inline-flex justify-content-between"
-              [ngClass]="chipClass"
-              (click)="onclick && onclick()"
-              [selected]="selected">
-
-              <span>
-                {{ parcel?.groupName ? (parcel?.groupName + ' - ') : '' }}{{ parcel && (parcel.displayName || parcel.name) }}
-              </span>
-
-              <!-- info icon -->
-              <ng-template [ngIf]="parcel?.originDatasets?.length > 0" [ngIfElse]="infoIconBasic">
-
-                <mat-icon
-                  *ngFor="let ds of parcel.originDatasets"
-                  fontSet="fas"
-                  fontIcon="fa-info-circle"
-                  iav-stop="click"
-                  iav-dataset-show-dataset-dialog
-                  [iav-dataset-show-dataset-dialog-kgid]="ds['kgId']"
-                  [iav-dataset-show-dataset-dialog-kgschema]="ds['kgSchema']"
-                  [iav-dataset-show-dataset-dialog-name]="parcel?.properties?.name"
-                  [iav-dataset-show-dataset-dialog-description]="parcel?.properties?.description">
-                </mat-icon>
-
-              </ng-template>
-
-              <ng-template #infoIconBasic>
-                <mat-icon *ngIf="parcel?.properties?.name && parcel?.properties?.description"
-                  fontSet="fas"
-                  fontIcon="fa-info-circle"
-                  iav-stop="click"
-                  iav-dataset-show-dataset-dialog
-                  [iav-dataset-show-dataset-dialog-name]="parcel.properties.name"
-                  [iav-dataset-show-dataset-dialog-description]="parcel.properties.description">
-
-                </mat-icon>
-              </ng-template>
-
-              <!-- dismiss icon -->
-              <mat-icon
-                *ngIf="dismissable"
-                (click)="clearAdditionalLayer(parcel); $event.stopPropagation()"
-                fontSet="fas"
-                fontIcon="fa-times">
-              </mat-icon>
-            </mat-chip>
-          </ng-template>
-
-          <!-- layer version selector -->
-          <mat-menu #layerVersionMenu
-            class="bg-none box-shadow-none"
-            [hasBackdrop]="false">
-            <ng-template matMenuContent let-layerVersionMenuTrigger="layerVersionMenuTrigger">
-              <div (iav-outsideClick)="layerVersionMenuTrigger.closeMenu()">
-                <ng-container *ngFor="let parcVer of selectedLayerVersions$ | async">
-                  <ng-container *ngTemplateOutlet="chipTmpl; context: {
-                    parcel: parcVer,
-                    selected: selectedParcellation && selectedParcellation['@id'] === parcVer['@id'],
-                    dismissable: false,
-                    class: 'w-100',
-                    onclick: bindFns([
-                      [ selectParcellation.bind(this), parcVer ],
-                      [ layerVersionMenuTrigger.closeMenu.bind(layerVersionMenuTrigger) ]
-                    ])
-                  }">
-                  </ng-container>
-                  <div class="mt-1"></div>
-                </ng-container>
-              </div>
-            </ng-template>
-          </mat-menu>
-
-          <ng-template #selectedRegionTmpl>
-
-            <!-- regions chip -->
-            <ng-template [ngIf]="selectedRegions$ | async" let-selectedRegions="ngIf">
-              <!-- if regions.length > 1 -->
-              <!-- use group chip -->
-              <ng-template [ngIf]="selectedRegions.length > 1" [ngIfElse]="singleRegionTmpl">
-                <mat-chip
-                  color="primary"
-                  selected
-                  (click)="uiNehubaContainer.matDrawerMinor.open() && uiNehubaContainer.navSideDrawerMainSwitch.open()"
-                  class="pe-all position-relative z-index-1 ml-8-n">
-                  <span class="iv-custom-comp text text-truncate d-inline pl-4">
-                    {{ CONST.MULTI_REGION_SELECTION }}
-                  </span>
-                  <mat-icon
-                    (click)="clearSelectedRegions()"
-                    fontSet="fas"
-                    iav-stop="click"
-                    fontIcon="fa-times">
-                  </mat-icon>
-                </mat-chip>
-              </ng-template>
-
-              <!-- if reginos.lengt === 1 -->
-              <!-- use single region chip -->
-              <ng-template #singleRegionTmpl>
-                <ng-container *ngFor="let r of selectedRegions">
-
-                  <!-- region chip for discrete map -->
-                  <mat-chip
-                    iav-region
-                    (click)="uiNehubaContainer.matDrawerMinor.open() && uiNehubaContainer.navSideDrawerMainSwitch.open()"
-                    [region]="r"
-                    class="pe-all position-relative z-index-1 ml-8-n"
-                    [ngClass]="{
-                      'darktheme':regionDirective.rgbDarkmode === true,
-                      'lighttheme': regionDirective.rgbDarkmode === false
-                    }"
-                    [style.backgroundColor]="regionDirective.rgbString"
-                    #regionDirective="iavRegion">
-                    <span class="iv-custom-comp text text-truncate d-inline pl-4">
-                      {{ r.name }}
-                    </span>
-                    <mat-icon
-                      class="iv-custom-comp text"
-                      (click)="clearSelectedRegions()"
-                      fontSet="fas"
-                      iav-stop="click"
-                      fontIcon="fa-times">
-                    </mat-icon>
-                  </mat-chip>
-    
-                  <!-- chips for previewing origin datasets/continous map -->
-                  <ng-container *ngFor="let originDataset of (r.originDatasets || []); let index = index">
-                    <div class="hidden"
-                      iav-dataset-preview-dataset-file
-                      [iav-dataset-preview-dataset-file-kgid]="originDataset.kgId"
-                      [iav-dataset-preview-dataset-file-filename]="originDataset.filename"
-                      #previewDirective="iavDatasetPreviewDatasetFile">
-                    </div>
-                    <mat-chip *ngIf="previewDirective.active"
-                      (click)="uiNehubaContainer.matDrawerMinor.open() && uiNehubaContainer.navSideDrawerMainSwitch.open()"
-                      class="pe-all position-relative ml-8-n">
-                      <span class="pl-4">
-                        {{ regionDirective.regionOriginDatasetLabels$ | async | renderViewOriginDatasetlabel : index }}
-                      </span>
-                      <mat-icon (click)="previewDirective.onClick()"
-                        fontSet="fas"
-                        iav-stop="click"
-                        fontIcon="fa-times">
-                      </mat-icon>
-                    </mat-chip>
-    
-                    <mat-chip *ngFor="let key of clearViewKeys$ | async"
-                      (click)="uiNehubaContainer.matDrawerMinor.open() && uiNehubaContainer.navSideDrawerMainSwitch.open()"
-                      class="pe-all position-relative ml-8-n">
-                      <span class="pl-4">
-                        {{ key }}
-                      </span>
-                      <mat-icon (click)="unsetClearViewByKey(key)"
-                        fontSet="fas"
-                        iav-stop="click"
-                        fontIcon="fa-times">
-    
-                      </mat-icon>
-                    </mat-chip>
-                  </ng-container>
-    
-                </ng-container>
-              </ng-template>
-            </ng-template>
-
-          </ng-template>
-
-          <ng-template #selectedDatasetPreview let-layers="layers">
-
-            <ng-container *ngFor="let layer of layers">
-              <div class="hidden"
-                iav-dataset-preview-dataset-file
-                [iav-dataset-preview-dataset-file-kgid]="layer.datasetId"
-                [iav-dataset-preview-dataset-file-filename]="layer.filename"
-                #preview="iavDatasetPreviewDatasetFile">
-
-              </div>
-              <mat-chip class="pe-all"
-                (click)="uiNehubaContainer.matDrawerMinor.open() && uiNehubaContainer.navSideDrawerMainSwitch.open()">
-                {{ layer.file?.name || layer.filename || 'Unknown data preview' }}
-                <mat-icon fontSet="fas" fontIcon="fa-times"
-                  (click)="preview.onClick()"
-                  iav-stop="click">
-                </mat-icon>
-              </mat-chip>
-            </ng-container>
-          </ng-template>
-
-        </ng-template>
-      </div>
-
-      <!-- top left content transclusion -->
-      <div ui-nehuba-container-overlay-top-left class="d-inline-flex pe-none w-100 align-items-start m-2">
-        <ui-status-card
-          *ngIf="uiNehubaContainer.viewerLoaded"
-          class="pe-all muted-7"
-          [selectedTemplateName]="uiNehubaContainer?.selectedTemplate?.name"
-          [nehubaViewer]="uiNehubaContainer?.nehubaViewer">
-        </ui-status-card>
-      </div>
-    </ui-nehuba-container>
- */
\ No newline at end of file
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
index d9b52d1dc..e0bace5b0 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
@@ -18,7 +18,7 @@ import { IViewer, TViewerEvent } from "../../viewer.interface";
 import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component";
 import { NehubaViewerContainerDirective } from "../nehubaViewerInterface/nehubaViewerInterface.directive";
 import { calculateSliceZoomFactor, getFourPanel, getHorizontalOneThree, getSinglePanel, getVerticalOneThree, NEHUBA_INSTANCE_INJTKN, scanSliceViewRenderFn, takeOnePipe } from "../util";
-import { API_SERVICE_SET_VIEWER_HANDLE_TOKEN, IUserLandmark, TSetViewerHandle } from "src/atlasViewer/atlasViewer.apiService.service";
+import { API_SERVICE_SET_VIEWER_HANDLE_TOKEN, TSetViewerHandle } from "src/atlasViewer/atlasViewer.apiService.service";
 import { MouseHoverDirective } from "src/mouseoverModule";
 
 interface INgLayerInterface {
@@ -80,7 +80,7 @@ export class NehubaGlueCmp implements IViewer, OnChanges, OnDestroy{
   public perspectiveViewLoading$: Observable<string|null>
   public hoveredPanelIndices$: Observable<number>
   private viewPanelWeakMap = new WeakMap<HTMLElement, number>()
-  private viewPanels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement] = [null, null, null, null]
+  public viewPanels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement] = [null, null, null, null]
   private findPanelIndex = (panel: HTMLElement) => this.viewPanelWeakMap.get(panel)
   public nanometersToOffsetPixelsFn: Array<(...arg) => any> = []
 
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
index 45b20af1f..5c612b295 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
@@ -1,8 +1,18 @@
-<div class="d-block"
-  iav-nehuba-viewer-container
-  iav-mouse-hover
-  (iavNehubaViewerContainerViewerLoading)="handleViewerLoadedEvent($event)">
+<div class="d-block w-100 h-100"
+  (touchmove)="$event.preventDefault()"
+  iav-viewer-touch-interface
+  [iav-viewer-touch-interface-v-panels]="viewPanels"
+  [iav-viewer-touch-interface-vp-to-data]="iavContainer?.viewportToDatas"
+  [iav-viewer-touch-interface-ngviewer]="iavContainer?.nehubaViewerInstance?.nehubaViewer?.ngviewer"
+  [iav-viewer-touch-interface-nehuba-config]="selectedTemplate?.nehubaConfig">
+
+  <div class="d-block"
+    iav-nehuba-viewer-container
+    #iavContainer="iavNehubaViewerContainer"
+    iav-mouse-hover
+    (iavNehubaViewerContainerViewerLoading)="handleViewerLoadedEvent($event)">
 
+  </div>
 </div>
 
 <current-layout *ngIf="viewerLoaded$ | async" class="position-absolute w-100 h-100 d-block pe-none top-0 left-0">
-- 
GitLab