diff --git a/.gitignore b/.gitignore
index 32421de853e3cedece91cd22372d33bc5bf2284f..78a09cc0fddf6a5df8b83f762a55c96a25f888bd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,11 +5,8 @@
 /tmp
 /out-tsc
 /src/assets/docs
-/compodoc-fr
-/docs/fr/pdf
-/docs/en/pdf
 /release
-docs/pdf_build
+/build
 
 # dependencies
 /node_modules
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a56bc3b8c5babe3aed662a852a7452e831becec2..0364a248cc7a8396b5457b83c11a14d78cde3f57 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
 # Historique des versions
 
+### 4.16.3 - 2023-01-11
+
+#### Correction de bogues
+
+* Lechapt et Calmon : erreur de sélection de matériau
+([jalhyd#337](https://gitlab.irstea.fr/cassiopee/jalhyd/-/issues/337), [nghyd#589](https://gitlab.irstea.fr/cassiopee/nghyd/-/issues/589))
+
 ### 4.16.1 - 2022-11-16
 
 #### Correction de bogues
diff --git a/docs/latex/cassiopee_doc_en.tex b/docs/latex/cassiopee_doc_en.tex
index 66d99b1dc9aeb5f7d29e838e8b3ca316cf4ae15c..7f86d9a6b60419d05a409e67eaf47f3b55dd61b6 100644
--- a/docs/latex/cassiopee_doc_en.tex
+++ b/docs/latex/cassiopee_doc_en.tex
@@ -13,15 +13,16 @@
 % Insertion des différents préambules au document
 \input{rapport/english/preambule_rapport_english}
 \input{rapport_inrae/preambule_inrae}
-
+% Cassiopée version in the form \newcommand{\cassiopeeversion}{x.y.z}
+\input{cassiopee_version}
 
 %*******************************************************************************
 %Données de titre et d'auteur pour la page de garde, les entêtes et pieds de page
 %*******************************************************************************
 % Le titre doit être relativement court mais assez explicite
 \newcommand{\service}{UMR G-EAU}
-\newcommand{\titre}{Cassiopée 4 software}
-\newcommand{\sousTitre}{User documentation}
+\newcommand{\titre}{Cassiopée software}
+\newcommand{\sousTitre}{version \cassiopeeversion\\User documentation}
 %Statut du document [rapport final, rapport intermédiaire]
 % auteur intellectuel, rédacteur du document, il peut y avoir plusieurs auteurs ; chaque auteur est renseigné sous la forme « Prénom NOM »
 \newcommand{\auteur}{David DORCHIES, Mathias CHOUET, François GRAND}
diff --git a/docs/latex/cassiopee_doc_fr.tex b/docs/latex/cassiopee_doc_fr.tex
index ca5a85f9a344642ade7dbc5d6bc2a65ba95a3ad9..3360b058313a441e29f778790ae30aac12ad9abc 100644
--- a/docs/latex/cassiopee_doc_fr.tex
+++ b/docs/latex/cassiopee_doc_fr.tex
@@ -13,15 +13,16 @@
 % Insertion des différents préambules au document
 \input{rapport/francais/preambule_rapport_francais}
 \input{rapport_inrae/preambule_inrae}
-
+% version de Cassiopée sous la forme \newcommand{\cassiopeeversion}{x.y.z}
+\input{cassiopee_version}
 
 %*******************************************************************************
 %Données de titre et d'auteur pour la page de garde, les entêtes et pieds de page
 %*******************************************************************************
 % Le titre doit être relativement court mais assez explicite
 \newcommand{\service}{UMR G-EAU}
-\newcommand{\titre}{Logiciel Cassiopée 4}
-\newcommand{\sousTitre}{Documentation utilisateur}
+\newcommand{\titre}{Logiciel Cassiopée}
+\newcommand{\sousTitre}{version \cassiopeeversion\\Documentation utilisateur}
 %Statut du document [rapport final, rapport intermédiaire]
 % auteur intellectuel, rédacteur du document, il peut y avoir plusieurs auteurs ; chaque auteur est renseigné sous la forme « Prénom NOM »
 \newcommand{\auteur}{David DORCHIES, Mathias CHOUET, François GRAND}
diff --git a/e2e/lechapt-calmon.e2e-spec.ts b/e2e/lechapt-calmon.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f0b991c6dc52504a8c725ef68306d2a1cc09b229
--- /dev/null
+++ b/e2e/lechapt-calmon.e2e-spec.ts
@@ -0,0 +1,74 @@
+import { ListPage } from "./list.po";
+import { browser, by } from "protractor";
+import { CalculatorPage } from "./calculator.po";
+import { PreferencesPage } from "./preferences.po";
+import { Navbar } from "./navbar.po";
+
+/**
+ * Check that created/cloned structures have empty fields when
+ * "empty fields on calculator creation" is enabled
+ */
+describe("Lechapt&Calmon - ", () => {
+    let prefPage: PreferencesPage;
+    let listPage: ListPage;
+    let calcPage: CalculatorPage;
+    let navBar: Navbar;
+
+    beforeAll(() => {
+        prefPage = new PreferencesPage();
+        listPage = new ListPage();
+        calcPage = new CalculatorPage();
+        navBar = new Navbar();
+        browser.manage().window().setPosition(2000, 30);
+    });
+
+    beforeEach(async () => {
+        // disable evil option "empty fields on module creation"
+        await prefPage.navigateTo();
+        await browser.sleep(200);
+        await prefPage.disableEvilEmptyFields();
+        await browser.sleep(200);
+    });
+
+    async function setup() {
+        // start page
+        await navBar.clickNewCalculatorButton();
+        await browser.sleep(200);
+
+        // open Lechapt-Calmon calculator
+        await listPage.clickMenuEntryForCalcType(1);
+        await browser.sleep(200);
+    }
+
+    it("when material is modified, results should change", async () => {
+        await setup();
+
+        // select last material type
+        const materialSelect = calcPage.getSelectById("select_material");
+        await calcPage.changeSelectValue(materialSelect, 8);
+        await browser.sleep(200);
+
+        // run calculation
+        const calcButton = calcPage.getCalculateButton();
+        await calcButton.click();
+        await browser.sleep(200);
+
+        // store total pressure loss result
+        const res1 = calcPage.getAllFixedResultsRows().get(4);
+        const pl1 = await res1.all(by.css("td")).get(1).getText();
+
+        // select first material type
+        await calcPage.changeSelectValue(materialSelect, 0);
+        await browser.sleep(200);
+
+        // run calculation
+        await calcButton.click();
+        await browser.sleep(200);
+
+        // compare total pressure loss result with first calculaiotn
+        const res2 = calcPage.getAllFixedResultsRows().get(4);
+        const pl2 = await res2.all(by.css("td")).get(1).getText();
+
+        expect(pl1).not.toEqual(pl2);
+    });
+});
diff --git a/mkdocs-en.yml b/mkdocs/mkdocs-en.yml
similarity index 100%
rename from mkdocs-en.yml
rename to mkdocs/mkdocs-en.yml
diff --git a/mkdocs-fr.yml b/mkdocs/mkdocs-fr.yml
similarity index 100%
rename from mkdocs-fr.yml
rename to mkdocs/mkdocs-fr.yml
diff --git a/package-lock.json b/package-lock.json
index e2a3561486f5c49882076688cfdece8dbf9da6b6..9661a8c876a23a46f8118a8d679270b97149b3f7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "fr.irstea.cassiopee",
-  "version": "4.16.1",
+  "version": "4.16.3",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "fr.irstea.cassiopee",
-      "version": "4.16.1",
+      "version": "4.16.3",
       "hasInstallScript": true,
       "license": "MIT",
       "dependencies": {
@@ -80,7 +80,7 @@
       }
     },
     "jalhyd": {
-      "version": "4.16.1",
+      "version": "4.16.3",
       "license": "LGPL-3.0-or-later",
       "dependencies": {
         "@types/base-64": "^1.0.0",
diff --git a/package.json b/package.json
index e13bbb080a559fc297fb8a1f39213574cc934117..1a21cb21d20dcf170515f86947fc56fa2eb1a9a3 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
   "displayName": "Cassiopée",
   "description": "Hydraulic calculators",
   "author": "Inrae",
-  "version": "4.16.1",
+  "version": "4.16.3",
   "main": "main.js",
   "homepage": "https://cassiopee.g-eau.fr",
   "license": "MIT",
@@ -14,12 +14,13 @@
     "e2e": "npm run preprocess && node scripts/check-translations.js && npm run ng -- e2e --suite=regular --webdriver-update=false",
     "e2equick": "node scripts/check-translations.js && npm run ng -- e2e --dev-server-target= --suite=regular --webdriver-update=false",
     "monkeytest": "npm run ng -- e2e --dev-server-target= --suite=monkeyTest --webdriver-update=false",
-    "mkdocs": "node scripts/python3.js -m mkdocs build -f mkdocs-fr.yml && node scripts/python3.js -m mkdocs build -f mkdocs-en.yml && node scripts/mkdocs-postprocess.js",
-    "mkdocs2pdf": "node scripts/python3.js mkdocs2pdf.py",
-    "preprocess": "node scripts/preprocessors.js && npm run mkdocs",
-    "start": "npm run preprocess && npm run ng serve -- --host 0.0.0.0 --poll 5000",
-    "build-no-pdf": "npm run preprocess && npm run ng build -- --configuration production",
-    "build": "npm run preprocess && npm run mkdocs2pdf && npm run ng build -- --configuration production",
+    "mkdocs": "bash scripts/prepare_mkdocs.sh; cd build; python3 -m mkdocs build -f mkdocs-fr.yml && python3 -m mkdocs build -f mkdocs-en.yml && cd .. && node scripts/mkdocs-postprocess.js",
+    "mkdocs2pdf": "node scripts/extract-nghyd-version.js build/cassiopee_version.tex && python3 scripts/mkdocs2pdf.py && node scripts/mkdocs2pdf-postprocess.js",
+    "clean": "rm -rf build dist release src/date_revision.ts src/assets/docs",
+    "preprocess": "mkdir -p build; node scripts/preprocessors.js",
+    "start": "npm run preprocess && npm run mkdocs && npm run ng serve -- --host 0.0.0.0 --poll 5000",
+    "build-no-pdf": "npm run preprocess && npm run mkdocs && npm run ng build -- --configuration production",
+    "build": "npm run preprocess && npm run mkdocs && npm run ng build -- --configuration production && npm run mkdocs2pdf",
     "update-dist-index-mimetypes": "node scripts/update-dist-index-mimetypes.js",
     "electron": "npm run update-dist-index-mimetypes && \"node_modules/.bin/electron\" .",
     "release-linux-nocompile": "npm run update-dist-index-mimetypes && \"node_modules/.bin/electron-builder\"",
diff --git a/scripts/extract-nghyd-version.js b/scripts/extract-nghyd-version.js
new file mode 100644
index 0000000000000000000000000000000000000000..aff3a3dd01a1b015880534983b5f0bdac5895b12
--- /dev/null
+++ b/scripts/extract-nghyd-version.js
@@ -0,0 +1,65 @@
+/*
+ * extract Cassiopée version from package.json and write files according to provided paths extension :
+ * - a LateX file defining a variable in the form \newcommand\{\cassiopeeversion}{x.y.z} for path(s) with .tex extension
+ * - a plain text file with version value (x.y.z) for path(s) without extension
+ */
+
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+
+if (process.argv.length < 3) {
+    console.error("ERROR : missing output file path(s)\n");
+    console.error("syntax : extract-nghyd-version <path> [<path> ...]");
+    console.error("  extract ngHyd current version to given files according to extension");
+    console.error("  available extensions : .tex (LateX file with variable), <none (plain version in text file)>");
+    process.exit(1);
+}
+
+function createMissingDirs(p) {
+    const targetDir = path.dirname(p);
+    if (!fs.existsSync(targetDir)) {
+        console.log("creating output directory", targetDir)
+        fs.mkdirSync(targetDir, { recursive: true });
+    }
+}
+
+function writeTex(outPath, ver) {
+    // make LateX variable
+    const s = `\\newcommand\{\\cassiopeeversion\}\{${ver}\}`;
+
+    // create intermediate folders if necessary
+    createMissingDirs(outPath)
+
+    // write file
+    console.log("writing LateX file", outPath);
+    fs.writeFileSync(outPath, s);
+}
+
+function writePlain(outPath, ver) {
+    // create intermediate folders if necessary
+    createMissingDirs(outPath)
+
+    // write file
+    console.log("writing plain file", outPath);
+    fs.writeFileSync(outPath, ver);
+}
+
+// read package.json
+console.log("reading package.json");
+var fdata = fs.readFileSync('package.json', 'utf8');
+var data = JSON.parse(fdata)
+
+// get Cassiopée version
+const ver = data.version
+console.log("got ngHyd version", ver);
+
+for (let i = 2; i < process.argv.length; i++) {
+    const p = process.argv[i];
+    if (p.endsWith(".tex")) {
+        writeTex(p, ver);
+    } else {
+        writePlain(p, ver);
+    }
+}
diff --git a/scripts/mkdocs-postprocess.js b/scripts/mkdocs-postprocess.js
index 61d0abe11e823477c9cbe239a6ddc8c7f60ac110..558e8300fe0d45f43ee54530b3a9208fb2725d07 100644
--- a/scripts/mkdocs-postprocess.js
+++ b/scripts/mkdocs-postprocess.js
@@ -52,6 +52,3 @@ fs.copySync("docs/matomo-tracking.js", destPath_EN_JS + "/matomo-tracking.js");
 fs.copySync("node_modules/mermaid/dist/mermaid.min.js", destPath_JS + "/mermaid.min.js");
 fs.copySync("node_modules/mermaid/dist/mermaid.min.js", destPath_FR_JS + "/mermaid.min.js");
 fs.copySync("node_modules/mermaid/dist/mermaid.min.js", destPath_EN_JS + "/mermaid.min.js");
-
-// copy illustrated guide (not related to MkDocs, but still a part of the doc)
-fs.copySync("docs/cassiopee_notice_illustree_fr.pdf", "src/assets/docs/pdf/cassiopee_notice_illustree_fr.pdf");
diff --git a/scripts/mkdocs2pdf-postprocess.js b/scripts/mkdocs2pdf-postprocess.js
new file mode 100644
index 0000000000000000000000000000000000000000..0752898f8f37391cbaced681ebda9bea5bcd3261
--- /dev/null
+++ b/scripts/mkdocs2pdf-postprocess.js
@@ -0,0 +1,13 @@
+'use strict';
+
+/*
+ * mkdocs2pdf post processing.
+ * - copy illustrated guide (not related to MkDocs, but still a part of the doc) to dist/assets/docs/pdf
+ */
+
+const fs = require('fs-extra');
+
+const destPath_PDF = "dist/assets/docs/pdf"; // pour la doc illustrée
+
+fs.ensureDirSync(destPath_PDF);
+fs.copySync("docs/cassiopee_notice_illustree_fr.pdf", destPath_PDF + "/cassiopee_notice_illustree_fr.pdf");
diff --git a/mkdocs2pdf.py b/scripts/mkdocs2pdf.py
similarity index 75%
rename from mkdocs2pdf.py
rename to scripts/mkdocs2pdf.py
index c83f54033c7e7552d95cde47f9be82610c89d94b..6e3cf68040aa15e43debd48019a955e3e13d9b2a 100644
--- a/mkdocs2pdf.py
+++ b/scripts/mkdocs2pdf.py
@@ -20,19 +20,24 @@ import yaml
 import re
 import shutil
 
-baseDir = os.getcwd();
-
-buildDir = os.path.join(baseDir, 'docs/pdf_build')
-outputDir = os.path.join(baseDir, 'src/assets/docs/pdf')
+baseDir = os.getcwd()
+buildDir = os.path.join(baseDir, 'build')
+latexSourceDir = os.path.join(baseDir, 'docs/latex')
+pdfBuildDir = os.path.join(buildDir, 'pdf_build')
+outputDir = os.path.join(baseDir, 'dist/assets/docs/pdf')
 
 latexModelDir = 'latex_models'
-modelDir = os.path.join(buildDir, latexModelDir)
+modelDir = os.path.join(pdfBuildDir, latexModelDir)
 
 mergedDocFilenamePrefix = 'cassiopee_doc_contents_'
 filenamePrefix = 'cassiopee_doc_'
 
 latexModelRepository = 'https://gitlab.irstea.fr/david.dorchies/latex_models.git'
 
+def runCommand(cmd):
+    if os.waitstatus_to_exitcode(os.system(cmd)) != 0:
+        raise RuntimeError("error executing:",cmd)
+
 # Reads an MkDocs configuration file
 def readConfig(sYAML):
     f = open(sYAML, 'r')
@@ -71,7 +76,7 @@ def exploreAndMerge(docs_dir, nav, output = '', level = 0):
             filepath = os.path.join(docs_dir, d)
             f = open(filepath, 'r')
             # Triple "../" because file will be compiled from pdf_build/latex_models
-            path = os.path.join('../../..', os.path.dirname(filepath))
+            path = os.path.join(baseDir, os.path.dirname(filepath))
             s = f.read() + "\n"
             # Modification of image and links paths
             s = re.sub(r'(\!\[.+\]\()(.+)(\))', r'\1'+path+r'/\2\3', s)
@@ -93,7 +98,7 @@ def exploreAndMerge(docs_dir, nav, output = '', level = 0):
 # Creates a filePath.tex LaTeX contents file based on filePath.md
 def convertMdToTex(filePath):
     # Convert .md to .tex
-    os.system(
+    runCommand(
         'pandoc {0}.md -f markdown -t latex -s -o {0}.tex'.format(filePath)
     )
     # Remove header of tex file
@@ -124,8 +129,8 @@ def convertMdToTex(filePath):
 
 def getLatexModel():
     # Clone Git repository
-    os.chdir(buildDir)
-    os.system(
+    os.chdir(pdfBuildDir)
+    runCommand(
         'git clone {} {}'.format(latexModelRepository, latexModelDir)
     )
     # back to original working drectory
@@ -141,22 +146,34 @@ def injectContentIntoModel(mergedDocFilenameTex, lang):
     # Symlink necessary resources
     os.chdir(modelDir)
     relPathToMergedTexDoc = os.path.join('..', mergedDocFilenameTex)
-    os.system(
+    runCommand(
         'ln -s {} .'.format(relPathToMergedTexDoc)
     )
-    latexTemplate = 'cassiopee_doc_' + lang + '.tex'
-    relPathToLatexTemplate = os.path.join('../../latex', latexTemplate)
-    os.system(
-        'ln -s {} .'.format(relPathToLatexTemplate)
+    latexTemplate = filenamePrefix + lang + '.tex'
+    relPathToLatexTemplate = os.path.join(latexSourceDir, latexTemplate)
+    runCommand(
+        'ln -s {}'.format(relPathToLatexTemplate)
     )
-    os.system(
-        'ln -s ../../latex/logo_pole.png .'
+    runCommand(
+        'ln -s {}'.format(os.path.join(latexSourceDir, 'logo_pole.png'))
     )
-    os.system(
+    runCommand(
+        'ln -s {}/schema_rugosite_fond.png'.format(os.path.join(baseDir, 'docs', lang, 'calculators', 'pam'))
+    )
+    runCommand(
+        'ln -s {}/bloc_cylindre.png'.format(os.path.join(baseDir, 'docs', lang, 'calculators', 'pam'))
+    )
+    runCommand(
+        'ln -s {}/bloc_face_arrondie.png'.format(os.path.join(baseDir, 'docs', lang, 'calculators', 'pam'))
+    )
+    runCommand(
+        'ln -s {}/bloc_base_carree.png'.format(os.path.join(baseDir, 'docs', lang, 'calculators', 'pam'))
+    )
+    runCommand(
         'rm rapport_inrae/logos.tex'
     )
-    os.system(
-        'ln -s ../../../latex/logos.tex rapport_inrae/'
+    runCommand(
+        'ln -s {} rapport_inrae/'.format(os.path.join(latexSourceDir, 'logos.tex'))
     )
     # back to original working drectory
     os.chdir(baseDir)
@@ -165,8 +182,13 @@ def injectContentIntoModel(mergedDocFilenameTex, lang):
 def buildPDF(lang):
     # Compile LaTeX source
     os.chdir(modelDir)
-    sourceTexFile = 'cassiopee_doc_' + lang + '.tex'
-    outputPdfFile = 'cassiopee_doc_' + lang + '.pdf'
+    sourceTexFile = filenamePrefix + lang + '.tex'
+    outputPdfFile = filenamePrefix + lang + '.pdf'
+
+    # copy Cassiopée version LateX file
+    cvt = os.path.join(buildDir, 'cassiopee_version.tex')
+    shutil.copy(cvt, modelDir)
+
     os.system(
         'latexmk -f -xelatex -pdf -interaction=nonstopmode {} > /dev/null 2>&1'.format(sourceTexFile)
     )
@@ -179,19 +201,19 @@ def buildPDF(lang):
 def buildDocForLang(lang):
 
     # Prepare temporary build directory
-    os.makedirs(buildDir, exist_ok=True)
+    os.makedirs(pdfBuildDir, exist_ok=True)
     # Prepare output directory
     os.makedirs(outputDir, exist_ok=True)
 
     # Read config
-    yamlPath = 'mkdocs-' + lang + '.yml'
+    yamlPath = 'mkdocs/mkdocs-' + lang + '.yml'
     dMkdocsYaml = readConfig(yamlPath)
 
     # Create string with merged MarkDown
     s = exploreAndMerge(dMkdocsYaml['docs_dir'], dMkdocsYaml['nav'])
     # Save the merged .md file
     mergedDocFilename = mergedDocFilenamePrefix + lang
-    mergedDocOutputPath = os.path.join(buildDir, mergedDocFilename)
+    mergedDocOutputPath = os.path.join(pdfBuildDir, mergedDocFilename)
     # remove internal links @TODO convert them to hyperref ?
     s = re.sub(r'\[([^/]+)\]\([^ ]+\.md\)', r'\1', s)
     with open('{}.md'.format(mergedDocOutputPath), 'w') as f:
@@ -208,7 +230,8 @@ def buildDocForLang(lang):
     buildPDF(lang)
 
     # Clean build dir
-    shutil.rmtree(buildDir)
+    shutil.rmtree(pdfBuildDir)
+    #raise RuntimeError()
 
 
 if __name__ == '__main__':
diff --git a/scripts/prepare_mkdocs.sh b/scripts/prepare_mkdocs.sh
new file mode 100644
index 0000000000000000000000000000000000000000..af53d10dcba3d84c8ab5c753c75b72cd513fd3da
--- /dev/null
+++ b/scripts/prepare_mkdocs.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+set -o errexit
+
+BUILD_DIR=build
+VER_FILE=$BUILD_DIR/cassiopee_version
+
+function prepareMkdocs
+{
+  local lang=$1
+
+  # copy and modify Mkdocs configuration file :
+  # - add Cassiopée version
+  # - modify path to input files
+  # - modify path to output files
+  cat mkdocs/mkdocs-$lang.yml \
+  | sed "/^site_name:/ s/$/ v$VER/" \
+  | sed "/^docs_dir:/ s/docs_dir: /docs_dir: ..\//" \
+  | sed "/^site_dir:/ s/site_dir: /site_dir: ..\//" > $BUILD_DIR/mkdocs-$1.yml
+}
+
+node scripts/extract-nghyd-version.js $VER_FILE
+VER=$(cat $VER_FILE)
+
+prepareMkdocs fr
+prepareMkdocs en
diff --git a/scripts/python3.js b/scripts/python3.js
deleted file mode 100644
index 00ee016d7596dd3146f23e3a51a272adde966fd0..0000000000000000000000000000000000000000
--- a/scripts/python3.js
+++ /dev/null
@@ -1,15 +0,0 @@
-'use strict';
-
-const exec = require("child_process").execSync;
-const os = require("os");
-
-let py = "python3";
-if (os.platform() === "win32") {
-    py = "python";
-}
-
-const command = py + " " + process.argv.slice(2).join(" ");
-console.log("executing", command);
-
-const ret = exec(command);
-console.log(ret.toString());
diff --git a/src/app/calculators/pab/en.json b/src/app/calculators/pab/en.json
index d3fda007d382bbceb0f7694ff26ae4a6ac06cd08..a9360eb6c9b32cd8c8dde212325b80c1ece07856 100644
--- a/src/app/calculators/pab/en.json
+++ b/src/app/calculators/pab/en.json
@@ -4,6 +4,7 @@
     "Q": "Flow",
     "Z1": "Upstream elevation",
     "Z2": "Downstream elevation",
+    "ZW": "Water line (m)",
 
     "Z": "Water elevation",
     "LB": "Basin length",
diff --git a/src/app/calculators/pab/fr.json b/src/app/calculators/pab/fr.json
index d951248b73d41ab075deb3083c89cff81040e1ee..68b983df6591b6be62323af2b47044e0029eded9 100644
--- a/src/app/calculators/pab/fr.json
+++ b/src/app/calculators/pab/fr.json
@@ -4,6 +4,7 @@
     "Q": "Débit",
     "Z1": "Cote amont",
     "Z2": "Cote aval",
+    "ZW": "Ligne d'eau (m)",
 
     "Z": "Cote de l'eau",
     "LB": "Longueur du bassin",
@@ -29,4 +30,4 @@
     "UNIT_H1": "m",
     "UNIT_H2": "m",
     "UNIT_SUBMERGENCE": "%"
-}
\ No newline at end of file
+}
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 5bbc25c8fe1b056c20b6aef522b49e9bc2d348e1..c8eff7ec5fbb007f2b11bf6f48ca87a94e3edab1 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
@@ -16,6 +16,7 @@ import { CalculatorResults } from 'app/results/calculator-results';
 
 import zoomPlugin from 'chartjs-plugin-zoom';
 import { Chart } from "chart.js";
+import { FormulaireService } from "app/services/formulaire.service";
 
 @Component({
     selector: "pab-profile-chart",
@@ -70,6 +71,7 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
 
     public constructor(
         private intlService: I18nService,
+        private formService: FormulaireService,
         private cd: ChangeDetectorRef
     ) {
         super();
@@ -444,7 +446,7 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
                 label: (
                     this._results.variatedParameters.length > 0 ?
                     this.getLegendForSeries(n) :
-                    this.intlService.localizeText("INFO_LIB_ZW") // ligne d'eau
+                        this.formService.localizeText("ZW", this.formService.currentForm.calculatorType) // ligne d'eau
                 ),
                 color: palette[ n % palette.length ]
             });
diff --git a/src/app/components/pb-schema/pb-schema.component.ts b/src/app/components/pb-schema/pb-schema.component.ts
index 7ac6b72a7bc7a7ac2c2d6414e1bd11deccce26f7..6de70eecd8ddf7c49d2c45a200a9ae6a6cf0a009 100644
--- a/src/app/components/pb-schema/pb-schema.component.ts
+++ b/src/app/components/pb-schema/pb-schema.component.ts
@@ -435,6 +435,13 @@ export class PbSchemaComponent implements AfterViewInit, AfterContentInit, OnIni
     }
 
     public get enableRemoveButton() {
+        // do not allow to remove last basin
+        if (this._selectedItem instanceof PbBassin) {
+            if (this.predamService.bassins.length == 1) {
+                return false;
+            }
+        }
+
         if (this._selectedItem === this.predamService.upstreamBassin) {
             return false;
         }
diff --git a/src/app/services/formulaire.service.ts b/src/app/services/formulaire.service.ts
index c7486a1b1d74bb3f7340e5fc0c7efa6556b550a6..e54805c7d5ed9279f1cbed3150cdfe8f6ec5d65c 100644
--- a/src/app/services/formulaire.service.ts
+++ b/src/app/services/formulaire.service.ts
@@ -607,7 +607,7 @@ export class FormulaireService extends Observable {
         }
     }
 
-    private get currentForm(): FormulaireDefinition {
+    public get currentForm(): FormulaireDefinition {
         return this.getFormulaireFromId(this._currentFormId);
     }
 
diff --git a/src/styles.scss b/src/styles.scss
index cdcf478a9b498d3eadaef36a4ab1caf91feaaca3..734ff3487a0679dffda049d30c78384edb0ab5e2 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -272,6 +272,8 @@ field-set {
 
                         > input[type="number"] {
                             -moz-appearance: textfield;
+                            text-align: right;
+                            width: 88%;
                         }
                         input[type=number]::-webkit-outer-spin-button,
                         input[type=number]::-webkit-inner-spin-button {