diff --git a/.gitignore b/.gitignore
index e1d335288fa6a8bf17651ca70452f89f20a3f4a9..948f3336193af1936d77eab3eb99853937e3dead 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,7 +33,6 @@
 npm-debug.log
 testem.log
 /typings
-Makefile
 
 # e2e
 /e2e/*.js
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e94987b7770fd580605c84c6caf30b1f50d058cd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,30 @@
+SRC_DIR := src
+BUILD_DIR := build
+NODE_BASE := $(HOME)/Documents/dev/node-v6.10.2-linux-x64
+NODE := $(NODE_BASE)/bin/node
+
+JASMINE_CLI := ./node_modules/jasmine-node/lib/jasmine-node/cli.js
+
+#$(error $(NODE))
+
+SOURCE_FILES := $(shell find $(SRC_DIR) -name *.ts)
+
+all : compile
+
+compile : build-dir $(SOURCE_FILES)
+	npm run build
+
+build-dir :
+	mkdir -p $(BUILD_DIR)
+
+buildspec :
+	npm run buildspec
+
+jasmine : buildspec
+	npm run jasmine
+
+karma :
+	npm run karma
+
+clean :
+	rm -rf $(BUILD_DIR)
diff --git a/debug_test b/debug_test
new file mode 100755
index 0000000000000000000000000000000000000000..f575fbd7747b029b1ace8f306ed068a934705456
--- /dev/null
+++ b/debug_test
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+do_kill()
+{
+  local pid=$1
+  if [[ -n $pid ]]; then
+    if [[ -n $(ps -ef|grep $pid|grep -v grep) ]]; then
+      echo "killing $pid..."
+      kill $jm_pid
+    else
+      echo "no process with pid $pid"
+    fi
+  fi
+}
+
+do_exit()
+{
+#   echo "exits"
+   do_kill $jm_pid
+}
+
+syntax()
+{
+  echo "syntaxe : $(basename $0) <fichier spec>"
+  exit 1
+}
+
+trap do_exit SIGINT
+trap do_exit EXIT
+
+if [[ $# != 1 ]]; then
+  syntax
+fi
+
+ni=$(ps -ef|grep node-inspector|grep -v grep)
+if [[ -z $ni ]]; then
+  echo "starting node-inspector..."
+  node-inspector &
+else
+  echo "node-inspector already running"
+fi
+echo
+
+echo "debugging $1..."
+node --debug-brk ./node_modules/jasmine-node/bin/jasmine-node $1 &
+jm_pid=$!
+echo
+
+#ps -ef|grep jasmine-node|grep -v grep
+#pid=$(ps -ef|grep jasmine-node|grep -v grep|awk '{print $2}')
+#echo $pid $jm_pid
+
+echo "starting Chrome...."
+chromium-browser http://127.0.0.1:8080/?port=5858
diff --git a/karma.conf.js b/karma.conf.js
index acf16b031749452acef1db26b55090289d491894..2824ad868af44bb9ed876aba089370511b739eb2 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -15,9 +15,10 @@ module.exports = function (config) {
 
     // list of files / patterns to load in the browser
     files: [
-      { pattern: 'src/**/*.ts', included: false },
+      { pattern: 'spec/test-main.js', included: true },
       { pattern: 'spec/**/*.ts', included: false },
-      'spec/test-main.js'
+      { pattern: 'src/**/*.ts', included: false }
+      // { pattern: 'build/**/*.js', included: false }
     ],
 
 
@@ -29,17 +30,29 @@ module.exports = function (config) {
     // preprocess matching files before serving them to the browser
     // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
     preprocessors: {
-      '+(src|spec)**/*.ts': ['typescript']
+      // '+(src|spec)/**/*.ts': ['typescript']
+      '**/*.ts': ['typescript']
     },
 
     typescriptPreprocessor: {
+      // options passed to the typescript compiler 
       options: {
-        // https://github.com/Microsoft/TypeScript/blob/b0584b58fa07ee8c06e6d6f0f1bce2d4c37c7640/lib/typescript.d.ts#L1573
+        sourceMap: true, // (optional) Generates corresponding .map file. 
+
         // enum ScriptTarget { ES3 = 0, ES5 = 1, ES6 = 2, ES2015 = 2, Latest = 2 }
-        target: 1,
-        // https://github.com/Microsoft/TypeScript/blob/b0584b58fa07ee8c06e6d6f0f1bce2d4c37c7640/lib/typescript.d.ts#L1544
+        target: 'ES5', // (optional) Specify ECMAScript target version: 'ES3' (default), or 'ES5'
+
         // enum ModuleKind { None = 0, CommonJS = 1, AMD = 2, UMD = 3, System = 4, ES6 = 5, ES2015 = 5 }
-        module: 2
+        module: 'amd', // (optional) Specify module code generation: 'commonjs' or 'amd'
+
+        // noImplicitAny: true, // (optional) Warn on expressions and declarations with an implied 'any' type. 
+        // noResolve: true, // (optional) Skip resolution and preprocessing. 
+        // removeComments: true, // (optional) Do not emit comments to output. 
+        // concatenateOutput: false // (optional) Concatenate and emit output to single file. By default true if module option is omited, otherwise false. 
+      },
+      // transforming the filenames 
+      transformPath: function (path) {
+        return path.replace(/\.ts$/, '.js');
       }
     },
 
@@ -60,6 +73,7 @@ module.exports = function (config) {
     // level of logging
     // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
     logLevel: config.LOG_INFO,
+    // logLevel: config.LOG_DEBUG,
 
 
     // enable / disable watching file and executing tests whenever any file changes
diff --git a/package.json b/package.json
index 66b089a3aa528f80e74c09291ea371eb42ff7a60..47299514a7146cbc821c50f35d2cfe70bc3d3f62 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
   "devDependencies": {
     "@types/jasmine": "^2.5.47",
     "jasmine-core": "^2.5.2",
+    "jasmine-node": "^1.14.5",
     "karma": "^1.3.0",
     "karma-chrome-launcher": "^2.0.0",
     "karma-jasmine": "^1.0.2",
@@ -21,8 +22,9 @@
   },
   "scripts": {
     "build": "./node_modules/typescript/bin/tsc --p src/tsconfig.app.json",
-    "buildtest": "./node_modules/typescript/bin/tsc --p spec/tsconfig.spec.json",
-    "test": "./node_modules/typescript/bin/tsc --p spec/tsconfig.spec.json && ./node_modules/karma/bin/karma start",
+    "buildspec": "./node_modules/typescript/bin/tsc --p spec/tsconfig.spec.json",
+    "jasmine": "./node_modules/.bin/jasmine",
+    "karma": "./node_modules/typescript/bin/tsc --p spec/tsconfig.spec.json && ./node_modules/karma/bin/karma start",
     "lint": "./node_modules/tslint/bin/tslint",
     "viz": "tsviz -recursive src/ jalhyd_class_diagram.png"
   }
diff --git a/spec/base.spec.ts b/spec/base.spec.ts
index 6986c540fcaf7116080775b4bad8b60db89abe1e..0bb55fbd6efcc8a0aed291e0ee594ae7cd1420a3 100644
--- a/spec/base.spec.ts
+++ b/spec/base.spec.ts
@@ -1,14 +1,25 @@
 /// <reference path="../node_modules/@types/jasmine/index.d.ts" />
 
-import { nub, res } from "./nubtest";
+import { Result } from "../src/base";
+import { nub, precDigits } from "./nubtest";
+
 
 describe('Class Nub: ', () => {
-    beforeEach(() => {
-        res.vCalc = 3;
-    });
+    // beforeEach(() => {
+    //     res.vCalc = 3;
+    // });
     describe('Calc(): ', () => {
         it('should return a result.vCalc equal to 3', () => {
-            expect(nub.Calc("C")).toEqual(res);
+            let res = new Result(3);
+            expect(nub.Calc("C").vCalc).toBeCloseTo(res.vCalc, precDigits);
+        });
+        it('should return a result.vCalc equal to 1', () => {
+            let res = new Result(1);
+            expect(nub.Calc("A").vCalc).toBeCloseTo(res.vCalc, precDigits);
+        });
+        it('should return a result.vCalc equal to 2', () => {
+            let res = new Result(2); precDigits
+            expect(nub.Calc("B").vCalc).toBeCloseTo(res.vCalc, precDigits);
         });
     });
 });
diff --git a/spec/cond_distri.spec.ts b/spec/cond_distri.spec.ts
index 9bcebdc44b726159c616c1b18073615d04a890ac..23b04cecfdb336263dbb424538867108fa81912b 100644
--- a/spec/cond_distri.spec.ts
+++ b/spec/cond_distri.spec.ts
@@ -67,9 +67,6 @@ describe('Class ConduiteDistrib: ', () => {
             nub.v.j = 0.6;
             nub.v.nu = 1e-6;
 
-            let res = new Result;
-            res.vCalc = 737.0213567924325;
-
             expect(nub.Calc("lg").vCalc).toBeCloseTo(737.021, 3);
         });
     });
@@ -82,9 +79,6 @@ describe('Class ConduiteDistrib: ', () => {
             nub.v.j = 0.6;
             nub.v.lg = 100;
 
-            let res = new Result;
-            res.vCalc = 0.0029506676187219757;
-
             expect(nub.Calc("nu").vCalc).toBeCloseTo(0.00295, 5);
         });
     });
diff --git a/spec/dichotomie.spec.ts b/spec/dichotomie.spec.ts
index a2c6d9b54c90955641ee9c64e39468d3eb20605d..003c2724416f92ebaa75de5b9a8b95e8ee9815c4 100644
--- a/spec/dichotomie.spec.ts
+++ b/spec/dichotomie.spec.ts
@@ -1,6 +1,7 @@
 /// <reference path="../node_modules/@types/jasmine/index.d.ts" />
 
-import { nub, res } from "./nubtest";
+// import { nub, res } from "./nubtest";
+import { nub } from "./nubtest";
 import { Dichotomie } from "../src/dichotomie"
 
 let dicho: Dichotomie = new Dichotomie(nub, "A");
@@ -8,7 +9,7 @@ let dicho: Dichotomie = new Dichotomie(nub, "A");
 describe('Class Dichotomie: ', () => {
     describe('Dichotomie(3, 1E-6, 0): ', () => {
         it('should return a result close to 1', () => {
-            expect(dicho.Dichotomie(3, 1E-6, 0).vCalc).toBeCloseTo(1,1E-6);
+            expect(dicho.Dichotomie(3, 1E-6, 0).vCalc).toBeCloseTo(1, 1E-6);
         });
     });
 });
