From c67d1ea31b573057a71ccc2727e34d14771a5e1e Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Wed, 27 Sep 2017 11:51:51 +0200
Subject: [PATCH] =?UTF-8?q?-=20utilisation=20de=20l'enum=20ComputeTypeNode?=
 =?UTF-8?q?=20pour=20distinguer=20les=20param=C3=A8tres=20communs=20=C3=A0?=
 =?UTF-8?q?=20plusieurs=20sections=20dans=20un=20m=C3=AAme=20formulaire=20?=
 =?UTF-8?q?-=20suppression=20de=20l'enum=20SectionType?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../cond_distri/cond_distri.config.json       |   3 +-
 .../generic/calculator.component.ts           |  48 +++++-
 src/app/calculators/generic/formulaire.ts     | 138 ++++++++++++------
 src/app/calculators/generic/ngparam.ts        |  20 +--
 .../lechapt-calmon/lechapt-calmon.config.json |   3 +-
 .../section-param/section-param.config.json   |  15 +-
 .../section-param/section-param.fr.json       |   4 +-
 src/app/components/field-set/field-set.html   |   2 +-
 .../param-field-line.component.ts             |  24 ++-
 .../param-field-line/param-field-line.html    |   2 +-
 .../param-input/param-input.component.ts      |  28 ++--
 .../services/formulaire/formulaire.service.ts |  29 ++--
 src/app/services/param/param.service.ts       |  70 ++++++---
 src/app/util.ts                               |   7 +
 src/tsconfig.json                             |   3 +
 15 files changed, 271 insertions(+), 125 deletions(-)
 create mode 100644 src/app/util.ts

diff --git a/src/app/calculators/cond_distri/cond_distri.config.json b/src/app/calculators/cond_distri/cond_distri.config.json
index d5ce07670..52397b384 100644
--- a/src/app/calculators/cond_distri/cond_distri.config.json
+++ b/src/app/calculators/cond_distri/cond_distri.config.json
@@ -49,6 +49,7 @@
     },
     {
         "id": "options",
-        "idCal": "J"
+        "idCal": "J",
+        "nodeType": "CondDistri"
     }
 ]
\ No newline at end of file
diff --git a/src/app/calculators/generic/calculator.component.ts b/src/app/calculators/generic/calculator.component.ts
index 6cd3b4f59..024fabbdb 100644
--- a/src/app/calculators/generic/calculator.component.ts
+++ b/src/app/calculators/generic/calculator.component.ts
@@ -3,13 +3,13 @@ import { Response } from '@angular/http';
 import { Observable } from "rxjs/Observable";
 import 'rxjs/add/operator/toPromise';
 
-import { IParamsEquation, Nub, acSection } from "jalhyd";
+import { ComputeNodeType, IParamsEquation, Nub, acSection } from "jalhyd";
 
 import { ParamService } from '../../services/param/param.service';
 import { HttpService } from '../../services/http/http.service';
 import { FormulaireService } from '../../services/formulaire/formulaire.service';
 import { InternationalisationService } from '../../services/internationalisation/internationalisation.service';
-import { FieldSet, SelectField, SectionType, FormulaireDefinition, CalculatorType, Dependency, ExistenceDependency, ValueDependency } from '../../calculators/generic/formulaire';
+import { FieldSet, SelectField, FormulaireDefinition, CalculatorType, Dependency, ExistenceDependency, ValueDependency } from '../../calculators/generic/formulaire';
 import { NgParameter, ParamRadioConfig } from './ngparam';
 import { CalculatorResultsComponent } from '../../components/calculator-results/calculator-results.component';
 import { SectionResultsComponent } from '../../components/section-results/section-results.component';
@@ -37,6 +37,11 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
         this._calculatorType = CalculatorType[s];
     }
 
+    /**
+     * type de noeud de calcul actuel (utilisé pour les sections, à sortir de ce composant générique)
+     */
+    private _nodeType: ComputeNodeType = ComputeNodeType.SectionTrapeze;
+
     /**
      * composant d'affichage des résultats
      */
@@ -73,7 +78,7 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
     private get fieldSets(): FieldSet[] {
         if (this._formulaire == undefined)
             return [];
-        return this._formulaire.fieldSets;
+        return this._formulaire.getFieldSets(this._nodeType);
     }
 
     private loadLocalisation(): Promise<string> {
@@ -254,6 +259,10 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
         return this._formulaire.getParameterValue(symbol);
     }
 
+    protected getNodeParameterValue(nodeType: ComputeNodeType, symbol: string): number {
+        return this._formulaire.getNodeParameterValue(nodeType, symbol);
+    }
+
     private getComputedParameter(): NgParameter {
         return this._formulaire.getParamFromState(ParamRadioConfig.CAL);
     }
