diff --git a/src/res/css/extra_styles.css b/src/res/css/extra_styles.css
index 88e4a8d10e17d410aa6dcce4fbd3a842cb437766..3aa834fd880fdbb63398bba87fb98fa8cbf3bd5f 100644
--- a/src/res/css/extra_styles.css
+++ b/src/res/css/extra_styles.css
@@ -176,6 +176,11 @@ markdown-dom pre code
   white-space:pre;
 }
 
+markdown-dom p
+{
+  margin: 0;
+}
+
 .highlight
 {
   background-color:rgba(150,150,0,0.5);
diff --git a/src/ui/ui.module.ts b/src/ui/ui.module.ts
index be64909fc1852861252a9729f5c173a8b8367017..7145621bc27bf7ae34fd0d85dde3d3d43a7dc14e 100644
--- a/src/ui/ui.module.ts
+++ b/src/ui/ui.module.ts
@@ -3,7 +3,6 @@ import { ComponentsModule } from "src/components/components.module";
 
 import { FormsModule, ReactiveFormsModule } from "@angular/forms";
 import { LayoutModule } from "src/layouts/layout.module";
-// import { NehubaContainer } from "./nehubaContainer/nehubaContainer.component";
 
 import { FilterRegionDataEntries } from "src/util/pipes/filterRegionDataEntries.pipe";
 import { GroupDatasetByRegion } from "src/util/pipes/groupDataEntriesByRegion.pipe";
@@ -28,7 +27,6 @@ import { DatabrowserModule } from "../atlasComponents/databrowserModule/databrow
 import { LogoContainer } from "./logoContainer/logoContainer.component";
 import { MobileOverlay } from "./nehubaContainer/mobileOverlay/mobileOverlay.component";
 import { MobileControlNubStylePipe } from "./nehubaContainer/pipes/mobileControlNubStyle.pipe";
-// import { StatusCardComponent } from "./nehubaContainer/statusCard/statusCard.component";
 
 import { HumanReadableFileSizePipe } from "src/util/pipes/humanReadableFileSize.pipe";
 import { KgSearchBtnColorPipe } from "src/util/pipes/kgSearchBtnColor.pipe";
@@ -51,7 +49,6 @@ import { HANDLE_SCREENSHOT_PROMISE, TypeHandleScrnShotPromise } from "./screensh
 import { ParcellationRegionModule } from "src/atlasComponents/parcellationRegion";
 import { AtlasCmpParcellationModule } from "src/atlasComponents/parcellation";
 import { AtlasCmptConnModule } from "src/atlasComponents/connectivity";
-import { ViewerCtrlModule } from "src/viewerCtrl";
 
 @NgModule({
   imports : [
@@ -72,17 +69,13 @@ import { ViewerCtrlModule } from "src/viewerCtrl";
     ParcellationRegionModule,
     AtlasCmpParcellationModule,
     AtlasCmptConnModule,
-    ViewerCtrlModule,
   ],
   declarations : [
-    // NehubaContainer,
     
     CitationsContainer,
     LogoContainer,
     MobileOverlay,
 
-    // StatusCardComponent,
-
     ActionDialog,
 
     /* pipes */
diff --git a/src/viewerCtrl/module.ts b/src/viewerCtrl/module.ts
index dd1a100beeba314400417dc5ac19670bf090bde4..e9722976e74ca4d7f754478f7d4ab61480e8775d 100644
--- a/src/viewerCtrl/module.ts
+++ b/src/viewerCtrl/module.ts
@@ -1,14 +1,18 @@
 import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
+import { FormsModule } from "@angular/forms";
+import { ComponentsModule } from "src/components";
 import { AngularMaterialModule } from "src/ui/sharedModules/angularMaterial.module";
+import { UtilModule } from "src/util";
 import { ViewerCtrlCmp } from "./viewerCtrlCmp/viewerCtrlCmp.component";
 
-// Migrate to viewer specific submodule when merged to dev
-
 @NgModule({
   imports: [
     CommonModule,
     AngularMaterialModule,
+    UtilModule,
+    FormsModule,
+    ComponentsModule,
   ],
   declarations: [
     ViewerCtrlCmp,
diff --git a/src/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts b/src/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
index 93e6f3def9078f23195e9bea73dac0165214c17f..a431d20c9ec166fc139552b78a07ea651b079f95 100644
--- a/src/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
+++ b/src/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
@@ -1,8 +1,13 @@
-import { Component, HostBinding } from "@angular/core";
+import { Component, HostBinding, Inject, Optional } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { Subscription } from "rxjs";
-import { viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors";
-
+import { combineLatest, Observable, Subscription } from "rxjs";
+import { filter, map } from "rxjs/operators";
+import { ngViewerActionSetPerspOctantRemoval } from "src/services/state/ngViewerState/actions";
+import { ngViewerSelectorOctantRemoval } from "src/services/state/ngViewerState/selectors";
+import { viewerStateCustomLandmarkSelector, viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors";
+import { NehubaViewerUnit } from "src/viewerModule/nehuba";
+import { NEHUBA_INSTANCE_INJTKN } from "src/viewerModule/nehuba/util";
+import { ARIA_LABELS, IDS } from 'common/constants'
 
 @Component({
   selector: 'viewer-ctrl-component',
@@ -15,14 +20,49 @@ import { viewerStateSelectedTemplatePureSelector } from "src/services/state/view
 
 export class ViewerCtrlCmp{
 
+  public ARIA_LABELS = ARIA_LABELS
+
   @HostBinding('attr.darktheme')
   darktheme = false
 
+  private _flagDelin = true
+  get flagDelin(){
+    return this._flagDelin
+  }
+  set flagDelin(flag){
+    this._flagDelin = flag
+    this.toggleParcVsbl()
+  }
+
   private sub: Subscription[] = []
   private hiddenLayerNames: string[] = []
 
+  private _removeOctantFlag: boolean
+  get removeOctantFlag(){
+    return this._removeOctantFlag
+  }
+  set removeOctantFlag(val){
+    this._removeOctantFlag = val
+    this.setOctantRemoval(this._removeOctantFlag)
+  }
+
+  public nehubaViewerPerspectiveOctantRemoval$ = this.store$.pipe(
+    select(ngViewerSelectorOctantRemoval),
+  )
+
+  public customLandmarks$: Observable<any> = this.store$.pipe(
+    select(viewerStateCustomLandmarkSelector),
+    map(lms => lms.map(lm => ({
+      ...lm,
+      geometry: {
+        position: lm.position
+      }
+    }))),
+  )
+
   constructor(
-    private store$: Store<any>
+    private store$: Store<any>,
+    @Optional() @Inject(NEHUBA_INSTANCE_INJTKN) private nehubaInst$: Observable<NehubaViewerUnit>,
   ){
 
     this.sub.push(
@@ -31,9 +71,22 @@ export class ViewerCtrlCmp{
       ).subscribe(tmpl => {
         const { useTheme } = tmpl || {}
         this.darktheme = useTheme === 'dark'
+      }),
+
+      this.nehubaViewerPerspectiveOctantRemoval$.subscribe(
+        flag => this.removeOctantFlag = flag
+      ),
+
+      combineLatest([
+        this.customLandmarks$,
+        this.nehubaInst$,
+      ]).pipe(
+        filter(([_, neubaInst]) => !!neubaInst),
+      ).subscribe(([landmarks, nehubainst]) => {
+        this.setOctantRemoval(landmarks.length === 0)
+        nehubainst.updateUserLandmarks(landmarks)
       })
     )
-
   }
 
   public toggleParcVsbl(){
@@ -41,9 +94,7 @@ export class ViewerCtrlCmp{
       .slice(1)
       .filter(({ visible }) => visible)
 
-    const allParcHidden = visibleParcLayers.length === 0
-    
-    if (allParcHidden) {
+    if (this.flagDelin) {
       for (const name of this.hiddenLayerNames) {
         const l = (window as any).viewer.layerManager.getLayerByName(name)
         l && l.setVisible(true)
@@ -62,4 +113,12 @@ export class ViewerCtrlCmp{
       (window as any).viewer.display.scheduleRedraw()
     })
   }
-}
\ No newline at end of file
+
+  public setOctantRemoval(octantRemovalFlag: boolean) {
+    this.store$.dispatch(
+      ngViewerActionSetPerspOctantRemoval({
+        octantRemovalFlag
+      })
+    )
+  }
+}
diff --git a/src/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html b/src/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html
index 2ba8e30622edf364319af102febfd0fe26d6d30c..8af6169e30f0adc086d4b010950dd3e3a3733bcd 100644
--- a/src/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html
+++ b/src/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html
@@ -1,14 +1,26 @@
-<h3 class="iv-custom-comp text mat-title">
-  Parcellations
+<h3 class="iv-custom-comp text mat-h3">
+  Volumes
 </h3>
 
-<mat-divider></mat-divider>
+<mat-slide-toggle [(ngModel)]="flagDelin"
+  #delinToggle="matSlideToggle"
+  [iav-key-listener]="[{ type: 'keydown', key: 'q', target: 'document', capture: true }]"
+  (iav-key-event)="delinToggle.toggle()">
 
-<button mat-flat-button color="warn"
-  class="mt-2"
-  (click)="toggleParcVsbl()">
-  <i class="fas fa-eye-slash"></i>
-  <span>
-    Clear All
+  <markdown-dom class="d-inline-block iv-custom-comp text">
+    Show delineations `[q]`
+  </markdown-dom>
+</mat-slide-toggle>
+
+<mat-divider class="mt-2 mb-2"></mat-divider>
+
+<h3 class="iv-custom-comp text mat-h3">
+  Perspective View
+</h3>
+
+<mat-slide-toggle [(ngModel)]="removeOctantFlag"
+  [aria-label]="ARIA_LABELS.TOGGLE_FRONTAL_OCTANT">
+  <span class="iv-custom-comp text">
+    Remove frontal octant
   </span>
-</button>
\ No newline at end of file
+</mat-slide-toggle>
diff --git a/src/viewerModule/nehuba/module.ts b/src/viewerModule/nehuba/module.ts
index b0bdeec6eef7d448804954174d8d7e9f65866447..d621278ebb4ab7d185e963e7be6c6b8fad1e2b63 100644
--- a/src/viewerModule/nehuba/module.ts
+++ b/src/viewerModule/nehuba/module.ts
@@ -23,6 +23,7 @@ import { FormsModule, ReactiveFormsModule } from "@angular/forms";
 import { BehaviorSubject } from "rxjs";
 import { StateModule } from "src/state";
 import { AuthModule } from "src/auth";
+import { ViewerCtrlModule } from "src/viewerCtrl";
 
 @NgModule({
   imports: [
@@ -36,6 +37,7 @@ import { AuthModule } from "src/auth";
     ComponentsModule,
     MouseoverModule,
     ShareModule,
+    ViewerCtrlModule,
 
     /**
      * should probably break this into its own...
diff --git a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
index 9fb2ce89790bda6c23d4ac26259585067c5c0990..fa177742e73717e3fe1d9719172f97122be3e2b4 100644
--- a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
@@ -149,6 +149,8 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
 
   public nehubaLoaded: boolean = false
 
+  public landmarksLoaded: boolean = false
+
   constructor(
     public elementRef: ElementRef,
     private workerService: AtlasWorkerService,
@@ -249,6 +251,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
         debounceTime(100),
         map(e => e.data.url),
       ).subscribe(url => {
+        this.landmarksLoaded = !!url
         this.removeuserLandmarks()
 
         /**
@@ -258,13 +261,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
           /**
            * remove transparency from meshes in current layer(s)
            */
-          for (const layerKey of this.multiNgIdsLabelIndexMap.keys()) {
-            const layer = this.nehubaViewer.ngviewer.layerManager.getLayerByName(layerKey)
-            if (layer) {
-              layer.layer.displayState.objectAlpha.restoreState(1.0)
-            }
-          }
-  
+          this.setMeshTransparency(false)
           return
         }
         const _ = {}
@@ -278,12 +275,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
         /**
          * adding transparency to meshes in current layer(s)
          */
-        for (const layerKey of this.multiNgIdsLabelIndexMap.keys()) {
-          const layer = this.nehubaViewer.ngviewer.layerManager.getLayerByName(layerKey)
-          if (layer) {
-            layer.layer.displayState.objectAlpha.restoreState(0.2)
-          }
-        }
+        this.setMeshTransparency(true)
       }),
     )
   }
@@ -771,6 +763,38 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     this.nehubaViewer.ngviewer.navigationState.pose.rotateRelative(this.vec3([0, 0, 1]), amount / 4.0 * Math.PI / 180.0)
   }
 
+  public toggleOctantRemoval(flag?: boolean) {
+    const ctrl = this.nehubaViewer?.ngviewer?.showPerspectiveSliceViews
+    if (!ctrl) {
+      this.log.error(`toggleOctantRemoval failed. this.nehubaViewer.ngviewer?.showPerspectiveSliceViews returns falsy`)
+      return
+    }
+    const newVal = typeof flag === 'undefined'
+      ? !ctrl.value
+      : flag
+    ctrl.restoreState(newVal)
+
+    if (this.landmarksLoaded) {
+      /**
+       * showPerspectSliceView -> ! meshTransparency
+       */
+      this.setMeshTransparency(!newVal)
+    }
+  }
+
+  public setMeshTransparency(flag: boolean){
+
+    /**
+     * remove transparency from meshes in current layer(s)
+     */
+    for (const layerKey of this.multiNgIdsLabelIndexMap.keys()) {
+      const layer = this.nehubaViewer.ngviewer.layerManager.getLayerByName(layerKey)
+      if (layer) {
+        layer.layer.displayState.objectAlpha.restoreState(flag ? 0.2 : 1.0)
+      }
+    }
+  }
+
   /**
    *
    * @param arrayIdx label indices of the shown segment(s)
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
index 430782c05f95c1ff8b42dcbbc1eff7814afffaf6..7692a747ac3a8eff562f6777cfb21854629d7a6a 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
@@ -1,12 +1,12 @@
 import { Component, ElementRef, EventEmitter, Inject, Input, OnChanges, OnDestroy, Optional, Output, SimpleChanges, ViewChild } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { asyncScheduler, combineLatest, fromEvent, interval, merge, Observable, of, Subject, timer } from "rxjs";
-import { ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer, ngViewerActionSetPerspOctantRemoval, ngViewerActionToggleMax } from "src/services/state/ngViewerState/actions";
+import { asyncScheduler, combineLatest, fromEvent, interval, merge, Observable, of, Subject } from "rxjs";
+import { ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer, ngViewerActionToggleMax } from "src/services/state/ngViewerState/actions";
 import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
 import { uiStateMouseOverSegmentsSelector } from "src/services/state/uiState/selectors";
 import { debounceTime, distinctUntilChanged, filter, map, mapTo, scan, shareReplay, startWith, switchMap, switchMapTo, take, tap, throttleTime, withLatestFrom } from "rxjs/operators";
 import { viewerStateAddUserLandmarks, viewerStateChangeNavigation, viewerStateMouseOverCustomLandmark, viewerStateSelectRegionWithIdDeprecated, viewerStateSetSelectedRegions, viewreStateRemoveUserLandmarks } from "src/services/state/viewerState/actions";
-import { ngViewerSelectorLayers, ngViewerSelectorClearView, ngViewerSelectorPanelOrder, ngViewerSelectorOctantRemoval, ngViewerSelectorPanelMode } from "src/services/state/ngViewerState/selectors";
+import { ngViewerSelectorLayers, ngViewerSelectorClearView, ngViewerSelectorPanelOrder, ngViewerSelectorPanelMode } from "src/services/state/ngViewerState/selectors";
 import { viewerStateCustomLandmarkSelector, viewerStateNavigationStateSelector, viewerStateSelectedRegionsSelector } from "src/services/state/viewerState/selectors";
 import { serialiseParcellationRegion } from 'common/util'
 import { ARIA_LABELS, IDS } from 'common/constants'
@@ -92,31 +92,6 @@ export class NehubaGlueCmp implements IViewer, OnChanges, OnDestroy{
     }))),
   )
 
-  private forceUI$ = this.customLandmarks$.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
-        }
-      }
-    })
-  )
-
-  public disableOctantRemovalCtrl$ = this.forceUI$.pipe(
-    filter(({ target }) => target === 'perspective:octantRemoval'),
-  )
-
-  public nehubaViewerPerspectiveOctantRemoval$ = this.store$.pipe(
-    select(ngViewerSelectorOctantRemoval),
-  )
-
   public panelOrder$ = this.store$.pipe(
     select(ngViewerSelectorPanelOrder),
     distinctUntilChanged(),
@@ -464,19 +439,6 @@ export class NehubaGlueCmp implements IViewer, OnChanges, OnDestroy{
     })
     this.onDestroyCb.push(() => perspectiveRenderEvSub.unsubscribe())
 
-    const perspOctCtrlSub = this.customLandmarks$.pipe(
-      withLatestFrom(
-        this.nehubaViewerPerspectiveOctantRemoval$
-      ),
-      switchMap(this.waitForNehuba.bind(this))
-    ).subscribe(([ landmarks, flag ]) => {
-      this.nehubaContainerDirective.toggleOctantRemoval(
-        landmarks.length > 0 ? false : flag
-      )
-      this.nehubaContainerDirective.nehubaViewerInstance.updateUserLandmarks(landmarks)
-    })
-    this.onDestroyCb.push(() => perspOctCtrlSub.unsubscribe())
-
     this.sliceRenderEvent$ = fromEvent<CustomEvent>(this.el.nativeElement, 'sliceRenderEvent')
     this.sliceViewLoadingMain$ = this.sliceRenderEvent$.pipe(
       scan(scanSliceViewRenderFn, [null, null, null]),
@@ -730,14 +692,6 @@ export class NehubaGlueCmp implements IViewer, OnChanges, OnDestroy{
     )
   }
 
-  public setOctantRemoval(octantRemovalFlag: boolean) {
-    this.store$.dispatch(
-      ngViewerActionSetPerspOctantRemoval({
-        octantRemovalFlag
-      })
-    )
-  }
-
   public toggleMaximiseMinimise(index: number) {
     this.store$.dispatch(ngViewerActionToggleMax({
       payload: { index }
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
index 65057b2b5f6b841514f2619dc063b96fe136afe7..d5f86d163f05dcb062d6883476a76670d9e132f0 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
@@ -115,12 +115,12 @@
 
     <!-- perspective specific control -->
     <ng-container *ngIf="panelIndex === 3">
-      <ng-container *ngTemplateOutlet="perspectiveOctantRemovalTmpl; context: {
-        state: (nehubaViewerPerspectiveOctantRemoval$ | async),
-        disableOctantRemovalCtrl: disableOctantRemovalCtrl$ | async
-      }">
 
-      </ng-container>
+      <button mat-icon-button color="primary"
+        [matMenuTriggerFor]="viewerCtrlMenu">
+        <i class="fas fa-cog"></i>
+      </button>
+
     </ng-container>
 
     <!-- factor < 1.0 === zoom in -->
@@ -145,28 +145,12 @@
 
 </ng-template>
 
-<!-- tmpl for toggling perspective frontal octant -->
-<ng-template #perspectiveOctantRemovalTmpl
-  let-state="state"
-  let-disableOctantRemovalCtrl="disableOctantRemovalCtrl">
-  <div class="d-inline-block"
-    [matTooltip]="disableOctantRemovalCtrl?.mode !== null ? disableOctantRemovalCtrl.message : null">
-    <button
-      (click)="setOctantRemoval(!state)"
-      mat-icon-button
-      [disabled]="disableOctantRemovalCtrl?.mode !== null"
-      [attr.aria-label]="ARIA_LABELS.TOGGLE_FRONTAL_OCTANT"
-      color="primary">
-
-      <!-- octant removal is true -->
-      <ng-template [ngIf]="disableOctantRemovalCtrl?.mode !== null ? disableOctantRemovalCtrl.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>
\ No newline at end of file
+<!-- viewer ctrl -->
+<mat-menu #viewerCtrlMenu>
+  <!-- NB must not lazy load. key listener needs to work even when component is not yet rendered -->
+  <!-- stop propagation is needed, or else click will result in dismiss of menu -->
+  <viewer-ctrl-component class="d-block m-2 ml-3 mr-3"
+    #viewerCtrlCmp="viewerCtrlCmp"
+    (click)="$event.stopPropagation()">
+  </viewer-ctrl-component>
+</mat-menu>
diff --git a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
index cdb000a9cfa40f0c34ba86f7dc6e697a7ea6267a..f34e5140cfd10fccd91dbc3ad4fc7e9a360faaa8 100644
--- a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
+++ b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
@@ -290,11 +290,7 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
   }
 
   public toggleOctantRemoval(flag: boolean){
-    const showPerspectiveSliceViews = this.nehubaViewerInstance?.nehubaViewer?.ngviewer?.showPerspectiveSliceViews
-    if (showPerspectiveSliceViews) showPerspectiveSliceViews.restoreState(flag)
-    else {
-      this.log && this.log.warn(`showPerspectiveSliceViews not defined`)
-    }
+    this.nehubaViewerInstance.toggleOctantRemoval(flag)
   }
 
   createNehubaInstance(template: any, lifeCycle: INehubaLifecycleHook = {}){