diff --git a/spec/nubtest.ts b/spec/nubtest.ts
index ef81b541c26edea19746383808123783103995b3..64a2f4f87438dc9ccaecc8aa39099e0fdbbb434f 100644
--- a/spec/nubtest.ts
+++ b/spec/nubtest.ts
@@ -1,15 +1,26 @@
-import { Nub, Result, IParametres } from "../src/base";
+import { Result, IParamsEquation } from "../src/base";
+import { Nub } from "../src/nub";
 
 export class NubTest extends Nub {
-    constructor(v: IParametres) {
+    constructor(v: IParamsEquation) {
         super(v);
         this.sVarsEq = ["C"];
     }
     Equation(): Result {
-        let res: Result = new Result();
-        res.vCalc = this.v["A"] + this.v["B"];
-        return res;
+        return new Result(this.v["A"] + this.v["B"]);
     }
 }
-export let nub = new NubTest({ "A": 1, "B": 2, "C": null });
-export let res = new Result;
\ No newline at end of file
+export let nub = new NubTest({ "A": 1, "B": 2, "C": 3 });
+//export let res = new Result(0);
+
+
+/**
+ * précision de calcul (nombre de décimales)
+ */
+export let precDigits = 3;
+
+
+/**
+ * précision de calcul (max de abs(v-v'))
+ */
+export let precDist = Math.pow(10, -precDigits);
diff --git a/spec/regime_uniforme_rect.spec.ts b/spec/regime_uniforme_rect.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a6dd6ab07d4e7897e7f3fcf378e6dc6301319a04
--- /dev/null
+++ b/spec/regime_uniforme_rect.spec.ts
@@ -0,0 +1,68 @@
+/// <reference path="../node_modules/@types/jasmine/index.d.ts" />
+
+import { Result } from "../src/base";
+import { RegimeUniforme } from "../src/regime_uniforme";
+import { cSnRectang } from "../src/section/section_rectang";
+import { cParamsCanal } from "../src/section/section_type";
+import { precDigits, precDist } from "./nubtest";
+
+describe('Class RegimeUniforme / section rectangulaire : ', () => {
+    // beforeAll(() => {
+    // });
+
+    describe('Calc(): ', () => {
+        it('Q should be 1.568', () => {
+            let sect: cSnRectang;
+            let prmsCanal: cParamsCanal;
+
+            //  Ks=Strickler, Q=Débit, If=pente du font, précision, YB=hauteur de berge, YCL=Condition limite en cote à l'amont ou à l'aval
+            prmsCanal = new cParamsCanal(40, 0, 0.001, precDist, 1)
+
+            // largeur de fond
+            sect = new cSnRectang(false, prmsCanal, 2.5);
+            // tirant d'eau
+            sect.v.Y = 0.8;
+
+            var ru = new RegimeUniforme(sect);
+
+            // nom variable à calculer, valeur de Q
+            expect(ru.Calc("Q").vCalc).toBeCloseTo(1.568, precDigits);
+        });
+
+        it('Q should be 0.731', () => {
+            let sect: cSnRectang;
+            let prmsCanal: cParamsCanal;
+
+            //  Ks=Strickler, Q=Débit, If=pente du font, précision, YB=hauteur de berge, YCL=Condition limite en cote à l'amont ou à l'aval
+            prmsCanal = new cParamsCanal(30, 0, 0.0001, precDist, 1.2)
+
+            // largeur de fond
+            sect = new cSnRectang(false, prmsCanal, 3);
+            // tirant d'eau
+            sect.v.Y = 1.1;
+
+            var ru = new RegimeUniforme(sect);
+
+            // nom variable à calculer, valeur de Q
+            expect(ru.Calc("Q").vCalc).toBeCloseTo(0.731, precDigits);
+        });
+
+        it('Strickler should be 30.618', () => {
+            let sect: cSnRectang;
+            let prmsCanal: cParamsCanal;
+
+            //  Ks=Strickler, Q=Débit, If=pente du font, précision, YB=hauteur de berge, YCL=Condition limite en cote à l'amont ou à l'aval
+            prmsCanal = new cParamsCanal(40, 1.2, 0.001, precDist, 1)
+
+            // largeur de fond
+            sect = new cSnRectang(false, prmsCanal, 2.5);
+            // tirant d'eau
+            sect.v.Y = 0.8;
+
+            var ru = new RegimeUniforme(sect);
+
+            // nom variable à calculer, valeur de Ks
+            expect(ru.Calc("Ks").vCalc).toBeCloseTo(30.618, precDigits);
+        });
+    });
+});
diff --git a/spec/regime_uniforme_trapeze.spec.ts b/spec/regime_uniforme_trapeze.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..51acbad5f8a50478f272848581e6120a3652b916
--- /dev/null
+++ b/spec/regime_uniforme_trapeze.spec.ts
@@ -0,0 +1,47 @@
+/// <reference path="../node_modules/@types/jasmine/index.d.ts" />
+
+import { Result } from "../src/base";
+import { RegimeUniforme } from "../src/regime_uniforme";
+import { cSnTrapez } from "../src/section/section_trapez";
+import { cParamsCanal } from "../src/section/section_type";
+import { precDigits, precDist } from "./nubtest";
+
+describe('Class RegimeUniforme / section trapèze: ', () => {
+    beforeAll(() => {
+    });
+
+    describe('Calc(): ', () => {
+        it('Q should be 1.988', () => {
+            let sect: cSnTrapez;
+            let paramCnl: cParamsCanal;
+            //  Ks=Strickler, Q=Débit, If=pente du font, précision, YB=hauteur de berge, YCL=Condition limite en cote à l'amont ou à l'aval
+            paramCnl = new cParamsCanal(40, 0, 0.001, precDist, 1)
+            // largeur de fond, fruit
+            sect = new cSnTrapez(false, paramCnl, 2.5, 0.56);
+            // tirant d'eau
+            sect.v.Y = 0.8;
+
+            var ru: RegimeUniforme;
+            ru = new RegimeUniforme(sect);
+
+            expect(ru.Calc("Q").vCalc).toBeCloseTo(1.988, precDigits);
+        });
+
+
+        it('LargeurFond should be 1.516', () => {
+            let sect: cSnTrapez;
+            let paramCnl: cParamsCanal;
+            //  Ks=Strickler, Q=Débit, If=pente du font, précision, YB=hauteur de berge, YCL=Condition limite en cote à l'amont ou à l'aval
+            paramCnl = new cParamsCanal(40, 1.2, 0.001, 0.001, 1)
+            // largeur de fond, fruit
+            sect = new cSnTrapez(false, paramCnl, 0, 0.56);
+            // tirant d'eau
+            sect.v.Y = 0.8;
+
+            var ru: RegimeUniforme;
+            ru = new RegimeUniforme(sect);
+
+            expect(ru.Calc("LargeurFond").vCalc).toBeCloseTo(1.516, precDigits);
+        });
+    });
+});
diff --git a/spec/support/jasmine.json b/spec/support/jasmine.json
new file mode 100644
index 0000000000000000000000000000000000000000..0fb3c6b2c9961bc8a76f6b07699501d45bce7b90
--- /dev/null
+++ b/spec/support/jasmine.json
@@ -0,0 +1,11 @@
+{
+  "spec_dir": "build/spec",
+  "spec_files": [
+    "**/*[sS]pec.js"
+  ],
+  "helpers": [
+    "helpers/**/*.js"
+  ],
+  "stopSpecOnExpectationFailure": false,
+  "random": false
+}
\ No newline at end of file
diff --git a/spec/test-main.js b/spec/test-main.js
index f0c8158df2311f09f8af93b0ef58848116a2dbbf..441e4ba26e8d4d7ac0ed403dd8878e2a41f8517e 100644
--- a/spec/test-main.js
+++ b/spec/test-main.js
@@ -1,8 +1,10 @@
 var TEST_REGEXP = /(spec|test)\.js$/i;
 var allTestFiles = [];
 
+//console.log('files ' + Object.keys(window.__karma__.files));
+
 // Get a list of all the test files to include
-Object.keys(window.__karma__.files).forEach(function(file) {
+Object.keys(window.__karma__.files).forEach(function (file) {
   if (TEST_REGEXP.test(file)) {
     // Normalize paths to RequireJS module names.
     // If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
diff --git a/src/base.ts b/src/base.ts
index 01adbca1bb1db0bbc4d0d7a54d20702ba65ed7dd..be69087500c424fbe703aaeb7cd5ff36c3d8b2ff 100644
--- a/src/base.ts
+++ b/src/base.ts
@@ -1,15 +1,23 @@
-
-
 /**
  * Résultat de calcul comprenant la valeur du résultat et des calculs annexes (flag, calculs intermédiaires...)
  */
+
 export class Result {
     /** Valeur calculée */
-    public vCalc: number;
+    private _vCalc: number;
+
     /** Variables intermédiaires, flags d'erreur */
     public extraVar: {};
+
+    constructor(v: number) {
+        this._vCalc = v
+        this.extraVar = {}
+    };
+
+    get vCalc() { return this._vCalc; }
 }
 
+
 /**
  * Série de valeurs à calculer définie par le nom de la variable à sérier et le vecteur de valeur
  */
@@ -23,8 +31,10 @@ export class Serie {
     }
 }
 
-
-export interface IParametres {
+/**
+ * liste des valeurs des variables
+ */
+export interface IParamsEquation {
     [key: string]: number; // map : array of numbers with string keys
 }
 
@@ -48,69 +58,3 @@ export abstract class Debug {
         if (this.DBG) console.log(s);
     }
 }
-
-
-/**
- * Classe abstraite de Noeud de calcul : classe de base pour tous les calculs
- */
-export abstract class Nub extends Debug {
-    /// Nom des variables calculées par la méthode Equation
-    private _varsEq: string[] = [];
-
-    public v: IParametres;
-
-    constructor(parametres: IParametres) {
-        super(false);
-        this.v = parametres;
-    }
-
-
-    /**
-     * Formule utilisée pour le calcul analytique (solution directe ou méthode de résolution spécifique)
-     */
-    abstract Equation(sVarCalc: string): Result;
-
-
-    /** 
-     * Calcul d'une équation quelque soit l'inconnue à calculer
-     */
-    Calc(sVarCalc: string): Result {
-        for (let sVarEq of this._varsEq) {
-            if (sVarCalc == sVarEq) {
-                return this.Equation(sVarCalc);
-            }
-        }
-        return this.Solve(sVarCalc);
-    }
-
-
-    CalcSerie(svarCalc: string, serie: Serie): Result[] {
-        /** @todo faire une boucle pour appeler this.Calc avec chaque valeur de serie.values
-         * 
-         */
-        let results = [new (Result)];
-        return results;
-    }
-
-    get sVarsEq(): string[] {
-        return this._varsEq;
-    }
-
-    set sVarsEq(sVarsEq: string[]) {
-        this._varsEq = sVarsEq;
-    }
-
-    AddVarEq(sVarEq: string) {
-        this._varsEq.push(sVarEq);
-    }
-
-
-    /** 
-     * Résoud l'équation par une méthode numérique
-     */
-    Solve(sVarCalc: string): Result {
-        let res: Result;
-        /** @todo Résolution par méthode numérique (dichotomie...) */
-        return res;
-    }
-}
diff --git a/src/cond_distri.ts b/src/cond_distri.ts
index 0534f39bdaeb40533e6e3403bd2ec4ce3442db6d..cc365c4c2d426dd3bcfb44b68873a02071142529 100644
--- a/src/cond_distri.ts
+++ b/src/cond_distri.ts
@@ -1,8 +1,9 @@
-import { Nub, Result, IParametres } from "./base";
+import { Result, IParamsEquation } from "./base";
+import { Nub } from "./nub";
 
 
 // export interface IParamConduiteDistrib extends IParametres {
-export class ParamConduiteDistrib implements IParametres {
+export class ParamConduiteDistrib implements IParamsEquation {
     [key: string]: number;
 
     /** Débit */
@@ -39,33 +40,34 @@ export class ConduiteDistrib extends Nub {
     }
 
     Equation(sVarCalc: string): Result {
-        let res: Result = new Result();
+        let res: Result;
+        let v: number;
 
         var K = 0.3164 * Math.pow(4, 1.75) / (5.5 * 9.81 * Math.pow(3.1415, 1.75)); // Constante de la formule
 
         switch (sVarCalc) {
             case "j":
-                res.vCalc = K * Math.pow(this.v.nu, 0.25) * Math.pow(this.v.q, 1.75) * this.v.lg / Math.pow(this.v.d, 4.75);
+                v = K * Math.pow(this.v.nu, 0.25) * Math.pow(this.v.q, 1.75) * this.v.lg / Math.pow(this.v.d, 4.75);
                 break;
 
             case "d":
-                res.vCalc = Math.pow(this.v.j / (K * Math.pow(this.v.nu, 0.25) * Math.pow(this.v.q, 1.75) * this.v.lg), 1 / 4.75);
+                v = Math.pow(this.v.j / (K * Math.pow(this.v.nu, 0.25) * Math.pow(this.v.q, 1.75) * this.v.lg), 1 / 4.75);
                 break;
 
             case "q":
-                res.vCalc = Math.pow(this.v.j / (K * Math.pow(this.v.nu, 0.25) * this.v.lg / Math.pow(this.v.d, 4.75)), 1 / 1.75)
+                v = Math.pow(this.v.j / (K * Math.pow(this.v.nu, 0.25) * this.v.lg / Math.pow(this.v.d, 4.75)), 1 / 1.75)
                 break;
 
             case "lg":
-                res.vCalc = this.v.j / (K * Math.pow(this.v.nu, 0.25) * Math.pow(this.v.q, 1.75) / Math.pow(this.v.d, 4.75));
+                v = this.v.j / (K * Math.pow(this.v.nu, 0.25) * Math.pow(this.v.q, 1.75) / Math.pow(this.v.d, 4.75));
                 break;
 
             case "nu":
-                res.vCalc = Math.pow(this.v.j / (K * Math.pow(this.v.q, 1.75) * this.v.lg / Math.pow(this.v.d, 4.75)), 1 / 0.25);
+                v = Math.pow(this.v.j / (K * Math.pow(this.v.q, 1.75) * this.v.lg / Math.pow(this.v.d, 4.75)), 1 / 0.25);
                 break;
         }
 
 
-        return res;
+        return new Result(v);
     }
 }
\ No newline at end of file
diff --git a/src/dichotomie.ts b/src/dichotomie.ts
index 88aea0bcbe9249157b75ccf602fe5c903e4f6ad8..21a5b729bce461843bd3c597af78ed750860d6aa 100644
--- a/src/dichotomie.ts
+++ b/src/dichotomie.ts
@@ -1,4 +1,5 @@
-import { Debug, Nub, Result } from "./base";
+import { Debug, Result } from "./base";
+import { Nub } from "./nub";
 
 export class Dichotomie extends Debug {
     /**  Pas de parcours de l'intervalle pour initialisation dichotomie */
@@ -34,7 +35,6 @@ export class Dichotomie extends Debug {
         return (a || b) && !(a && b);
     }
 
-
     /**
      * Calcul de l'équation analytique.
      * @note Wrapper vers this.nub.Equation pour simplifier le code.
@@ -48,10 +48,8 @@ export class Dichotomie extends Debug {
         return this.nub.Equation(this.nub.sVarsEq[0]);
     }
 
-
     /**
     * Calcul à l'ouvrage
-    * @param sVarCalc Nom de la variable à calculer
     * @param rTarget Valeur cible
     * @param rtol Précision attendue du résultat
     * @param rInit Valeur initiale de l'inconnue à rechercher
@@ -79,7 +77,7 @@ export class Dichotomie extends Debug {
 
         v1 = v;
         v2 = v;
-        this.debug(nIterMax);
+
         //** @todo : Chercher en dehors de l'intervalle en le décalant à droite ou à gauche en fonction de la valeur */
         let nIter: number;
         for (nIter = 1; nIter < nIterMax; nIter++) {
@@ -113,11 +111,12 @@ export class Dichotomie extends Debug {
             }
             if (this.XOR(rTarget > v1, rTarget >= v2)) { break; }
         }
+        this.debug("intervalle initial " + X1 + ", " + X2);
 
         // Gestion de l'absence de solution dans l'intervalle de recherche
         if (nIter >= this.IDEFINT) {
             this.debug("nIter >= this.IDEFINT");
-            
+
             if (v2 < rTarget && v1 < rTarget) {
                 // Cote de l'eau trop basse pour passer le débit il faut ouvrir un autre ouvrage
                 this.vX = XmaxInit;
@@ -154,8 +153,6 @@ export class Dichotomie extends Debug {
             res.extraVar["flag"] = -1; // la valeur cible n'est pas dans l'intervalle de recherche
             return res;
         }
-        res = new Result();
-        res.vCalc = X;
-        return res;
+        return new Result(X);
     }
 }
diff --git a/src/lechaptcalmon.ts b/src/lechaptcalmon.ts
index 17dd57bcdfe8dacccc738752ae2f67580452b60e..0a349a7a46a2ad13ab145d252ff66c475902514c 100644
--- a/src/lechaptcalmon.ts
+++ b/src/lechaptcalmon.ts
@@ -1,9 +1,9 @@
-import { Nub, Result, IParametres } from "./base";
+import { Result, IParamsEquation } from "./base";
+import { Nub } from "./nub";
 
-
-interface IParamLechaptCalmon extends IParametres {
+interface IParamLechaptCalmon extends IParamsEquation {
     /** Débit */
-    Q: number; 
+    Q: number;
     /** Diamètre */
     D: number;
     /** Perte de charge */
@@ -32,22 +32,28 @@ class LechaptCalmon extends Nub {
     }
 
     Equation(sVarCalc: string): Result {
-        let res: Result;
+        let v: number;
 
         switch (sVarCalc) {
             case "Q":
-                res.vCalc = Math.pow((((this.v.J * Math.pow(this.v.D, this.v.N)) / this.v.L) * (1000 / this.v.Lg)), 1 / this.v.M);
+                v = Math.pow((((this.v.J * Math.pow(this.v.D, this.v.N)) / this.v.L) * (1000 / this.v.Lg)), 1 / this.v.M);
                 break;
+
             case "D":
-                res.vCalc = Math.pow((((this.v.L * Math.pow(this.v.Q, this.v.M)) / this.v.J) * (this.v.Lg / 1000)), 1 / this.v.N);
+                v = Math.pow((((this.v.L * Math.pow(this.v.Q, this.v.M)) / this.v.J) * (this.v.Lg / 1000)), 1 / this.v.N);
                 break
+
             case "J":
-                res.vCalc = ((this.v.L * Math.pow(this.v.Q, this.v.M)) / Math.pow(this.v.D, this.v.N)) * (this.v.Lg / 1000);
+                v = ((this.v.L * Math.pow(this.v.Q, this.v.M)) / Math.pow(this.v.D, this.v.N)) * (this.v.Lg / 1000);
                 break;
+
             case "Lg":
-                res.vCalc = ((this.v.J * Math.pow(this.v.D, this.v.N)) / (this.v.L * Math.pow(this.v.Q, this.v.M))) * 1000;
+                v = ((this.v.J * Math.pow(this.v.D, this.v.N)) / (this.v.L * Math.pow(this.v.Q, this.v.M))) * 1000;
+
+            default:
+                throw "invalid variable name " + sVarCalc;
         }
 
-        return res;
+        return new Result(v);
     }
 }
\ No newline at end of file
diff --git a/src/nub.ts b/src/nub.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ff654c2caee6b226da6555ccb48f8cc4be7cf781
--- /dev/null
+++ b/src/nub.ts
@@ -0,0 +1,74 @@
+import { Debug, IParamsEquation, Result, Serie } from "./base"
+import { Dichotomie } from "./dichotomie"
+
+/**
+ * Classe abstraite de Noeud de calcul : classe de base pour tous les calculs
+ */
+export abstract class Nub extends Debug {
+    /// Nom des variables calculées par la méthode Equation
+    private _varsEq: string[] = [];
+
+    public v: IParamsEquation;
+
+    constructor(paramsEq: IParamsEquation, dbg: boolean = false) {
+        super(dbg);
+        this.v = paramsEq;
+    }
+
+
+    /** 
+     * Formule utilisée pour le calcul analytique (solution directe ou méthode de résolution spécifique)
+     */
+    abstract Equation(sVarCalc: string): Result;
+
+
+    /** 
+     * Calcul d'une équation quelque soit l'inconnue à calculer
+     * @param sVarCalc nom de la variable à calculer
+     * @param rInit valeur initiale de la variable à calculer dans le cas de la dichotomie
+     * @param rPrec précision de calcul
+     */
+    Calc(sVarCalc: string, rInit: number = 0, rPrec: number = 0.001): Result {
+        for (let sVarEq of this._varsEq) {
+            if (sVarCalc == sVarEq) {
+                return this.Equation(sVarCalc);
+            }
+        }
+        return this.Solve(sVarCalc, rInit, rPrec);
+    }
+
+
+    CalcSerie(svarCalc: string, serie: Serie): Result[] {
+        /** @todo faire une boucle pour appeler this.Calc avec chaque valeur de serie.values
+         * 
+         */
+        // let results = [new (Result)];
+        let results = [new Result(0)];
+        return results;
+    }
+
+    get sVarsEq(): string[] {
+        return this._varsEq;
+    }
+
+    set sVarsEq(sVarsEq: string[]) {
+        this._varsEq = sVarsEq;
+    }
+
+    AddVarEq(sVarEq: string) {
+        this._varsEq.push(sVarEq);
+    }
+
+
+    /** 
+     * Résoud l'équation par une méthode numérique
+     * @param sVarCalc nom de la variable à calculer
+     * @param rInit valeur initiale de la variable à calculer dans le cas de la dichotomie
+     * @param rPrec précision de calcul
+     */
+    Solve(sVarCalc: string, rInit: number, rPrec: number): Result {
+        let dicho: Dichotomie = new Dichotomie(this, sVarCalc);
+        var target = this.v[this._varsEq[0]];
+        return dicho.Dichotomie(target, rPrec, rInit);
+    }
+}
diff --git a/src/regime_uniforme.ts b/src/regime_uniforme.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ac6130dbcad186e456ba53333e3d7eb8340c839f
--- /dev/null
+++ b/src/regime_uniforme.ts
@@ -0,0 +1,61 @@
+import { Result, IParamsEquation } from "./base";
+import { Nub } from "./nub";
+import { acSection, cParamsCanal } from "./section/section_type";
+
+
+
+export class RegimeUniforme extends Nub {
+    private Sn: acSection; ///< Objet section
+
+    constructor(s: acSection) {
+        // let paramsEq: { [key: string]: number } = {};
+        super(s.v, false);
+
+        this.debug('constructeur RU');
+
+        this.Sn = s;
+
+        this.AddVarEq("Q");
+        this.AddVarEq("Y");
+    }
+
+    /**
+   * Calcul du débit en régime uniforme.
+   * @return Débit en régime uniforme
+   */
+    Calc_Qn() {
+        this.Sn.Reset(true);
+        if (this.Sn.oP.v.If <= 0) {
+            var Qn = 0; // ? false bool
+            //this.oLog.Add('h_normale_pente_neg_nul',true);
+        } else {
+            Qn = this.Sn.oP.v.Ks * Math.pow(this.Sn.Calc('R', this.Sn.v.Y), 2 / 3) * this.Sn.Calc('S', this.Sn.v.Y) * Math.sqrt(this.Sn.oP.v.If);
+            this.debug("RU : Qn=" + Qn);
+        }
+        return Qn;
+    }
+
+    Equation(sVarCalc: string): Result {
+        let v: number;
+
+        switch (sVarCalc) {
+            case 'Y':
+                v = this.Sn.Calc('Yn');
+                break;
+
+            case 'Q':
+                v = this.Calc_Qn();
+                break;
+
+            // default:
+            //     var oDicho = new cDichotomie(this.oLog, this, 'Calc_Qn');
+            //     v = oDicho.calculer(this.v['Q'], this.precision, rInit);
+            //     break;
+
+            default:
+                throw "invalid variable name " + sVarCalc;
+        }
+
+        return new Result(v);
+    }
+}
\ No newline at end of file
diff --git a/src/section/log.ts b/src/section/log.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a86d67c10c8e95a3e6786eaaf10dadebc1a01029
--- /dev/null
+++ b/src/section/log.ts
@@ -0,0 +1,23 @@
+
+export class cLog {
+        
+        public txt;
+        
+        constructor() {
+                this.txt = '';
+        }
+        
+        Add(sTxt,bErr=false) {
+        // peut on mettre des balises ?
+            this.txt += '<li';
+            if(bErr) {this.txt += ' class="hyd_erreur"';}
+            this.txt += '>'+sTxt+'</li>';
+        }
+        Result() {
+            if(this.txt!='') {
+                return this.txt;
+            } else {
+                    return '';
+            }
+        }
+}
\ No newline at end of file
diff --git a/src/section/newton.ts b/src/section/newton.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d237ddab55dacb5c6c20a7c8ed3a0dd81a0fce20
--- /dev/null
+++ b/src/section/newton.ts
@@ -0,0 +1,110 @@
+import { cParamsCanal } from "./section_type"
+
+export abstract class acNewton {
+        protected rTol;
+        protected Dx;
+        private iCpt = 0;
+        private iCptMax = 50;
+        private rRelax = 1; /// Coefficient de relaxation
+        private rFnPrec = 0; /// Mémorisation du Fn précédent pour détecter le changement de signe
+        private iOscil = 0; /// Nombre de changement de signe de Delta
+        private oLog;
+        /**
+         * Constructeur de la classe
+         * @param $oSn Section sur laquelle on fait le calcul
+         * @param $oP Paramètres supplémentaires (Débit, précision...)
+         */
+        constructor(oP: cParamsCanal) {
+                this.rTol = oP.v.Prec;
+                this.Dx = oP.v.Prec / 10;
+        }
+        /**
+         * Calcul de la fonction f(x) dont on cherche le zéro.
+         * @param $rX x
+         * @return Calcul de la fonction
+         */
+        abstract CalcFn(rX);
+        /**
+         * Calcul de la dérivée f'(x) (peut être redéfini pour calcul analytique)
+         * @param $rX x
+         * @return Calcul de la fonction
+         */
+        protected CalcDer($x) {
+                //~ spip_log('Newton:CalcDer $rX='.$x,'hydraulic.'._LOG_DEBUG);
+                return (this.CalcFn($x + this.Dx) - this.CalcFn($x - this.Dx)) / (2 * this.Dx);
+        }
+        /**
+         * Test d'égalité à une tolérance près
+         * @param $rFn x
+         * @return True si égal, False sinon
+         */
+        private FuzzyEqual($rFn) {
+                return (Math.abs($rFn) < this.rTol);
+        }
+        /**
+         * Fonction récursive de calcul de la suite du Newton
+         * @param $rX x
+         * @return Solution du zéro de la fonction
+         */
+        XOR(a, b) {
+                return (a || b) && !(a && b);
+        }
+
+        public Newton(rX) {
+                this.iCpt++;
+                var rFn = this.CalcFn(rX);
+                if (this.FuzzyEqual(rFn) || this.iCpt >= this.iCptMax) {
+                        return rX;
+                }
+                else {
+                        var rDer = this.CalcDer(rX);
+                        //~ echo(' - f\' = '.$rDer);
+                        if (rDer != 0) {
+                                if (this.XOR(rFn < 0, this.rFnPrec < 0)) {
+                                        this.iOscil++;
+                                        if (this.rRelax > 1) {
+                                                // Sur une forte relaxation, au changement de signe on réinitialise
+                                                this.rRelax = 1;
+                                        }
+                                        else if (this.iOscil > 2) {
+                                                // On est dans le cas d'une oscillation autour de la solution
+                                                // On réduit le coefficient de relaxation
+                                                this.rRelax = this.rRelax * 0.5;
+                                        }
+                                }
+                                this.rFnPrec = rFn;
+                                var Delta = rFn / rDer;
+                                //2^8 = 2E8 ?
+                                while (Math.abs(Delta * this.rRelax) < this.rTol && rFn > 10 * this.rTol && this.rRelax < 2E8) {
+                                        // On augmente le coefficicient de relaxation s'il est trop petit
+                                        this.rRelax = this.rRelax * 2;
+                                }
+                                var rRelax = this.rRelax;
+                                while (rX - Delta * rRelax <= 0 && rRelax > 1E-4) {
+                                        // On diminue le coeficient de relaxation si on passe en négatif
+                                        rRelax = rRelax * 0.5; // Mais on ne le mémorise pas pour les itérations suivantes
+                                }
+                                rX = rX - Delta * rRelax;
+                                //this.rDelta = Delta; ???
+                                if (rX < 0) { rX = this.rTol; } // Aucune valeur recherchée ne peut être négative ou nulle
+                                return this.Newton(rX);
+                        }
+                        else {
+                                // Echec de la résolution
+                                return false;
+                        }
+                }
+        }
+        /**
+         * Pour savoir si le Newton a convergé
+         * @return true si oui, false sinon
+         */
+        public HasConverged() {
+                if (this.iCpt >= this.iCptMax) {
+                        return false;
+                }
+                else {
+                        return true;
+                }
+        }
+}
\ No newline at end of file
diff --git a/src/section/section_circulaire.ts b/src/section/section_circulaire.ts
new file mode 100644
index 0000000000000000000000000000000000000000..56bb10999ae80b1c3acf8970f9bcf2f91c1467c1
--- /dev/null
+++ b/src/section/section_circulaire.ts
@@ -0,0 +1,151 @@
+import { acSection } from "./section_type";
+
+/**
+ * Calculs de la section circulaire
+ */
+export class cSnCirc extends acSection {
+
+        //public D;      /// Diamètre du cercle
+        private Alpha;    /// Angle de la surface libre par rapport au fond
+        protected nbDessinPoints = 50;
+
+        constructor(oLog, oP, D) {
+                super(oLog, oP);
+                this.v.D = D;
+                if (oP.YB > D) { oP.YB = D; } // On place la berge au sommet du cercle
+        }
+        /**
+         * Calcul de l'angle Alpha de la surface libre par rapport au fond.
+         * @return Alpha
+         */
+        Calc_Alpha() {
+                if (this.v.Y > this.oP.v.YB) {
+                        var rY = this.oP.v.YB;
+                }
+                else {
+                        rY = this.v.Y;
+                }
+                if (rY <= 0) {
+                        return 0;
+                }
+                else if (rY > this.v.D) {
+                        return Math.PI;
+                }
+                else {
+                        var alpha = Math.acos(1. - rY / (this.v.D / 2.));
+                        if (alpha > Math.PI) {
+                                return Math.PI;
+                        }
+                        else {
+                                return alpha;
+                        }
+                }
+        }
+
+        /**
+         * Calcul de dérivée de l'angle Alpha de la surface libre par rapport au fond.
+         * @return dAlpha
+         */
+        Calc_dAlpha() {
+                if (this.v.Y <= 0 || this.v.Y >= this.v.D || this.v.Y > this.oP.v.YB) {
+                        return 0;
+                }
+                else {
+                        return 2. / this.v.D / Math.sqrt(1. - Math.pow(1. - 2. * this.v.Y / this.v.D, 2));
+                }
+        }
+
+        /**
+         * Calcul de la largeur au miroir.
+         * @return B
+         */
+        Calc_B() {
+                if (this.v.Y > this.oP.v.YB) {
+                        return super.Calc_B_Debordement();
+                }
+                else {
+                        return this.v.D * Math.sin(this.Calc('Alpha'));
+                }
+        }
+
+        /**
+         * Calcul du périmètre mouillé.
+         * @param $rY Uniquement présent car la méthode parent a cet argument
+         * @return B
+         */
+        Calc_P($rY = 0) {
+                if (this.v.Y > this.oP.v.YB && !this.bSnFermee) {
+                        // On n'ajoute pas le périmètre dans le cas d'une fente de Preissmann
+                        return this.CalcGeo('P') + super.Calc_P_Debordement(this.v.Y - this.oP.v.YB);
+                }
+                else {
+                        return this.v.D * this.Calc('Alpha');
+                }
+        }
+
+        /**
+         * Calcul de la surface mouillée.
+         * @param $rY Uniquement présent car la méthode parent a cet argument
+         * @return S
+         */
+        Calc_S($rY = 0) {
+                if (this.v.Y > this.oP.v.YB) {
+                        return this.CalcGeo('S') + super.Calc_S_Debordement(this.v.Y - this.oP.v.YB);
+                }
+                else {
+                        return Math.pow(this.v.D, 2) / 4 * (this.Calc('Alpha') - Math.sin(this.Calc('Alpha')) * Math.cos(this.Calc('Alpha')));
+                }
+        }
+
+
+        /**
+         * Calcul de dérivée du périmètre hydraulique par rapport au tirant d'eau.
+         * @return dP
+         */
+        Calc_dP() {
+                if (this.v.Y > this.oP.v.YB && !this.bSnFermee) {
+                        return super.Calc_dP_Debordement();
+                }
+                else {
+                        return this.v.D * this.Calc('dAlpha');
+                }
+        }
+        /**
+         * Calcul de dérivée de la largeur au miroir par rapport au tirant d'eau.
+         * @return dB
+         */
+        Calc_dB() {
+                if (this.v.Y > this.oP.v.YB) {
+                        return super.Calc_dB_Debordement();
+                }
+                else {
+                        return this.v.D * this.Calc('dAlpha') * Math.cos(this.Calc('Alpha'));
+                }
+        }
+        /**
+         * Calcul de la distance du centre de gravité de la section à la surface libre
+         * multiplié par la surface hydraulique
+         * @param $rY Uniquement présent car la méthode parent a cet argument
+         * @return S x Yg
+         */
+        Calc_SYg($rY = 0) {
+                var SYg = Math.sin(this.Calc('Alpha')) - Math.pow(Math.sin(this.Calc('Alpha')), 3) / 3 - this.Calc('Alpha') * Math.cos(this.Calc('Alpha'));
+                SYg = Math.pow(this.v.D, 3) / 8 * SYg;
+                return SYg;
+        }
+        /**
+         * Calcul de la dérivée de la distance du centre de gravité de la section à la surface libre
+         * multiplié par la surface hydraulique
+         * @param $rY Uniquement présent car la méthode parent a cet argument
+         * @return S x Yg
+         */
+        Calc_dSYg($rY = 0) {
+                var cos = Math.cos(this.Calc('Alpha'));
+                var sin = Math.sin(this.Calc('Alpha'));
+                var SYg = this.Calc('dAlpha') * cos;
+                SYg += - this.Calc('dAlpha') * cos * Math.pow(sin, 2);
+                SYg += - this.Calc('dAlpha') * cos + this.Calc('Alpha') * this.Calc('dAlpha') * sin;
+                SYg = 3 * Math.pow(this.v.D, 3) / 8 * SYg;
+                return SYg;
+        }
+}
\ No newline at end of file
diff --git a/src/section/section_puissance.ts b/src/section/section_puissance.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1afb789b01788281ecd32a3fc421694dfc939bad
--- /dev/null
+++ b/src/section/section_puissance.ts
@@ -0,0 +1,97 @@
+import { acSection } from "./section_type";
+
+/**
+ * Calculs de la section parabolique ou "puissance"
+ */
+export class cSnPuiss extends acSection {
+        //public k;      /// Coefficient de forme compris entre 0 et 1
+        //$LargeurBerge => La largeur des berges est déjà présente dans acSection
+        protected nbDessinPoints = 50;
+
+        constructor(oLog, oP, rk, LargeurBerge) {
+                super(oLog, oP);
+                this.v.k = rk;
+                this.v.LargeurBerge = LargeurBerge;
+        }
+        /**
+         * Calcul de Lambda (mais on garde la routine Alpha commune avec la section circulaire)
+         * @return Lambda
+         */
+        Calc_Alpha() {
+                return this.v.LargeurBerge / Math.pow(this.oP.v.YB, this.v.k);
+        }
+        /**
+         * Calcul de la largeur au miroir.
+         * @return B
+         */
+        Calc_B() {
+                if (this.v.Y >= this.oP.v.YB) {
+                        return this.v.LargeurBerge;
+                }
+                else {
+                        return this.Calc('Alpha') * Math.pow(this.v.Y, this.v.k);
+                }
+        }
+        /**
+         * Calcul du périmètre mouillé.
+         * @param $rY Uniquement présent car la méthode parent a cet argument
+         * @return B
+         */
+        Calc_P($rY = 0) {
+                var n = 100; /// Le nombre de partie pour le calcul de l'intégrale
+                var Lambda2 = Math.pow(this.Calc('Alpha'), 2);
+                var P = 0; /// Le périmètre à calculer
+                var Previous = 0;
+                for (var i = 1; i <= n; i++) {
+                        var Current = Math.pow(this.v.Y * i / n, this.v.k) / 2;
+                        P += Math.sqrt(Math.pow(n, -2) + Lambda2 * Math.pow(Current - Previous, 2));
+                        Previous = Current;
+                }
+                P *= 2;
+                return P;
+        }
+
+        /**
+         * Calcul de la surface mouillée.
+         * @param $rY Uniquement présent car la méthode parent a cet argument
+         * @return S
+         */
+        Calc_S($rY = 0) {
+                return this.Calc('Alpha') * Math.pow(this.v.Y, this.v.k + 1) / (this.v.k + 1);
+        }
+
+        /**
+         * Calcul de dérivée du périmètre hydraulique par rapport au tirant d'eau.
+         * @return dP
+         */
+        Calc_dP() {
+                return 2 * Math.sqrt(1 + Math.pow(this.v.k * this.Calc('Alpha') / 2, 2) * Math.pow(this.v.Y, 2 * (this.v.k - 1)));
+        }
+
+        /**
+         * Calcul de dérivée de la largeur au miroir par rapport au tirant d'eau.
+         * @return dB
+         */
+        Calc_dB() {
+                return this.Calc('Alpha') * this.v.k * Math.pow(this.v.Y, this.v.k - 1);
+        }
+        /**
+         * Calcul de la distance du centre de gravité de la section à la surface libre
+         * multiplié par la surface hydraulique
+         * @param $rY Uniquement présent car la méthode parent a cet argument
+         * @return S x Yg
+         */
+        Calc_SYg($rY = 0) {
+                return this.Calc('Alpha') * Math.pow(this.v.Y, this.v.k + 2) / ((this.v.k + 1) * (this.v.k + 2));
+        }
+        /**
+         * Calcul de la dérivée distance du centre de gravité de la section à la surface libre
+         * multiplié par la surface hydraulique
+         * @param $rY Uniquement présent car la méthode parent a cet argument
+         * @return S x Yg
+         */
+        Calc_dSYg($rY = 0) {
+                var SYg = this.Calc('dAlpha') * Math.pow(this.v.Y, this.v.k + 2) + this.Calc('Alpha') * Math.pow(this.v.Y, this.v.k + 1) * (this.v.k + 2);
+                return SYg / ((this.v.k + 1) * (this.v.k + 2));
+        }
+}
\ No newline at end of file
diff --git a/src/section/section_rectang.ts b/src/section/section_rectang.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1a7b0b739c280b59c8ef927a0ae9bba056e719a2
--- /dev/null
+++ b/src/section/section_rectang.ts
@@ -0,0 +1,43 @@
+import { acSection } from "./section_type";
+
+/**
+ * Calculs de la section rectangulaire
+ */
+export class cSnRectang extends acSection {
+        constructor(oLog, oP, LargeurFond) {
+                super(oLog, oP);
+                this.v.LargeurBerge = LargeurFond;
+        }
+        /**
+         * Calcul du périmètre mouillé
+         * @param $rY Uniquement présent car la méthode parent à cet argument
+         * @return Périmètre mouillé (m)
+         */
+        Calc_P($rY = 0) {
+                return this.v.LargeurBerge + super.Calc_P_Debordement(this.v.Y);
+        }
+
+        Calc_dP() {
+                return super.Calc_dP_Debordement();
+        }
+
+        Calc_B() {
+                return super.Calc_B_Debordement();
+        }
+
+        Calc_dB() {
+                return super.Calc_dB_Debordement();
+        }
+
+        Calc_S() {
+                return super.Calc_S_Debordement(this.v.Y);
+        }
+
+        /**
+         * Calcul du tirant d'eau conjugué avec la formule analytique pour la section rectangulaire
+         * @return tirant d'eau conjugué
+         */
+        CalcYco() {
+                return this.v.Y * (Math.sqrt(1 + 8 * Math.pow(this.Calc('Fr'), 2)) - 1) / 2;
+        }
+}
\ No newline at end of file
diff --git a/src/section/section_trapez.ts b/src/section/section_trapez.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e1a67989fa1a61d3824320b54f440fe178da6548
--- /dev/null
+++ b/src/section/section_trapez.ts
@@ -0,0 +1,114 @@
+import { acSection } from "./section_type";
+
+/**
+ * Calculs de la section trapézoïdale
+ */
+export class cSnTrapez extends acSection {
+        // public LargeurFond;    /// Largeur au fond
+        // public Fruit;          /// Fruit des berges
+        constructor(oLog, oP, LargeurFond, Fruit) {
+                super(oLog, oP);
+                this.v.LargeurFond = LargeurFond;
+                this.v.Fruit = Fruit;
+        }
+
+        Calc_B(bBerge = false) {
+                if (!bBerge && this.v.Y > this.oP.v.YB) {
+                        return this.v.LargeurBerge;
+                }
+                else {
+                        return this.v.LargeurFond + 2 * this.v.Fruit * this.v.Y;
+                }
+        }
+
+        /**
+         * Calcul du périmètre mouillé
+         * @param $rY Uniquement présent car la méthode parent à cet argument
+         * @return Périmètre mouillé (m)
+         */
+        Calc_P($rY = 0) {
+                if (this.v.Y > this.oP.v.YB) {
+                        var P = this.CalcGeo('P') + super.Calc_P_Debordement(this.v.Y - this.oP.v.YB);
+                }
+                else {
+                        P = this.v.LargeurFond + 2 * Math.sqrt(1 + Math.pow(this.v.Fruit, 2)) * this.v.Y;
+                }
+                //~ spip_log('Trapez->CalcP(rY='.$this->rY.')='.$P,'hydraulic.'._LOG_DEBUG);
+                return P;
+        }
+
+        /**
+         * Calcul de la surface mouillée
+         * @param $rY Uniquement présent car la méthode parent à cet argument
+         * @return Surface mouillée (m2)
+         */
+        Calc_S($rY = 0) {
+                if (this.v.Y > this.oP.v.YB) {
+                        var S = this.CalcGeo('S') + super.Calc_S_Debordement(this.v.Y - this.oP.v.YB);
+                }
+                else {
+                        S = this.v.Y * (this.v.LargeurFond + this.v.Fruit * this.v.Y);
+                }
+                //~ spip_log('Trapez->CalcS(rY='.$this->rY.')='.$S,'hydraulic.'._LOG_DEBUG);
+                return S;
+        }
+
+        /**
+         * Calcul de dérivée de la surface hydraulique par rapport au tirant d'eau.
+         * @return dS
+         */
+        Calc_dS() {
+                if (this.v.Y > this.oP.v.YB) {
+                        return super.Calc_dS();
+                }
+                else {
+                        return this.v.LargeurFond + 2 * this.v.Fruit * this.v.Y;
+                }
+        }
+
+        /**
+         * Calcul de dérivée du périmètre hydraulique par rapport au tirant d'eau.
+         * @return dP
+         */
+        Calc_dP() {
+                if (this.v.Y > this.oP.v.YB) {
+                        return super.Calc_dP_Debordement();
+                }
+                else {
+                        return 2 * Math.sqrt(1 + this.v.Fruit * this.v.Fruit);
+                }
+        }
+
+        /**
+         * Calcul de dérivée de la largeur au miroir par rapport au tirant d'eau.
+         * @return dB
+         */
+        Calc_dB() {
+                if (this.v.Y > this.oP.v.YB) {
+                        return super.Calc_dB_Debordement();
+                }
+                else {
+                        return 2 * this.v.LargeurFond * this.v.Fruit;
+                }
+        }
+        /**
+         * Calcul de la distance du centre de gravité de la section à la surface libre
+         * multiplié par la surface hydraulique
+         * @param $rY Uniquement présent car la méthode parent à cet argument
+         * @return S x Yg
+         */
+        Calc_SYg($rY = 0) {
+                return (this.v.LargeurFond / 2 + this.v.Fruit * this.v.Y / 3) * Math.pow(this.v.Y, 2);
+        }
+        /**
+         * Calcul de la dérivée de la distance du centre de gravité de la section à la surface libre
+         * multiplié par la surface hydraulique
+         * @param $rY Uniquement présent car la méthode parent à cet argument
+         * @return S x Yg
+         */
+        Calc_dSYg($rY = 0) {
+                var SYg = this.v.Fruit / 3 * Math.pow(this.v.Y, 2);
+                SYg += (this.v.LargeurFond / 2 + this.v.Fruit * this.v.Y / 3) * 2 * this.v.Y;
+                return SYg;
+        }
+}
\ No newline at end of file
diff --git a/src/section/section_type.ts b/src/section/section_type.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8a75981ae56904345e7c824a946eaeadb5ef91c1
--- /dev/null
+++ b/src/section/section_type.ts
@@ -0,0 +1,773 @@
+import { Debug } from "../base"
+import { acNewton } from "./newton";
+import { cLog } from "./log";
+import { IParamsEquation } from "../base";
+
+/**
+ * Calcul de la hauteur critique
+ */
+export class cHautCritique extends acNewton {
+        private Sn;
+        private oP;
+        /**
+         * Constructeur de la classe
+         * @param oSn Section sur laquelle on fait le calcul
+         * @param oP Paramètres supplémentaires (Débit, précision...)
+         */
+        constructor(Sn: acSection, oP: cParamsCanal) {
+                super(oP);
+                this.Sn = Sn;
+                this.oP = oP;
+
+        }
+        /**
+         * Calcul de la fonction dont on cherche le zéro
+         * @param rX Variable dont dépend la fonction
+         */
+        CalcFn(rX) {
+                // Calcul de la fonction
+                if (this.Sn.Calc('S', rX) != 0) {
+                        var Fn = (Math.pow(this.oP.Q, 2) * this.Sn.Calc('B', rX) / Math.pow(this.Sn.Calc('S', rX), 3) / this.oP.G - 1);
+                }
+                else {
+                        Fn = Infinity;
+                }
+                return Fn;
+        }
+        /**
+         * Calcul analytique de la dérivée de la fonction dont on cherche le zéro
+         * @param rX Variable dont dépend la fonction
+         */
+        CalcDer(rX) {
+                if (this.Sn.Calc('S') != 0) {
+                        // L'initialisation à partir de rX a été faite lors de l'appel à CalcFn
+                        var Der = (this.Sn.Calc('dB') * this.Sn.Calc('S') - 3 * this.Sn.Calc('B') * this.Sn.Calc('B'));
+                        Der = Math.pow(this.oP.Q, 2) / this.oP.G * Der / Math.pow(this.Sn.Calc('S'), 4);
+                }
+                else {
+                        Der = Infinity;
+                }
+                //spip_log('cHautCritique:CalcDer('.rX.')='.rDer,'hydraulic.'._LOG_DEBUG);
+                return Der;
+        }
+}
+/**
+ * Calcul de la hauteur normale
+ */
+export class cHautNormale extends acNewton {
+        private Sn;
+        private Q;
+        private Ks;
+        private If;
+        private G;
+        /**
+         * Constructeur de la classe
+         * @param oSn Section sur laquelle on fait le calcul
+         * @param oP Paramètres supplémentaires (Débit, précision...)
+         */
+        constructor(Sn: acSection, oP: cParamsCanal) {
+                super(oP);
+                this.Sn = Sn;
+                this.Q = oP.v.Q;
+                this.Ks = oP.v.Ks;
+                this.If = oP.v.If;
+                this.G = oP.v.G;
+        }
+        /**
+         * Calcul de la fonction dont on cherche le zéro
+         * @param rX Variable dont dépend la fonction
+         */
+        CalcFn(rX) {
+                // Calcul de la fonction
+                var Fn = (this.Q - this.Ks * Math.pow(this.Sn.Calc('R', rX), 2 / 3) * this.Sn.Calc('S', rX) * Math.sqrt(this.If));
+                return Fn;
+        }
+        /**
+         * Calcul analytique de la dérivée de la fonction dont on cherche le zéro
+         * @param rX Variable dont dépend la fonction
+         */
+        CalcDer(rX) {
+                // L'initialisation a été faite lors de l'appel à CalcFn
+                var Der = 2 / 3 * this.Sn.Calc('dR') * Math.pow(this.Sn.Calc('R'), -1 / 3) * this.Sn.Calc('S');
+                Der = Der + Math.pow(this.Sn.Calc('R'), 2 / 3) * this.Sn.Calc('B');
+                Der = Der * -this.Ks * Math.sqrt(this.If);
+                //spip_log('cHautNormale:CalcDer('.rX.')='.rDer,'hydraulic.'._LOG_DEBUG);
+                return Der;
+        }
+}
+/**
+ * Calcul de la hauteur correspondante (charge égale)
+ */
+export class cHautCorrespondante extends acNewton {
+        private Y; // Tirant d'eau connu
+        private rS2; // 1/S^2 associé au tirant d'eau connu
+        private Sn; // Section contenant les données de la section avec la hauteur à calculer
+        private rQ2G; // Constante de gravité
+        /**
+         * Constructeur de la classe
+         * @param oSn Section sur laquelle on fait le calcul
+         * @param oP Paramètres supplémentaires (Débit, précision...)
+         */
+        constructor(Sn: acSection, oP: cParamsCanal) {
+                super(oP);
+                this.Y = Sn.v.Y;
+                this.rS2 = Math.pow(Sn.Calc('S'), -2);
+                this.Sn = Sn;
+                this.rQ2G = Math.pow(oP.v.Q, 2) / (2 * oP.v.G);
+        }
+        /**
+         * Calcul de la fonction dont on cherche le zéro
+         * @param rX Variable dont dépend la fonction
+         */
+        CalcFn(rX) {
+                // Calcul de la fonction
+                var Fn = this.Y - rX + (this.rS2 - Math.pow(this.Sn.Calc('S', rX), -2)) * this.rQ2G;
+                //~ spip_log('cHautCorrespondante:CalcFn('.rX.')='.rFn,'hydraulic.'._LOG_DEBUG);
+                return Fn;
+        }
+        /**
+         * Calcul analytique de la dérivée de la fonction dont on protected function cherche le zéro
+         * @param rX Variable dont dépend la fonction
+         */
+        CalcDer(rX) {
+                // L'initialisation a été faite lors de l'appel à CalcFn
+                if (this.Sn.Calc('S') != 0) {
+                        var Der = -1 + 2 * this.rQ2G * this.Sn.Calc('B') / Math.pow(this.Sn.Calc('S'), 3);
+                }
+                else {
+                        Der = Infinity;
+                }
+                //~ spip_log('cHautCorrespondante:CalcDer('.rX.')='.rDer,'hydraulic.'._LOG_DEBUG);
+                return Der;
+        }
+}
+/**
+ * Calcul de la hauteur conjuguée (Impulsion égale)
+ */
+export class cHautConjuguee extends acNewton {
+        /** Tirant d'eau connu */
+        private Y;
+        /** 1/S^2 associé au tirant d'eau connu */
+        private rS2;
+        /** Section contenant les données de la section avec la hauteur à calculer */
+        private Sn;
+        /** Constante de gravité */
+        private G;
+        /** Carré du débit */
+        private rQ2;
+        /** Surface hydraulique associée au tirant d'eau connu */
+        private rS;
+        /** SYg associée au tirant d'eau connu */
+        private rSYg;
+        /**
+         * Constructeur de la classe
+         * @param oSn Section sur laquelle on fait le calcul
+         * @param oP Paramètres supplémentaires (Débit, précision...)
+         */
+        constructor(oSn: acSection, oP: cParamsCanal) {
+                super(oP);
+                this.Y = oSn.v.Y;
+                this.rQ2 = Math.pow(oP.v.Q, 2);
+                this.Sn = oSn;
+                this.G = oP.v.G;
+                this.rS = oSn.Calc('S');
+                this.rSYg = oSn.Calc('SYg');
+        }
+        /**
+         * Calcul de la fonction dont on cherche le zéro
+         * @param rX Variable dont dépend la fonction
+         */
+        CalcFn(rX) {
+                // Réinitialisation des paramètres hydrauliques de oSn avec l'appel this->oSn->Calc('S',rX)
+                if (this.rS > 0 && this.Sn.Calc('S', rX) > 0) {
+                        var Fn = this.rQ2 * (1 / this.rS - 1 / this.Sn.Calc('S'));
+                        Fn = Fn + this.G * (this.rSYg - this.Sn.Calc('SYg'));
+                }
+                else {
+                        Fn = -Infinity;
+                }
+                //~ spip_log('cHautConjuguee:CalcFn('.rX.')='.rFn,'hydraulic.'._LOG_DEBUG);
+                return Fn;
+        }
+        /**
+         * Calcul analytique de la dérivée de la fonction dont on cherche le zéro
+         * @param rX Variable dont dépend la fonction
+         */
+        CalcDer(rX) {
+                // L'initialisation a été faite lors de l'appel à CalcFn
+                if (this.rS > 0 && this.Sn.Calc('S') > 0) {
+                        var Der = this.rQ2 * this.Sn.Calc('dS') * Math.pow(this.Sn.Calc('S'), -2);
+                        Der = Der - this.G * this.Sn.Calc('dSYg', rX);
+                }
+                else {
+                        Der = -Infinity;
+                }
+                //~ spip_log('cHautConjuguee:CalcDer('.rX.')='.rDer,'hydraulic.'._LOG_DEBUG);
+                return Der;
+        }
+}
+
+/**
+ * Gestion des Paramètres du canal (hors section)
+ */
+export class cParamsCanal {
+        private _v: IParamsEquation = {};
+
+        // public YCL;   /// Condition limite en cote à l'amont ou à l'aval
+        // public Ks;    /// Strickler
+        // public Q;     /// Débit
+        // public Long;  /// Longueur du bief
+        // public If;    /// Pente du fond
+        // public Dx;    /// Pas d'espace (positif en partant de l'aval, négatif en partant de l'amont)
+        // public Prec;  /// Précision de calcul et d'affichage
+        // public G = 9.81;/// Constante de gravité
+        // public iPrec;  /// Précision en nombre de décimales
+        // public YB;    /// Hauteur de berge
+        // public Resolution; /// Méthode de résolution "Euler" ou "RK4"
+        constructor(rKs, rQ, rIf, rPrec, rYB, rYCL = 0, rDx = 0, rLong = 0) //, sResolution = '') {
+        {
+                //this.v.Resolution = sResolution;
+                this.v.YCL = rYCL;
+                this.v.Ks = rKs;
+                this.v.Q = rQ;
+                this.v.Long = rLong;
+                this.v.If = rIf;
+                this.v.Dx = rDx;
+                this.v.Prec = rPrec;
+                this.v.YB = rYB;
+                this.v.iPrec = -Math.log(rPrec) / Math.log(10);
+        }
+
+        get v() { return this._v; }
+}
+
+/**
+ * Gestion commune pour les différents types de section.
+ * Comprend les formules pour la section rectangulaire pour gérer les débordements
+ */
+export abstract class acSection extends Debug {
+        private _v: IParamsEquation;
+
+
+        //public Y;          /// Tirant d'eau
+        public HautCritique;  /// Tirant d'eau critique
+        public HautNormale;   /// Tirant d'eau normal
+        public oP: cParamsCanal;   /// Paramètres du système canal (classe oParam)
+        protected oLog: cLog; /// Pour l'affichage du journal de calcul
+        //public LargeurBerge; /// largeur au débordement
+        protected bSnFermee = false; /// true si la section est fermée (fente de Preissmann)
+        /**
+         * Tableau contenant les données dépendantes du tirant d'eau this->rY.
+         *
+         * Les clés du tableau peuvent être :
+         * - S : la surface hydraulique
+         * - P : le périmètre hydraulique
+         * - R : le rayon hydraulique
+         * - B : la largeur au miroir
+         * - J : la perte de charge
+         * - Fr : le nombre de Froude
+         * - dP : la dérivée de P par rapport Y
+         * - dR : la dérivée de R par rapport Y
+         * - dB : la dérivée de B par rapport Y
+         */
+        private arCalc = {};
+        protected calcGeo = {}; /// Données ne dépendant pas de la cote de l'eau
+        private Y_old; /// Mémorisation du tirant d'eau pour calcul intermédiaire
+        private Calc_old = {}; /// Mémorisation des données hydrauliques pour calcul intermédiaire
+        /**
+         * Nombre de points nécessaires pour le dessin de la section (hors point de berge)
+         * Valeur de 1 par défaut pour les sections rectangulaires et trapézoïdales
+         */
+        protected nbDessinPoints = 1;
+        /**
+         * Construction de la classe.
+         * Calcul des hauteurs normale et critique
+         */
+        constructor(oLog, oP, dbg = false) {
+                super(dbg);
+                this.oP = oP;
+                this.oLog = oLog;
+                this.CalcGeo['B'];
+
+                this._v = this.oP.v;
+                this.v.Y = 0;
+                this.v.LargeurBerge = 0;
+        }
+
+        get v() { return this._v; }
+        set v(v) { this._v = v; }
+
+        /**
+         * Efface toutes les données calculées pour forcer le recalcul
+         * @param bGeo Réinitialise les données de géométrie aussi
+         */
+        Reset(bGeo = true) {
+                this.arCalc = {};
+                if (bGeo) {
+                        this.calcGeo = {};
+                }
+        }
+        /**
+         * Mémorise les données hydraulique en cours ou les restitue
+         * @param bMem true pour mémorisation, false pour restitution
+         */
+        Swap(bMem) {
+                if (bMem) {
+                        this.Y_old = this.v.Y;
+                        this.Calc_old = this.arCalc;
+                }
+                else {
+                        this.v.Y = this.Y_old;
+                        this.arCalc = this.Calc_old;
+                        this.Calc_old = {};
+                }
+        }
+
+        /**
+         * Calcul des données à la section
+         * @param sDonnee Clé de la donnée à calculer (voir this->arCalc)
+         * @param bRecalc Pour forcer le recalcul de la donnée
+         * @return la donnée calculée
+         */
+        Calc(sDonnee, rY: number = undefined) {
+                if (rY != undefined && rY != this.v.Y) {
+                        this.v.Y = rY;
+                        // On efface toutes les données dépendantes de Y pour forcer le calcul
+                        this.Reset(false);
+                }
+                // | or || ???
+                if (this.arCalc[sDonnee] == undefined) {
+                        // La donnée a besoin d'être calculée
+                        switch (sDonnee) {
+                                case 'I-J': // Variation linéaire de l'énergie spécifique (I-J) en m/m
+                                        this.arCalc[sDonnee] = this.oP.v.If - this.Calc('J');
+                                        break;
+                                case 'Yn': // Hauteur normale
+                                        return this.Calc_Yn();
+                                default:
+                                        var methode = 'Calc_' + sDonnee;
+                                        this.arCalc[sDonnee] = this[methode]();
+                        }
+                }
+                //this.debug(sDonnee + '  ' + this.arCalc[sDonnee]);
+                return this.arCalc[sDonnee];
+        }
+
+        /**
+         * Calcul des données uniquement dépendantes de la géométrie de la section
+         * @param sDonnee Clé de la donnée à calculer (voir this->arCalcGeo)
+         * @param rY Hauteur d'eau
+         * @return la donnée calculée
+         */
+        CalcGeo(sDonnee) {
+                this.debug("in CalcGeo");
+                if (sDonnee != 'B' && !this.CalcGeo['B']) {
+                        // Si la largeur aux berges n'a pas encore été calculée, on commence par ça
+                        this.CalcGeo('B');
+                }
+                if (!this.CalcGeo[sDonnee]) {
+                        // La donnée a besoin d'être calculée
+                        this.Swap(true); // On mémorise les données hydrauliques en cours
+                        this.Reset(false);
+                        this.v.Y = this.oP.v.YB;
+                        switch (sDonnee) {
+                                case 'B': // Largeur aux berges
+                                        this.CalcGeo[sDonnee] = this.Calc_B();
+                                        if (this.calcGeo[sDonnee] < this.oP.v.YB / 100) {
+                                                // Section fermée
+                                                this.bSnFermee = true;
+                                                // On propose une fente de Preissmann égale à 1/100 de la hauteur des berges
+                                                this.CalcGeo[sDonnee] = this.oP.v.YB / 100;
+                                        }
+                                        this.v.LargeurBerge = this.CalcGeo[sDonnee];
+                                        break;
+                                default:
+                                        /*var methode = 'Calc_'+sDonnee + '()';
+                                        this.CalcGeo[sDonnee] = eval(methode);*/
+                                        var methode = 'Calc_' + sDonnee;
+                                        this.CalcGeo[sDonnee] = this[methode]();
+                                        this.debug("methodecalcgeo " + this[methode]());
+                        }
+                        //~ spip_log('CalcGeo('.sDCalcGeonnee.',rY='.this->oP->rYB.')='.this->arCalcGeo[sDonnee],'hydraulic.'._LOG_DEBUG);
+                        this.Swap(false); // On restitue les données hydrauliques en cours
+                }
+                this.debug('calcgeo  ' + sDonnee + '  ' + this.CalcGeo[sDonnee]);
+
+                return this.CalcGeo[sDonnee];
+        }
+
+        /**
+         * Calcul de la surface hydraulique.
+         * @return La surface hydraulique
+         */
+        abstract Calc_S();
+
+
+        Calc_dS() {
+                return this.Calc('B'); // largeur au miroir
+        }
+
+        /**
+         *  calcul de la surface hydraulique en cas de débordement
+         * @param Y hauteur d'eau au dela de la berge
+         **/
+        Calc_S_Debordement(Y: number) {
+                return Y * this.v.LargeurBerge;
+        }
+
+        /**
+         * Calcul de la dérivée surface hydraulique.
+         * @return La dérivée de la surface hydraulique
+         */
+        //abstract Calc_dS();
+
+        /**
+         * Calcul de la dérivée surface hydraulique en cas de débordement
+         * @return La dérivée de la surface hydraulique en cas de débordement
+         */
+        Calc_dS_Debordement() {
+                return this.v.LargeurBerge;
+        }
+
+        /**
+         * Calcul du périmètre hydraulique.
+         * @return Le périmètre hydraulique
+         */
+        abstract Calc_P();
+
+        /**
+         * Calcul du périmètre hydraulique en cas de débordement
+         * @param Y hauteur d'eau au dela de la berge
+         */
+        Calc_P_Debordement(Y: number) {
+                return 2 * Y;
+        }
+
+        /**
+         * Calcul de dérivée du périmètre hydraulique par rapport au tirant d'eau.
+         * @return dP
+         */
+        abstract Calc_dP();
+
+        /**
+         * Calcul de dérivée du périmètre hydraulique par rapport au tirant d'eau en cas de débordement
+         * @return la dérivée du périmètre hydraulique par rapport au tirant d'eau en cas de débordement
+         */
+        Calc_dP_Debordement() {
+                return 2;
+        }
+
+        /**
+         * Calcul du rayon hydraulique.
+         * @return Le rayon hydraulique
+         */
+        Calc_R() {
+                this.debug("in calc_R")
+                if (this.Calc('P') != 0) {
+                        return this.Calc('S') / this.Calc('P');
+                }
+                else {
+                        return Infinity;
+                }
+        }
+        /**
+         * Calcul de dérivée du rayon hydraulique par rapport au tirant d'eau.
+         * @return dR
+         */
+        Calc_dR() {
+                if (this.Calc('P') != 0) {
+                        return (this.Calc('B') * this.Calc('P') - this.Calc('S') * this.Calc('dP') / Math.pow(this.Calc('P'), 2));
+                }
+                else {
+                        return 0;
+                }
+        }
+
+        /**
+         * Calcul de la largeur au miroir.
+         * @return La largeur au miroir
+         */
+        abstract Calc_B();
+
+
+        /**
+           * Calcul de la largeur au miroir en cas de débordement
+           * @return La largeur au miroir en cas de débordement
+           */
+        Calc_B_Debordement() {
+                return this.v.LargeurBerge;
+        }
+
+        /**
+          * Calcul de dérivée de la largeur au miroir par rapport au tirant d'eau.
+          * @return dB
+          */
+        abstract Calc_dB();
+
+        /**
+         * Calcul de dérivée de la largeur au miroir par rapport au tirant d'eau en cas de débordement
+         * @return la dérivée de la largeur au miroir par rapport au tirant d'eau en cas de débordement
+         */
+        Calc_dB_Debordement() {
+                return 0;
+        }
+
+        /**
+         * Calcul de la perte de charge par la formule de Manning-Strickler.
+         * @return La perte de charge
+         */
+        Calc_J() {
+                if (this.Calc('R') != 0) {
+                        return Math.pow(this.Calc('V') / this.oP.v.Ks, 2) / Math.pow(this.Calc('R'), 4 / 3);
+                }
+                else {
+                        return Infinity;
+                }
+        }
+        /**
+         * Calcul du nombre de Froude.
+         * @return Le nombre de Froude
+         */
+        Calc_Fr() {
+                if (this.Calc('S') != 0) {
+                        return this.oP.v.Q / this.Calc('S') * Math.sqrt(this.Calc('B') / this.Calc('S') / this.oP.v.G);
+                }
+                else {
+                        return Infinity;
+                }
+        }
+        /**
+         * Calcul de dy/dx
+         */
+        Calc_dYdX(Y) {
+                // L'appel à Calc('J') avec Y en paramètre réinitialise toutes les données dépendantes de la ligne d'eau
+                return - (this.oP.v.If - this.Calc('J', Y) / (1 - Math.pow(this.Calc('Fr', Y), 2)));
+        }
+
+        XOR(a, b) {
+                return (a || b) && !(a && b);
+        }
+
+        /**
+         * Calcul du point suivant de la courbe de remous par la méthode Euler explicite.
+         * @return Tirant d'eau
+         */
+        Calc_Y_Euler(Y) {
+                // L'appel à Calc('J') avec Y en paramètre réinitialise toutes les données dépendantes de la ligne d'eau
+                var Y2 = Y + this.oP.v.Dx * this.Calc_dYdX(Y);
+                if (this.XOR(this.oP.v.Dx > 0, !(Y2 < this.HautCritique))) {
+                        return false;
+                } else {
+                        return Y2;
+                }
+        }
+        /**
+         * Calcul du point suivant de la courbe de remous par la méthode RK4.
+         * @return Tirant d'eau
+         */
+        Calc_Y_RK4(Y) {
+                // L'appel à Calc('J') avec Y en paramètre réinitialise toutes les données dépendantes de la ligne d'eau
+                var Dx = this.oP.v.Dx;
+                var k1 = this.Calc_dYdX(Y);
+                if (this.XOR(Dx > 0, !(Y + Dx / 2 * k1 < this.HautCritique))) { return false; }
+                var k2 = this.Calc_dYdX(Y + Dx / 2 * k1);
+                if (this.XOR(Dx > 0, !(Y + Dx / 2 * k2 < this.HautCritique))) { return false; }
+                var k3 = this.Calc_dYdX(Y + Dx / 2 * k2);
+                if (this.XOR(Dx > 0, !(Y + Dx / 2 * k3 < this.HautCritique))) { return false; }
+                var k4 = this.Calc_dYdX(Y + Dx * k3);
+                if (this.XOR(Dx > 0, !(Y + Dx / 6 * (k1 + 2 * (k2 + k3) + k4) < this.HautCritique))) { return false; }
+                return Y + Dx / 6 * (k1 + 2 * (k2 + k3) + k4);
+        }
+        /**
+         * Calcul du point suivant d'une courbe de remous
+         * @return Tirant d'eau
+         */
+        // Calc_Y(rY) {
+        // var funcCalcY = 'Calc_Y_' + this.oP.Resolution;
+        // var methods = Object.getOwnPropertyNames(this).filter(function (p) {
+        //         return typeof this[p] === 'function';
+        // });
+        // for (var m of methods) {
+        //         if (funcCalcY == m) {
+        //                 return this[funcCalcY](rY);
+        //         }
+        //         else {
+        //                 return false;
+        //         }
+        // }
+        // }
+
+        /**
+         * Calcul de la vitesse moyenne.
+         * @return Vitesse moyenne
+         */
+        Calc_V() {
+                if (this.Calc('S') != 0) {
+                        return this.oP.v.Q / this.Calc('S');
+                }
+                else {
+                        return Infinity;
+                }
+        }
+        /**
+         * Calcul de la charge spécifique.
+         * @return Charge spécifique
+         */
+        Calc_Hs() {
+                return this.v.Y + Math.pow(this.Calc('V'), 2) / (2 * this.oP.v.G);
+        }
+        /**
+         * Calcul de la charge spécifique critique.
+         * @return Charge spécifique critique
+         */
+        Calc_Hsc() {
+                this.Swap(true); // On mémorise les données hydrauliques en cours
+                // On calcule la charge avec la hauteur critique
+                var Hsc = this.Calc('Hs', this.CalcGeo('Yc'));
+                // On restitue les données initiales
+                this.Swap(false);
+                return Hsc;
+        }
+        /**
+         * Calcul du tirant d'eau critique.
+         * @return tirant d'eau critique
+         */
+        Calc_Yc() {
+                this.debug("in calcYc");
+                var hautCritique = new cHautCritique(this, this.oP);
+                /*if(!this.HautCritique == hautCritique.Newton(this.oP.YB) || !hautCritique.HasConverged()) {
+                      //traduction de code de langue:
+                      //this.oLog.Add(_T('hydraulic:h_critique')+' : '+_T('hydraulic:newton_non_convergence'),true);
+                }*/
+                this.HautCritique = hautCritique.Newton(this.oP.v.YB);
+                return this.HautCritique;
+        }
+        /**
+         * Calcul du tirant d'eau normal.
+         * @return tirant d'eau normal
+         */
+        Calc_Yn() {
+                this.debug("in calc_Yn");
+                if (this.oP.v.If <= 0) {
+                        this.HautNormale = false;
+                        //this.oLog.Add(_T('hydraulic:h_normale_pente_neg_nul'),true);
+                } else {
+                        var oHautNormale = new cHautNormale(this, this.oP);
+                        //if(!this.HautNormale == oHautNormale.Newton(this.CalcGeo('Yc')) || !oHautNormale.HasConverged()) {
+                        //this.oLog.Add(_T('hydraulic:h_normale').' : '._T('hydraulic:newton_non_convergence'),true);
+                        this.HautNormale = oHautNormale.Newton(this.CalcGeo('Yc'));
+                        this.debug("hautnormale" + this.HautNormale);
+                        //  }
+                }
+                return this.HautNormale;
+        }
+        /**
+         * Calcul du tirant d'eau fluvial.
+         * @return tirant d'eau fluvial
+         */
+        Calc_Yf() {
+                if (this.v.Y > this.CalcGeo('Yc')) {
+                        return this.v.Y;
+                }
+                else {
+                        var oHautCorrespondante = new cHautCorrespondante(this, this.oP);
+                        return oHautCorrespondante.Newton(this.Calc('Yc') * 2);
+                }
+        }
+        /**
+         * Calcul du tirant d'eau torrentiel.
+         * @return tirant d'eau torrentiel
+         */
+        Calc_Yt() {
+                if (this.v.Y < this.CalcGeo('Yc')) {
+                        return this.v.Y;
+                }
+                else {
+                        var oHautCorrespondante = new cHautCorrespondante(this, this.oP);
+                        return oHautCorrespondante.Newton(this.CalcGeo('Yc') / 2);
+                }
+        }
+        /**
+         * Calcul du tirant d'eau conjugué.
+         * @return tirant d'eau conjugué
+         */
+        Calc_Yco() {
+                var oHautConj = new cHautConjuguee(this, this.oP);
+                // Choisir une valeur initiale du bon côté de la courbe
+                if (this.Calc('Fr') < 1) {
+                        // Ecoulement fluvial, on cherche la conjuguée à partir du tirant d'eau torrentiel
+                        var Y0 = this.Calc('Yt');
+                }
+                else {
+                        // Ecoulement torrentiel, on cherche la conjuguée à partir du tirant d'eau fluvial
+                        Y0 = this.Calc('Yf');
+                }
+                /* if(!Yco = oHautConj->Newton(Y0) || !oHautConj.HasConverged()) {
+                         //this->oLog->Add(_T('hydraulic:h_conjuguee').' : '._T('hydraulic:newton_non_convergence'),true);
+                 }
+                 return Yco;*/ // c quoi Yco ?
+        }
+        /**
+         * Calcul de la contrainte de cisaillement.
+         * @return contrainte de cisaillement
+         */
+        Calc_Tau0() {
+                return 1000 * this.oP.v.G * this.Calc('R') * this.Calc('J');
+        }
+        /**
+         * Calcul de la distance du centre de gravité de la section à la surface libre
+         * multiplié par la surface hydraulique
+         * @return S x Yg
+         */
+        Calc_SYg(rY) {
+                return Math.pow(rY, 2) * this.v.LargeurBerge / 2;
+        }
+        /**
+         * Calcul de la dérivée distance du centre de gravité de la section à la surface libre
+         * multiplié par la surface hydraulique
+         * @return S x Yg
+         */
+        Calc_dSYg(rY) {
+                return rY * this.v.LargeurBerge;
+        }
+        /**
+         * Calcul de l'impulsion hydraulique.
+         * @return Impulsion hydraulique
+         */
+        Calc_Imp() {
+                return 1000 * (this.oP.v.Q * this.Calc('V') + this.oP.v.G * this.Calc('SYg'));
+        }
+        /**
+         * Calcul de l'angle Alpha entre la surface libre et le fond pour les sections circulaires.
+         * @return Angle Alpha pour une section circulaire, 0 sinon.
+         */
+        Calc_Alpha() {
+                return 0;
+        }
+        /**
+         * Calcul de la dérivée de l'angle Alpha entre la surface libre et le fond pour les sections circulaires.
+         * @return Dérivée de l'angle Alpha pour une section circulaire, 0 sinon.
+         */
+        Calc_dAlpha() {
+                return 0;
+        }
+        /**
+         * Fournit les coordonnées des points d'une demi section pour le dessin
+         * @return tableau de couples de coordonnées (x,y)
+         */
+        /*DessinCoordonnees() {
+                var Pas = this.oP.YB / this.nbDessinPoints;
+                var Points = new Array();
+                this.Swap(true); // On mémorise les données hydrauliques en cours
+                for(var Y=0; Y<this.oP.YB+Pas/2; Y=Y+Pas) {
+                        //Y boolean or what ?
+                        Points['x'][] = this.Calc('B',Y)/2;
+                        Points['y'][] = Y;
+                }
+                // On restitue les données initiales
+                this.Swap(false);
+                return Points;
+        }*/
+
+}
+
diff --git a/src/tsconfig.app.json b/src/tsconfig.app.json
index b66f5dea9bddb60494f5d16e9ce6f7ce7de5eeb1..37d0e791fd2733723c0555bcae2f8d85adbc4dc7 100644
--- a/src/tsconfig.app.json
+++ b/src/tsconfig.app.json
@@ -1,10 +1,11 @@
 {
   "extends": "../tsconfig.json",
   "compilerOptions": {
-    "types": []
+    "types": [],
+    "removeComments": false
   },
   "include": [
     "../src/**/*.ts"
   ],
   "exclude": []
-}
+}
\ No newline at end of file