diff --git a/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.html b/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.html
index 8aaa38b574869ea5514a918197709af4ce0a6e82..a89d43d5f7b0adb2acadfb9241787329118b318e 100644
--- a/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.html
+++ b/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.html
@@ -60,7 +60,21 @@
   </div>
 </div>
 
-<app-dialog-action-buttons
-  buttonsLabelSection="content"
-  [cancelButtonClickAction]="buildDeclineActionCallback()">
-</app-dialog-action-buttons>
+<ars-row ars-flex-box class="action-button-container">
+  <ars-col>
+    <button
+      mat-flat-button
+      class="help-button"
+      (click)="openHelp()">
+      <mat-icon>help</mat-icon>
+      {{ 'explanation.label' | translate}}
+    </button>
+  </ars-col>
+  <ars-col>
+    <app-dialog-action-buttons
+      buttonsLabelSection="content"
+      [spacing]="false"
+      [cancelButtonClickAction]="buildDeclineActionCallback()">
+    </app-dialog-action-buttons>
+  </ars-col>
+</ars-row>
diff --git a/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.scss b/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.scss
index d1e8b0aa62fbfd83e3345a00f7d2d77e89e4fed6..58ba3e36a813d14461a197de1f6dabd1560360b9 100644
--- a/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.scss
+++ b/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.scss
@@ -22,7 +22,6 @@ p {
 }
 
 .mat-stroked-button {
-  margin-left: 30px;
   width: 130px;
   height: 40px;
   margin: auto;
@@ -50,4 +49,26 @@ p {
 .validator .mat-stroked-button {
   float: right;
   margin-left: -40%;
-}
\ No newline at end of file
+}
+
+.action-button-container {
+  @media screen and (max-width: 500px) {
+    overflow: auto;
+    display: flex;
+    justify-content: space-between;
+    flex-direction: column !important;
+    flex-wrap: wrap;
+    align-items: flex-end;
+  }
+}
+
+.help-button {
+  background-color: var(--secondary);
+  color: var(--on-secondary);
+  margin-top: 1rem;
+
+  .mat-icon {
+    font-size: 18px;
+    margin-top: 3px;
+  }
+}
diff --git a/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.ts b/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.ts
index ce5f9ed8ee4d5725f8fa2fb353e1133e8310b6fb..3bf7960f886ee2ee65bf49a8117c996888d1287f 100644
--- a/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.ts
+++ b/src/app/components/creator/_dialogs/bonus-token/bonus-token.component.ts
@@ -12,6 +12,7 @@ import { Subject, Subscription } from 'rxjs';
 import { debounceTime } from 'rxjs/operators';
 import { isNumeric } from 'rxjs/internal-compatibility';
 import { EventService } from '../../../../services/util/event.service';
+import { ExplanationDialogComponent } from '../../../shared/_dialogs/explanation-dialog/explanation-dialog.component';
 
 @Component({
   selector: 'app-bonus-token',
@@ -39,7 +40,8 @@ export class BonusTokenComponent implements OnInit, OnDestroy {
 
   ngOnInit() {
     this.bonusTokenService.getTokensByRoomId(this.room.id).subscribe(list => {
-      this.bonusTokens = list.sort((a, b) => (a.token > b.token) ? 1 : -1);
+      list.sort((a, b) => (a.token > b.token) ? 1 : -1);
+      this.bonusTokens = list;
     });
     this.lang = localStorage.getItem('currentLang');
     this.subscription = this.modelChanged
@@ -105,9 +107,9 @@ export class BonusTokenComponent implements OnInit, OnDestroy {
   }
 
   navToCommentByValue() {
-    if(this.valid) {
-      this.bonusTokens.map(b => {
-        if(b.token === this.value) {
+    if (this.valid) {
+      this.bonusTokens.forEach(b => {
+        if (b.token === this.value) {
           this.navToComment(b.commentId);
         }
       });
@@ -133,7 +135,7 @@ export class BonusTokenComponent implements OnInit, OnDestroy {
 
   inputToken() {
     const index = this.validateTokenInput(this.value);
-    if(index) {
+    if (index) {
       this.translationService.get('token-validator.valid').subscribe(msg => {
         this.notificationService.show(msg);
       });
@@ -146,8 +148,15 @@ export class BonusTokenComponent implements OnInit, OnDestroy {
     }
   }
 
+  openHelp() {
+    const ref = this.dialog.open(ExplanationDialogComponent, {
+      autoFocus: false
+    });
+    ref.componentInstance.translateKey = 'explanation.bonus-archive';
+  }
+
   validateTokenInput(input: any) {
-    if(input.length === 8 && isNumeric(input)) {
+    if (input.length === 8 && isNumeric(input)) {
       return this.bonusTokens.map((c, index) => {
         if (c.token === input) {
           return index;
diff --git a/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.ts b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.ts
index 1006684aa26ca7e6f900d42ad02ed35504193fda..3da889c4dae991dd14b5efec59e906681fd03b41 100644
--- a/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.ts
+++ b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.ts
@@ -1,13 +1,9 @@
-import { AfterViewInit, Component, Inject, ViewChild } from '@angular/core';
-import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
+import { AfterViewInit, Component, Input, ViewChild } from '@angular/core';
+import { MatDialogRef } from '@angular/material/dialog';
 import { RoomCreatorPageComponent } from '../../room-creator-page/room-creator-page.component';
-import { NotificationService } from '../../../../services/util/notification.service';
 import { TranslateService } from '@ngx-translate/core';
 import { RoomService } from '../../../../services/http/room.service';
-import { Router } from '@angular/router';
-import { EventService } from '../../../../services/util/event.service';
 import { Room } from '../../../../models/room';
-import { FormControl, Validators } from '@angular/forms';
 import { WriteCommentComponent } from '../../../shared/write-comment/write-comment.component';
 
 @Component({
@@ -18,17 +14,11 @@ import { WriteCommentComponent } from '../../../shared/write-comment/write-comme
 export class RoomDescriptionSettingsComponent implements AfterViewInit {
 
   @ViewChild(WriteCommentComponent) writeComment: WriteCommentComponent;
-  editRoom: Room;
-  roomNameFormControl = new FormControl('', [Validators.required, Validators.minLength(3), Validators.maxLength(30)]);
+  @Input() editRoom: Room;
 
   constructor(public dialogRef: MatDialogRef<RoomCreatorPageComponent>,
-              public dialog: MatDialog,
-              public notificationService: NotificationService,
               public translationService: TranslateService,
-              protected roomService: RoomService,
-              public router: Router,
-              public eventService: EventService,
-              @Inject(MAT_DIALOG_DATA) public data: any) {
+              protected roomService: RoomService) {
   }
 
 
@@ -39,26 +29,17 @@ export class RoomDescriptionSettingsComponent implements AfterViewInit {
   }
 
   buildCloseDialogActionCallback(): () => void {
-    return () => this.closeDialog('abort');
+    return () => this.dialogRef.close('abort');
   }
 
   buildSaveActionCallback(): () => void {
     return () => this.save();
   }
 
-  closeDialog(type: string): void {
-    this.dialogRef.close(type);
-  }
-
   save(): void {
     this.editRoom.description = this.writeComment.commentData.currentData;
     this.roomService.updateRoom(this.editRoom).subscribe(r => this.editRoom = r);
-    if (!this.roomNameFormControl.hasError('required')
-      && !this.roomNameFormControl.hasError('minlength')
-      && !this.roomNameFormControl.hasError('maxlength')) {
-      this.closeDialog('update');
-    }
-    this.closeDialog('update');
+    this.dialogRef.close('update');
   }
 
 }
diff --git a/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.html b/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..25a131cd29f8105283631f510026695efe313aa3
--- /dev/null
+++ b/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.html
@@ -0,0 +1,28 @@
+<h2 class="oldtypo-h2">{{ 'session.edit-session-name' | translate }}</h2>
+<div mat-dialog-content
+     *ngIf="editRoom">
+  <mat-form-field class="input-block">
+    <input (focus)="eventService.makeFocusOnInputTrue()"
+           (blur)="eventService.makeFocusOnInputFalse()"
+           matInput
+           [formControl]="roomNameFormControl"
+           name="room-name"
+           maxlength="20"
+           aria-labelledby="room-name"/>
+    <mat-placeholder class="placeholder">{{ 'session.session-name' | translate }}</mat-placeholder>
+    <mat-hint align="end"><span aria-hidden="true">{{ editRoom.name.length }} / 20</span></mat-hint>
+    <mat-error *ngIf="roomNameFormControl.hasError('required')
+          || roomNameFormControl.hasError('minlength')
+          || roomNameFormControl.hasError('maxlength')">
+      {{ 'room-page.name-length-error' | translate }}
+    </mat-error>
+  </mat-form-field>
+</div>
+<app-dialog-action-buttons
+  [buttonsLabelSection]="'room-page'"
+  [confirmButtonLabel]="'update'"
+  [showDivider]="false"
+  [spacing]="false"
+  [cancelButtonClickAction]="buildCloseDialogActionCallback()"
+  [confirmButtonClickAction]="buildConfirmDialogActionCallback()"
+></app-dialog-action-buttons>
diff --git a/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.scss b/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.spec.ts b/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..694be328f0d5dbbd25ae96eb84d3d04bb6bf9607
--- /dev/null
+++ b/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.spec.ts
@@ -0,0 +1,26 @@
+/*import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RoomNameSettingsComponent } from './room-name-settings.component';
+
+describe('RoomNameSettingsComponent', () => {
+  let component: RoomNameSettingsComponent;
+  let fixture: ComponentFixture<RoomNameSettingsComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ RoomNameSettingsComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(RoomNameSettingsComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
+ */
diff --git a/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.ts b/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..47a8dcf6a7f1fb1e225d10456f17ed2f782494c8
--- /dev/null
+++ b/src/app/components/creator/_dialogs/room-name-settings/room-name-settings.component.ts
@@ -0,0 +1,47 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { Room } from '../../../../models/room';
+import { FormControl, Validators } from '@angular/forms';
+import { EventService } from '../../../../services/util/event.service';
+import { MatDialogRef } from '@angular/material/dialog';
+import { RoomCreatorPageComponent } from '../../room-creator-page/room-creator-page.component';
+import { RoomService } from '../../../../services/http/room.service';
+
+@Component({
+  selector: 'app-room-name-settings',
+  templateUrl: './room-name-settings.component.html',
+  styleUrls: ['./room-name-settings.component.scss']
+})
+export class RoomNameSettingsComponent implements OnInit {
+
+  @Input() editRoom: Room;
+  roomNameFormControl = new FormControl('', [
+    Validators.required, Validators.minLength(3), Validators.maxLength(20)
+  ]);
+
+  constructor(private dialogRef: MatDialogRef<RoomCreatorPageComponent>,
+              public eventService: EventService,
+              private roomService: RoomService) {
+  }
+
+  ngOnInit() {
+    this.roomNameFormControl.setValue(this.editRoom.name);
+  }
+
+  buildCloseDialogActionCallback(): () => void {
+    return () => this.dialogRef.close('abort');
+  }
+
+  buildConfirmDialogActionCallback(): () => void {
+    return () => this.save();
+  }
+
+  private save(): void {
+    if (!this.roomNameFormControl.hasError('required')
+      && !this.roomNameFormControl.hasError('minlength')
+      && !this.roomNameFormControl.hasError('maxlength')) {
+      this.editRoom.name = this.roomNameFormControl.value;
+      this.roomService.updateRoom(this.editRoom).subscribe(r => this.editRoom = r);
+      this.dialogRef.close('update');
+    }
+  }
+}
diff --git a/src/app/components/creator/creator.module.ts b/src/app/components/creator/creator.module.ts
index b876aea134afe3d6bebcb146b45e339e0cf7881c..1f6944e22c53e24a2e2961dcaf97d3875f78ce35 100644
--- a/src/app/components/creator/creator.module.ts
+++ b/src/app/components/creator/creator.module.ts
@@ -25,6 +25,7 @@ import { ArsModule } from '../../../../projects/ars/src/lib/ars.module';
 import { MatRippleModule } from '@angular/material/core';
 import { ProfanitySettingsComponent } from './_dialogs/profanity-settings/profanity-settings.component';
 import { RoomDescriptionSettingsComponent } from './_dialogs/room-description-settings/room-description-settings.component';
+import { RoomNameSettingsComponent } from './_dialogs/room-name-settings/room-name-settings.component';
 
 @NgModule({
   imports: [
@@ -60,7 +61,8 @@ import { RoomDescriptionSettingsComponent } from './_dialogs/room-description-se
     DeleteAnswerComponent,
     QuestionWallComponent,
     ProfanitySettingsComponent,
-    RoomDescriptionSettingsComponent
+    RoomDescriptionSettingsComponent,
+    RoomNameSettingsComponent
   ],
   exports: []
 })
diff --git a/src/app/components/creator/room-creator-page/room-creator-page.component.html b/src/app/components/creator/room-creator-page/room-creator-page.component.html
index 3fdd9b3c900921f0004752f7bbbbe02a727ff03c..ac7a221f4b20d0c6ffa09b8773b275fcb3b6dc03 100644
--- a/src/app/components/creator/room-creator-page/room-creator-page.component.html
+++ b/src/app/components/creator/room-creator-page/room-creator-page.component.html
@@ -12,6 +12,12 @@
                          fxLayout="row">
           <mat-card-title fxLayoutAlign="center">
             <h2 class="oldtypo-h2">&raquo;{{room.name}}&laquo;</h2>
+            <button mat-icon-button
+                    class="inline-icon-button"
+                    (click)="editSessionName()"
+                    aria-labelledby="edit_session_name">
+              <mat-icon matTooltip="{{ 'session.edit-session-name' | translate}}">edit</mat-icon>
+            </button>
           </mat-card-title>
           <mat-card-subtitle fxLayoutAlign="center">
             <span class="room-short-id">
@@ -131,6 +137,7 @@
                  [room]="room"></app-active-user>
 
 <div class="visually-hidden">
+  <div id="edit_session_name">{{'room-page.a11y-room-name' | translate}}</div>
   <div id="cloud_download">{{'room-page.a11y-cloud_download' | translate}}</div>
   <div id="question_answer">{{'room-page.a11y-question_answer' | translate}}</div>
   <div id="gavel">{{'room-page.a11y-gavel' | translate}}</div>
diff --git a/src/app/components/creator/room-creator-page/room-creator-page.component.scss b/src/app/components/creator/room-creator-page/room-creator-page.component.scss
index 215de327e5bad5d6d6e1fda3492f3c373f38fc27..fb0fd0d2d8356fcd2da226fd23f9c1fa278534bf 100644
--- a/src/app/components/creator/room-creator-page/room-creator-page.component.scss
+++ b/src/app/components/creator/room-creator-page/room-creator-page.component.scss
@@ -143,3 +143,8 @@ markdown {
   background: var(--secondary);
   color: var(--on-secondary);
 }
+
+.inline-icon-button {
+  width: max-content;
+  margin: 0.25em 0.25em 0.25em 0.75em;
+}
diff --git a/src/app/components/creator/room-creator-page/room-creator-page.component.ts b/src/app/components/creator/room-creator-page/room-creator-page.component.ts
index 5556ea46d56cfe5aaff54e84c97b7f4a2a0090f8..a4d1c17977747bdf2abb46c22d1d766d371fc339 100644
--- a/src/app/components/creator/room-creator-page/room-creator-page.component.ts
+++ b/src/app/components/creator/room-creator-page/room-creator-page.component.ts
@@ -36,6 +36,7 @@ import { ArsComposeService } from '../../../../../projects/ars/src/lib/services/
 import { UserRole } from '../../../models/user-roles.enum';
 import { Palette } from '../../../../theme/Theme';
 import { ArsObserver } from '../../../../../projects/ars/src/lib/models/util/ars-observer';
+import { RoomNameSettingsComponent } from '../_dialogs/room-name-settings/room-name-settings.component';
 
 @Component({
   selector:'app-room-creator-page',
@@ -216,6 +217,16 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni
     dialogRef.componentInstance.editRoom = this.room;
   }
 
+  editSessionName() {
+    const dialogRef = this.dialog.open(RoomNameSettingsComponent, {
+      width: '900px',
+      maxWidth: 'calc( 100% - 50px )',
+      maxHeight: 'calc( 100vh - 50px )',
+      autoFocus: false
+    });
+    dialogRef.componentInstance.editRoom = this.room;
+  }
+
   editSessionDescription(){
     const dialogRef = this.dialog.open(RoomDescriptionSettingsComponent, {
       width:'900px',
diff --git a/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.html b/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.html
index 69fb893e51e3eb0a9065a1704f87baef0c31ac62..e5802e8ff5e4de19da66e4655f94f1530ddfb0c6 100644
--- a/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.html
+++ b/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.html
@@ -41,7 +41,21 @@
   </div>
 </div>
 
-<app-dialog-action-buttons
-  buttonsLabelSection="introduction"
-  [cancelButtonClickAction]="buildDeclineActionCallback()">
-</app-dialog-action-buttons>
+<ars-row ars-flex-box class="action-button-container">
+  <ars-col>
+    <button
+      mat-flat-button
+      class="help-button"
+      (click)="openHelp()">
+      <mat-icon>help</mat-icon>
+      {{ 'explanation.label' | translate}}
+    </button>
+  </ars-col>
+  <ars-col>
+    <app-dialog-action-buttons
+      buttonsLabelSection="introduction"
+      [spacing]="false"
+      [cancelButtonClickAction]="buildDeclineActionCallback()">
+    </app-dialog-action-buttons>
+  </ars-col>
+</ars-row>
diff --git a/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.scss b/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.scss
index fe3b4e59a6241b7ce247a169ea8a0e39a129ba0b..3517dacc41918933513224c005abfb872d0ba2b7 100644
--- a/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.scss
+++ b/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.scss
@@ -25,3 +25,25 @@ form {
 ::ng-deep .mat-form-field .mat-form-field-infix {
   max-width: 400px;
 }
+
+.action-button-container {
+  @media screen and (max-width: 500px) {
+    overflow: auto;
+    display: flex;
+    justify-content: space-between;
+    flex-direction: column !important;
+    flex-wrap: wrap;
+    align-items: flex-end;
+  }
+}
+
+.help-button {
+  background-color: var(--secondary);
+  color: var(--on-secondary);
+  margin-top: 1rem;
+
+  .mat-icon {
+    font-size: 18px;
+    margin-top: 3px;
+  }
+}
diff --git a/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.ts b/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.ts
index 47b7c1ef7b6f34f5f619cbf798ecc037d184d10c..90f6484704241e08466268a07cf1332436b3227e 100644
--- a/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.ts
+++ b/src/app/components/participant/_dialogs/user-bonus-token/user-bonus-token.component.ts
@@ -3,11 +3,12 @@ import { BonusTokenService } from '../../../../services/http/bonus-token.service
 import { RoomService } from '../../../../services/http/room.service';
 import { BonusToken } from '../../../../models/bonus-token';
 import { BonusTokenRoomMixin } from '../../../../models/bonus-token-room-mixin';
-import { MatDialogRef } from '@angular/material/dialog';
+import { MatDialog, MatDialogRef } from '@angular/material/dialog';
 import { MatOptionSelectionChange } from '@angular/material/core';
 import { Router } from '@angular/router';
 import { TranslateService } from '@ngx-translate/core';
 import { NotificationService } from '../../../../services/util/notification.service';
+import { ExplanationDialogComponent } from '../../../shared/_dialogs/explanation-dialog/explanation-dialog.component';
 
 export class MinRoom {
   name: string;
@@ -37,18 +38,18 @@ export class UserBonusTokenComponent implements OnInit {
     private dialogRef: MatDialogRef<UserBonusTokenComponent>,
     protected router: Router,
     private translationService: TranslateService,
+    private dialog: MatDialog,
     private notificationService: NotificationService
   ) {
   }
 
   ngOnInit() {
-    this.bonusTokenService.getTokensByUserId(this.userId).subscribe( list => {
-      this.bonusTokens = list.sort((a, b) => {
-        return (a.token > b.token) ? 1 : -1;
-      });
+    this.bonusTokenService.getTokensByUserId(this.userId).subscribe(list => {
+      list.sort((a, b) => (a.token > b.token) ? 1 : -1);
+      this.bonusTokens = list;
       for (const bt of this.bonusTokens) {
         this.roomService.getRoom(bt.roomId).subscribe(room => {
-          const btm = <BonusTokenRoomMixin> bt;
+          const btm = bt as BonusTokenRoomMixin;
           btm.roomShortId = room.shortId;
           btm.roomName = room.name;
           this.bonusTokensMixin.push(btm);
@@ -76,6 +77,13 @@ export class UserBonusTokenComponent implements OnInit {
     return tokens;
   }
 
+  openHelp() {
+    const ref = this.dialog.open(ExplanationDialogComponent, {
+      autoFocus: false
+    });
+    ref.componentInstance.translateKey = 'explanation.user-bonus';
+  }
+
   setCurrentRoom(event: MatOptionSelectionChange, room: MinRoom) {
     if (event.source.selected) {
       this.currentRoom = room;
diff --git a/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts
index df77ec4f0b719af90b159d2a4eef17c2e9dfcc40..3f18d73fd46f226e8395da1ab794fe147a131d04 100644
--- a/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts
+++ b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts
@@ -4,7 +4,6 @@ import { ViewCommentDataComponent } from '../../view-comment-data/view-comment-d
 import { NotificationService } from '../../../../services/util/notification.service';
 import { LanguageService } from '../../../../services/util/language.service';
 import { TranslateService } from '@ngx-translate/core';
-import { WriteCommentComponent } from '../../write-comment/write-comment.component';
 import { ExplanationDialogComponent } from '../explanation-dialog/explanation-dialog.component';
 import { DeepLService, FormalityType, TargetLang } from '../../../../services/http/deep-l.service';
 import { Observable } from 'rxjs';
@@ -95,7 +94,7 @@ export class DeepLDialogComponent implements OnInit, AfterViewInit {
       text: this.data.improvedText,
       view: this.improved
     };
-    this.radioButtonValue = this.normalValue;
+    this.radioButtonValue = this.improvedValue;
   }
 
   ngAfterViewInit() {
diff --git a/src/app/components/shared/_dialogs/remove-from-history/remove-from-history.component.html b/src/app/components/shared/_dialogs/remove-from-history/remove-from-history.component.html
index dea1a2f44dd7b9f8060f5f3905d25053880c1b77..ffd442b681805813ead328969d30040a772c0193 100644
--- a/src/app/components/shared/_dialogs/remove-from-history/remove-from-history.component.html
+++ b/src/app/components/shared/_dialogs/remove-from-history/remove-from-history.component.html
@@ -1,7 +1,9 @@
 <div mat-dialog-content>
-  <h2 class="oldtypo-h2" tabindex="0">{{ 'header.sure' | translate }}</h2>
-  <p class="oldtypo-p" tabindex="0">{{ (role < 3 ? 'room-list.really-remove' : 'room-list.really-delete') | translate }}
-    <strong>{{roomName}}</strong>{{ (role < 3 ? 'room-list.really-remove-2' : 'room-list.really-delete-2') | translate }}</p>
+  <h2 class="oldtypo-h2"
+      tabindex="0">{{ 'header.sure' | translate }}</h2>
+  <p class="oldtypo-p"
+     tabindex="0">{{ (role < 3 ? 'room-list.really-remove' : 'room-list.really-delete') | translate }}<strong>{{roomName}}</strong>{{ (role < 3 ? 'room-list.really-remove-2' : 'room-list.really-delete-2') | translate }}
+  </p>
   <app-dialog-action-buttons
     buttonsLabelSection="delete-account"
     confirmButtonLabel="delete"
diff --git a/src/app/components/shared/_dialogs/topic-cloud-administration/TopicCloudAdminData.ts b/src/app/components/shared/_dialogs/topic-cloud-administration/TopicCloudAdminData.ts
index 42b959a8fb6bccabd7877bcaa4a58e774069cccb..e0cc85d7b401aa39ada5ae2dee8264bcbab9d69c 100644
--- a/src/app/components/shared/_dialogs/topic-cloud-administration/TopicCloudAdminData.ts
+++ b/src/app/components/shared/_dialogs/topic-cloud-administration/TopicCloudAdminData.ts
@@ -1,5 +1,26 @@
 import { ProfanityFilter } from '../../../../models/room';
 
+export interface TopicCloudAdminDataScoring {
+  score: number;
+}
+
+export enum TopicCloudAdminDataScoringKey {
+  countComments = 'countComments',
+  countUsers = 'countUsers',
+  countSelectedByQuestioner = 'countSelectedByQuestioner',
+  countKeywordByModerator = 'countKeywordByModerator',
+  countKeywordByCreator = 'countKeywordByCreator',
+  countCommentsAnswered = 'countCommentsAnswered',
+  summedUpvotes = 'summedUpvotes',
+  summedDownvotes = 'summedDownvotes',
+  summedVotes = 'summedVotes',
+  cappedSummedVotes = 'cappedSummedVotes'
+}
+
+export type TopicCloudAdminDataScoringObject = {
+  [key in TopicCloudAdminDataScoringKey]: TopicCloudAdminDataScoring;
+};
+
 export interface TopicCloudAdminData {
   blacklist: string[];
   wantedLabels: {
@@ -15,8 +36,65 @@ export interface TopicCloudAdminData {
   minUpvotes: number;
   startDate: string;
   endDate: string;
+  scorings: TopicCloudAdminDataScoringObject;
 }
 
+export const ensureDefaultScorings = (data: TopicCloudAdminData) => {
+  if (!data.scorings) {
+    data.scorings = {} as TopicCloudAdminDataScoringObject;
+  }
+  for (const option of Object.keys(TopicCloudAdminDataScoringKey)) {
+    if (data.scorings[option]) {
+      continue;
+    }
+    switch (option) {
+      case TopicCloudAdminDataScoringKey.cappedSummedVotes:
+        data.scorings[option] = {
+          score: 0.1
+        };
+        break;
+      case TopicCloudAdminDataScoringKey.countUsers:
+        data.scorings[option] = {
+          score: 0.5
+        };
+        break;
+      case TopicCloudAdminDataScoringKey.countCommentsAnswered:
+      case TopicCloudAdminDataScoringKey.countKeywordByCreator:
+      case TopicCloudAdminDataScoringKey.countKeywordByModerator:
+      case TopicCloudAdminDataScoringKey.countSelectedByQuestioner:
+        data.scorings[option] = {
+          score: 1
+        };
+        break;
+      default:
+        data.scorings[option] = {
+          score: 0
+        };
+        break;
+    }
+  }
+};
+
+export type TopicCloudAdminDataScoringPreset = {
+  [key in TopicCloudAdminDataScoringKey]: {
+    min: number;
+    max: number;
+  };
+};
+
+export const keywordsScoringMinMax: TopicCloudAdminDataScoringPreset = {
+  countComments: { min: -5, max: 5 },
+  countUsers: { min: -5, max: 5 },
+  countSelectedByQuestioner: { min: -5, max: 5 },
+  countKeywordByModerator: { min: -5, max: 5 },
+  countKeywordByCreator: { min: -5, max: 5 },
+  countCommentsAnswered: { min: -5, max: 5 },
+  summedUpvotes: { min: -5, max: 5 },
+  summedDownvotes: { min: -5, max: 5 },
+  summedVotes: { min: -5, max: 5 },
+  cappedSummedVotes: { min: -5, max: 5 }
+};
+
 export enum KeywordOrFulltext {
   keyword,
   fulltext,
@@ -40,33 +118,33 @@ export class Labels {
 }
 
 const deLabels: Label[] = [
-  {tag: 'sb', label: 'Subjekt', enabledByDefault: true},
-  {tag: 'op', label: 'Präpositionalobjekt', enabledByDefault: true},
-  {tag: 'og', label: 'Genitivobjekt', enabledByDefault: true},
-  {tag: 'da', label: 'Dativobjekt', enabledByDefault: true},
-  {tag: 'oa', label: 'Akkusativobjekt', enabledByDefault: true},
-  {tag: 'ROOT', label: 'Satzkernelement', enabledByDefault: true},
-  {tag: 'pd', label: 'Prädikat', enabledByDefault: false},
-  {tag: 'ag', label: 'Genitivattribut', enabledByDefault: false},
-  {tag: 'app', label: 'Apposition', enabledByDefault: false},
-  {tag: 'nk', label: 'Nomen Kernelement', enabledByDefault: false},
-  {tag: 'mo', label: 'Modifikator', enabledByDefault: false},
-  {tag: 'cj', label: 'Konjunktor', enabledByDefault: false},
-  {tag: 'par', label: 'Klammerzusatz', enabledByDefault: false}
+  { tag: 'sb', label: 'Subjekt', enabledByDefault: true },
+  { tag: 'op', label: 'Präpositionalobjekt', enabledByDefault: true },
+  { tag: 'og', label: 'Genitivobjekt', enabledByDefault: true },
+  { tag: 'da', label: 'Dativobjekt', enabledByDefault: true },
+  { tag: 'oa', label: 'Akkusativobjekt', enabledByDefault: true },
+  { tag: 'ROOT', label: 'Satzkernelement', enabledByDefault: true },
+  { tag: 'pd', label: 'Prädikat', enabledByDefault: false },
+  { tag: 'ag', label: 'Genitivattribut', enabledByDefault: false },
+  { tag: 'app', label: 'Apposition', enabledByDefault: false },
+  { tag: 'nk', label: 'Nomen Kernelement', enabledByDefault: false },
+  { tag: 'mo', label: 'Modifikator', enabledByDefault: false },
+  { tag: 'cj', label: 'Konjunktor', enabledByDefault: false },
+  { tag: 'par', label: 'Klammerzusatz', enabledByDefault: false }
 ];
 
 const enLabels: Label[] = [
-  {tag: 'nsubj', label: 'Nominal subject', enabledByDefault: true},
-  {tag: 'pobj', label: 'Object of preposition', enabledByDefault: true},
-  {tag: 'dobj', label: 'Direct object', enabledByDefault: true},
-  {tag: 'compound', label: 'Compound', enabledByDefault: true},
-  {tag: 'nsubjpass', label: 'Passive nominal subject', enabledByDefault: true},
-  {tag: 'ROOT', label: 'Sentence kernel element', enabledByDefault: true},
-  {tag: 'nummod', label: 'Numeric modifier', enabledByDefault: false},
-  {tag: 'amod', label: 'Adjectival modifier', enabledByDefault: false},
-  {tag: 'npadvmod', label: 'Noun phrase as adverbial modifier', enabledByDefault: false},
-  {tag: 'conj', label: 'Conjunct', enabledByDefault: false},
-  {tag: 'intj', label: 'Interjection', enabledByDefault: false}
+  { tag: 'nsubj', label: 'Nominal subject', enabledByDefault: true },
+  { tag: 'pobj', label: 'Object of preposition', enabledByDefault: true },
+  { tag: 'dobj', label: 'Direct object', enabledByDefault: true },
+  { tag: 'compound', label: 'Compound', enabledByDefault: true },
+  { tag: 'nsubjpass', label: 'Passive nominal subject', enabledByDefault: true },
+  { tag: 'ROOT', label: 'Sentence kernel element', enabledByDefault: true },
+  { tag: 'nummod', label: 'Numeric modifier', enabledByDefault: false },
+  { tag: 'amod', label: 'Adjectival modifier', enabledByDefault: false },
+  { tag: 'npadvmod', label: 'Noun phrase as adverbial modifier', enabledByDefault: false },
+  { tag: 'conj', label: 'Conjunct', enabledByDefault: false },
+  { tag: 'intj', label: 'Interjection', enabledByDefault: false }
 ];
 
 export const spacyLabels = new Labels(deLabels, enLabels);
diff --git a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html
index 222f911ca6e74c857377ccd66b5be3d498e777a8..bc7cb8d6563d74fe1872b5a72f7be745b16748ce 100644
--- a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html
+++ b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.html
@@ -28,11 +28,43 @@
           </mat-radio-group>
         </mat-card>
 
-        <mat-card style="background: none; margin-bottom: 10px;">
-          <mat-slide-toggle [(ngModel)]="considerVotes">
-            {{'topic-cloud-dialog.consider-votes' | translate}}
-          </mat-slide-toggle>
-        </mat-card>
+        <mat-accordion>
+          <mat-expansion-panel class="color-background margin-top margin-bottom keyword-scoring">
+            <mat-expansion-panel-header class="color-background">
+              <mat-panel-title>
+                {{'topic-cloud-dialog.keyword-scoring-header' | translate}}
+                <mat-icon class="help-explanation"
+                          matTooltip="{{'topic-cloud-dialog.keyword-scoring-header-info' | translate}}">help
+                </mat-icon>
+              </mat-panel-title>
+            </mat-expansion-panel-header>
+            <ng-container *ngFor="let option of scoringOptions">
+              <ars-row fxLayout="row">
+                <label
+                  id="keyword-scoring-{{option}}">{{'topic-cloud-dialog.keyword-scoring-' + option | translate}}</label>
+                <mat-icon class="help-explanation"
+                          matTooltip="{{'topic-cloud-dialog.keyword-scoring-' + option + '-info' | translate}}">help
+                </mat-icon>
+                <ars-fill></ars-fill>
+                <label>{{scorings[option].score}}</label>
+              </ars-row>
+              <mat-slider
+                [min]="scoringMinMax[option].min"
+                [max]="scoringMinMax[option].max"
+                [(ngModel)]="scorings[option].score"
+                [step]="0.1"
+                [thumbLabel]="true"
+                aria-labelledby="keyword-scoring-{{option}}">
+              </mat-slider>
+            </ng-container>
+            <button mat-button class="themeRequirementInput reset"
+                    [disabled]="isDefaultScoring()"
+                    (click)="setDefaultScoring()">
+              {{'topic-cloud-dialog.topic-requirement-reset' | translate}}
+            </button>
+          </mat-expansion-panel>
+        </mat-accordion>
+
         <div *ngIf="isCreatorOrMod">
           <mat-card style="background: none; margin-bottom: 10px;">
             <mat-slide-toggle (change)="showMessage('words-will-be-overwritten', $event.checked)"
@@ -339,7 +371,7 @@
         <p [ngClass]="{'animation-blink': searchMode}"
            matTooltip="{{'topic-cloud-dialog.keyword-counter' | translate}}">
           {{searchMode ? filteredKeywords.length :
-            selectedTabIndex === 0 ? keywords.size : blacklistKeywords.length}}</p>
+          selectedTabIndex === 0 ? keywords.size : blacklistKeywords.length}}</p>
       </div>
       <div class="margin-left vertical-center">
         <button [ngClass]="{'animation-blink': sortMode!=='alphabetic'}" mat-icon-button [matMenuTriggerFor]="sortMenu">
diff --git a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss
index d2d7016945f138f7beb5eee32166f0a01caa6b09..1887a126062e4152b1d0adee851b47de72ad894b 100644
--- a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss
+++ b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.scss
@@ -186,3 +186,19 @@ mat-dialog-content {
     color: var(--on-secondary);
   }
 }
+
+.keyword-scoring {
+  width: 100%;
+
+  mat-slider {
+    width: 100%;
+  }
+}
+
+.help-explanation {
+  width: 1.2em;
+  height: 1.2em;
+  line-height: 1.2em;
+  font-size: 1.2em;
+  margin: auto 0 auto 0.25em;
+}
diff --git a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.ts b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.ts
index a21c7bce9b54ab2ed9e3a07d073e5c911a8fb2dd..2822ca2f975633815ee0233780624da3b19de92a 100644
--- a/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.ts
+++ b/src/app/components/shared/_dialogs/topic-cloud-administration/topic-cloud-administration.component.ts
@@ -7,7 +7,13 @@ import { TranslateService } from '@ngx-translate/core';
 import { LanguageService } from '../../../../services/util/language.service';
 import { TopicCloudAdminService } from '../../../../services/util/topic-cloud-admin.service';
 import { ProfanityFilterService } from '../../../../services/util/profanity-filter.service';
-import { TopicCloudAdminData, Labels, spacyLabels, KeywordOrFulltext } from './TopicCloudAdminData';
+import {
+  TopicCloudAdminData,
+  Labels,
+  spacyLabels,
+  KeywordOrFulltext,
+  TopicCloudAdminDataScoringObject, TopicCloudAdminDataScoringKey, keywordsScoringMinMax, ensureDefaultScorings
+} from './TopicCloudAdminData';
 import { User } from '../../../../models/user';
 import { Comment } from '../../../../models/comment';
 import { CommentService } from '../../../../services/http/comment.service';
@@ -60,8 +66,12 @@ export class TopicCloudAdministrationComponent implements OnInit, OnDestroy {
   startDate: string;
   endDate: string;
   selectedTabIndex = 0;
+  scorings: TopicCloudAdminDataScoringObject;
+  scoringOptions = Object.keys(TopicCloudAdminDataScoringKey);
+  scoringMinMax = keywordsScoringMinMax;
 
   keywords: Map<string, Keyword> = new Map<string, Keyword>();
+  defaultScorings: TopicCloudAdminDataScoringObject;
   private topicCloudAdminData: TopicCloudAdminData;
   private profanityFilter: boolean;
   private censorPartialWordsCheck: boolean;
@@ -84,6 +94,9 @@ export class TopicCloudAdministrationComponent implements OnInit, OnDestroy {
     this.langService.langEmitter.subscribe(lang => {
       this.translateService.use(lang);
     });
+    const emptyData = {} as TopicCloudAdminData;
+    ensureDefaultScorings(emptyData);
+    this.defaultScorings = emptyData.scorings;
   }
 
   ngOnInit(): void {
@@ -194,14 +207,14 @@ export class TopicCloudAdministrationComponent implements OnInit, OnDestroy {
   /**
    * Returns a lambda which closes the dialog on call.
    */
-   buildCloseDialogActionCallback(): () => void {
+  buildCloseDialogActionCallback(): () => void {
     return () => this.ngOnDestroy();
   }
 
   /**
    * Returns a lambda which executes the dialog dedicated action on call.
    */
-   buildSaveActionCallback(): () => void {
+  buildSaveActionCallback(): () => void {
     return () => this.save();
   }
 
@@ -313,7 +326,8 @@ export class TopicCloudAdministrationComponent implements OnInit, OnDestroy {
       minQuestions: minQuestionsVerified,
       minUpvotes: minUpvotesVerified,
       startDate: this.startDate.length ? this.startDate : null,
-      endDate: this.endDate.length ? this.endDate : null
+      endDate: this.endDate.length ? this.endDate : null,
+      scorings: this.scorings
     };
     this.topicCloudAdminService.setAdminData(this.topicCloudAdminData, true, this.data.user.role);
   }
@@ -340,11 +354,13 @@ export class TopicCloudAdministrationComponent implements OnInit, OnDestroy {
       this.minUpvotes = String(this.topicCloudAdminData.minUpvotes);
       this.startDate = this.topicCloudAdminData.startDate || '';
       this.endDate = this.topicCloudAdminData.endDate || '';
+      this.scorings = this.topicCloudAdminData.scorings;
     }
   }
 
   getKeywordWithoutProfanity(keyword: string, lang: string): string {
-    return this.profanityFilterService.filterProfanityWords(keyword, this.censorPartialWordsCheck, this.censorLanguageSpecificCheck, lang);
+    return this.profanityFilterService.filterProfanityWords(keyword, this.censorPartialWordsCheck,
+      this.censorLanguageSpecificCheck, lang)[0];
   }
 
   sortQuestions(sortMode?: string) {
@@ -480,7 +496,7 @@ export class TopicCloudAdministrationComponent implements OnInit, OnDestroy {
       if (this.selectedTabIndex === 0) {
         const entries = [...this.keywords.entries()];
         this.filteredKeywords = entries.filter(([_, keyword]) =>
-        keyword.keyword.toLowerCase().includes(this.searchedKeyword.toLowerCase())
+          keyword.keyword.toLowerCase().includes(this.searchedKeyword.toLowerCase())
         ).map(e => e[1]);
       } else {
         this.filteredKeywords = this.blacklistKeywords.filter(keyword =>
@@ -590,11 +606,31 @@ export class TopicCloudAdministrationComponent implements OnInit, OnDestroy {
   getFilteredProfanity(): string {
     if (this.testProfanityWord) {
       // eslint-disable-next-line max-len
-      return this.profanityFilterService.filterProfanityWords(this.testProfanityWord, this.censorPartialWordsCheck, this.censorLanguageSpecificCheck, this.testProfanityLanguage);
+      return this.profanityFilterService.filterProfanityWords(this.testProfanityWord, this.censorPartialWordsCheck,
+        this.censorLanguageSpecificCheck, this.testProfanityLanguage)[0];
     } else {
       return '';
     }
   }
+
+  isDefaultScoring(): boolean {
+    for (const key of Object.keys(this.defaultScorings)) {
+      const subObject = this.defaultScorings[key];
+      const refSubObject = this.scorings[key];
+      for (const subKey in subObject) {
+        if (subObject[subKey] !== refSubObject[subKey]) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  setDefaultScoring() {
+    for (const key of Object.keys(this.defaultScorings)) {
+      this.scorings[key] = { ...this.defaultScorings[key] };
+    }
+  }
 }
 
 interface Keyword {
diff --git a/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts
index d1422670f2dc924aca61425ba711bec69d1ce5f6..5c7d2c91abcaf2781d770f9773724a9f1f4da004 100644
--- a/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts
+++ b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts
@@ -19,6 +19,7 @@ import { Room } from '../../../../models/room';
 import { ThemeService } from '../../../../../theme/theme.service';
 import { Theme } from '../../../../../theme/Theme';
 import { ExplanationDialogComponent } from '../explanation-dialog/explanation-dialog.component';
+import { ModeratorService } from '../../../../services/http/moderator.service';
 import { UserRole } from '../../../../models/user-roles.enum';
 import { RoomDataService } from '../../../../services/util/room-data.service';
 import { Subscription } from 'rxjs';
@@ -57,6 +58,7 @@ export class TopicCloudFilterComponent implements OnInit, OnDestroy {
   private _room: Room;
   private currentTheme: Theme;
   private _subscriptionCommentUpdates: Subscription;
+  private _currentModerators: string[];
 
   constructor(public dialogRef: MatDialogRef<RoomCreatorPageComponent>,
               public dialog: MatDialog,
@@ -68,6 +70,7 @@ export class TopicCloudFilterComponent implements OnInit, OnDestroy {
               @Inject(MAT_DIALOG_DATA) public data: any,
               public eventService: EventService,
               private topicCloudAdminService: TopicCloudAdminService,
+              private moderatorService: ModeratorService,
               private themeService: ThemeService,
               private roomDataService: RoomDataService) {
     langService.langEmitter.subscribe(lang => translationService.use(lang));
@@ -86,7 +89,10 @@ export class TopicCloudFilterComponent implements OnInit, OnDestroy {
       this._room = data.room;
       this.roomDataService.getRoomData(data.room.id).subscribe(roomData => {
         this.comments = roomData;
-        this.commentsLoadedCallback(true);
+        this.moderatorService.get(data.room.id).subscribe(moderators => {
+          this._currentModerators = moderators.map(moderator => moderator.accountId);
+          this.commentsLoadedCallback(true);
+        });
       });
       this._subscriptionCommentUpdates = this.roomDataService.receiveUpdates([{ finished: true }])
         .subscribe(_ => this.commentsLoadedCallback());
@@ -101,6 +107,9 @@ export class TopicCloudFilterComponent implements OnInit, OnDestroy {
   }
 
   commentsLoadedCallback(isNew = false) {
+    if (!this._currentModerators) {
+      return;
+    }
     this.allComments = this.getCommentCounts(this.comments);
     this.filteredComments = this.getCommentCounts(this.comments.filter(comment => this.tmpFilter.checkComment(comment)));
     if (isNew) {
@@ -136,7 +145,8 @@ export class TopicCloudFilterComponent implements OnInit, OnDestroy {
   }
 
   getCommentCounts(comments: Comment[]): CommentsCount {
-    const [data, users] = TagCloudDataService.buildDataFromComments(this._adminData, comments);
+    const [data, users] = TagCloudDataService.buildDataFromComments(this._room.ownerId, this._currentModerators,
+      this._adminData, this.roomDataService, comments);
     const counts = new CommentsCount();
     counts.comments = comments.length;
     counts.users = users.size;
diff --git a/src/app/components/shared/_dialogs/worker-config-dialog/worker-config-dialog.component.html b/src/app/components/shared/_dialogs/worker-config-dialog/worker-config-dialog.component.html
index 42f530582fa4dd4c9649bbf6b5f12cc20d2c5670..153a49439d1c504c507f7e1485c8217e53a00097 100644
--- a/src/app/components/shared/_dialogs/worker-config-dialog/worker-config-dialog.component.html
+++ b/src/app/components/shared/_dialogs/worker-config-dialog/worker-config-dialog.component.html
@@ -1,14 +1,15 @@
 <h3>{{'worker-config.heading' | translate}}</h3>
 <mat-dialog-content>
   <label id="worker-config-group-label">{{'worker-config.label' | translate}}</label>
-  <br>
-  <mat-radio-group aria-labelledby="worker-config-group-label" [(ngModel)]="selection">
+  <br><br>
+  <mat-radio-group aria-labelledby="worker-config-group-label"
+                   [(ngModel)]="selection">
     <mat-radio-button [value]="'normal'">
-      <small>{{'worker-config.normal' | translate}}</small>
+      {{'worker-config.normal' | translate}}
     </mat-radio-button>
     <br>
     <mat-radio-button [value]="'only-failed'">
-      <small>{{'worker-config.only-failed' | translate}}</small>
+      {{'worker-config.only-failed' | translate}}
     </mat-radio-button>
   </mat-radio-group>
 </mat-dialog-content>
diff --git a/src/app/components/shared/_dialogs/worker-config-dialog/worker-config-dialog.component.scss b/src/app/components/shared/_dialogs/worker-config-dialog/worker-config-dialog.component.scss
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..560a5cbb4a8e38ad80bde1ad98f993e174478931 100644
--- a/src/app/components/shared/_dialogs/worker-config-dialog/worker-config-dialog.component.scss
+++ b/src/app/components/shared/_dialogs/worker-config-dialog/worker-config-dialog.component.scss
@@ -0,0 +1,3 @@
+mat-radio-button {
+  margin: 5px;
+}
diff --git a/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.ts b/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.ts
index 438c5192aaaa1846215b6f97d4861d048a3df251..59cecafd13a75b0fb0121a0ac6009c6f9a03a03f 100644
--- a/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.ts
+++ b/src/app/components/shared/dialog/topic-dialog-comment/topic-dialog-comment.component.ts
@@ -12,7 +12,7 @@ export class TopicDialogCommentComponent implements OnInit {
 
   @Input() question: string;
   @Input() language: Language;
-  @Input() keyword: string ;
+  @Input() keyword: string;
   @Input() maxShowedCharachters: number;
   @Input() profanityFilter: boolean;
   @Input() languageSpecific;
@@ -28,21 +28,22 @@ export class TopicDialogCommentComponent implements OnInit {
   public partsShort: string[];
   public partsWithoutProfanityShort: string[];
 
-  constructor(private profanityFilterService: ProfanityFilterService) {}
+  constructor(private profanityFilterService: ProfanityFilterService) {
+  }
 
   get partsOfQuestion() {
     return this.profanityFilter ? this.partsWithoutProfanity : this.parts;
   }
 
-  get partsOfShortQuestion(){
+  get partsOfShortQuestion() {
     return this.profanityFilter ? this.partsWithoutProfanityShort : this.partsShort;
   }
 
-  splitShortQuestion(question: string){
+  splitShortQuestion(question: string) {
     return question.slice(0, this.maxShowedCharachters).split(this.keyword);
   }
 
-  splitQuestion(question: string){
+  splitQuestion(question: string) {
     return question.split(this.keyword);
   }
 
@@ -51,8 +52,8 @@ export class TopicDialogCommentComponent implements OnInit {
       return;
     }
     this.question = ViewCommentDataComponent.getTextFromData(this.question);
-    this.questionWithoutProfanity = this.profanityFilterService.
-                                    filterProfanityWords(this.question, this.partialWords, this.languageSpecific, this.language);
+    this.questionWithoutProfanity = this.profanityFilterService.filterProfanityWords(this.question,
+      this.partialWords, this.languageSpecific, this.language)[0];
     this.partsWithoutProfanity = this.splitQuestion(this.questionWithoutProfanity);
     this.parts = this.splitQuestion(this.question);
     this.partsWithoutProfanityShort = this.splitShortQuestion(this.questionWithoutProfanity);
diff --git a/src/app/components/shared/header/header.component.html b/src/app/components/shared/header/header.component.html
index 00ccef2516eabc63a07a9ce96927bf3c71852aae..f864a02026a522293c8260b57fd02762e195ebad 100644
--- a/src/app/components/shared/header/header.component.html
+++ b/src/app/components/shared/header/header.component.html
@@ -209,7 +209,7 @@
                       tabindex="0"
                       *ngIf="!router.url.endsWith('moderator/comments')"
                       routerLink="quiz">
-                <mat-icon>school
+                <mat-icon>timer
                 </mat-icon>
                 <span>{{'header.quiz-now' | translate}}</span>
               </button>
@@ -267,7 +267,7 @@
                   tabindex="0"
                   *ngIf="user && user.role > 0 && router.url.endsWith('/tagcloud')"
                   (click)="startWorkerDialog()">
-            <mat-icon>update
+            <mat-icon>cloud
             </mat-icon>
             <span>{{'header.update-spacy-keywords' | translate}}</span>
           </button>
diff --git a/src/app/components/shared/tag-cloud/tag-cloud.component.ts b/src/app/components/shared/tag-cloud/tag-cloud.component.ts
index 54c9b00f57a357f45ba18bc33fefbcf0ba05f3a9..73765a66b5e184e8b6def8046e1e7e28e543b9a0 100644
--- a/src/app/components/shared/tag-cloud/tag-cloud.component.ts
+++ b/src/app/components/shared/tag-cloud/tag-cloud.component.ts
@@ -23,7 +23,7 @@ import { ThemeService } from '../../../../theme/theme.service';
 import { TopicCloudAdministrationComponent } from '../_dialogs/topic-cloud-administration/topic-cloud-administration.component';
 import { WsCommentService } from '../../../services/websockets/ws-comment.service';
 import { CreateCommentWrapper } from '../../../utils/create-comment-wrapper';
-import { TopicCloudAdminService } from '../../../services/util/topic-cloud-admin.service';
+import { regexMaskKeyword, TopicCloudAdminService } from '../../../services/util/topic-cloud-admin.service';
 import { TagCloudPopUpComponent } from './tag-cloud-pop-up/tag-cloud-pop-up.component';
 import { TagCloudDataService, TagCloudDataTagEntry } from '../../../services/util/tag-cloud-data.service';
 import { WsRoomService } from '../../../services/websockets/ws-room.service';
@@ -32,6 +32,7 @@ import { SmartDebounce } from '../../../utils/smart-debounce';
 import { Theme } from '../../../../theme/Theme';
 import { MatDrawer } from '@angular/material/sidenav';
 import { DeviceInfoService } from '../../../services/util/device-info.service';
+import { SyncFence } from '../../../utils/SyncFence';
 
 class CustomPosition implements Position {
   left: number;
@@ -70,6 +71,9 @@ const transformationRotationKiller = /rotate\(([^)]*)\)/;
 
 const maskedCharsRegex = /[“”‘’„‚«»‹›『』﹃﹄「」﹁﹂",《》〈〉'`#&]|(\s(lu|li’u)(?=\s))|(^lu\s)|(\sli’u$)/gm;
 
+const CONDITION_ROOM = 0;
+const CONDITION_BUILT = 1;
+
 @Component({
   selector: 'app-tag-cloud',
   templateUrl: './tag-cloud.component.html',
@@ -113,6 +117,7 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit {
   private _calcFont: string = null;
   private readonly _smartDebounce = new SmartDebounce(50, 1_000);
   private _currentTheme: Theme;
+  private _syncFenceBuildCloud: SyncFence;
 
   constructor(private commentService: CommentService,
               private langService: LanguageService,
@@ -138,6 +143,8 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit {
     this.question = localStorage.getItem('tag-cloud-question');
     this._calcCanvas = document.createElement('canvas');
     this._calcRenderContext = this._calcCanvas.getContext('2d');
+    this._syncFenceBuildCloud = new SyncFence(2,
+      () => this.dataManager.bindToRoom(this.roomId, this.room.ownerId, this.userRole));
   }
 
   private static getCurrentCloudParameters(): CloudParameters {
@@ -215,6 +222,7 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit {
             this.roomService.addToHistory(this.room.id);
             this.authenticationService.setAccess(this.shortId, UserRole.PARTICIPANT);
           }
+          this._syncFenceBuildCloud.resolveCondition(CONDITION_ROOM);
         });
       });
     });
@@ -231,7 +239,7 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit {
 
   ngAfterContentInit() {
     this._calcFont = window.getComputedStyle(document.getElementById('tagCloudComponent')).fontFamily;
-    setTimeout(() => this.dataManager.bindToRoom(this.roomId, this.userRole));
+    setTimeout(() => this._syncFenceBuildCloud.resolveCondition(CONDITION_BUILT));
     this.dataManager.updateDemoData(this.translateService);
     this.setCloudParameters(TagCloudComponent.getCurrentCloudParameters(), false);
   }
@@ -310,7 +318,8 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit {
           if (rotation === null || this._currentSettings.randomAngles) {
             rotation = Math.floor(Math.random() * 30 - 15);
           }
-          const filteredTag = tag.replace(maskedCharsRegex, '').trim();
+          const filteredTag = tag.replace(maskedCharsRegex, '')
+            .replace(regexMaskKeyword, '').replace(/ +/, ' ').trim();
           newElements.push(new TagComment(filteredTag, tag, rotation, tagData.weight, tagData, newElements.length));
         }
       }
@@ -384,6 +393,7 @@ export class TagCloudComponent implements OnInit, OnDestroy, AfterContentInit {
       admin.minUpvotes = data.admin.minUpvotes;
       admin.startDate = data.admin.startDate;
       admin.endDate = data.admin.endDate;
+      admin.scorings = data.admin.scorings;
       data.admin = undefined;
       this.topicCloudAdmin.setAdminData(admin, false, this.userRole);
       if (this.deviceInfo.isCurrentlyMobile) {
diff --git a/src/app/services/util/profanity-filter.service.ts b/src/app/services/util/profanity-filter.service.ts
index 73045faea036f26f3e2854f0ce53f4ffad7f5bc9..3d710236f1c748f182ee6de2f2463f3ed72e834b 100644
--- a/src/app/services/util/profanity-filter.service.ts
+++ b/src/app/services/util/profanity-filter.service.ts
@@ -17,7 +17,8 @@ export class ProfanityFilterService {
     badNL.splice(badNL.indexOf('nicht'), 1);
     const badDE = BadWords['de'];
     badDE.splice(badDE.indexOf('ische'), 1);
-    this.profanityWords = BadWords['en']
+    const badEN = BadWords['en'];
+    this.profanityWords = badEN
       .concat(badDE)
       .concat(BadWords['fr'])
       .concat(BadWords['ar'])
@@ -65,33 +66,37 @@ export class ProfanityFilterService {
     localStorage.removeItem(this.profanityKey);
   }
 
-  filterProfanityWords(str: string, censorPartialWordsCheck: boolean, censorLanguageSpecificCheck: boolean, lang?: string){
-    let filteredString = str;
-    let profWords = [];
+  filterProfanityWords(str: string,
+                       censorPartialWordsCheck: boolean,
+                       censorLanguageSpecificCheck: boolean,
+                       lang?: string): [string, boolean] {
+    let profWords: any[];
     if (censorLanguageSpecificCheck) {
       profWords = BadWords[(lang !== 'AUTO' ? lang.toLowerCase() : localStorage.getItem('currentLang'))];
     } else {
       profWords = this.profanityWords;
     }
-    str = str.replace(new RegExp(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi), '');
-    const toCensoredString = censorPartialWordsCheck ? str.toLowerCase() : str.toLowerCase().split(/[\s,.]+/);
-    profWords.concat(this.getProfanityListFromStorage()).forEach(word => {
-      if (toCensoredString.includes(word)) {
-        filteredString = this.replaceString(filteredString, word, this.generateCensoredWord(word.length));
+    const list = profWords.concat(this.getProfanityListFromStorage());
+    if (list.length < 1) {
+      return [str, false];
+    }
+    const escapeRegex = /[.*+\-?^${}()|\[\]\\]/g;
+    const censoredWords = list
+      .reduce((acc, elem) => acc + (acc.length > 1 ? '|' : '') + elem.replace(escapeRegex, '\\$&'), '(') + ')';
+    const regex = new RegExp(censorPartialWordsCheck ? censoredWords : '\\b' + censoredWords + '\\b', 'gmi');
+    let result = '';
+    let censored = false;
+    let m: RegExpExecArray;
+    let lastIndex = 0;
+    while ((m = regex.exec(str)) !== null) {
+      result += str.substring(lastIndex, m.index) + '*'.repeat(regex.lastIndex - m.index);
+      lastIndex = regex.lastIndex;
+      censored = true;
+      if (m.index === regex.lastIndex) {
+        regex.lastIndex++;
       }
-    });
-    return filteredString;
-  }
-
-  private replaceString(str: string, search: string, replace: string) {
-    return str.replace(new RegExp(search, 'gi'), replace);
-  }
-
-  private generateCensoredWord(count: number) {
-    let res = '';
-    for (let i = 0; i < count; i++) {
-      res += '*';
     }
-    return res;
+    result += str.substring(lastIndex);
+    return [result, censored];
   }
 }
diff --git a/src/app/services/util/room-data.service.ts b/src/app/services/util/room-data.service.ts
index 54ccdc019c82af6bca997f7388879d691122af38..c1802e7b8659a3093af0cb70a69dcdeb0a16bac2 100644
--- a/src/app/services/util/room-data.service.ts
+++ b/src/app/services/util/room-data.service.ts
@@ -16,7 +16,7 @@ export interface UpdateInformation {
   subtype?: string;
   comment: Comment;
   finished?: boolean;
-  updates?: string[];
+  updates?: (keyof Comment)[];
 }
 
 class RoomDataUpdateSubscription {
@@ -82,7 +82,14 @@ interface FastRoomAccessObject {
   [commentId: string]: Comment;
 }
 
-type CommentFilterData = [body: string, genKeywords: SpacyKeyword[], userKeywords: SpacyKeyword[]];
+interface CommentFilterData {
+  body: string;
+  bodyCensored?: boolean;
+  genKeywords: SpacyKeyword[];
+  genKeywordsCensored?: boolean[];
+  userKeywords: SpacyKeyword[];
+  userKeywordsCensored?: boolean[];
+}
 
 @Injectable({
   providedIn: 'root'
@@ -148,11 +155,15 @@ export class RoomDataService {
   public checkProfanity(comment: Comment) {
     const finish = new Subject<boolean>();
     const subscription = finish.asObservable().subscribe(_ => {
+      let obj;
       if (this.room.profanityFilter !== ProfanityFilter.deactivated) {
-        [comment.body, comment.keywordsFromSpacy, comment.keywordsFromQuestioner] = this._savedCommentsAfterFilter.get(comment.id);
+        obj = this._savedCommentsAfterFilter.get(comment.id);
       } else {
-        [comment.body, comment.keywordsFromSpacy, comment.keywordsFromQuestioner] = this._savedCommentsBeforeFilter.get(comment.id);
+        obj = this._savedCommentsBeforeFilter.get(comment.id);
       }
+      comment.body = obj.body;
+      comment.keywordsFromSpacy = obj.genKeywords;
+      comment.keywordsFromQuestioner = obj.userKeywords;
       subscription.unsubscribe();
     });
 
@@ -180,16 +191,27 @@ export class RoomDataService {
     return this._savedCommentsAfterFilter.get(id)[0];
   }
 
+  getCensoredInformation(comment: Comment): CommentFilterData {
+    return this._savedCommentsAfterFilter.get(comment.id);
+  }
+
   private setCommentBody(comment: Comment) {
     const genKeywords = RoomDataService.cloneKeywords(comment.keywordsFromSpacy);
     const userKeywords = RoomDataService.cloneKeywords(comment.keywordsFromQuestioner);
-    this._savedCommentsBeforeFilter.set(comment.id, [comment.body, genKeywords, userKeywords]);
+    this._savedCommentsBeforeFilter.set(comment.id, {
+      body: comment.body,
+      genKeywords,
+      userKeywords
+    });
     this._savedCommentsAfterFilter.set(comment.id, this.filterCommentOfProfanity(this.room, comment));
   }
 
   private filterAllCommentsBodies() {
     this._currentComments.forEach(comment => {
-      [comment.body, comment.keywordsFromSpacy, comment.keywordsFromQuestioner] = this._savedCommentsBeforeFilter.get(comment.id);
+      const obj = this._savedCommentsBeforeFilter.get(comment.id);
+      comment.body = obj.body;
+      comment.keywordsFromSpacy = obj.genKeywords;
+      comment.keywordsFromQuestioner = obj.userKeywords;
       this.setCommentBody(comment);
       this.checkProfanity(comment);
     });
@@ -198,11 +220,20 @@ export class RoomDataService {
   private filterCommentOfProfanity(room: Room, comment: Comment): CommentFilterData {
     const partialWords = room.profanityFilter === ProfanityFilter.all || room.profanityFilter === ProfanityFilter.partialWords;
     const languageSpecific = room.profanityFilter === ProfanityFilter.all || room.profanityFilter === ProfanityFilter.languageSpecific;
-    return [
-      this.profanityFilterService.filterProfanityWords(comment.body, partialWords, languageSpecific, comment.language),
-      this.checkKeywords(comment.keywordsFromSpacy, partialWords, languageSpecific, comment.language),
-      this.checkKeywords(comment.keywordsFromQuestioner, partialWords, languageSpecific, comment.language)
-    ];
+    const [body, bodyCensored] = this.profanityFilterService
+      .filterProfanityWords(comment.body, partialWords, languageSpecific, comment.language);
+    const [genKeywords, genKeywordsCensored] = this
+      .checkKeywords(comment.keywordsFromSpacy, partialWords, languageSpecific, comment.language);
+    const [userKeywords, userKeywordsCensored] = this
+      .checkKeywords(comment.keywordsFromQuestioner, partialWords, languageSpecific, comment.language);
+    return {
+      body,
+      bodyCensored,
+      genKeywords,
+      genKeywordsCensored,
+      userKeywords,
+      userKeywordsCensored
+    };
   }
 
   private removeCommentBodies(key: string) {
@@ -440,14 +471,21 @@ export class RoomDataService {
     this._fastCommentAccess[id] = undefined;
   }
 
-  private checkKeywords(keywords: SpacyKeyword[], partialWords: boolean, languageSpecific: boolean, lang: string): SpacyKeyword[] {
+  private checkKeywords(keywords: SpacyKeyword[],
+                        partialWords: boolean,
+                        languageSpecific: boolean,
+                        lang: string): [SpacyKeyword[], boolean[]] {
     const newKeywords = [...keywords];
+    const censored: boolean[] = new Array(keywords.length);
     for (let i = 0; i < newKeywords.length; i++) {
+      const [text, textCensored] = this.profanityFilterService
+        .filterProfanityWords(newKeywords[i].text, partialWords, languageSpecific, lang);
+      censored[i] = textCensored;
       newKeywords[i] = {
-        text: this.profanityFilterService.filterProfanityWords(newKeywords[i].text, partialWords, languageSpecific, lang),
+        text,
         dep: newKeywords[i].dep
       };
     }
-    return newKeywords;
+    return [newKeywords, censored];
   }
 }
diff --git a/src/app/services/util/tag-cloud-data.service.ts b/src/app/services/util/tag-cloud-data.service.ts
index 2e4e038f25ce664a4ef8b47e965ef12406a151c2..f737f79d0215af57d71b1f566f1acdb70ff0482d 100644
--- a/src/app/services/util/tag-cloud-data.service.ts
+++ b/src/app/services/util/tag-cloud-data.service.ts
@@ -10,6 +10,7 @@ import { SpacyKeyword } from '../http/spacy.service';
 import { UserRole } from '../../models/user-roles.enum';
 import { CloudParameters } from '../../utils/cloud-parameters';
 import { SmartDebounce } from '../../utils/smart-debounce';
+import { ModeratorService } from '../http/moderator.service';
 
 export interface TagCloudDataTagEntry {
   weight: number;
@@ -26,6 +27,8 @@ export interface TagCloudDataTagEntry {
   generatedByQuestionerCount: number;
   taggedCommentsCount: number;
   answeredCommentsCount: number;
+  commentsByCreator: number;
+  commentsByModerators: number;
 }
 
 export interface TagCloudMetaData {
@@ -71,7 +74,6 @@ export class TagCloudDataService {
   private _metaDataBus: BehaviorSubject<TagCloudMetaData>;
   private _commentSubscription = null;
   private _roomId = null;
-  private _calcWeightType = TagCloudCalcWeightType.byLength;
   private _lastFetchedData: TagCloudData = null;
   private _lastFetchedComments: Comment[] = null;
   private _lastMetaData: TagCloudMetaData = null;
@@ -80,10 +82,13 @@ export class TagCloudDataService {
   private _adminData: TopicCloudAdminData = null;
   private _subscriptionAdminData: Subscription;
   private _currentFilter: CommentFilter;
+  private _currentModerators: string[];
+  private _currentOwner: string;
   private readonly _smartDebounce = new SmartDebounce(200, 3_000);
 
   constructor(private _tagCloudAdmin: TopicCloudAdminService,
-              private _roomDataService: RoomDataService) {
+              private _roomDataService: RoomDataService,
+              private _moderatorService: ModeratorService) {
     this._isDemoActive = false;
     this._isAlphabeticallySorted = false;
     this._dataBus = new BehaviorSubject<TagCloudData>(null);
@@ -98,11 +103,15 @@ export class TagCloudDataService {
     this._metaDataBus = new BehaviorSubject<TagCloudMetaData>(null);
   }
 
-  static buildDataFromComments(adminData: TopicCloudAdminData, comments: Comment[]): [TagCloudData, Set<number>] {
+  static buildDataFromComments(roomOwner: string,
+                               moderators: string[],
+                               adminData: TopicCloudAdminData,
+                               roomDataService: RoomDataService,
+                               comments: Comment[]): [TagCloudData, Set<number>] {
     const data: TagCloudData = new Map<string, TagCloudDataTagEntry>();
     const users = new Set<number>();
     for (const comment of comments) {
-      TopicCloudAdminService.approveKeywordsOfComment(comment, adminData,
+      TopicCloudAdminService.approveKeywordsOfComment(comment, roomDataService, adminData,
         (keyword: SpacyKeyword, isFromQuestioner: boolean) => {
           let current: TagCloudDataTagEntry = data.get(keyword.text);
           const commentDate = new Date(comment.timestamp);
@@ -121,7 +130,9 @@ export class TagCloudDataService {
               lastTimeStamp: commentDate,
               generatedByQuestionerCount: 0,
               taggedCommentsCount: 0,
-              answeredCommentsCount: 0
+              answeredCommentsCount: 0,
+              commentsByCreator: 0,
+              commentsByModerators: 0
             };
             data.set(keyword.text, current);
           }
@@ -133,6 +144,11 @@ export class TagCloudDataService {
           current.generatedByQuestionerCount += +isFromQuestioner;
           current.taggedCommentsCount += +!!comment.tag;
           current.answeredCommentsCount += +!!comment.answer;
+          if (comment.creatorId === roomOwner) {
+            ++current.commentsByCreator;
+          } else if (moderators.includes(comment.creatorId)) {
+            ++current.commentsByModerators;
+          }
           if (comment.tag) {
             current.categories.add(comment.tag);
           }
@@ -155,12 +171,18 @@ export class TagCloudDataService {
     ];
   }
 
-  bindToRoom(roomId: string, userRole: UserRole): void {
+  bindToRoom(roomId: string, roomOwner: string, userRole: UserRole): void {
     if (this._subscriptionAdminData) {
       throw new Error('Room already bound.');
     }
+    this._currentModerators = null;
     this._currentFilter = CommentFilter.currentFilter;
     this._roomId = roomId;
+    this._currentOwner = roomOwner;
+    this._moderatorService.get(roomId).subscribe(moderators => {
+      this._currentModerators = moderators.map(moderator => moderator.accountId);
+      this.rebuildTagData();
+    });
     this._lastFetchedComments = null;
     this._subscriptionAdminData = this._tagCloudAdmin.getAdminData.subscribe(adminData => {
       this.onReceiveAdminData(adminData, true);
@@ -212,7 +234,9 @@ export class TagCloudDataService {
           lastTimeStamp: new Date(),
           generatedByQuestionerCount: 0,
           taggedCommentsCount: 0,
-          answeredCommentsCount: 0
+          answeredCommentsCount: 0,
+          commentsByCreator: 0,
+          commentsByModerators: 0
         });
       }
     });
@@ -226,17 +250,6 @@ export class TagCloudDataService {
     return this._dataBus.value;
   }
 
-  set weightCalcType(type: TagCloudCalcWeightType) {
-    if (type !== this._calcWeightType) {
-      this._calcWeightType = type;
-      this.rebuildTagData();
-    }
-  }
-
-  get weightCalcType(): TagCloudCalcWeightType {
-    return this._calcWeightType;
-  }
-
   get demoActive(): boolean {
     return this._isDemoActive;
   }
@@ -306,7 +319,6 @@ export class TagCloudDataService {
 
   private onReceiveAdminData(data: TopicCloudAdminData, update = false) {
     this._adminData = data;
-    this._calcWeightType = this._adminData.considerVotes ? TagCloudCalcWeightType.byLengthAndVotes : TagCloudCalcWeightType.byLength;
     if (update) {
       this.rebuildTagData();
     }
@@ -330,36 +342,34 @@ export class TagCloudDataService {
   }
 
   private calculateWeight(tagData: TagCloudDataTagEntry): number {
-    const value = Math.max(tagData.cachedVoteCount, 0);
-    const additional = (tagData.distinctUsers.size - 1) * 0.5 +
-      tagData.comments.reduce((acc, comment) => acc + +!!comment.createdFromLecturer, 0) +
-      tagData.generatedByQuestionerCount +
-      tagData.taggedCommentsCount +
-      tagData.answeredCommentsCount;
-    switch (this._calcWeightType) {
-      case TagCloudCalcWeightType.byVotes:
-        return value + additional;
-      case TagCloudCalcWeightType.byLengthAndVotes:
-        return value / 10.0 + tagData.comments.length + additional;
-      default:
-        return tagData.comments.length + additional;
-    }
+    const scorings = this._adminData.scorings;
+    return tagData.comments.length * scorings.countComments.score +
+      tagData.distinctUsers.size * scorings.countUsers.score +
+      tagData.generatedByQuestionerCount * scorings.countSelectedByQuestioner.score +
+      tagData.commentsByModerators * scorings.countKeywordByModerator.score +
+      tagData.commentsByCreator * scorings.countKeywordByCreator.score +
+      tagData.answeredCommentsCount * scorings.countCommentsAnswered.score +
+      tagData.cachedUpVotes * scorings.summedUpvotes.score +
+      tagData.cachedDownVotes * scorings.summedDownvotes.score +
+      tagData.cachedVoteCount * scorings.summedVotes.score +
+      Math.max(tagData.cachedVoteCount, 0) * scorings.cappedSummedVotes.score;
   }
 
   private rebuildTagData() {
-    if (!this._lastFetchedComments) {
+    if (!this._lastFetchedComments || !this._currentModerators) {
       return;
     }
     const currentMeta = this._isDemoActive ? this._lastMetaData : this._currentMetaData;
     const filteredComments = this._lastFetchedComments.filter(comment => this._currentFilter.checkComment(comment));
     currentMeta.commentCount = filteredComments.length;
-    const [data, users] = TagCloudDataService.buildDataFromComments(this._adminData, filteredComments);
+    const [data, users] = TagCloudDataService.buildDataFromComments(this._currentOwner, this._currentModerators,
+      this._adminData, this._roomDataService, filteredComments);
     let minWeight = null;
     let maxWeight = null;
     for (const value of data.values()) {
       value.weight = this.calculateWeight(value);
-      minWeight = Math.min(value.weight, minWeight || value.weight);
-      maxWeight = Math.max(value.weight, maxWeight || value.weight);
+      minWeight = Math.min(value.weight, minWeight === null ? value.weight : minWeight);
+      maxWeight = Math.max(value.weight, maxWeight === null ? value.weight : maxWeight);
     }
     //calculate weight counts and adjusted weights
     const same = minWeight === maxWeight;
diff --git a/src/app/services/util/topic-cloud-admin.service.ts b/src/app/services/util/topic-cloud-admin.service.ts
index eea4ab450faf91e970d0c232a52a3142a674aeeb..0ab7787b47a6d2078eeb16671339589aa0daf15e 100644
--- a/src/app/services/util/topic-cloud-admin.service.ts
+++ b/src/app/services/util/topic-cloud-admin.service.ts
@@ -1,5 +1,6 @@
 import { Injectable } from '@angular/core';
 import {
+  ensureDefaultScorings,
   KeywordOrFulltext,
   spacyLabels,
   TopicCloudAdminData
@@ -14,6 +15,9 @@ import { BehaviorSubject, Observable, Subject, Subscription } from 'rxjs';
 import { Comment } from '../../models/comment';
 import { UserRole } from '../../models/user-roles.enum';
 import { CloudParameters } from '../../utils/cloud-parameters';
+import { RoomDataService } from './room-data.service';
+
+export const regexMaskKeyword = /\b(frage|antwort|aufgabe|hallo|test|bzw|muss|more to come)\b/gmi;
 
 @Injectable({
   providedIn: 'root',
@@ -47,36 +51,47 @@ export class TopicCloudAdminService {
       minQuestions: admin.minQuestions,
       minUpvotes: admin.minUpvotes,
       startDate: admin.startDate,
-      endDate: admin.endDate
+      endDate: admin.endDate,
+      scorings: admin.scorings
     };
     room.tagCloudSettings = JSON.stringify(settings);
   }
 
-  static approveKeywordsOfComment(comment: Comment, config: TopicCloudAdminData, keywordFunc: (SpacyKeyword, boolean) => void) {
+  static approveKeywordsOfComment(comment: Comment,
+                                  roomDataService: RoomDataService,
+                                  config: TopicCloudAdminData,
+                                  keywordFunc: (SpacyKeyword, boolean) => void) {
     let source = comment.keywordsFromQuestioner;
+    let censored = roomDataService.getCensoredInformation(comment).userKeywordsCensored;
     let isFromQuestioner = true;
     if (config.keywordORfulltext === KeywordOrFulltext.both) {
       if (!source || !source.length) {
-        source = comment.keywordsFromSpacy;
         isFromQuestioner = false;
+        source = comment.keywordsFromSpacy;
+        censored = roomDataService.getCensoredInformation(comment).genKeywordsCensored;
       }
     } else if (config.keywordORfulltext === KeywordOrFulltext.fulltext) {
       isFromQuestioner = false;
       source = comment.keywordsFromSpacy;
+      censored = roomDataService.getCensoredInformation(comment).genKeywordsCensored;
     }
     if (!source) {
       return;
     }
     const wantedLabels = config.wantedLabels[comment.language.toLowerCase()];
-    for (const keyword of source) {
-      if (wantedLabels && (!keyword.dep || !keyword.dep.some(e => wantedLabels.includes(e)))) {
+    for (let i = 0; i < source.length; i++) {
+      const keyword = source[i];
+      if (keyword.text.replace(regexMaskKeyword, '').replace(/ +/, ' ').trim().length < 3) {
         continue;
       }
-      let isProfanity = !!keyword.text.match(/\*/);
-      if (isProfanity) {
+      if (censored[i]) {
+        continue;
+      }
+      if (wantedLabels && (!keyword.dep || !keyword.dep.some(e => wantedLabels.includes(e)))) {
         continue;
       }
       const lowerCasedKeyword = keyword.text.toLowerCase();
+      let isProfanity = false;
       for (const word of config.blacklist) {
         if (lowerCasedKeyword.includes(word)) {
           isProfanity = true;
@@ -120,9 +135,11 @@ export class TopicCloudAdminService {
         minQuestions: 1,
         minUpvotes: 0,
         startDate: null,
-        endDate: null
+        endDate: null,
+        scorings: null
       };
     }
+    ensureDefaultScorings(data);
     return data;
   }
 
diff --git a/src/app/utils/SyncFence.ts b/src/app/utils/SyncFence.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bbe6079a65f6badff2f81e7c4fd6b533f7a9b576
--- /dev/null
+++ b/src/app/utils/SyncFence.ts
@@ -0,0 +1,17 @@
+export class SyncFence {
+  private readonly _conditions: boolean[];
+
+  constructor(public readonly conditionCount: number,
+              public readonly satisfyCallback: () => void) {
+    this._conditions = new Array(conditionCount).fill(false);
+  }
+
+  resolveCondition(index: number) {
+    if (!this._conditions[index]) {
+      this._conditions[index] = true;
+      if (this._conditions.every(condition => condition)) {
+        this.satisfyCallback();
+      }
+    }
+  }
+}
diff --git a/src/assets/i18n/creator/de.json b/src/assets/i18n/creator/de.json
index b59892eb4c508a091eee798a11e232793c31ed77..42b35de3843309a51aa52f5abadc75de6e85db90 100644
--- a/src/assets/i18n/creator/de.json
+++ b/src/assets/i18n/creator/de.json
@@ -194,8 +194,8 @@
     "grammar-check": "Text prüfen",
     "show-comment-with-filter": "Vulgäre Wörter ausixen",
     "show-comment-without-filter": "Vulgäre Wörter anzeigen",
-    "upvote": "positiv",
-    "downvote": "negativ"
+    "upvote": "positiv:",
+    "downvote": "negativ:"
   },
   "content": {
     "abort": "Abbrechen",
@@ -250,11 +250,13 @@
     "more": "Formell"
   },
   "explanation": {
-    "label": "Warum?",
+    "label": "Erklärung",
     "close": "Schließen",
     "deepl": "## Text optimieren \n\nUm deine Frage optimal lesbar und verständlich zu präsentieren, lassen wir sie mit dem KI-Übersetzungsprogramm [DeepL](https://www.deepl.com/translator) ins Englische und zurück ins Deutsche übersetzen. \n\nDie Rückübersetzung ist in fast allen Fällen besser als das Original in Bezug auf Rechtschreibung, Grammatik, Interpunktion und Sprachstil.",
     "spacy": "## Stichwörter \n\nMittels NLP (Natural Language Processing) wird deine Frage grammatikalisch analysiert. Die erkannten Substantive werden in ihre Grundform gebracht, d. h. lemmatisiert, und dir als Stichwörter vorgeschlagen. Für die Textanalyse verwenden wir die freie NLP-Software [spaCy](https://spacy.io/). \n\nDie Stichwörter können verwendet werden, um die Liste der Fragen zu filtern oder um eine Wortwolke zu erstellen.",
-    "topic-cloud": "## Themen als Wortwolke \n\nUnsere **Themenwolke** visualisiert die Bedeutung der Stichwörter. \n\n  In die Berechnung der Schriftgröße gehen ein:\n\n* die Differenz zwischen Up- und Down-Votes, wenn sie positiv ist,\n* die Anzahl der Fragen mit diesem Stichwort,\n* die Anzahl der Fragesteller mit diesem Stichwort,\n* die Rolle des Fragenstellers: Raumersteller, Moderator oder Teilnehmer,\n* ob der Fragensteller eine Fragenkategorie ausgewählt hat,\n* ob das Stichwort generiert oder vom Fragensteller vergeben wurde,\n* ob die Frage vom Raumersteller oder einem Moderator beantwortet wurde.\n\nDie Themenwolke dient als **Navigator** zu allen Fragen zu einem Stichwort: Wenn du auf ein Wort in der Wolke klickst, gelangst du zu den Fragen mit diesem Stichwort."
+    "topic-cloud": "## Themen als Wortwolke \n\nUnsere **Themenwolke** visualisiert die Bedeutung der Stichwörter. \n\n  In die Berechnung der Schriftgröße gehen ein:\n\n* die Differenz zwischen Up- und Down-Votes, wenn sie positiv ist,\n* die Anzahl der Fragen mit diesem Stichwort,\n* die Anzahl der Fragensteller mit diesem Stichwort,\n* die Rolle des Fragenstellers: Raumersteller, Moderator oder Teilnehmer,\n* ob der Fragensteller eine Fragenkategorie ausgewählt hat,\n* ob das Stichwort generiert oder vom Fragensteller vergeben wurde,\n* ob die Frage vom Raumersteller oder einem Moderator beantwortet wurde.\n\nDie Themenwolke dient als **Navigator** zu allen Fragen zu einem Stichwort: Wenn du auf ein Wort in der Wolke klickst, gelangst du zu den Fragen mit diesem Stichwort.",
+    "user-bonus": "Die Lehrperson kann »gute« Fragen für einen Bonus markieren. Deine Fragen aus allen Kursen (Räumen), die einen Stern erhalten haben, werden hier aufgelistet.\n\nJe nach Vereinbarung kannst du den Token des Sterns per E-Mail an die Lehrperson schicken, um ihn gegen einen Bonus einzulösen.",
+    "bonus-archive": "Hier werden alle Fragen aufgelistet, die du in deinen Räumen mit einem Stern markiert hast. Anhand der Liste kannst du überprüfen, ob der Token, den dir ein Teilnehmer per Mail geschickt hat, gültig ist. \n\nUm einen Token schnell zu finden, gibt es ein Suchfeld. Ist der Token gültig, kannst du dir die entsprechende Frage direkt über einen Link anzeigen lassen."
   },
   "home-page": {
     "create-session": "Neue Sitzung",
@@ -392,6 +394,7 @@
     "description": "Text",
     "max-ls": "Maximale Anzahl Zeichen:",
     "session-name": "Name der Sitzung",
+    "edit-session-name": "Name der Sitzung bearbeiten",
     "preview": "Vorschau"
   },
   "tag-cloud-popup": {
@@ -416,7 +419,28 @@
     "question-count-plural": "Fragen",
     "edit-keyword-tip": "Neues Thema",
     "no-keywords-note": "Es gibt keine Themen.",
-    "consider-votes": "Bewertungen der Fragen berücksichtigen",
+    "keyword-scoring-header": "Bewertung der Stichwörter",
+    "keyword-scoring-header-info": "Einstellbare Multiplikatoren für die Gewichtung der Schlüsselwörter",
+    "keyword-scoring-countComments": "Anzahl Kommentare",
+    "keyword-scoring-countComments-info": "Anzahl der Kommentare, aus denen die Schlüsselwörter extrahiert wurden",
+    "keyword-scoring-countUsers": "Anzahl Fragensteller*innen",
+    "keyword-scoring-countUsers-info": "Anzahl exklusiver Fragensteller*innen, die dieses Schlüsselwort verwendet haben",
+    "keyword-scoring-countSelectedByQuestioner": "Anzahl verifiziert",
+    "keyword-scoring-countSelectedByQuestioner-info": "Anzahl der Verifizierungen eines Schlüsselworts durch einen Fragesteller*in",
+    "keyword-scoring-countKeywordByModerator": "Anzahl Schlüsselwörter von Moderatoren",
+    "keyword-scoring-countKeywordByModerator-info": "Anzahl der Verwendungen dieses Schlüsselworts durch Moderatoren",
+    "keyword-scoring-countKeywordByCreator": "Anzahl Schlüsselwörter vom Ersteller",
+    "keyword-scoring-countKeywordByCreator-info": "Anzahl der Verwendungen dieses Schlüsselworts durch den Ersteller",
+    "keyword-scoring-countCommentsAnswered": "Anzahl beantwortete Kommentare",
+    "keyword-scoring-countCommentsAnswered-info": "Anzahl der Kommentare, die dieses Stichwort enthalten und beantwortet wurden",
+    "keyword-scoring-summedUpvotes": "Anzahl aller Upvotes",
+    "keyword-scoring-summedUpvotes-info": "Anzahl aller Upvotes, die auf den Kommentaren mit diesem Schlüsselwort gemacht worden sind",
+    "keyword-scoring-summedDownvotes": "Anzahl aller Downvotes",
+    "keyword-scoring-summedDownvotes-info": "Anzahl aller Downvotes, die auf den Kommentaren mit diesem Schlüsselwort gemacht worden sind",
+    "keyword-scoring-summedVotes": "Summe aller Votes",
+    "keyword-scoring-summedVotes-info": "Summe aus den Up- und Downvotes, die auf den Kommentaren mit diesem Schlüsselwort gemacht worden sind",
+    "keyword-scoring-cappedSummedVotes": "Summe aller Votes (>= 0)",
+    "keyword-scoring-cappedSummedVotes-info": "(Siehe Summe aller Votes). Die Summe kann nicht unter null fallen und wird minimal 0",
     "profanity": "Vulgäre Wörter mit »***« überschreiben",
     "hide-blacklist-words": "Themen aus der Blacklist verbergen",
     "sort-alpha": "Alphabetisch",
@@ -452,7 +476,7 @@
     "only-specific-language-will-be-filtered": "Nur Vulgärausdrücke in der Sprache der Frage filtern",
     "partial-words-will-be-filtered": "Vulgäre Teilwörter auch filtern",
     "keyword-from-spacy": "Stichwort aus der Textanalyse",
-    "keyword-from-questioner": "Stichwort vom Fragesteller",
+    "keyword-from-questioner": "Stichwort vom Fragensteller",
     "Keyword-from-both": "Stichwort vom Fragensteller und aus der Textanalyse",
     "test-profanity": "Profanität testen",
     "word": "Wort",
@@ -556,9 +580,9 @@
     "manual-weight-number-note": "Begrenzt die Anzahl Themen einer Häufigkeitsgruppe auf den eingestellten Wert"
   },
   "token-validator": {
-    "valid": "VALID",
-    "invalid": "INVALID",
-    "cant-find-comment": "Die Frage kann nicht gefunden werden"
+    "valid": "Gültiger Token",
+    "invalid": "Ungültiger Token",
+    "cant-find-comment": "Es gibt keine Frage mit diesem Token."
   },
   "worker-dialog": {
     "running": "Laufend",
diff --git a/src/assets/i18n/creator/en.json b/src/assets/i18n/creator/en.json
index dbaf88ac4b8ee5d519da631a79b71e75dbe44ccf..2a3d3e1cecdabb814bdca303217f123aa26fd16e 100644
--- a/src/assets/i18n/creator/en.json
+++ b/src/assets/i18n/creator/en.json
@@ -195,8 +195,8 @@
     "grammar-check": "Check text",
     "show-comment-with-filter": "Hide vulgar words",
     "show-comment-without-filter": "Show vulgar words",
-    "upvote": "upvotes",
-    "downvote": "downvotes"
+    "upvote": "upvotes:",
+    "downvote": "downvotes:"
   },
   "content": {
     "abort": "Abort",
@@ -255,7 +255,9 @@
     "close": "Close",
     "deepl": "## Text optimization\n\nTo make your question as readable and understandable as possible, we have it translated into German and back into English using the translation program [DeepL](https://www.deepl.com/translator).\n\nThe back translation is in almost all cases better than the original in terms of spelling, grammar, punctuation and language style.",
     "spacy": "## Text analysis\n\nUsing NLP (Natural Language Processing) your question will be analyzed grammatically. The recognized nouns are put into their basic form, i.e. lemmatized, and suggested to you as keywords. For the text analysis we use the free NLP software [spaCy](https://spacy.io/). \n\nThe keywords can be used to filter the list of questions or to create a word cloud.",
-    "topic-cloud": "## Topics as tags in a word cloud\n\nOur **topic cloud** visualizes the significance of the keywords. \n\n The calculation of the font size includes:\n\n* the difference between up- and down-votes, if it is positive\n* the number of questions with this keyword\n* the number of questioners with this keyword.\n* the role of the questioner: room creator, moderator or participant \n* whether the questioner has selected a question category \n* whether the keyword was generated or assigned by the question poser\n* whether the question was answered by the room creator or a moderator \n\n The topic cloud serves as a **navigator** to all questions related to a selected keyword: If you click on a word in the cloud, you will get to the questions related to this keyword."
+    "topic-cloud": "## Topics as tags in a word cloud\n\nOur **topic cloud** visualizes the significance of the keywords. \n\n The calculation of the font size includes:\n\n* the difference between up- and down-votes, if it is positive\n* the number of questions with this keyword\n* the number of questioners with this keyword.\n* the role of the questioner: room creator, moderator or participant \n* whether the questioner has selected a question category \n* whether the keyword was generated or assigned by the question poser\n* whether the question was answered by the room creator or a moderator \n\n The topic cloud serves as a **navigator** to all questions related to a selected keyword: If you click on a word in the cloud, you will get to the questions related to this keyword.",
+    "user-bonus": "The teacher can mark »good« questions for a bonus. Your questions from all courses (rooms) that have received a star will be listed here.\n\nDepending on the agreement, you can email the token of the star to the teacher to redeem it for a bonus.",
+    "bonus-archive": "All questions that you have marked with a star in your rooms are listed here. You can use the list to check whether the token that a participant sent you by mail is valid. \n\nTo find a token quickly, there is a search field. If the token is valid, you can display the corresponding question directly via a link."
   },
   "home-page": {
     "create-session": "New session",
@@ -391,6 +393,7 @@
     "description": "Description",
     "max-ls": "Max. characters:",
     "session-name": "Session name",
+    "edit-session-name": "Edit session name",
     "preview": "Preview"
   },
   "tag-cloud": {
@@ -426,7 +429,28 @@
     "question-count-plural": "Questions",
     "edit-keyword-tip": "New topic",
     "no-keywords-note": "There are no topics.",
-    "consider-votes": "Consider Votes",
+    "keyword-scoring-header": "Keyword weighting",
+    "keyword-scoring-header-info": "Adjustable multipliers for the weighting of keywords",
+    "keyword-scoring-countComments": "Number of comments",
+    "keyword-scoring-countComments-info": "Number of comments from which the keywords have been extracted",
+    "keyword-scoring-countUsers": "Number of questioners",
+    "keyword-scoring-countUsers-info": "Number of exclusive questioners who used this keyword",
+    "keyword-scoring-countSelectedByQuestioner": "Number verified",
+    "keyword-scoring-countSelectedByQuestioner-info": "Number of times a keyword has been verified by a questioner",
+    "keyword-scoring-countKeywordByModerator": "Number of keywords from moderators",
+    "keyword-scoring-countKeywordByModerator-info": "Number of times this keyword has been used by moderators",
+    "keyword-scoring-countKeywordByCreator": "Number of keywords from creator",
+    "keyword-scoring-countKeywordByCreator-info": "Number of times this keyword has been used by the creator",
+    "keyword-scoring-countCommentsAnswered": "Number of answered comments",
+    "keyword-scoring-countCommentsAnswered-info": "Number of comments that have this keyword and have been answered",
+    "keyword-scoring-summedUpvotes": "Number of all upvotes",
+    "keyword-scoring-summedUpvotes-info": "Number of all upvotes made on the comments with this keyword",
+    "keyword-scoring-summedDownvotes": "Number of all downvotes",
+    "keyword-scoring-summedDownvotes-info": "Number of all downvotes made on the comments with this keyword",
+    "keyword-scoring-summedVotes": "Sum of all votes",
+    "keyword-scoring-summedVotes-info": "Sum of the upvotes and downvotes made on the comments with this keyword",
+    "keyword-scoring-cappedSummedVotes": "Sum of all votes (>= 0)",
+    "keyword-scoring-cappedSummedVotes-info": "(See the sum of all votes). The sum cannot fall below zero and becomes a minimum of 0",
     "profanity": "Censor profanity",
     "hide-blacklist-words": "Hide blacklist keywords",
     "sort-alpha": "Alphabetically",
@@ -554,9 +578,9 @@
     "manual-weight-number-note": "Limits the respective weight class to a self-defined value"
   },
   "token-validator": {
-    "valid": "VALID",
-    "invalid": "INVALID",
-    "cant-find-comment": "Can't find comment"
+    "valid": "Valid token",
+    "invalid": "Invalid token",
+    "cant-find-comment": "There is no question with this token."
   },
   "worker-dialog": {
     "running": "Running",
diff --git a/src/assets/i18n/demo/demo-de.html b/src/assets/i18n/demo/demo-de.html
index b73747316176429c0f47384c06f850660c008d3b..14b4d6b4ab686a29de5b318bdaf751f33cb22084 100644
--- a/src/assets/i18n/demo/demo-de.html
+++ b/src/assets/i18n/demo/demo-de.html
@@ -81,7 +81,7 @@
     Hier hilft die KI mit NLP (Natural Language Processing),
     den Überblick zu behalten:
     Die Substantive in den Texten werden auf ihre grammatische Stellung im Satz analysiert
-    und als Stichwörter dem Fragensteller oder der Fragestellerin zur thematischen Einordnung vorgeschlagen.
+    und als Stichwörter dem Fragensteller oder der Fragenstellerin zur thematischen Einordnung vorgeschlagen.
     </p>
     <p>
     Wohl wissend, dass die sprachliche Qualität eines anonymen Textes
diff --git a/src/assets/i18n/home/de.json b/src/assets/i18n/home/de.json
index 04bf4a358357c2c0e682c93af1ed1d3a34bc8f3f..4facef22093e71b43bda58391e50df258c1ac90c 100644
--- a/src/assets/i18n/home/de.json
+++ b/src/assets/i18n/home/de.json
@@ -49,7 +49,7 @@
     "cancel": "Abbrechen",
     "continue": "Weiter",
     "reset": "Zurücksetzen",
-    "brainstorming-question": "Überschrift der Wortwolke",
+    "brainstorming-question": "Überschrift des Brainstorming-Boards",
     "tag-cloud-info": "Je größer die Schrift, desto häufiger wurde das Wort  in den Fragen verwendet oder als Stichwort vergeben. Auch die Bewertungen der Fragen beeinflussen die Schriftgröße.",
     "tag-cloud-questions-title": "Welche Fragen soll die Themenwolke umfassen?",
     "tag-cloud-questions-all": "Alle Fragen",
@@ -60,11 +60,13 @@
     "tag-cloud-create": "Weiter"
   },
   "explanation": {
-    "label": "Warum?",
+    "label": "Erklärung",
     "close": "Schließen",
     "deepl": "## Text optimieren \n\nUm deine Frage optimal lesbar und verständlich zu präsentieren, lassen wir sie mit dem KI-Übersetzungsprogramm [DeepL](https://www.deepl.com/translator) ins Englische und zurück ins Deutsche übersetzen. \n\nDie Rückübersetzung ist in fast allen Fällen besser als das Original in Bezug auf Rechtschreibung, Grammatik, Interpunktion und Sprachstil.",
     "spacy": "## Stichwörter \n\nMittels NLP (Natural Language Processing) wird deine Frage grammatikalisch analysiert. Die erkannten Substantive werden in ihre Grundform gebracht, d. h. lemmatisiert, und dir als Stichwörter vorgeschlagen. Für die Textanalyse verwenden wir die freie NLP-Software [spaCy](https://spacy.io/). \n\nDie Stichwörter können verwendet werden, um die Liste der Fragen zu filtern oder um eine Wortwolke zu erstellen.",
-    "topic-cloud": "## Themen als Wortwolke \n\nUnsere **Themenwolke** visualisiert die Bedeutung der Stichwörter. \n\n  In die Berechnung der Schriftgröße gehen ein:\n\n* die Differenz zwischen Up- und Down-Votes, wenn sie positiv ist,\n* die Anzahl der Fragen mit diesem Stichwort,\n* die Anzahl der Fragesteller mit diesem Stichwort,\n* die Rolle des Fragenstellers: Raumersteller, Moderator oder Teilnehmer,\n* ob der Fragensteller eine Fragenkategorie ausgewählt hat,\n* ob das Stichwort generiert oder vom Fragensteller vergeben wurde,\n* ob die Frage vom Raumersteller oder einem Moderator beantwortet wurde.\n\nDie Themenwolke dient als **Navigator** zu allen Fragen zu einem Stichwort: Wenn du auf ein Wort in der Wolke klickst, gelangst du zu den Fragen mit diesem Stichwort."
+    "topic-cloud": "## Themen als Wortwolke \n\nUnsere **Themenwolke** visualisiert die Bedeutung der Stichwörter. \n\n  In die Berechnung der Schriftgröße gehen ein:\n\n* die Differenz zwischen Up- und Down-Votes, wenn sie positiv ist,\n* die Anzahl der Fragen mit diesem Stichwort,\n* die Anzahl der Fragensteller mit diesem Stichwort,\n* die Rolle des Fragenstellers: Raumersteller, Moderator oder Teilnehmer,\n* ob der Fragensteller eine Fragenkategorie ausgewählt hat,\n* ob das Stichwort generiert oder vom Fragensteller vergeben wurde,\n* ob die Frage vom Raumersteller oder einem Moderator beantwortet wurde.\n\nDie Themenwolke dient als **Navigator** zu allen Fragen zu einem Stichwort: Wenn du auf ein Wort in der Wolke klickst, gelangst du zu den Fragen mit diesem Stichwort.",
+    "user-bonus": "Die Lehrperson kann »gute« Fragen für einen Bonus markieren. Deine Fragen aus allen Kursen (Räumen), die einen Stern erhalten haben, werden hier aufgelistet.\n\nJe nach Vereinbarung kannst du den Token des Sterns per E-Mail an die Lehrperson schicken, um ihn gegen einen Bonus einzulösen.",
+    "bonus-archive": "Hier werden alle Fragen aufgelistet, die du in deinen Räumen mit einem Stern markiert hast. Anhand der Liste kannst du überprüfen, ob der Token, den dir ein Teilnehmer per Mail geschickt hat, gültig ist. \n\nUm einen Token schnell zu finden, gibt es ein Suchfeld. Ist der Token gültig, kannst du dir die entsprechende Frage direkt über einen Link anzeigen lassen."
   },
   "header": {
     "abort": "Abbrechen",
@@ -116,7 +118,7 @@
     "create-question": "Frage stellen",
     "questionwall": "Präsentation",
     "tag-cloud": "Themenwolke",
-    "fullscreen": "Vollbild & Text",
+    "fullscreen": "Vollbild & Textgröße",
     "motd": "News & FAQ",
     "tag-cloud-config": "Aussehen & Animation",
     "tag-cloud-administration": "Einstellungen & Suche",
@@ -124,8 +126,8 @@
     "overview-question-tooltip": "Anzahl Fragen",
     "overview-questioners-tooltip": "Anzahl Fragensteller",
     "overview-keywords-tooltip": "Anzahl Stichwörter",
-    "update-spacy-keywords": "Fragen analysieren",
-    "overview-admin-config-enabled": "Themeneinschränkung aktiv",
+    "update-spacy-keywords": "Stichwörter extrahieren",
+    "overview-admin-config-enabled": "Themenbeschränkung aktiv",
     "quiz-now": "Quizzen",
     "moderation-warning": "Moderationsboard mit nicht freigegebenen Fragen",
     "tour": "Tour"
@@ -307,11 +309,11 @@
     "panel-session-id": "Raum-Code",
     "panel-session-name": "Veranstaltung",
     "panel-user-role": "Rolle",
-    "participant-role": "Du bist Teilnehmer*in in diesem Raum.",
-    "really-remove": "Willst du die besuchte Veranstaltung »",
-    "really-remove-2": "« wirklich aus der Liste streichen?",
+    "participant-role": "Du bist Teilnehmer in diesem Raum.",
+    "really-remove": "Willst du den Eintrag für die Veranstaltung »",
+    "really-remove-2": "« wirklich löschen?",
     "really-delete": "Willst du den Raum »",
-    "really-delete-2": "« wirklich unwiderruflich löschen?",
+    "really-delete-2": "« unwiderruflich löschen?",
     "room-successfully-removed": "Die Veranstaltung wurde aus der Liste entfernt.",
     "room-successfully-deleted": "Der Raum wurde gelöscht.",
     "canceled-remove": "Vorgang wurde abgebrochen.",
@@ -370,10 +372,10 @@
     "remove-successful": "Wort entfernt"
   },
   "worker-config": {
-    "heading": "Fragen analysieren",
-    "label": "Wähle ein Analysemodus",
-    "normal": "Alle Fragen",
-    "only-failed": "Nicht analysierte Fragen",
+    "heading": "Stichwörter extrahieren",
+    "label": "Wähle, aus welchen Fragen mittels Künstlicher Intelligenz (siehe »Einführung« in der Fußzeile) Stichwörter extrahiert werden sollen:",
+    "normal": "Alle Fragen des Raumes neu analysieren",
+    "only-failed": "Nur Fragen, die nicht analysiert worden sind",
     "continue": "Weiter",
     "cancel": "Abbrechen"
   },
diff --git a/src/assets/i18n/home/en.json b/src/assets/i18n/home/en.json
index 6d12d685def4a43641d758111be5917172494857..d736f132fbe8fd1664b2cf12ea65d8b44a0c5fed 100644
--- a/src/assets/i18n/home/en.json
+++ b/src/assets/i18n/home/en.json
@@ -47,11 +47,13 @@
     "motd-mark-read": "Mark as read"
   },
   "explanation": {
-    "label": "Explain",
+    "label": "Explanation",
     "close": "Close",
     "deepl": "## Text optimization\n\nTo make your question as readable and understandable as possible, we have it translated into English and back into German using the translation program [DeepL] (https://www.deepl.com/translator). \n\nThe back translation is in almost all cases better than the original in terms of spelling, grammar, punctuation and language style.",
     "spacy": "## Text analysis\n\nUsing NLP (Natural Language Processing) your question will be analyzed grammatically. The recognized nouns are put into their basic form, i.e. lemmatized, and suggested to you as keywords. For the text analysis we use the free NLP software [spaCy] (https://spacy.io/). \n\nThe keywords can be used to filter the list of questions or to create a word cloud.",
-    "topic-cloud": "## Topics as tags in a word cloud\n\nOur **topic cloud** visualizes the significance of the keywords. \n\n The calculation of the font size includes:\n\n* the difference between up- and down-votes, if it is positive\n* the number of questions with this keyword\n* the number of questioners with this keyword.\n* the role of the questioner: room creator, moderator or participant \n* whether the questioner has selected a question category\n* whether the keyword was generated or assigned by the question poser\n* whether the question was answered by the room creator or a moderator \n\n The topic cloud serves as a **navigator** to all questions related to a selected keyword: If you click on a word in the cloud, you will get to the questions related to this keyword."
+    "topic-cloud": "## Topics as tags in a word cloud\n\nOur **topic cloud** visualizes the significance of the keywords. \n\n The calculation of the font size includes:\n\n* the difference between up- and down-votes, if it is positive\n* the number of questions with this keyword\n* the number of questioners with this keyword.\n* the role of the questioner: room creator, moderator or participant \n* whether the questioner has selected a question category\n* whether the keyword was generated or assigned by the question poser\n* whether the question was answered by the room creator or a moderator \n\n The topic cloud serves as a **navigator** to all questions related to a selected keyword: If you click on a word in the cloud, you will get to the questions related to this keyword.",
+    "user-bonus": "The teacher can mark »good« questions for a bonus. Your questions from all courses (rooms) that have received a star will be listed here.\n\nDepending on the agreement, you can email the token of the star to the teacher to redeem it for a bonus.",
+    "bonus-archive": "All questions that you have marked with a star in your rooms are listed here. You can use the list to check whether the token that a participant sent you by mail is valid. \n\nTo find a token quickly, there is a search field. If the token is valid, you can display the corresponding question directly via a link."
   },
   "header": {
     "abort": "Cancel",
@@ -103,7 +105,7 @@
     "create-question": "Ask a question",
     "questionwall": "Presentation",
     "tag-cloud": "Topic cloud",
-    "fullscreen": "Fullscreen & Text",
+    "fullscreen": "Fullscreen & Text size",
     "motd": "News & FAQ",
     "tag-cloud-config": "Modify cloud view",
     "tag-cloud-administration": "Edit cloud topics",
@@ -111,7 +113,7 @@
     "overview-question-tooltip": "Number of questions",
     "overview-questioners-tooltip": "Number of questioners",
     "overview-keywords-tooltip": "Number of Keywords",
-    "update-spacy-keywords": "Analyze questions",
+    "update-spacy-keywords": "Extract keywords",
     "overview-admin-config-enabled": "Themes requirement active",
     "quiz-now": "Quizzing",
     "moderation-warning": "Moderation board with unreleased questions",
@@ -152,7 +154,7 @@
     "cancel": "Cancel",
     "continue": "Continue",
     "reset": "Reset",
-    "brainstorming-question": "Word cloud heading",
+    "brainstorming-question": "Heading of the brainstorming board",
     "tag-cloud-info": "The word cloud in »frag.jetzt« serves as a semantic filter: the larger the font, the more often the word was used grammatically in the questions or assigned as a keyword. The ratings of the questions also influence the font size.",
     "tag-cloud-questions-title": "Which questions should the topic cloud include?",
     "tag-cloud-questions-all": "All questions",
@@ -372,10 +374,10 @@
     "remove-successful": "Word removed"
   },
   "worker-config": {
-    "heading": "Analyze questions",
-    "label": "Choose an analysis mode",
-    "normal": "All questions",
-    "only-failed": "Questions not analyzed",
+    "heading": "Extract keywords",
+    "label": "Choose from which questions to extract keywords using Artificial Intelligence (see »Introduction« in the footer):",
+    "normal": "Reanalyze all questions in the room",
+    "only-failed": "Only questions that have not been analyzed",
     "continue": "Continue",
     "cancel": "Cancel"
   },
diff --git a/src/assets/i18n/participant/de.json b/src/assets/i18n/participant/de.json
index 1c90c168f7e3825942b0402f90e8facffcac759e..d95b0400dd922c3e8159acc9d943ff85a3b84423 100644
--- a/src/assets/i18n/participant/de.json
+++ b/src/assets/i18n/participant/de.json
@@ -161,8 +161,8 @@
     "show-less": "Weniger anzeigen ↑",
     "sure": "Bist du sicher?",
     "grammar-check": "Text prüfen",
-    "upvote": "positiv",
-    "downvote": "negativ"
+    "upvote": "positiv:",
+    "downvote": "negativ:"
   },
   "deepl": {
     "header": "Text prüfen",
@@ -178,11 +178,13 @@
     "more": "Formell"
   },
   "explanation": {
-    "label": "Warum?",
+    "label": "Erklärung",
     "close": "Schließen",
     "deepl": "## Text optimieren \n\nUm deine Frage optimal lesbar und verständlich zu präsentieren, lassen wir sie mit dem KI-Übersetzungsprogramm [DeepL](https://www.deepl.com/translator) ins Englische und zurück ins Deutsche übersetzen. \n\nDie Rückübersetzung ist in fast allen Fällen besser als das Original in Bezug auf Rechtschreibung, Grammatik, Interpunktion und Sprachstil.",
     "spacy": "## Stichwörter \n\nMittels NLP (Natural Language Processing) wird deine Frage grammatikalisch analysiert. Die erkannten Substantive werden in ihre Grundform gebracht, d. h. lemmatisiert, und dir als Stichwörter vorgeschlagen. Für die Textanalyse verwenden wir die freie NLP-Software [spaCy](https://spacy.io/). \n\nDie Stichwörter können verwendet werden, um die Liste der Fragen zu filtern oder um eine Wortwolke zu erstellen.",
-    "topic-cloud": "## Themen als Wortwolke \n\nUnsere **Themenwolke** visualisiert die Bedeutung der Stichwörter. \n\n  In die Berechnung der Schriftgröße gehen ein:\n\n* die Differenz zwischen Up- und Down-Votes, wenn sie positiv ist,\n* die Anzahl der Fragen mit diesem Stichwort,\n* die Anzahl der Fragesteller mit diesem Stichwort,\n* die Rolle des Fragenstellers: Raumersteller, Moderator oder Teilnehmer,\n* ob der Fragensteller eine Fragenkategorie ausgewählt hat,\n* ob das Stichwort generiert oder vom Fragensteller vergeben wurde,\n* ob die Frage vom Raumersteller oder einem Moderator beantwortet wurde.\n\nDie Themenwolke dient als **Navigator** zu allen Fragen zu einem Stichwort: Wenn du auf ein Wort in der Wolke klickst, gelangst du zu den Fragen mit diesem Stichwort."
+    "topic-cloud": "## Themen als Wortwolke \n\nUnsere **Themenwolke** visualisiert die Bedeutung der Stichwörter. \n\n  In die Berechnung der Schriftgröße gehen ein:\n\n* die Differenz zwischen Up- und Down-Votes, wenn sie positiv ist,\n* die Anzahl der Fragen mit diesem Stichwort,\n* die Anzahl der Fragensteller mit diesem Stichwort,\n* die Rolle des Fragenstellers: Raumersteller, Moderator oder Teilnehmer,\n* ob der Fragensteller eine Fragenkategorie ausgewählt hat,\n* ob das Stichwort generiert oder vom Fragensteller vergeben wurde,\n* ob die Frage vom Raumersteller oder einem Moderator beantwortet wurde.\n\nDie Themenwolke dient als **Navigator** zu allen Fragen zu einem Stichwort: Wenn du auf ein Wort in der Wolke klickst, gelangst du zu den Fragen mit diesem Stichwort.",
+    "user-bonus": "Die Lehrperson kann »gute« Fragen für einen Bonus markieren. Deine Fragen aus allen Kursen (Räumen), die einen Stern erhalten haben, werden hier aufgelistet.\n\nJe nach Vereinbarung kannst du den Token des Sterns per E-Mail an die Lehrperson schicken, um ihn gegen einen Bonus einzulösen.",
+    "bonus-archive": "Hier werden alle Fragen aufgelistet, die du in deinen Räumen mit einem Stern markiert hast. Anhand der Liste kannst du überprüfen, ob der Token, den dir ein Teilnehmer per Mail geschickt hat, gültig ist. \n\nUm einen Token schnell zu finden, gibt es ein Suchfeld. Ist der Token gültig, kannst du dir die entsprechende Frage direkt über einen Link anzeigen lassen."
   },
   "home-page": {
     "exactly-8": "Ein Raum-Code hat genau 8 Ziffern.",
@@ -321,7 +323,28 @@
     "question-count-plural": "Fragen",
     "edit-keyword-tip": "Neues Thema",
     "no-keywords-note": "Es gibt keine Themen.",
-    "consider-votes": "Bewertungen der Fragen berücksichtigen",
+    "keyword-scoring-header": "Bewertung der Stichwörter",
+    "keyword-scoring-header-info": "Einstellbare Multiplikatoren für die Gewichtung der Schlüsselwörter",
+    "keyword-scoring-countComments": "Anzahl Kommentare",
+    "keyword-scoring-countComments-info": "Anzahl der Kommentare, aus denen die Schlüsselwörter extrahiert wurden",
+    "keyword-scoring-countUsers": "Anzahl Fragensteller*innen",
+    "keyword-scoring-countUsers-info": "Anzahl exklusiver Fragensteller*innen, die dieses Schlüsselwort verwendet haben",
+    "keyword-scoring-countSelectedByQuestioner": "Anzahl verifiziert",
+    "keyword-scoring-countSelectedByQuestioner-info": "Anzahl der Verifizierungen eines Schlüsselworts durch einen Fragesteller*in",
+    "keyword-scoring-countKeywordByModerator": "Anzahl Schlüsselwörter von Moderatoren",
+    "keyword-scoring-countKeywordByModerator-info": "Anzahl der Verwendungen dieses Schlüsselworts durch Moderatoren",
+    "keyword-scoring-countKeywordByCreator": "Anzahl Schlüsselwörter vom Ersteller",
+    "keyword-scoring-countKeywordByCreator-info": "Anzahl der Verwendungen dieses Schlüsselworts durch den Ersteller",
+    "keyword-scoring-countCommentsAnswered": "Anzahl beantwortete Kommentare",
+    "keyword-scoring-countCommentsAnswered-info": "Anzahl der Kommentare, die dieses Stichwort enthalten und beantwortet wurden",
+    "keyword-scoring-summedUpvotes": "Anzahl aller Upvotes",
+    "keyword-scoring-summedUpvotes-info": "Anzahl aller Upvotes, die auf den Kommentaren mit diesem Schlüsselwort gemacht worden sind",
+    "keyword-scoring-summedDownvotes": "Anzahl aller Downvotes",
+    "keyword-scoring-summedDownvotes-info": "Anzahl aller Downvotes, die auf den Kommentaren mit diesem Schlüsselwort gemacht worden sind",
+    "keyword-scoring-summedVotes": "Summe aller Votes",
+    "keyword-scoring-summedVotes-info": "Summe aus den Up- und Downvotes, die auf den Kommentaren mit diesem Schlüsselwort gemacht worden sind",
+    "keyword-scoring-cappedSummedVotes": "Summe aller Votes (>= 0)",
+    "keyword-scoring-cappedSummedVotes-info": "(Siehe Summe aller Votes). Die Summe kann nicht unter null fallen und wird minimal 0",
     "profanity": "Vulgäre Wörter mit »***« überschreiben",
     "hide-blacklist-words": "Themen aus der Blacklist verbergen",
     "sort-alpha": "Alphabetisch",
@@ -352,7 +375,7 @@
     "keyword-counter": "Anzahl Themen",
     "sort": "Sortieren",
     "keyword-from-spacy": "Stichwort aus der Textanalyse",
-    "keyword-from-questioner": "Stichwort vom Fragesteller",
+    "keyword-from-questioner": "Stichwort vom Fragensteller",
     "Keyword-from-both": "Stichwort vom Fragensteller und aus der Textanalyse",
     "test-profanity": "Profanität testen",
     "word": "Wort",
diff --git a/src/assets/i18n/participant/en.json b/src/assets/i18n/participant/en.json
index 0e2924cd5bcd1060f41d977f14c5e99f83f55d3a..876f4dcee45448937ee31fb2b859ae5c285c65a4 100644
--- a/src/assets/i18n/participant/en.json
+++ b/src/assets/i18n/participant/en.json
@@ -170,8 +170,8 @@
     "show-less": "Show less ↑",
     "delete": "Delete question",
     "grammar-check": "Check text",
-    "upvote": "upvotes",
-    "downvote": "downvotes"
+    "upvote": "upvotes:",
+    "downvote": "downvotes:"
   },
   "deepl": {
     "header": "Check text",
@@ -191,7 +191,9 @@
     "close": "Close",
     "deepl": "## Text optimization\n\nTo make your question as readable and understandable as possible, we have it translated into German and back into English using the translation program [DeepL](https://www.deepl.com/translator).\n\nThe back translation is in almost all cases better than the original in terms of spelling, grammar, punctuation and language style.",
     "spacy": "## Text analysis\n\nUsing NLP (Natural Language Processing) your question will be analyzed grammatically. The recognized nouns are put into their basic form, i.e. lemmatized, and suggested to you as keywords. For the text analysis we use the free NLP software [spaCy](https://spacy.io/). \n\nThe keywords can be used to filter the list of questions or to create a word cloud.",
-    "topic-cloud": "## Topics as tags in a word cloud\n\nOur **topic cloud** visualizes the significance of the keywords. \n\n The calculation of the font size includes:\n\n* the difference between up- and down-votes, if it is positive\n* the number of questions with this keyword\n* the number of questioners with this keyword.\n* the role of the questioner: room creator, moderator or participant \n* whether the questioner has selected a question category\n* whether the keyword was generated or assigned by the question poser\n* whether the question was answered by the room creator or a moderator \n\n The topic cloud serves as a **navigator** to all questions related to a selected keyword: If you click on a word in the cloud, you will get to the questions related to this keyword."
+    "topic-cloud": "## Topics as tags in a word cloud\n\nOur **topic cloud** visualizes the significance of the keywords. \n\n The calculation of the font size includes:\n\n* the difference between up- and down-votes, if it is positive\n* the number of questions with this keyword\n* the number of questioners with this keyword.\n* the role of the questioner: room creator, moderator or participant \n* whether the questioner has selected a question category\n* whether the keyword was generated or assigned by the question poser\n* whether the question was answered by the room creator or a moderator \n\n The topic cloud serves as a **navigator** to all questions related to a selected keyword: If you click on a word in the cloud, you will get to the questions related to this keyword.",
+    "user-bonus": "The teacher can mark »good« questions for a bonus. Your questions from all courses (rooms) that have received a star will be listed here.\n\nDepending on the agreement, you can email the token of the star to the teacher to redeem it for a bonus.",
+    "bonus-archive": "All questions that you have marked with a star in your rooms are listed here. You can use the list to check whether the token that a participant sent you by mail is valid. \n\nTo find a token quickly, there is a search field. If the token is valid, you can display the corresponding question directly via a link."
   },
   "home-page": {
     "exactly-8": "A key is a combination of 8 digits.",
@@ -327,7 +329,28 @@
     "question-count-plural": "Questions",
     "edit-keyword-tip": "New topic",
     "no-keywords-note": "There are no topics.",
-    "consider-votes": "Consider Votes",
+    "keyword-scoring-header": "Keyword weighting",
+    "keyword-scoring-header-info": "Adjustable multipliers for the weighting of keywords",
+    "keyword-scoring-countComments": "Number of comments",
+    "keyword-scoring-countComments-info": "Number of comments from which the keywords have been extracted",
+    "keyword-scoring-countUsers": "Number of questioners",
+    "keyword-scoring-countUsers-info": "Number of exclusive questioners who used this keyword",
+    "keyword-scoring-countSelectedByQuestioner": "Number verified",
+    "keyword-scoring-countSelectedByQuestioner-info": "Number of times a keyword has been verified by a questioner",
+    "keyword-scoring-countKeywordByModerator": "Number of keywords from moderators",
+    "keyword-scoring-countKeywordByModerator-info": "Number of times this keyword has been used by moderators",
+    "keyword-scoring-countKeywordByCreator": "Number of keywords from creator",
+    "keyword-scoring-countKeywordByCreator-info": "Number of times this keyword has been used by the creator",
+    "keyword-scoring-countCommentsAnswered": "Number of answered comments",
+    "keyword-scoring-countCommentsAnswered-info": "Number of comments that have this keyword and have been answered",
+    "keyword-scoring-summedUpvotes": "Number of all upvotes",
+    "keyword-scoring-summedUpvotes-info": "Number of all upvotes made on the comments with this keyword",
+    "keyword-scoring-summedDownvotes": "Number of all downvotes",
+    "keyword-scoring-summedDownvotes-info": "Number of all downvotes made on the comments with this keyword",
+    "keyword-scoring-summedVotes": "Sum of all votes",
+    "keyword-scoring-summedVotes-info": "Sum of the upvotes and downvotes made on the comments with this keyword",
+    "keyword-scoring-cappedSummedVotes": "Sum of all votes (>= 0)",
+    "keyword-scoring-cappedSummedVotes-info": "(See the sum of all votes). The sum cannot fall below zero and becomes a minimum of 0",
     "profanity": "Censor profanity",
     "hide-blacklist-words": "Hide blacklist keywords",
     "sort-alpha": "Alphabetically",