diff --git a/jalhyd_branch b/jalhyd_branch
index 1f7391f92b6a3792204e07e99f71f643cc35e7e1..47cea457363c1be429e2baf6b5bfb8207cb69e13 100644
--- a/jalhyd_branch
+++ b/jalhyd_branch
@@ -1 +1 @@
-master
+261-pab-pouvoir-lier-et-varier-le-debit-d-attrait
diff --git a/src/app/components/ngparam-input/ngparam-input.component.ts b/src/app/components/ngparam-input/ngparam-input.component.ts
index 81db20827dce5fe36d9a3f1aab664f103cd9deaf..cbaf4e2fd445117c04738009b1dad2d200084530 100644
--- a/src/app/components/ngparam-input/ngparam-input.component.ts
+++ b/src/app/components/ngparam-input/ngparam-input.component.ts
@@ -1,6 +1,6 @@
 // cf. https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html
 
-import { Component, ChangeDetectorRef, OnDestroy } from "@angular/core";
+import { Component, ChangeDetectorRef, OnDestroy, Input, ElementRef } from "@angular/core";
 
 import { Message, Observer } from "jalhyd";
 
@@ -17,6 +17,10 @@ import { ApplicationSetupService } from "../../services/app-setup.service";
     ]
 })
 export class NgParamInputComponent extends GenericInputComponentDirective implements Observer, OnDestroy {
+
+    @Input()
+    public captureTabEvents: boolean;
+
     /**
      * paramètre géré
      */
@@ -33,9 +37,11 @@ export class NgParamInputComponent extends GenericInputComponentDirective implem
     constructor(
         intlService: I18nService,
         appSetupService: ApplicationSetupService,
-        cdRef: ChangeDetectorRef
+        cdRef: ChangeDetectorRef,
+        private element: ElementRef
     ) {
         super(cdRef, intlService, appSetupService);
+        this.captureTabEvents = true;
     }
 
     /**
@@ -114,6 +120,17 @@ export class NgParamInputComponent extends GenericInputComponentDirective implem
         }
     }
 
+    /**
+     * Renvoie l'événement au composant du dessus
+     */
+    public onTabPressed(event, shift: boolean) {
+        this.tabPressed.emit({ originalEvent: event, shift: shift });
+        // stop event propagation ?
+        if (this.captureTabEvents) {
+            return false;
+        } // else let it bubble !
+    }
+
     public ngOnDestroy() {
         this._paramDef.removeObserver(this);
     }
diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
index 5d9220b27bded151a062f9bdd91f1a6bfb813e72..449c050ffc94f34685a9aa280756ced6b9b051fc 100644
--- a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
+++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
@@ -12,6 +12,7 @@ import { AppComponent } from "../../app.component";
 import { CloisonAval, Cloisons, LoiDebit } from "jalhyd";
 
 import { sprintf } from "sprintf-js";
+import { CalculatorResults } from 'app/results/calculator-results';
 
 @Component({
     selector: "pab-profile-chart",
@@ -453,13 +454,14 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
      * @param n index of the variating parameter(s) iteration
      */
     private getLegendForSeries(n: number): string {
-        let i = 0;
+        /* let i = 0;
         return this.varValues.map((vv) => {
             const vp = this._results.variatedParameters[i];
             i++;
             let value = "0";
             value = vv[n];
-            return `${vp.param.symbol} = ${value}`;
-        }).join(", ");
+            return `${vp.symbol} = ${value}`;
+        }).join(", "); */
+        return CalculatorResults.variatingModalityLabel(this.varValues, this._results, n);
     }
 }
diff --git a/src/app/components/pab-table/pab-table.component.html b/src/app/components/pab-table/pab-table.component.html
index 96efe09a17616653a2c7ab330be912aa9af2cc1a..293bd1b077c9dde9b999c953e080508a8b516288 100644
--- a/src/app/components/pab-table/pab-table.component.html
+++ b/src/app/components/pab-table/pab-table.component.html
@@ -96,10 +96,19 @@
                         </mat-option>
                     </mat-select>
 
+                    <div *ngIf="isQA(cell)" class="qaFieldLineContainer">
+                        <div class="qaLabel">
+                            {{ cell.title }}
+                        </div>
+                        <param-field-line class="qaFieldLine" [param]="cell.model" (radio)="inputValueChanged($event, cell)"
+                            (input)="inputValueChanged($event, cell)" [captureTabEvents]="false">
+                        </param-field-line>
+                    </div>
+
                     <span *ngIf="! hasModel(cell)">{{ cellValue(cell) }}</span>
                 </td>
             </tr>
         </ng-template>
     </p-table>
 
-</mat-card-content>
\ No newline at end of file
+</mat-card-content>
diff --git a/src/app/components/pab-table/pab-table.component.scss b/src/app/components/pab-table/pab-table.component.scss
index abd5be33c92a9805a01f4605e3c0621dd8b48478..775e64397f7542fed4b014e0fd908095365b6cdb 100644
--- a/src/app/components/pab-table/pab-table.component.scss
+++ b/src/app/components/pab-table/pab-table.component.scss
@@ -36,10 +36,12 @@ mat-card-content {
     }
     .hyd-window-btns {
         text-align: right;
+        align-items: flex-end;
 
         #add-many-children {
             width: 3em;
             vertical-align: middle;
+            align-items: flex-start;
         }
 
         button.mat-icon-button {
@@ -47,3 +49,17 @@ mat-card-content {
         }
     }
 }
+
+.qaFieldLineContainer {
+    padding: 0 10px;
+    display: flex;
+    flex-wrap: wrap;
+    flex-direction: row;
+    justify-content:space-between;
+}
+
+.qaLabel {
+    margin-top: 13px;
+    font-weight: bold;
+}
+
diff --git a/src/app/components/pab-table/pab-table.component.ts b/src/app/components/pab-table/pab-table.component.ts
index b3c8934ecfc243a544c9a43a4aad2c119288d9b6..486789521a32d7efb0cf3e782f7f1be51bbf30ac 100644
--- a/src/app/components/pab-table/pab-table.component.ts
+++ b/src/app/components/pab-table/pab-table.component.ts
@@ -1,6 +1,6 @@
-import { Component, Input, Output, EventEmitter, OnInit, AfterViewInit } from "@angular/core";
+import { Component, Input, Output, EventEmitter, OnInit, AfterViewInit, AfterViewChecked } from "@angular/core";
 
-import { LoiDebit } from "jalhyd";
+import { LoiDebit, ParamValueMode } from "jalhyd";
 
 import { MatDialog } from "@angular/material/dialog";
 
@@ -27,6 +27,7 @@ import { NotificationsService } from "../../services/notifications.service";
 import { PabTable } from "../../formulaire/elements/pab-table";
 import { DialogEditPabComponent } from "../dialog-edit-pab/dialog-edit-pab.component";
 import { AppComponent } from "../../app.component";
+import { NgParameter, ParamRadioConfig } from "../../formulaire/elements/ngparam";
 
 /**
  * The big editable data grid for calculator type "Pab" (component)
@@ -38,7 +39,7 @@ import { AppComponent } from "../../app.component";
         "./pab-table.component.scss"
     ]
 })
-export class PabTableComponent implements AfterViewInit, OnInit {
+export class PabTableComponent implements AfterViewInit, AfterViewChecked, OnInit {
 
     @Input()
     private pabTable: PabTable;
@@ -85,6 +86,12 @@ export class PabTableComponent implements AfterViewInit, OnInit {
         this.selectedItems = [];
     }
 
+    /** update vary value from pab fish ladder and unable compute Button */
+  ngAfterViewChecked(): void {
+    this.updateValidity();
+  }
+
+
     public get title(): string {
         return this.i18nService.localizeText("INFO_PAB_TABLE");
     }
@@ -101,7 +108,7 @@ export class PabTableComponent implements AfterViewInit, OnInit {
 
     /** returns true if the cell is an editable number */
     public isNumberInput(cell: any): boolean {
-        return this.hasModel(cell) && ! this.isSelect(cell);
+        return this.hasModel(cell) && ! this.isSelect(cell) && ! this.isQA(cell);
     }
 
     /** returns true if the cell is a select box */
@@ -109,6 +116,11 @@ export class PabTableComponent implements AfterViewInit, OnInit {
         return this.hasModel(cell) && (cell.options !== undefined);
     }
 
+    /** returns true if the cell is a QA (Attraction flow) editor */
+    public isQA(cell: any): boolean {
+        return this.hasModel(cell) && cell.qa;
+    }
+
     /** value to display in a cell, if it is not editable */
     public cellValue(cell: any) {
         if (cell === undefined) {
@@ -166,8 +178,12 @@ export class PabTableComponent implements AfterViewInit, OnInit {
      */
     public isInvalid(cell: any): boolean {
         let valid = true;
-        if (this.hasModel(cell) && cell.model instanceof ParamDefinition) {
-            valid = valid && cell.model.isValid;
+        if (this.hasModel(cell)) {
+            if (cell.model instanceof ParamDefinition) {
+                valid = valid && cell.model.isValid;
+            } else if (cell.model instanceof NgParameter) { // for QA (currently has domain ANY but that might change)
+                valid = valid && cell.model.paramDefinition.isValid;
+            }
         }
         if (cell.uiValidity !== undefined) {
             valid = valid && cell.uiValidity;
@@ -443,7 +459,7 @@ export class PabTableComponent implements AfterViewInit, OnInit {
         const nDigits = this.appSetupService.displayPrecision;
         for (const c of this.model.children) {
             for (const p of c.parameterIterator) {
-                if (p.visible) {
+                if (p.visible && p.symbol !== "QA") { // QA might vary !
                     p.singleValue = round(p.singleValue, nDigits);
                 }
             }
@@ -461,7 +477,7 @@ export class PabTableComponent implements AfterViewInit, OnInit {
         bs = bs.concat(this.model.downWall);
         this.headers.push({
             title: this.i18nService.localizeText("INFO_PAB_BASSIN"),
-            colspan: 6,
+            colspan: 5,
             selectable: bs
         });
         // 1 header for each device of the wall having the most devices (including downwall)
@@ -476,7 +492,7 @@ export class PabTableComponent implements AfterViewInit, OnInit {
 
         // A. build columns set
         this.cols = [];
-        // 6 cols for basin
+        // 5 cols for basin
         this.cols.push({
             title: this.i18nService.localizeText("INFO_PAB_NUM_BASSIN"),
             selectable: bs
@@ -489,10 +505,6 @@ export class PabTableComponent implements AfterViewInit, OnInit {
             title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "BB"),
             selectable: bs
         });
-        this.cols.push({
-            title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "QA"),
-            selectable: bs
-        });
         this.cols.push({
             title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "ZRMB"),
             selectable: bs
@@ -523,16 +535,16 @@ export class PabTableComponent implements AfterViewInit, OnInit {
 
         // B. Build rows set
         this.rows = [];
+        // admissible LoiDebit (same for all cloisons)
+        const loisCloisons = this.model.children[0].getLoisAdmissiblesArray().map(l => {
+            return {
+                label: this.localizeLoiDebit(l),
+                value: l
+            };
+        });
         // B.1 many rows for each wall
         let childIndex = 0;
         for (const cloison of this.model.children) {
-            // admissible LoiDebit
-            const loisCloisons = cloison.getLoisAdmissiblesArray().map(l => { // @TODO move up ? (same for all cloisons)
-                return {
-                    label: this.localizeLoiDebit(l),
-                    value: l
-                };
-            });
             // as much rows as the greatest number of parameters among its devices
             const maxNbParams = this.findMaxNumberOfDeviceParameters(cloison);
             for (let i = 0; i < maxNbParams; i++) {
@@ -547,10 +559,10 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                         class: "basin_number",
                         selectable: cloison
                     });
-                    // 4 empty cells
+                    // 3 empty cells
                     deviceParamRow.cells.push({
-                        colspan: 4,
-                        rowspan: maxNbParams ,
+                        colspan: 3,
+                        rowspan: maxNbParams - 1,
                         selectable: cloison
                     });
                     // ZRAM
@@ -559,7 +571,22 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                         title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "ZRAM")
                     });
                 }
-                // 1 empty cell
+                // basin cells on the last but 1 row
+                if (i === maxNbParams - 1) {
+                    deviceParamRow.cells.push({
+                        model: cloison.prms.LB,
+                        title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "LB")
+                    });
+                    deviceParamRow.cells.push({
+                        model: cloison.prms.BB,
+                        title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "BB")
+                    });
+                    deviceParamRow.cells.push({
+                        model: cloison.prms.ZRMB,
+                        title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "ZRMB")
+                    });
+                }
+                // 1 empty cell below ZRAM
                 if (i === 1) {
                     deviceParamRow.cells.push({
                         rowspan: maxNbParams,
@@ -579,7 +606,7 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                             selectable: ouvrage
                         });
                     }
-                    // fill space
+                    // fill space below device type selector
                     if (i === 1) {
                         deviceParamRow.cells.push({
                             rowspan: (maxNbParams - 1),
@@ -626,37 +653,28 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                 // done !
                 this.rows.push(deviceParamRow);
             }
-            // 1 row for the basin after the wall
-            const basinRow: { selectable: any, cells: any[] } = {
-                selectable: cloison,
+            // 1 row for QA editor
+            const qaParam = new NgParameter(cloison.prms.QA, this.pabTable.form);
+            qaParam.radioConfig = ParamRadioConfig.VAR;
+            const qaRow: { selectable: any, cells: any[] } = {
+                selectable: undefined,
                 cells: [
-                    // no cell for basin number (defined by rowspan-n cell above)
-                    {
-                        model: cloison.prms.LB,
-                        title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "LB")
-                    },
                     {
-                        model: cloison.prms.BB,
-                        title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "BB")
-                    },
-                    {
-                        model: cloison.prms.QA,
+                        model: qaParam,
+                        colspan: 3,
+                        qa: true,
                         title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "QA")
-                    },
-                    {
-                        model: cloison.prms.ZRMB,
-                        title: this.formService.expandVariableNameAndUnit(CalculatorType.Pab, "ZRMB")
                     }
                 ]
             };
-            // fill horizontal space
-            for (let i = 0; i < maxNbDevices; i++) {
-                basinRow.cells.push({
-                    colspan: 3
-                });
-            }
+            // as many pairs of columns as the maximum number of devices
+            qaRow.cells.push({
+                colspan: maxNbDevices * 3,
+                // selectable: cloison @TODO oui ou non ?
+            });
             // done !
-            this.rows.push(basinRow);
+            this.rows.push(qaRow);
+
             childIndex ++;
         }
 
@@ -681,9 +699,9 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                     class: "basin_number",
                     selectable: this.model.downWall
                 });
-                // 4 empty cells
+                // 3 empty cells
                 deviceParamRowDW.cells.push({
-                    colspan: 4,
+                    colspan: 3,
                     rowspan: maxNbParamsDW ,
                     selectable: this.model.downWall
                 });
@@ -1033,8 +1051,10 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                 );
                 // copy parameter values
                 for (const p of si.prms) {
-                    newChild.getParameter(p.symbol).singleValue = p.singleValue;
+                    if (p.visible) {
+                        newChild.getParameter(p.symbol).loadObjectRepresentation(p.objectRepresentation());
                 }
+              }
                 // copy children
                 if (si instanceof ParallelStructure) {
                     for (const c of si.getChildren()) {
@@ -1218,7 +1238,8 @@ export class PabTableComponent implements AfterViewInit, OnInit {
             for (const av of availableVariables) {
                 for (const c of this.selectedItems) {
                     for (const p of c.parameterIterator) {
-                        if (p.visible && p.symbol === av.value) {
+                        // @TODO what todo when p varies (QA only) ?
+                        if (p.visible && p.symbol === av.value && ! p.hasMultipleValues) {
                             av.occurrences ++;
                             if (av.first === undefined) {
                                 av.first = p.singleValue;
@@ -1295,6 +1316,10 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                         case "set-value":
                             for (const s of this.selectedItems) {
                                 for (const p of s.parameterIterator) { // deep
+                                    // force single mode (QA only)
+                                    if (p.hasMultipleValues) {
+                                        p.valueMode = ParamValueMode.SINGLE;
+                                    }
                                     if (p.symbol === result.variable) {
                                         p.singleValue = result.value;
                                     }
@@ -1305,6 +1330,10 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                         case "delta":
                             for (const s of this.selectedItems) {
                                 for (const p of s.parameterIterator) { // deep
+                                    // force single mode (QA only)
+                                    if (p.hasMultipleValues) {
+                                        p.valueMode = ParamValueMode.SINGLE;
+                                    }
                                     if (p.symbol === result.variable) {
                                         p.singleValue += result.delta;
                                     }
@@ -1381,6 +1410,10 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                                     // for ZRMB, interpolatedValues length is shorter by 1 element
                                     if (interpolatedValues[idx] !== undefined) {
                                         for (const p of s.parameterIterator) { // deep
+                                            // force single mode (QA only)
+                                            if (p.hasMultipleValues) {
+                                                p.valueMode = ParamValueMode.SINGLE;
+                                            }
                                             if (p.symbol === result.variable) {
                                                 p.singleValue = interpolatedValues[idx];
                                                 idx ++;
@@ -1433,7 +1466,11 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                 const inputs = td.getElementsByTagName("input");
                 if (inputs.length > 0) {
                     const input = inputs[0];
-                    td.innerHTML = input.value;
+                    if (input.id.split("_")[1] === "QA") {
+                        td.innerHTML = NgParameter.preview(this.model.children[input.id.split("_")[0]].prms.QA);
+                    } else {
+                        td.innerHTML = input.value;
+                    }
                 }
             }
         }
diff --git a/src/app/components/param-field-line/param-field-line.component.html b/src/app/components/param-field-line/param-field-line.component.html
index 1143ac972b73bc22e3b3d8dad26e806443f92ff9..daad0ba4b73516eb51066cd77ed629066571ffe4 100644
--- a/src/app/components/param-field-line/param-field-line.component.html
+++ b/src/app/components/param-field-line/param-field-line.component.html
@@ -4,7 +4,7 @@
     <div fxFlex="1 0 120px">
         <!-- composant pour gérer le cas général (valeur numérique à saisir) -->
         <ngparam-input [title]="param.title" [hidden]="! isRadioFixChecked" (change)="onInputChange($event)"
-            (tabPressed)="onTabPressed($event)">
+            (tabPressed)="onTabPressed($event)" [captureTabEvents]="captureTabEvents">
         </ngparam-input>
 
         <!-- composant pour gérer le cas "paramètre calculé" -->
@@ -52,4 +52,4 @@
         </mat-button-toggle-group>
     </div>
 
-</div>
\ No newline at end of file
+</div>
diff --git a/src/app/components/param-field-line/param-field-line.component.scss b/src/app/components/param-field-line/param-field-line.component.scss
index 16c2b915393123bfb99d0342c04f8a4b15e3648d..4723ca17013a43f00f973db0024ea94a7acb8a56 100644
--- a/src/app/components/param-field-line/param-field-line.component.scss
+++ b/src/app/components/param-field-line/param-field-line.component.scss
@@ -6,3 +6,4 @@ mat-button-toggle-group {
     margin-top: 4px;
     box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
 }
+
diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts
index 22b7a92ad09a49c78ac0f54cb6ee01e44bc06fbc..f76d819c2cbf3fb3bbd01c5199a262eb0c3f69e4 100644
--- a/src/app/components/param-field-line/param-field-line.component.ts
+++ b/src/app/components/param-field-line/param-field-line.component.ts
@@ -4,7 +4,7 @@ import { I18nService } from "../../services/internationalisation.service";
 import { NgParameter, ParamRadioConfig } from "../../formulaire/elements/ngparam";
 import { NgParamInputComponent } from "../ngparam-input/ngparam-input.component";
 import { ServiceFactory } from "../../services/service-factory";
-import { ParamValueMode, ParallelStructure, ParamCalculability } from "jalhyd";
+import { ParamValueMode, ParallelStructure, ParamCalculability, Pab } from "jalhyd";
 import { FormulaireService } from "../../services/formulaire.service";
 import { ParamLinkComponent } from "../param-link/param-link.component";
 import { ParamValuesComponent } from "../param-values/param-values.component";
@@ -26,6 +26,7 @@ export class ParamFieldLineComponent implements OnChanges {
         this._formService = ServiceFactory.formulaireService;
         this.valid = new EventEmitter();
         this.inputChange = new EventEmitter();
+        this.captureTabEvents = true;
     }
 
     public get uitextParamFixe() {
@@ -86,6 +87,9 @@ export class ParamFieldLineComponent implements OnChanges {
     @Input()
     public param: NgParameter;
 
+    @Input()
+    public captureTabEvents: boolean;
+
     @ViewChild(NgParamInputComponent, { static: true })
     private _ngParamInputComponent: NgParamInputComponent;
 
@@ -173,7 +177,7 @@ export class ParamFieldLineComponent implements OnChanges {
                 return this._formService.getLinkableValues(this.param).length > 0;
             }
 
-            // ou un seul module de calcul "ouvrages parallèles"
+            // ou un seul module de calcul "ouvrages parallèles" avec au moins 2 ouvrages
             if (this._formService.formulaires[0].currentNub instanceof ParallelStructure) {
                 const ps: ParallelStructure = this._formService.formulaires[0].currentNub;
                 if (ps.structures.length > 1) {
@@ -181,6 +185,14 @@ export class ParamFieldLineComponent implements OnChanges {
                 }
             }
 
+            // ou un seul module de calcul "PAB" avec au mois 2 ouvrages
+            if (this._formService.formulaires[0].currentNub instanceof Pab) {
+                const pab: Pab = this._formService.formulaires[0].currentNub;
+                if (pab.children.length > 1) {
+                    return this._formService.getLinkableValues(this.param).length > 0;
+                }
+            }
+
         }
         return false;
     }
diff --git a/src/app/components/param-link/param-link.component.ts b/src/app/components/param-link/param-link.component.ts
index 058ed5a280a4b98a87df80aa0866caeba2799cb5..89255ef13580199816bf9f40f4a85a5ce31ea0e9 100644
--- a/src/app/components/param-link/param-link.component.ts
+++ b/src/app/components/param-link/param-link.component.ts
@@ -1,7 +1,7 @@
 import { Component, Input, Output, EventEmitter, OnChanges, OnDestroy } from "@angular/core";
 
 import { NgParameter } from "../../formulaire/elements/ngparam";
-import { LinkedValue, ParamValueMode, Observer, Structure, acSection, ParamDefinition, ChildNub } from "jalhyd";
+import { LinkedValue, ParamValueMode, Observer, acSection, ParamDefinition, ChildNub, Cloisons, Pab } from "jalhyd";
 import { FormulaireService } from "../../services/formulaire.service";
 import { I18nService } from "../../services/internationalisation.service";
 import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
@@ -169,7 +169,14 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy {
         }
 
         // 1. Paramètre / résultat d'un Nub enfant au sein d'un Nub parent
-        if (i.nub instanceof ChildNub) {
+        if (
+            (i.nub instanceof ChildNub)
+            || (
+                (i.nub instanceof Cloisons)
+                && i.nub.parent !== undefined
+                && (i.nub.parent instanceof Pab)
+            )
+        ) {
             let pos: number;
             pos = i.nub.findPositionInParent();
             return `${preview} - ` + sprintf(
diff --git a/src/app/components/variable-results-selector/variable-results-selector.component.ts b/src/app/components/variable-results-selector/variable-results-selector.component.ts
index 9f91c26b0b0a07218563491cabfb93847975a4bd..663f1f0e5215e8875c79aba15edf1d09db0a592c 100644
--- a/src/app/components/variable-results-selector/variable-results-selector.component.ts
+++ b/src/app/components/variable-results-selector/variable-results-selector.component.ts
@@ -4,8 +4,8 @@ import { I18nService } from "../../services/internationalisation.service";
 import { fv, longestVarParam } from "../../util";
 import { MultiDimensionResults } from "../../results/multidimension-results";
 import { PrebarrageResults } from "../../results/prebarrage-results";
-
 import { CalculatorType, PbBassin, PbCloison, Structure, VariatedDetails } from "jalhyd";
+import { CalculatorResults } from "../../results/calculator-results";
 
 @Component({
     selector: "variable-results-selector",
@@ -81,46 +81,7 @@ export class VariableResultsSelectorComponent implements OnChanges {
     }
 
     protected entryLabel(index: number): string {
-        const kv = [];
-        for (let i = 0; i < this.varValues.length; i++) {
-            const vv = this.varValues[i];
-            const vp = this.results.variatedParameters[i];
-            let symbol = vp.param.symbol;
-            // is vp a parameter of a child Nub ?
-            if (
-                vp.param.parentNub
-                && vp.param.parentNub !== vp.param.originNub
-            ) {
-                let childPrefix: string;
-                // prefix the label depending on (grand)children type
-                switch (vp.param.originNub.calcType) {
-                    case CalculatorType.PreBarrage:
-                        const pbRes = this.results as PrebarrageResults;
-                        if (vp.param.parentNub instanceof Structure) {
-                            const struct = vp.param.parentNub as Structure;
-                            const wall = struct.parent as PbCloison;
-                            const posS = struct.findPositionInParent() + 1;
-                            childPrefix = this.intlService.localizeMessage(wall.description);
-                            // there might be multiple walls between the same pair of basins
-                            if (wall.uid in pbRes.wallsSuffixes) {
-                                childPrefix += " (" + pbRes.wallsSuffixes[wall.uid] + ")";
-                            }
-                            childPrefix += "_" + this.intlService.localizeText("INFO_LIB_STRUCTURE_N_COURT") + posS;
-                        } else if (vp.param.parentNub instanceof PbBassin) {
-                            const bassin = vp.param.parentNub as PbBassin;
-                            childPrefix = this.intlService.localizeMessage(bassin.description);
-                        }
-                        break;
-                    case CalculatorType.MacroRugoCompound:
-                        const posMR = vp.param.parentNub.findPositionInParent() + 1;
-                        childPrefix = this.intlService.localizeText("INFO_LIB_RADIER_N_COURT") + posMR;
-                        break;
-                }
-                symbol = childPrefix + "_" + symbol;
-            }
-            kv.push(`${symbol} = ${vv[index]}`);
-        }
-        return kv.join(", ");
+        return CalculatorResults.variatingModalityLabel(this.varValues, this.results, index);
     }
 
     public get selectedValue(): number {
diff --git a/src/app/formulaire/definition/form-pab.ts b/src/app/formulaire/definition/form-pab.ts
index d88ae78269c05b9aa8139f04b24d951bc98ecbae..af9b7f56d9ea67134a0d682678477961df20f646 100644
--- a/src/app/formulaire/definition/form-pab.ts
+++ b/src/app/formulaire/definition/form-pab.ts
@@ -2,7 +2,7 @@ import { Pab, Result, VariatedDetails } from "jalhyd";
 
 import { FormulaireDefinition } from "./form-definition";
 import { PabResults } from "../../results/pab-results";
-import { NgParameter } from "../elements/ngparam";
+import { NgParameter, ParamRadioConfig } from "../elements/ngparam";
 import { longestVarParam } from "../../util";
 import { CalculatorResults } from "../../results/calculator-results";
 
diff --git a/src/app/results/calculator-results.ts b/src/app/results/calculator-results.ts
index f573b6c99c7585784791e58f964736e606eb22ba..a205ceddd259c84ec09bd3ee34ed2e78b6f7252e 100644
--- a/src/app/results/calculator-results.ts
+++ b/src/app/results/calculator-results.ts
@@ -1,9 +1,11 @@
-import { Nub, capitalize } from "jalhyd";
+import { CalculatorType, Nub, capitalize, MacrorugoCompound, Pab, Structure, PbCloison, PbBassin } from "jalhyd";
 
 import { NgParameter } from "../formulaire/elements/ngparam";
 import { ServiceFactory } from "../services/service-factory";
 
 import { sprintf } from "sprintf-js";
+import { MultiDimensionResults } from "./multidimension-results";
+import { PrebarrageResults } from "./prebarrage-results";
 
 export abstract class CalculatorResults {
 
@@ -45,6 +47,61 @@ export abstract class CalculatorResults {
         return res;
     }
 
+    /**
+     * Returns a label showing the boundary conditions values of all variating parameters,
+     * for the given iteration
+     * @param varvalues array of values: one element per variating parameter, itself an array of
+     *     values, one per iteration
+     * @param variatedParameters array of variating parameters, in the same order as varvalues
+     * @param n index of the variating parameter(s) iteration
+     */
+    public static variatingModalityLabel(varValues: any[], results: MultiDimensionResults, index: number): string {
+        const kv = [];
+        for (let i = 0; i < varValues.length; i++) {
+            const vv = varValues[i];
+            const vp = results.variatedParameters[i];
+            let symbol = vp.param.symbol;
+            // is vp a parameter of a child Nub ?
+            if (
+                vp.param.parentNub
+                && vp.param.parentNub !== vp.param.originNub
+            ) {
+                let childPrefix: string;
+                // prefix the label depending on (grand)children type
+                switch (vp.param.originNub.calcType) {
+                    case CalculatorType.PreBarrage:
+                        const pbRes = results as PrebarrageResults;
+                        if (vp.param.parentNub instanceof Structure) {
+                            const struct = vp.param.parentNub as Structure;
+                            const wall = struct.parent as PbCloison;
+                            const posS = struct.findPositionInParent() + 1;
+                            childPrefix = ServiceFactory.i18nService.localizeMessage(wall.description);
+                            // there might be multiple walls between the same pair of basins
+                            if (wall.uid in pbRes.wallsSuffixes) {
+                                childPrefix += " (" + pbRes.wallsSuffixes[wall.uid] + ")";
+                            }
+                            childPrefix += "_" + ServiceFactory.i18nService.localizeText("INFO_LIB_STRUCTURE_N_COURT") + posS;
+                        } else if (vp.param.parentNub instanceof PbBassin) {
+                            const bassin = vp.param.parentNub as PbBassin;
+                            childPrefix = ServiceFactory.i18nService.localizeMessage(bassin.description);
+                        }
+                        break;
+                    case CalculatorType.MacroRugoCompound:
+                        const posMR = vp.param.parentNub.findPositionInParent() + 1;
+                        childPrefix = ServiceFactory.i18nService.localizeText("INFO_LIB_RADIER_N_COURT") + posMR;
+                        break;
+                    case CalculatorType.Pab:
+                        const posPAB = vp.param.parentNub.findPositionInParent() + 1;
+                        childPrefix = ServiceFactory.i18nService.localizeText("INFO_LIB_CLOISON_N_COURT") + posPAB;
+                        break;
+                }
+                symbol = childPrefix + "_" + symbol;
+            }
+            kv.push(`${symbol} = ${vv[index]}`);
+        }
+        return kv.join(", ");
+    }
+
     /**
      * remet tous les résultats à zero
      */
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index b21bd2204fe17d48f765121b1f8c93199f288531..94d4434ca1cfaee8579877855884f47302b02989 100755
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -285,6 +285,7 @@
     "INFO_LIB_CDT": "Discharge coefficient triangular weir",
     "INFO_LIB_CDO": "Discharge coefficient orifice",
     "INFO_LIB_CLOISON": "Cross wall #",
+    "INFO_LIB_CLOISON_N_COURT": "W",
     "INFO_LIB_COTE": "Elevation (m)",
     "INFO_LIB_COTE_VANNE_LEVANTE": "Lift gate elevation",
     "INFO_LIB_CV": "Cv: Velocity coefficient",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 5169ac6aeb341c19fcea66666e9101a3425cd8bc..6e487527a3f6a9a6e897c53855ef36410d77c039 100755
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -286,6 +286,7 @@
     "INFO_LIB_CDT": "Coefficient de débit seuil triangulaire",
     "INFO_LIB_CDO": "Coefficient de débit orifice",
     "INFO_LIB_CLOISON": "Cloison n°",
+    "INFO_LIB_CLOISON_N_COURT": "C",
     "INFO_LIB_COTE": "Cote (m)",
     "INFO_LIB_COTE_VANNE_LEVANTE": "Cote vanne levante",
     "INFO_LIB_CV": "Cv&nbsp;: Coefficient de vitesse d'approche",
diff --git a/src/styles.scss b/src/styles.scss
index 4f086079ecf28da2a005d9c00a31a5a3c3b2f211..87774a115ad792fd74586403d54677cda31c5e95 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -129,15 +129,64 @@ field-set {
         .mat-select-value, .mat-select-arrow {
             color: #fff;
         }
-        
+
         .mat-form-field-infix {
             border-bottom: 2px solid #fff;
         }
     }
 }
 
+.qaFieldLineContainer {
+
+    .qaFieldLine {
+        .mat-button-toggle-label-content {
+            line-height: 24px !important;
+        }
+    }
+
+    ngparam-input {
+        height: 38px;
+        margin-top: 0;
+    }
+
+    param-values {
+        margin-top: 0;
+    }
+
+    param-link {
+        margin-top: 0;
+
+        .status-icons-container {
+            display: none;
+        }
+    }
+
+    mat-form-field {
+
+        .mat-form-field-wrapper {
+            padding-bottom: 5px;
+        }
+
+        input.form-control.mat-input-element {
+            width: 100%;
+        }
+
+        button.param-values-more {
+            display: none;
+        }
+
+        .mat-form-field-underline {
+            display: none;
+        }
+
+        mat-error.mat-error {
+            display: none;
+        }
+    }
+}
+
 .pab-data-table {
-    
+
     .editable-cell-bg {
         @extend .bg-accent-extralight;
     }
@@ -222,7 +271,7 @@ field-set {
                         > input[type="number"] {
                             -moz-appearance: textfield;
                         }
-                        input[type=number]::-webkit-outer-spin-button, 
+                        input[type=number]::-webkit-outer-spin-button,
                         input[type=number]::-webkit-inner-spin-button {
                             -webkit-appearance: none;
                             margin: 0;
@@ -248,7 +297,7 @@ mat-checkbox.wrapped-checkbox {
 param-computed, param-values {
 
     mat-form-field {
-    
+
         input.mat-input-element {
             width: calc(100% - 40px);
             text-overflow: ellipsis;
@@ -304,7 +353,7 @@ mat-list {
         > .mat-list-item {
             height: auto;
             margin-bottom: .5em;
-    
+
             > .mat-list-item-content {
                 align-items: start;
 
@@ -317,7 +366,7 @@ mat-list {
 }
 
 table.mat-table {
-    
+
     .material-icons {
         font-size: 1.4em;
         vertical-align: bottom;