@@ -265,7 +274,7 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
     private addFixedResults(nDigits: number) {
         for (let p of this._formulaire.getInputParameters())
             if (p.radioState == ParamRadioConfig.FIX && p.symbol !== "Pr")
-                this.resultsComponent.addFixedResult(p, p.v, nDigits);
+                this.resultsComponent.addFixedResult(p, p.getValue(), nDigits);
     }
 
     private addSectionFixedResult(val: number, label: string, nDigits: number, drawLabel: string = undefined) {
@@ -276,13 +285,13 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
         this.sectionResultsComponent.reset();
 
         let ssf: SelectField = <SelectField>this._formulaire.getFormulaireElementById("select_section");
-        let typeSect: SectionType = FormulaireDefinition.getSectionType(ssf.getValue());
+        let typeSect: ComputeNodeType = FormulaireDefinition.getSectionType(ssf.getValue());
         var np: [acSection, IParamsEquation] = this.formulaireService.getSectionNubAndParameters(typeSect);
 
         let sect: acSection = np[0];
         let prms: IParamsEquation = np[1];
 
-        let prec: number = this.getParameterValue("Pr"); // précision
+        let prec: number = this.getNodeParameterValue(ComputeNodeType.SectionParametree, "Pr"); // précision
         let nDigits = -Math.log10(prec);
 
         let Y = prms.Y.v; // tirant d'eau original (doit être fourni à acSection.Calc() sous peine d'être modifié par les appels successifs car c'est en même temps un paramètre et une variable temporaire)
@@ -437,10 +446,37 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
             });
     }
 
+    private updateSectionType(val: string) {
+        let select_prefix: string = "select_section_";
+        //TODO ici on fait un cas particulier, il faudra sortir ça
+        if (val.startsWith(select_prefix)) {
+            let l = select_prefix.length;
+            let type: string = val.substr(l, val.length - l);
+            switch (type) {
+                case "trapez":
+                    this._nodeType = ComputeNodeType.SectionTrapeze;
+                    break;
+
+                case "rect":
+                    this._nodeType = ComputeNodeType.SectionRectangle;
+                    break;
+
+                case "circ":
+                    this._nodeType = ComputeNodeType.SectionCercle;
+                    break;
+
+                case "puiss":
+                    this._nodeType = ComputeNodeType.SectionPuissance;
+                    break;
+            }
+        }
+    }
+
     /**
      * réception d'un événement d'un select
      */
     private onSelectChanged(val: string) {
+        this.updateSectionType(val);
         this.applyDependencies();
     }
 }
diff --git a/src/app/calculators/generic/formulaire.ts b/src/app/calculators/generic/formulaire.ts
index a8c688813..a18610654 100644
--- a/src/app/calculators/generic/formulaire.ts
+++ b/src/app/calculators/generic/formulaire.ts
@@ -1,17 +1,14 @@
-import { ParamDefinition } from 'jalhyd';
+import { ComputeNodeType, ParamDefinition } from 'jalhyd';
 
 import { NgParameter, ParamRadioConfig } from '../generic/ngparam';
 import { ParamService } from '../../services/param/param.service';
 import { StringMap } from '../../stringmap';
+import { logObject } from '../../util';
 
 export enum CalculatorType {
     ConduiteDistributrice, LechaptCalmon, SectionParametree
 }
 
-export enum SectionType {
-    Trapeze, Rectangle, Cercle, Parabole
-}
-
 export class FormulaireDefinition {
     /**
      * objet JSON chargé depuis le fichier de configuration de la calculette
@@ -27,6 +24,11 @@ export class FormulaireDefinition {
 
     private _dependencies: Dependency[] = [];
 
+    /**
+     * type de noeud de calcul par défaut
+     */
+    private _defaultNodeType: ComputeNodeType;
+
     constructor(private paramService: ParamService, private _type: CalculatorType) {
     }
 
@@ -34,8 +36,14 @@ export class FormulaireDefinition {
         return this._type;
     }
 
-    public get fieldSets(): FieldSet[] {
-        return this._fieldSets;
+    public getFieldSets(nodeType: ComputeNodeType): FieldSet[] {
+        let res: FieldSet[] = [];
+
+        for (let fs of this._fieldSets)
+            if (fs.computeNodeType == nodeType || fs.computeNodeType == this._defaultNodeType)
+                res.push(fs);
+
+        return res;
     }
 
     public get dependencies(): Dependency[] {
@@ -107,14 +115,15 @@ export class FormulaireDefinition {
         return res;
     }
 
-    public getParameterValue(symbol: string): number {
+    public getNodeParameterValue(nodeType: ComputeNodeType, symbol: string): number {
         for (let fs of this._fieldSets) {
             for (let p of fs.fields) {
                 if (p instanceof NgParameter)
-                    if (p.symbol === symbol) {
+                    // if (p.computeNodeType == nodeType && (p.symbol === symbol || p.alias == symbol)) {
+                    if (p.computeNodeType == nodeType && p.symbol === symbol) {
                         switch (p.radioState) {
                             case ParamRadioConfig.FIX:
-                                return p.v;
+                                return p.getValue();
 
                             case ParamRadioConfig.VAR:
                             case ParamRadioConfig.CAL:
@@ -123,6 +132,12 @@ export class FormulaireDefinition {
                     }
             }
         }
+
+        return this.getNodeParameterValue(this._defaultNodeType, symbol);
+    }
+
+    public getParameterValue(symbol: string): number {
+        return this.getNodeParameterValue(this._defaultNodeType, symbol);
     }
 
     public getFormulaireElementById(id: string): FormulaireElement {
@@ -182,9 +197,9 @@ export class FormulaireDefinition {
         }
     }
 
-    private parse_select(field: {}): SelectField {
+    private parse_select(node_type: ComputeNodeType, field: {}): SelectField {
         let id = field["id"];
-        let res: SelectField = new SelectField(id);
+        let res: SelectField = new SelectField(node_type, id);
         let values = field["select"];
 
         for (let v of values) {
@@ -197,36 +212,44 @@ export class FormulaireDefinition {
         return res;
     }
 
-    private parse_input(fieldset: {}, field: {}): NgParameter {
-        let input_id = field["id"];
-        let res: NgParameter = this.paramService.getParameter(input_id);
-        if (res != undefined) {
-            res.unit = field["unit"];
-            let val = field["value"];
-            if (val != undefined)
-                res.v = +val;
-            res.radioConfig = NgParameter.getRadioConfig(fieldset["option"]);
-            res.radioState = ParamRadioConfig.FIX;
-            res.isDefault = false; // malgré le fait qu'il soit initialisé dans la déclaration de la classe NgParam à false, quand on relit sa valeur, il vaut undefined (merci Microsoft)
+    private parse_input(node_type: ComputeNodeType, fieldset: {}, field: {}): NgParameter {
+        let input_id: string = field["id"];
+        let res: NgParameter = this.paramService.getParameter(node_type, input_id);
+        if (res == undefined)
+            res = this.paramService.getParameter(this._defaultNodeType, input_id);
+        if (res == undefined)
+            throw "pas de paramètre '" + input_id + "' trouvé dans le noeud " + ComputeNodeType[node_type] + "(" + node_type + ") ou " + ComputeNodeType[this._defaultNodeType] + "(" + this._defaultNodeType + ")";
+
+        res.unit = field["unit"];
+        let val = field["value"];
+        if (val != undefined)
+            res.setValue(+val);
+        res.radioConfig = NgParameter.getRadioConfig(fieldset["option"]);
+        res.radioState = ParamRadioConfig.FIX;
+        res.isDefault = false; // malgré le fait qu'il soit initialisé dans la déclaration de la classe NgParam à false, quand on relit sa valeur, il vaut undefined (merci Microsoft)
+
+        this.parse_dependencies(res, field);
 
-            this.parse_dependencies(res, field);
-        }
         return res;
     }
 
     private parse_fieldset(fieldset: {}, conf_id: string) {
-        let res: FieldSet = new FieldSet(conf_id);
+        let nt: string = fieldset["nodeType"];
+        let node_type: ComputeNodeType;
+        node_type = nt == undefined ? this._defaultNodeType : ComputeNodeType[nt];
+
+        let res: FieldSet = new FieldSet(node_type, conf_id);
         this._fieldSets.push(res);
 
         let fields = fieldset["fields"];
         for (let field_index in fields) {
             let field = fields[field_index];
             if (field["type"] === "input") {
-                let param = this.parse_input(fieldset, field);
+                let param = this.parse_input(node_type, fieldset, field);
                 if (param != undefined)
                     res.addField(param);
             } else if (field["type"] === "select") {
-                let param = this.parse_select(field);
+                let param = this.parse_select(node_type, field);
                 res.addField(param);
             }
         }
@@ -234,11 +257,30 @@ export class FormulaireDefinition {
         this.parse_dependencies(res, fieldset);
     }
 
+    private getOption(option: string): string {
+        for (let conf_index in this._config) {
+            let conf = this._config[conf_index];
+            if (conf["id"] === "options")
+                return conf[option];
+        }
+
+        return undefined;
+    }
+
+    private parseNodeType() {
+        let nt: string = this.getOption("nodeType");
+        if (nt == undefined)
+            throw "l'option obligatoire 'nodeType' est absente du fichier de définition de formulaire";
+        this._defaultNodeType = ComputeNodeType[nt];
+    }
+
     public parseConfig(config: {}) {
         this._config = config;
         this._dependencies = [];
         this._defaultCalculatedParam = undefined;
 
+        this.parseNodeType();
+
         for (let conf_index in this._config) {
             let conf = this._config[conf_index];
             let conf_id: string = conf["id"];
@@ -304,15 +346,15 @@ export class FormulaireDefinition {
             console.log(d.toString());
     }
 
-    public static getSectionType(s: string): SectionType {
+    public static getSectionType(s: string): ComputeNodeType {
         if (s === "select_section_trapez")
-            return SectionType.Trapeze;
+            return ComputeNodeType.SectionTrapeze;
         if (s === "select_section_rect")
-            return SectionType.Rectangle;
+            return ComputeNodeType.SectionRectangle;
         if (s === "select_section_circ")
-            return SectionType.Cercle;
-        if (s === "select_section_para")
-            return SectionType.Parabole;
+            return ComputeNodeType.SectionCercle;
+        if (s === "select_section_puiss")
+            return ComputeNodeType.SectionPuissance;
 
         throw "Formulaire.getSectionType() : type de section '" + s + "' inconnu"
     }
@@ -323,15 +365,21 @@ export class FormulaireDefinition {
 }
 
 export abstract class FormulaireElement {
+    private _nodeType: ComputeNodeType;
     private _id: string;
     public isDisplayed: boolean;
     public label: string;
 
-    constructor(id: string) {
+    constructor(nodeType: ComputeNodeType, id: string) {
+        this._nodeType = nodeType;
         this._id = id;
         this.isDisplayed = true;
     }
 
+    get computeNodeType(): ComputeNodeType {
+        return this._nodeType;
+    }
+
     get id(): string {
         return this._id;
     }
@@ -348,16 +396,16 @@ export enum FieldType {
 }
 
 export abstract class Field extends FormulaireElement {
-    constructor(id: string, private _type: FieldType) {
-        super(id);
+    constructor(nodeType: ComputeNodeType, id: string, private _fieldType: FieldType) {
+        super(nodeType, id);
     }
 
     public get isInput(): boolean {
-        return this._type == FieldType.Input;
+        return this._fieldType == FieldType.Input;
     }
 
     public get isSelect(): boolean {
-        return this._type == FieldType.Select;
+        return this._fieldType == FieldType.Select;
     }
 
     public abstract getValue(): any;
@@ -367,8 +415,8 @@ export abstract class Field extends FormulaireElement {
 export class FieldSet extends FormulaireElement {
     private _fields: Field[];
 
-    constructor(id: string) {
-        super(id);
+    constructor(nodeType: ComputeNodeType, id: string) {
+        super(nodeType, id);
         this._fields = [];
     }
 
@@ -427,8 +475,8 @@ export class SelectField extends Field {
         return this._entries;
     }
 
-    constructor(id: string) {
-        super(id, FieldType.Select);
+    constructor(nodeType: ComputeNodeType, id: string) {
+        super(nodeType, id, FieldType.Select);
         this._entries = [];
     }
 
@@ -463,8 +511,8 @@ export class SelectField extends Field {
 export class InputField extends Field {
     private _value: any;
 
-    constructor(id: string) {
-        super(id, FieldType.Input);
+    constructor(type: ComputeNodeType, id: string) {
+        super(type, id, FieldType.Input);
     }
 
     public getValue() {
diff --git a/src/app/calculators/generic/ngparam.ts b/src/app/calculators/generic/ngparam.ts
index c68dbe4e5..4fda34057 100644
--- a/src/app/calculators/generic/ngparam.ts
+++ b/src/app/calculators/generic/ngparam.ts
@@ -1,4 +1,4 @@
-import { ParamDefinition, ParamDomainValue, ErrorMessage } from 'jalhyd';
+import { ComputeNodeType, ParamDefinition, ParamDomainValue, ErrorMessage } from 'jalhyd';
 
 import { InputField } from './formulaire';
 import { StringMap } from '../../stringmap';
@@ -32,8 +32,8 @@ export class NgParameter extends InputField {
     public maxValue: number; // valeur max dans le cas ParamRadioConfig.VAR
     public stepValue: number; // pas de progression dans le cas ParamRadioConfig.VAR
 
-    constructor(private _paramDef: ParamDefinition, id: string = undefined) {
-        super(id == undefined ? _paramDef.symbol : id);
+    constructor(private _paramDef: ParamDefinition) {
+        super(_paramDef.computeNodeType, _paramDef.symbol);
         switch (this._paramDef.getDomain().domain) {
             case ParamDomainValue.ANY:
                 this.minValue = -10;
@@ -61,20 +61,16 @@ export class NgParameter extends InputField {
         return this._paramDef.symbol;
     }
 
-    get v(): number {
-        return this._paramDef.v;
-    }
-
-    set v(val: number) {
-        this._paramDef.v = val;
-    }
+    // get alias(): string {
+    //     return this._paramDef.symbolAlias;
+    // }
 
     public getValue() {
-        return this.v;
+        return this._paramDef.v;
     }
 
     public setValue(val: number) {
-        this.v = val;
+        this._paramDef.v = val;
     }
 
     get isDefined(): boolean {
diff --git a/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json b/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
index 5ba3de5e0..77ce3598f 100644
--- a/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
+++ b/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
@@ -238,6 +238,7 @@
     },
     {
         "id": "options",
-        "idCal": "J"
+        "idCal": "J",
+        "nodeType": "LechaptCalmon"
     }
 ]
\ No newline at end of file
diff --git a/src/app/calculators/section-param/section-param.config.json b/src/app/calculators/section-param/section-param.config.json
index 2aa73b1d9..962648469 100644
--- a/src/app/calculators/section-param/section-param.config.json
+++ b/src/app/calculators/section-param/section-param.config.json
@@ -16,7 +16,7 @@
                         "id": "select_section_circ"
                     },
                     {
-                        "id": "select_section_para"
+                        "id": "select_section_puiss"
                     }
                 ]
             }
@@ -24,6 +24,7 @@
     },
     {
         "id": "fs_section_trapez",
+        "nodeType": "SectionTrapeze",
         "option": "var",
         "dep_exist": [
             {
@@ -48,6 +49,7 @@
     },
     {
         "id": "fs_section_rect",
+        "nodeType": "SectionRectangle",
         "option": "var",
         "dep_exist": [
             {
@@ -58,7 +60,7 @@
         "fields": [
             {
                 "type": "input",
-                "id": "LargeurFond",
+                "id": "LargeurBerge",
                 "unit": "m",
                 "value": 2.5
             }
@@ -66,6 +68,7 @@
     },
     {
         "id": "fs_section_circ",
+        "nodeType": "SectionCercle",
         "option": "var",
         "dep_exist": [
             {
@@ -83,12 +86,13 @@
         ]
     },
     {
-        "id": "fs_section_para",
+        "id": "fs_section_puissance",
+        "nodeType": "SectionPuissance",
         "option": "var",
         "dep_exist": [
             {
                 "refid": "select_section",
-                "refvalue": "select_section_para"
+                "refvalue": "select_section_puiss"
             }
         ],
         "fields": [
@@ -161,6 +165,7 @@
         ]
     },
     {
-        "id": "options"
+        "id": "options",
+        "nodeType": "SectionParametree"
     }
 ]
\ No newline at end of file
diff --git a/src/app/calculators/section-param/section-param.fr.json b/src/app/calculators/section-param/section-param.fr.json
index e30aac7a8..51a2fd90c 100644
--- a/src/app/calculators/section-param/section-param.fr.json
+++ b/src/app/calculators/section-param/section-param.fr.json
@@ -4,14 +4,14 @@
     "select_section_trapez": "Trapézoïdale",
     "select_section_rect": "Rectangulaire",
     "select_section_circ": "Circulaire",
-    "select_section_para": "Parabolique",
+    "select_section_puiss": "Parabolique",
     "fs_section_trapez": "Définition de la section trapézoïdale",
     "LargeurFond": "Largeur au fond",
     "Fruit": "Fruit des berges",
     "fs_section_rect": "Définition de la section rectangulaire",
     "fs_section_circ": "Définition de la section circulaire",
     "D": "Diamètre",
-    "fs_section_para": "Définition de la section parabolique",
+    "fs_section_puissance": "Définition de la section parabolique",
     "k": "Coefficient",
     "LargeurBerge": "Largeur au niveau des berges",
     "fs_bief": "Caractéristiques du bief",
diff --git a/src/app/components/field-set/field-set.html b/src/app/components/field-set/field-set.html
index 35773c065..689778a93 100644
--- a/src/app/components/field-set/field-set.html
+++ b/src/app/components/field-set/field-set.html
@@ -12,7 +12,7 @@
     </tr>
     <tr id="tr_type_section_fs" *ngFor="let p of _fieldSet.fields">
         <td *ngIf="p.isInput" colspan="5">
-            <param-field-line [symbol]=p.symbol (onRadio)=onRadioClick($event)></param-field-line>
+            <param-field-line [computeNodeType]=_fieldSet.computeNodeType [symbol]=p.symbol (onRadio)=onRadioClick($event)></param-field-line>
         </td>
         <td *ngIf="p.isSelect" colspan="5">
             <select-field-line [id]=p.id (onSelectChange)=onSelectChanged($event)></select-field-line>
diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts
index 65682d61f..a6b09030a 100644
--- a/src/app/components/param-field-line/param-field-line.component.ts
+++ b/src/app/components/param-field-line/param-field-line.component.ts
@@ -1,5 +1,7 @@
 import { Component, Input, Output, DoCheck, EventEmitter } from '@angular/core';
 
+import { ComputeNodeType } from 'jalhyd';
+
 import { ParamService } from '../../services/param/param.service';
 import { NgParameter, ParamRadioConfig } from '../../calculators/generic/ngparam';
 
@@ -35,20 +37,34 @@ export class ParamFieldLineComponent {
     }
 
     /**
-     * Parameter symbol (Q, Ks, B, ...) input attribute
+     * type de noeud de calcul
      */
+    private _computeNode: ComputeNodeType;
+
+    private get nodeType(): ComputeNodeType {
+        return this._computeNode;
+    }
+
     @Input()
-    private set symbol(s: string) {
-        this._param = this.paramService.getParameter(s);
+    private set computeNodeType(t: ComputeNodeType) {
+        this._computeNode = t;
     }
 
     /**
-     * Parameter symbol string
+     * Parameter symbol (Q, Ks, B, ...) input attribute
      */
     private get symbol(): string {
         return this._param.symbol;
     }
 
+    @Input()
+    private set symbol(s: string) {
+        this._param = this.paramService.getParameter(this._computeNode, s);
+        if (this._param == undefined)
+            throw "symbole de paramètre '" + s + "' incorrect";
+    }
+
+
     /**
      * calcule la présence du radio "paramètre fixé"
      */
diff --git a/src/app/components/param-field-line/param-field-line.html b/src/app/components/param-field-line/param-field-line.html
index 162c64fc2..c70baf871 100644
--- a/src/app/components/param-field-line/param-field-line.html
+++ b/src/app/components/param-field-line/param-field-line.html
@@ -5,7 +5,7 @@
         <!--
         <input id="champ_FT_rLargeurFond" type="text" value="2.5" maxlength="30" name="FT_rLargeurFond" />
         -->
-        <param-input [symbol]="symbol"></param-input>
+        <param-input [computeNodeType]="nodeType" [symbol]="symbol"></param-input>
     </td>
     <td align="center" class="radio_param">
         <input *ngIf="hasRadioFix()" type="radio" name="radio_param_{{symbol}}" value="fix" (click)="onRadioClick(symbol, 'fix')"
diff --git a/src/app/components/param-input/param-input.component.ts b/src/app/components/param-input/param-input.component.ts
index 9ea37e20d..a83c81ba9 100644
--- a/src/app/components/param-input/param-input.component.ts
+++ b/src/app/components/param-input/param-input.component.ts
@@ -3,14 +3,14 @@
 import { Component, Input, forwardRef, OnInit, DoCheck, ChangeDetectorRef } from '@angular/core';
 import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl } from '@angular/forms';
 
-import { ParamDefinition, NumericalString, ErrorMessage } from 'jalhyd';
+import { ComputeNodeType, ParamDefinition, NumericalString, ErrorMessage } from 'jalhyd';
 
 import { ParamService } from '../../services/param/param.service';
 import { InternationalisationService, LanguageCode } from '../../services/internationalisation/internationalisation.service';
 import { NgParameter } from '../../calculators/generic/ngparam';
 
 @Component({
-    selector: 'param-input[symbol]',
+    selector: 'param-input',
     /* OK
     <input placeholder="{{_paramDef.symbol}}" [ngModel]="_paramDef.v" (ngModelChange)="setValue($event)"/>
     <p *ngIf="_message">{{_message}}</p>
@@ -31,8 +31,18 @@ import { NgParameter } from '../../calculators/generic/ngparam';
 })
 export class ParamInputComponent implements ControlValueAccessor, OnInit, DoCheck {
     /**
-      * Parameter symbol (Q, Ks, B, ...) attribute
-      */
+     * type de noeud de calcul
+     */
+    private _computeNode: ComputeNodeType;
+
+    @Input()
+    private set computeNodeType(t: ComputeNodeType) {
+        this._computeNode = t;
+    }
+
+    /**
+     * Parameter symbol (Q, Ks, B, ...) attribute
+     */
     @Input('symbol')
     private _paramSymbol: string;
 
@@ -90,7 +100,7 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec
 
     ngOnInit() {
         // retrieve parameter from symbol
-        this._paramDef = this.paramService.getParameter(this._paramSymbol);
+        this._paramDef = this.paramService.getParameter(this._computeNode, this._paramSymbol);
     }
 
     /**
@@ -114,8 +124,8 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec
             this.updateMessage(this._uiValue);
         else {
             if (this._paramDef.isDefined) {
-                this.updateMessage(new NumericalString(this._paramDef.v));
-                this._uiValue.value = String(this._paramDef.v);
+                this.updateMessage(new NumericalString(this._paramDef.getValue()));
+                this._uiValue.value = String(this._paramDef.getValue());
             }
             else
                 this.updateMessage(this._uiValue);
@@ -163,8 +173,8 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec
         let ok: boolean = this._uiValue.isNumerical;
         if (ok) {
             try {
-                if (!this._paramDef.isDefined || this._paramDef.v != this._uiValue.numericalValue) {
-                    this._paramDef.v = this._uiValue.numericalValue;
+                if (!this._paramDef.isDefined || this._paramDef.getValue() != this._uiValue.numericalValue) {
+                    this._paramDef.setValue(this._uiValue.numericalValue);
                     this.changeDetector.detectChanges();  // provoque une détection des changements dans les contrôles
                 }
             }
diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts
index a75ea90dc..2c47590c9 100644
--- a/src/app/services/formulaire/formulaire.service.ts
+++ b/src/app/services/formulaire/formulaire.service.ts
@@ -1,14 +1,13 @@
 import { Injectable } from '@angular/core';
 import { Response } from '@angular/http';
 
-import { IParamsEquation, acSection, Nub, ConduiteDistrib, ConduiteDistribParams } from "jalhyd";
+import { ComputeNodeType, IParamsEquation, acSection, Nub, ConduiteDistrib, ConduiteDistribParams } from "jalhyd";
 import { LechaptCalmon, LechaptCalmonParams, ParamsSectionTrapez, cSnTrapez } from "jalhyd";
 import { ParamsSectionRectang, cSnRectang, ParamsSectionCirc, cSnCirc, ParamsSectionPuiss, cSnPuiss } from "jalhyd";
 
-
 import { ParamService } from '../param/param.service';
 import { HttpService } from '../../services/http/http.service';
-import { FormulaireDefinition, FormulaireElement, CalculatorType, SectionType, SelectField } from '../../calculators/generic/formulaire';
+import { FormulaireDefinition, FormulaireElement, CalculatorType, SelectField } from '../../calculators/generic/formulaire';
 import { StringMap } from '../../stringmap';
 
 @Injectable()
@@ -115,11 +114,11 @@ export class FormulaireService {
         }
     }
 
-    public getSectionNubAndParameters(st: SectionType): [acSection, IParamsEquation] {
+    public getSectionNubAndParameters(st: ComputeNodeType): [acSection, IParamsEquation] {
         let f = this.getFormulaire(CalculatorType.SectionParametree);
 
         // bief
-        let Ks = f.getParameterValue("Ks");; // Strickler
+        let Ks = f.getParameterValue("Ks"); // Strickler
         let If: number = f.getParameterValue("If"); // Pente du fond
         let YB: number = f.getParameterValue("YB"); // Hauteur de berge
 
@@ -135,35 +134,35 @@ export class FormulaireService {
         // let Long: number = f.getParameterValue("Long"); // Longueur du bief
 
         switch (st) {
-            case SectionType.Trapeze:
+            case ComputeNodeType.SectionTrapeze:
                 {
-                    let LargeurFond = f.getParameterValue("LargeurFond"); // Largeur au fond
-                    let Fruit = f.getParameterValue("Fruit"); // Fruit des berges
+                    let LargeurFond = f.getNodeParameterValue(st, "LargeurFond"); // Largeur au fond
+                    let Fruit = f.getNodeParameterValue(st, "Fruit"); // Fruit des berges
                     let prms = new ParamsSectionTrapez(LargeurFond, Fruit, Y, Ks, Q, If, Prec, YB);
                     let cn = new cSnTrapez(undefined, prms);
                     return [cn, prms];
                 }
 
-            case SectionType.Rectangle:
+            case ComputeNodeType.SectionRectangle:
                 {
-                    let LargeurFond = f.getParameterValue("LargeurFond"); // Largeur au fond
+                    let LargeurFond = f.getNodeParameterValue(st, "LargeurBerge"); // Largeur au fond
                     let prms = new ParamsSectionRectang(Y, LargeurFond, Ks, Q, If, Prec, YB);
                     let cn = new cSnRectang(undefined, prms);
                     return [cn, prms];
                 }
 
-            case SectionType.Cercle:
+            case ComputeNodeType.SectionCercle:
                 {
-                    let D = f.getParameterValue("D"); // Largeur au fond
+                    let D = f.getNodeParameterValue(st, "D"); // Largeur au fond
                     let prms = new ParamsSectionCirc(D, Y, Ks, Q, If, Prec, YB);
                     let cn = new cSnCirc(undefined, prms);
                     return [cn, prms];
                 }
 
-            case SectionType.Parabole:
+            case ComputeNodeType.SectionPuissance:
                 {
-                    let k = f.getParameterValue("k"); // coefficient
-                    let LargeurBerge = f.getParameterValue("LargeurBerge"); // Largeur au niveau des berges
+                    let k = f.getNodeParameterValue(st, "k"); // coefficient
+                    let LargeurBerge = f.getNodeParameterValue(st, "LargeurBerge"); // Largeur au niveau des berges
                     let prms = new ParamsSectionPuiss(k, Y, LargeurBerge, Ks, Q, If, Prec, YB);
                     let cn = new cSnPuiss(undefined, prms);
                     return [cn, prms];
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
index eefef0c07..e74446685 100644
--- a/src/app/services/param/param.service.ts
+++ b/src/app/services/param/param.service.ts
@@ -1,6 +1,7 @@
-import { ComputeNodeParameters, IParamsEquation, ParamDefinition, ParamDomainValue, ParamCalculability } from 'jalhyd';
+import { ParamDomain, ComputeNodeType, ComputeNodeParameters, IParamsEquation, ParamsSectionRectang, ParamDefinition, ParamDomainValue, ParamCalculability } from 'jalhyd';
 
 import { NgParameter } from "../../calculators/generic/ngparam";
+import { logObject } from '../../util';
 
 export class ParamService {
     // private _params: ParamDefinition[];
@@ -9,29 +10,45 @@ export class ParamService {
     constructor() {
         this._params = [];
 
+        this.addParameters(ComputeNodeType.CondDistri);
+        this.addParameters(ComputeNodeType.LechaptCalmon);
+        this.addParameters(ComputeNodeType.SectionTrapeze);
+        this.addParameters(ComputeNodeType.SectionRectangle);
+        this.addParameters(ComputeNodeType.SectionCercle);
+        this.addParameters(ComputeNodeType.SectionPuissance);
+
         // précision de calcul
-        let pr = new ParamDefinition('Pr', ParamDomainValue.POS, 0.001);
-        pr.calculability = ParamCalculability.FREE;
-        this._params.push(new NgParameter(pr));
-
-        this.addParameters("cond_distri");
-        this.addParameters("lechapt_calmon");
-        this.addParameters("section_param_trapez");
-        this.addParameters("section_param_rect");
-        this.addParameters("section_param_circ");
-        this.addParameters("section_param_para");
+
+        let d = new ParamDomain(ParamDomainValue.POS, 1e-10, 100);
+        let p = new ParamDefinition(ComputeNodeType.LechaptCalmon, 'Pr', d);
+        p.calculability = ParamCalculability.FREE;
+        this.addParameter(p);
+
+        p = new ParamDefinition(ComputeNodeType.CondDistri, 'Pr', d);
+        p.calculability = ParamCalculability.FREE;
+        this.addParameter(p);
+
+        p = new ParamDefinition(ComputeNodeType.SectionParametree, 'Pr', d);
+        p.calculability = ParamCalculability.FREE;
+        this.addParameter(p);
     }
 
-    private hasParameter(symbol: string): boolean {
+    private hasParameter(prm: ParamDefinition): boolean {
         for (let p of this._params)
-            if (p.symbol === symbol)
+            // if (p.computeNodeType == prm.computeNodeType && (p.symbol == prm.symbol || p.alias == prm.symbol))
+            if (p.computeNodeType == prm.computeNodeType && p.symbol == prm.symbol)
                 return true;
 
         return false;
     }
 
-    private addParameters(computeNodeName: string) {
-        let cdp: IParamsEquation = ComputeNodeParameters.getInstance().getComputeNodeParameters(computeNodeName);
+    private addParameter(p: ParamDefinition) {
+        if (!this.hasParameter(p))
+            this._params.push(new NgParameter(p));
+    }
+
+    private addParameters(nodeType: ComputeNodeType) {
+        let cdp: IParamsEquation = ComputeNodeParameters.getInstance().getComputeNodeParameters(nodeType);
         for (let pi in cdp) {
             /*
             Langage de m.... !
@@ -50,19 +67,26 @@ export class ParamService {
               if (!this.hasParameter(p.symbol)) 
                   this._params.push(new NgParameter(p));
             */
-            let p = cdp[pi];
+            let p = cdp[pi]; // on peut écrire let p:ParamDefinition = cdp[pi]; ça ne dérange pas le compilateur
             if (p instanceof ParamDefinition) // obligatoire car malgré le typage de p, p peut être = constructor ou n'importe quel autre membre
-                if (!this.hasParameter(p.symbol))
-                    this._params.push(new NgParameter(p));
+                this.addParameter(p);
         }
     }
 
-    public getParameter(s: string): NgParameter {
-        for (let p of this._params) {
-            if (p.symbol == s)
+    public getParameter(nodeType: ComputeNodeType, symbol: string): NgParameter {
+        for (let p of this._params)
+            if (p.computeNodeType == nodeType && p.symbol == symbol)
                 return p;
-        }
 
-        return undefined;
+        switch (nodeType) {
+            case ComputeNodeType.SectionCercle:
+            case ComputeNodeType.SectionPuissance:
+            case ComputeNodeType.SectionRectangle:
+            case ComputeNodeType.SectionTrapeze:
+                return this.getParameter(ComputeNodeType.SectionParametree, symbol);
+
+            default:
+                return undefined;
+        }
     }
 }
diff --git a/src/app/util.ts b/src/app/util.ts
new file mode 100644
index 000000000..b6777e733
--- /dev/null
+++ b/src/app/util.ts
@@ -0,0 +1,7 @@
+export function logObject(obj: {}, m?: string) {
+    // évite le message "Value below was evaluated just now" dans le debugger de Chrome
+    if (m == undefined)
+        console.log(JSON.stringify(obj));
+    else
+        console.log(m + " " + JSON.stringify(obj));
+}
\ No newline at end of file
diff --git a/src/tsconfig.json b/src/tsconfig.json
index 2c7260d1b..235097dff 100644
--- a/src/tsconfig.json
+++ b/src/tsconfig.json
@@ -8,6 +8,9 @@
     "experimentalDecorators": true,
     "lib": [ "es2015", "dom" ],
     "noImplicitAny": true,
+    "removeComments": true,
+    "noImplicitReturns": true,
+    "alwaysStrict": true,
     "suppressImplicitAnyIndexErrors": true
   }
 }
-- 
GitLab