From d7b4e1804a691dc32ddb64a6c9ee3eecb98211cb Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 3 Aug 2017 16:15:24 +0200
Subject: [PATCH] =?UTF-8?q?-=20d=C3=A9but=20de=20cr=C3=A9ation=20de=20la?=
 =?UTF-8?q?=20calculette=20"conduite=20distributrice"=20-=20r=C3=A9organis?=
 =?UTF-8?q?ation=20des=20r=C3=A9pertoires=20source?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/app.component.ts                      |  12 +-
 src/app/app.module.ts                         |  10 +-
 .../cond_distri/cond_distri.config.json       |  54 +++++
 .../cond_distri/cond_distri.en.json           |  10 +
 .../cond_distri/cond_distri.fr.json           |  10 +
 .../cond_distri/conddistri.component.js       |  95 +++++++++
 .../cond_distri/conddistri.component.js.map   |   1 +
 .../cond_distri/conddistri.component.ts       | 101 +++++++++
 .../field-set/field-set.component.js          |  55 +++++
 .../field-set/field-set.component.js.map      |   1 +
 .../field-set/field-set.component.ts          |  43 ++++
 src/app/components/field-set/field-set.html   |  14 ++
 .../param-field-line.component.js             |  50 +++++
 .../param-field-line.component.js.map         |   1 +
 .../param-field-line.component.ts             |  36 ++++
 .../param-field-line/param-field-line.html    |  28 +++
 .../param-input/param-input.component.html    |   2 +-
 .../param-input/param-input.component.js      | 198 ++++++++++++++++++
 .../param-input/param-input.component.js.map  |   1 +
 .../param-input/param-input.component.ts      |  14 +-
 src/app/param-service/param.service.ts        |  21 --
 src/app/services/http/http.service.js         |  49 +++++
 src/app/services/http/http.service.js.map     |   1 +
 src/app/{ => services/http}/http.service.ts   |   0
 .../internationalisation.service.js           | 119 +++++++++++
 .../internationalisation.service.js.map       |   1 +
 .../internationalisation.service.ts           |  26 ++-
 src/app/services/ngparam.js                   |  37 ++++
 src/app/services/ngparam.js.map               |   1 +
 src/app/services/ngparam.ts                   |  28 +++
 src/app/services/param/param.service.js       |  52 +++++
 src/app/services/param/param.service.js.map   |   1 +
 src/app/services/param/param.service.ts       |  58 +++++
 33 files changed, 1091 insertions(+), 39 deletions(-)
 create mode 100644 src/app/calculators/cond_distri/cond_distri.config.json
 create mode 100644 src/app/calculators/cond_distri/cond_distri.en.json
 create mode 100644 src/app/calculators/cond_distri/cond_distri.fr.json
 create mode 100644 src/app/calculators/cond_distri/conddistri.component.js
 create mode 100644 src/app/calculators/cond_distri/conddistri.component.js.map
 create mode 100644 src/app/calculators/cond_distri/conddistri.component.ts
 create mode 100644 src/app/components/field-set/field-set.component.js
 create mode 100644 src/app/components/field-set/field-set.component.js.map
 create mode 100644 src/app/components/field-set/field-set.component.ts
 create mode 100644 src/app/components/field-set/field-set.html
 create mode 100644 src/app/components/param-field-line/param-field-line.component.js
 create mode 100644 src/app/components/param-field-line/param-field-line.component.js.map
 create mode 100644 src/app/components/param-field-line/param-field-line.component.ts
 create mode 100644 src/app/components/param-field-line/param-field-line.html
 rename src/app/{ => components}/param-input/param-input.component.html (89%)
 create mode 100644 src/app/components/param-input/param-input.component.js
 create mode 100644 src/app/components/param-input/param-input.component.js.map
 rename src/app/{ => components}/param-input/param-input.component.ts (94%)
 delete mode 100644 src/app/param-service/param.service.ts
 create mode 100644 src/app/services/http/http.service.js
 create mode 100644 src/app/services/http/http.service.js.map
 rename src/app/{ => services/http}/http.service.ts (100%)
 create mode 100644 src/app/services/internationalisation/internationalisation.service.js
 create mode 100644 src/app/services/internationalisation/internationalisation.service.js.map
 rename src/app/{ => services/internationalisation}/internationalisation.service.ts (96%)
 create mode 100644 src/app/services/ngparam.js
 create mode 100644 src/app/services/ngparam.js.map
 create mode 100644 src/app/services/ngparam.ts
 create mode 100644 src/app/services/param/param.service.js
 create mode 100644 src/app/services/param/param.service.js.map
 create mode 100644 src/app/services/param/param.service.ts

diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index eff21d726..776f64968 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,30 +1,28 @@
 import { Component } from '@angular/core';
 
-import { ParamService } from './param-service/param.service';
-import { HttpService } from './http.service';
-import { InternationalisationService } from './internationalisation.service';
+import { ParamService } from './services/param/param.service';
+import { HttpService } from './services/http/http.service';
+import { InternationalisationService } from './services/internationalisation/internationalisation.service';
 
 @Component({
   selector: 'nghyd-app',
   template: `
+  <cond-distri></cond-distri>
+  <!--
   <h1>{{title}}</h1>
   <param-input symbol="Q"></param-input>
   <param-input symbol="Q"></param-input>
   <param-input symbol="Ks"></param-input>
-  <!--
   -->
   `,
   providers: [ParamService, InternationalisationService, HttpService]
 })
 export class AppComponent {
-  title = "Calculette hydro";
-
   constructor(private intlService: InternationalisationService) { }
 
   private initLocale() {
     let docLocale: string = document['locale'] as string;
     this.intlService.setLocale(docLocale);
-    //console.log("doc locale " + docLocale);
   }
 
   ngOnInit() {
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 087257e7d..f31d975f0 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -6,7 +6,10 @@ import { FormsModule } from '@angular/forms'; // <-- NgModel lives here
 import { MdInputModule } from '@angular/material';
 
 import { AppComponent } from './app.component';
-import { ParamInputComponent } from './param-input/param-input.component';
+import { ParamInputComponent } from './components/param-input/param-input.component';
+import { FieldSetComponent } from './components/field-set/field-set.component';
+import { ParamFieldLineComponent } from './components/param-field-line/param-field-line.component';
+import { CondDistriComponent } from './calculators/cond_distri/conddistri.component';
 
 @NgModule({
   imports: [
@@ -17,7 +20,10 @@ import { ParamInputComponent } from './param-input/param-input.component';
   ],
   declarations: [
     AppComponent,
-    ParamInputComponent
+    ParamInputComponent,
+    FieldSetComponent,
+    ParamFieldLineComponent,
+    CondDistriComponent
   ],
   bootstrap: [AppComponent]
 })
diff --git a/src/app/calculators/cond_distri/cond_distri.config.json b/src/app/calculators/cond_distri/cond_distri.config.json
new file mode 100644
index 000000000..d5ce07670
--- /dev/null
+++ b/src/app/calculators/cond_distri/cond_distri.config.json
@@ -0,0 +1,54 @@
+[
+    {
+        "id": "fs_hydraulique",
+        "option": "cal",
+        "fields": [
+            {
+                "type": "input",
+                "id": "Q",
+                "unit": "m³/s",
+                "value": 3
+            },
+            {
+                "type": "input",
+                "id": "D",
+                "unit": "m",
+                "value": 1.2
+            },
+            {
+                "type": "input",
+                "id": "J",
+                "unit": "m",
+                "value": 0.6
+            },
+            {
+                "type": "input",
+                "id": "Lg",
+                "unit": "m",
+                "value": 100
+            },
+            {
+                "type": "input",
+                "id": "Nu",
+                "unit": "Pa·s",
+                "value": 1E-6
+            }
+        ]
+    },
+    {
+        "id": "fs_param_calc",
+        "option": "fix",
+        "fields": [
+            {
+                "type": "input",
+                "id": "Pr",
+                "unit": "m",
+                "value": 0.001
+            }
+        ]
+    },
+    {
+        "id": "options",
+        "idCal": "J"
+    }
+]
\ No newline at end of file
diff --git a/src/app/calculators/cond_distri/cond_distri.en.json b/src/app/calculators/cond_distri/cond_distri.en.json
new file mode 100644
index 000000000..372fff647
--- /dev/null
+++ b/src/app/calculators/cond_distri/cond_distri.en.json
@@ -0,0 +1,10 @@
+{
+    "fs_hydraulique": "Hydraulic features",
+    "Q": "Flow",
+    "D": "Pipe diameter",
+    "J": "Head drop",
+    "Lg": "Pipe length",
+    "Nu": "Dynamic (shear) viscosity",
+    "fs_param_calc": "Calculation parameters",
+    "Pr": "Display accuracy"
+}
\ No newline at end of file
diff --git a/src/app/calculators/cond_distri/cond_distri.fr.json b/src/app/calculators/cond_distri/cond_distri.fr.json
new file mode 100644
index 000000000..4ca85d1b5
--- /dev/null
+++ b/src/app/calculators/cond_distri/cond_distri.fr.json
@@ -0,0 +1,10 @@
+{
+    "fs_hydraulique": "Caractéristiques hydrauliques",
+    "Q": "Débit",
+    "D": "Diamètre du tuyau",
+    "J": "Perte de charge",
+    "Lg": "Longueur du tuyau",
+    "Nu": "Viscosité dynamique",
+    "fs_param_calc": "Paramètres de calcul",
+    "Pr": "Précision de calcul"
+}
\ No newline at end of file
diff --git a/src/app/calculators/cond_distri/conddistri.component.js b/src/app/calculators/cond_distri/conddistri.component.js
new file mode 100644
index 000000000..4db6ed09a
--- /dev/null
+++ b/src/app/calculators/cond_distri/conddistri.component.js
@@ -0,0 +1,95 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var core_1 = require("@angular/core");
+var param_service_1 = require("../../services/param/param.service");
+var http_service_1 = require("../../services/http/http.service");
+var internationalisation_service_1 = require("../../services/internationalisation/internationalisation.service");
+var field_set_component_1 = require("../../components/field-set/field-set.component");
+var CondDistriComponent = (function () {
+    function CondDistriComponent(paramService, httpService, intlService) {
+        this.paramService = paramService;
+        this.httpService = httpService;
+        this.intlService = intlService;
+        this._title = "Conduite distributrice";
+        this._localisation = {};
+        this._config = {};
+        this._fieldSets = [];
+    }
+    CondDistriComponent.prototype.loadLocalisation = function () {
+        var ths = this;
+        var processData = function (s) {
+            // fermeture nécessaire pour capturer la valeur de this (undefined sinon)
+            ths._localisation = JSON.parse(s);
+            ths.paramService.updateLocalisation(ths._localisation);
+        };
+        var f = "app/calculators/cond_distri/cond_distri." + this.intlService.languageCode + ".json";
+        this.httpService.httpGetRequest(undefined, undefined, undefined, f, processData);
+    };
+    CondDistriComponent.prototype.logObject = function (obj) {
+        console.log(JSON.stringify(obj));
+    };
+    CondDistriComponent.prototype.parseConfig = function () {
+        this._fieldSets = [];
+        for (var conf_index in this._config) {
+            //this.logObject(this._fieldSets);
+            var conf = this._config[conf_index];
+            //console.log(conf);
+            var conf_id = conf["id"];
+            if (conf_id.startsWith("fs_")) {
+                var fieldSet = new field_set_component_1.FieldSet();
+                fieldSet.title = this._localisation[conf_id];
+                var fields = conf["fields"];
+                for (var field_index in fields) {
+                    var field = fields[field_index];
+                    // console.log(field);
+                    if (field["type"] === "input") {
+                        var input_id = field["id"];
+                        // console.log(input_id);
+                        var param = this.paramService.getParameter(input_id);
+                        if (param != undefined) {
+                            //this.logObject(param);
+                            fieldSet.params.push(param);
+                        }
+                    }
+                }
+                if (fieldSet.params.length > 0) {
+                    // this.logObject(fieldSet);
+                    this._fieldSets.push(fieldSet);
+                }
+            }
+        }
+    };
+    CondDistriComponent.prototype.loadConfig = function () {
+        var ths = this;
+        var processData = function (s) {
+            // fermeture nécessaire pour capturer la valeur de this (undefined sinon)
+            ths._config = JSON.parse(s);
+            ths.parseConfig();
+        };
+        var f = "app/calculators/cond_distri/cond_distri.config.json";
+        this.httpService.httpGetRequest(undefined, undefined, undefined, f, processData);
+    };
+    CondDistriComponent.prototype.ngOnInit = function () {
+        this.loadLocalisation();
+        this.loadConfig();
+    };
+    return CondDistriComponent;
+}());
+CondDistriComponent = __decorate([
+    core_1.Component({
+        selector: 'cond-distri',
+        template: "\n  <h1>{{_title}}</h1>\n  <field-set *ngFor=\"let fs of _fieldSets\" [fieldSet]=fs></field-set>\n  <!--\n  <field-set *ngFor=\"let fs of _fieldSets\" title=\"fs.title\" fields=\"fs.paramList\"></field-set>\n  <field-set title=\"titre de field set\" fields=\"Q,D\"></field-set>\n  <param-input symbol=\"Q\"></param-input>\n  <param-input symbol=\"Q\"></param-input>\n  <param-input symbol=\"Ks\"></param-input>\n  <field-set title=\"aaaa\"></field-set>\n  -->\n  "
+    }),
+    __metadata("design:paramtypes", [param_service_1.ParamService, http_service_1.HttpService, internationalisation_service_1.InternationalisationService])
+], CondDistriComponent);
+exports.CondDistriComponent = CondDistriComponent;
+//# sourceMappingURL=conddistri.component.js.map
\ No newline at end of file
diff --git a/src/app/calculators/cond_distri/conddistri.component.js.map b/src/app/calculators/cond_distri/conddistri.component.js.map
new file mode 100644
index 000000000..6c31c4ec8
--- /dev/null
+++ b/src/app/calculators/cond_distri/conddistri.component.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"conddistri.component.js","sourceRoot":"","sources":["conddistri.component.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/src/app/calculators/cond_distri/conddistri.component.ts b/src/app/calculators/cond_distri/conddistri.component.ts
new file mode 100644
index 000000000..c5cf553ed
--- /dev/null
+++ b/src/app/calculators/cond_distri/conddistri.component.ts
@@ -0,0 +1,101 @@
+import { Component, OnInit } from '@angular/core';
+
+import { ParamService } from '../../services/param/param.service';
+import { HttpService } from '../../services/http/http.service';
+import { InternationalisationService } from '../../services/internationalisation/internationalisation.service';
+import { FieldSet } from '../../components/field-set/field-set.component';
+
+@Component({
+    selector: 'cond-distri',
+    template: `
+  <h1>{{_title}}</h1>
+  <field-set *ngFor="let fs of _fieldSets" [fieldSet]=fs></field-set>
+  <!--
+  <field-set *ngFor="let fs of _fieldSets" title="fs.title" fields="fs.paramList"></field-set>
+  <field-set title="titre de field set" fields="Q,D"></field-set>
+  <param-input symbol="Q"></param-input>
+  <param-input symbol="Q"></param-input>
+  <param-input symbol="Ks"></param-input>
+  <field-set title="aaaa"></field-set>
+  -->
+  `
+})
+export class CondDistriComponent implements OnInit {
+    private _title = "Conduite distributrice";
+
+    private _localisation = {};
+    private _config = {};
+    private _fieldSets: FieldSet[] = [];
+
+    constructor(private paramService: ParamService, private httpService: HttpService, private intlService: InternationalisationService) {
+    }
+
+    private loadLocalisation() {
+        let ths = this;
+        let processData = function (s: string) {
+            // fermeture nécessaire pour capturer la valeur de this (undefined sinon)
+            ths._localisation = JSON.parse(s);
+            ths.paramService.updateLocalisation(ths._localisation);
+        }
+
+
+        let f: string = "app/calculators/cond_distri/cond_distri." + this.intlService.languageCode + ".json"
+        this.httpService.httpGetRequest(undefined, undefined, undefined, f, processData);
+    }
+
+    private logObject(obj: {}) {
+        console.log(JSON.stringify(obj));
+    }
+
+    private parseConfig() {
+        this._fieldSets = [];
+
+        for (let conf_index in this._config) {
+            //this.logObject(this._fieldSets);
+
+            let conf = this._config[conf_index];
+            //console.log(conf);
+            let conf_id: string = conf["id"];
+            if (conf_id.startsWith("fs_")) {
+                let fieldSet: FieldSet = new FieldSet();
+                fieldSet.title = this._localisation[conf_id];
+
+                let fields = conf["fields"];
+                for (let field_index in fields) {
+                    let field = fields[field_index];
+                    // console.log(field);
+                    if (field["type"] === "input") {
+                        let input_id = field["id"];
+                        // console.log(input_id);
+                        let param = this.paramService.getParameter(input_id);
+                        if (param != undefined) {
+                            //this.logObject(param);
+                            fieldSet.params.push(param);
+                        }
+                    }
+                }
+                if (fieldSet.params.length > 0) {
+                    // this.logObject(fieldSet);
+                    this._fieldSets.push(fieldSet);
+                }
+            }
+        }
+    }
+
+    private loadConfig() {
+        let ths = this;
+        let processData = function (s: string) {
+            // fermeture nécessaire pour capturer la valeur de this (undefined sinon)
+            ths._config = JSON.parse(s);
+            ths.parseConfig();
+        }
+
+        let f: string = "app/calculators/cond_distri/cond_distri.config.json"
+        this.httpService.httpGetRequest(undefined, undefined, undefined, f, processData);
+    }
+
+    ngOnInit() {
+        this.loadLocalisation();
+        this.loadConfig();
+    }
+}
diff --git a/src/app/components/field-set/field-set.component.js b/src/app/components/field-set/field-set.component.js
new file mode 100644
index 000000000..7de090967
--- /dev/null
+++ b/src/app/components/field-set/field-set.component.js
@@ -0,0 +1,55 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var core_1 = require("@angular/core");
+var ngparam_1 = require("../../services/ngparam");
+var FieldSet = (function () {
+    function FieldSet() {
+        this.params = [];
+    }
+    FieldSet.prototype.addParameter = function (prm) {
+        this.params.push(new ngparam_1.NgParameter(prm));
+    };
+    return FieldSet;
+}());
+exports.FieldSet = FieldSet;
+var FieldSetComponent = (function () {
+    function FieldSetComponent() {
+    }
+    Object.defineProperty(FieldSetComponent.prototype, "fieldSet", {
+        set: function (fs) {
+            this._fieldSet = fs;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return FieldSetComponent;
+}());
+__decorate([
+    core_1.Input(),
+    __metadata("design:type", FieldSet),
+    __metadata("design:paramtypes", [FieldSet])
+], FieldSetComponent.prototype, "fieldSet", null);
+FieldSetComponent = __decorate([
+    core_1.Component({
+        selector: "field-set",
+        templateUrl: "./field-set.html",
+        styles: [".field_set_title {\
+        font-weight: bold;\
+        margin: 0.3em 0 0.2em;\
+        padding: 0.3em;\
+        background-color: #eeeeee;\
+        }"]
+    }),
+    __metadata("design:paramtypes", [])
+], FieldSetComponent);
+exports.FieldSetComponent = FieldSetComponent;
+//# sourceMappingURL=field-set.component.js.map
\ No newline at end of file
diff --git a/src/app/components/field-set/field-set.component.js.map b/src/app/components/field-set/field-set.component.js.map
new file mode 100644
index 000000000..4dc6e9d41
--- /dev/null
+++ b/src/app/components/field-set/field-set.component.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"field-set.component.js","sourceRoot":"","sources":["field-set.component.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,sCAAiD;AAIjD,kDAAqD;AAErD;IAII;QACI,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACrB,CAAC;IAEM,+BAAY,GAAnB,UAAoB,GAAoB;QACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,qBAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IACL,eAAC;AAAD,CAAC,AAXD,IAWC;AAXY,4BAAQ;AAuBrB,IAAa,iBAAiB;IAW1B;IACA,CAAC;IALD,sBAAY,uCAAQ;aAApB,UAAqB,EAAY;YAC7B,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACxB,CAAC;;;OAAA;IAIL,wBAAC;AAAD,CAAC,AAbD,IAaC;AANG;IADC,YAAK,EAAE;8BACiB,QAAQ;qCAAR,QAAQ;iDAEhC;AATQ,iBAAiB;IAV7B,gBAAS,CAAC;QACP,QAAQ,EAAE,WAAW;QACrB,WAAW,EAAE,kBAAkB;QAC/B,MAAM,EAAE,CAAC;;;;;UAKH,CAAC;KACV,CAAC;;GACW,iBAAiB,CAa7B;AAbY,8CAAiB"}
\ No newline at end of file
diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts
new file mode 100644
index 000000000..a51264ac7
--- /dev/null
+++ b/src/app/components/field-set/field-set.component.ts
@@ -0,0 +1,43 @@
+import { Component, Input } from '@angular/core';
+
+import { ParamDefinition } from 'jalhyd';
+
+import { NgParameter } from '../../services/ngparam';
+
+export class FieldSet {
+    title: string;
+    params: NgParameter[];
+
+    constructor() {
+        this.params = [];
+    }
+
+    public addParameter(prm: ParamDefinition) {
+        this.params.push(new NgParameter(prm));
+    }
+}
+
+@Component({
+    selector: "field-set",
+    templateUrl: "./field-set.html",
+    styles: [".field_set_title {\
+        font-weight: bold;\
+        margin: 0.3em 0 0.2em;\
+        padding: 0.3em;\
+        background-color: #eeeeee;\
+        }"]
+})
+export class FieldSetComponent {
+    /**
+    * field set attribute
+    */
+    private _fieldSet: FieldSet;
+
+    @Input()
+    private set fieldSet(fs: FieldSet) {
+        this._fieldSet = fs;
+    }
+
+    constructor() {
+    }
+}
diff --git a/src/app/components/field-set/field-set.html b/src/app/components/field-set/field-set.html
new file mode 100644
index 000000000..16418ef86
--- /dev/null
+++ b/src/app/components/field-set/field-set.html
@@ -0,0 +1,14 @@
+<table>
+    <tr id="tr_type_section_fs">
+        <td colspan="5">
+            <div class="field_set_title">{{_fieldSet.title}}</div>
+            <div *ngFor="let p of _fieldSet.params">
+                <param-field-line [symbol]=p.symbol></param-field-line>
+            </div>
+        </td>
+    </tr>
+</table>
+<!--
+            <div *ngFor="let s of _fieldList">
+            <param-field-line *ngFor="let s of _fieldList" [symbol]=s></param-field-line>
+-->
\ No newline at end of file
diff --git a/src/app/components/param-field-line/param-field-line.component.js b/src/app/components/param-field-line/param-field-line.component.js
new file mode 100644
index 000000000..519eaf1e8
--- /dev/null
+++ b/src/app/components/param-field-line/param-field-line.component.js
@@ -0,0 +1,50 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var core_1 = require("@angular/core");
+var param_service_1 = require("../../services/param/param.service");
+var ParamFieldLineComponent = (function () {
+    function ParamFieldLineComponent(paramService) {
+        this.paramService = paramService;
+    }
+    Object.defineProperty(ParamFieldLineComponent.prototype, "symbol", {
+        /**
+         * Parameter symbol string
+         */
+        get: function () {
+            return this._param.symbol;
+        },
+        /**
+         * Parameter symbol (Q, Ks, B, ...) input attribute
+         */
+        set: function (s) {
+            this._param = this.paramService.getParameter(s);
+            this._label = this._param.label;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return ParamFieldLineComponent;
+}());
+__decorate([
+    core_1.Input(),
+    __metadata("design:type", String),
+    __metadata("design:paramtypes", [String])
+], ParamFieldLineComponent.prototype, "symbol", null);
+ParamFieldLineComponent = __decorate([
+    core_1.Component({
+        selector: "param-field-line",
+        templateUrl: "./param-field-line.html"
+    }),
+    __metadata("design:paramtypes", [param_service_1.ParamService])
+], ParamFieldLineComponent);
+exports.ParamFieldLineComponent = ParamFieldLineComponent;
+//# sourceMappingURL=param-field-line.component.js.map
\ No newline at end of file
diff --git a/src/app/components/param-field-line/param-field-line.component.js.map b/src/app/components/param-field-line/param-field-line.component.js.map
new file mode 100644
index 000000000..6f5f61c09
--- /dev/null
+++ b/src/app/components/param-field-line/param-field-line.component.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"param-field-line.component.js","sourceRoot":"","sources":["param-field-line.component.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,sCAAyD;AAEzD,oEAAkE;AAOlE,IAAa,uBAAuB;IAwBhC,iCAAoB,YAA0B;QAA1B,iBAAY,GAAZ,YAAY,CAAc;IAC9C,CAAC;IAbD,sBAAY,2CAAM;QAKlB;;WAEG;aACH;YACI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QAC9B,CAAC;QAdD;;WAEG;aAEH,UAAmB,CAAS;YACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QACpC,CAAC;;;OAAA;IAWL,8BAAC;AAAD,CAAC,AA1BD,IA0BC;AAdG;IADC,YAAK,EAAE;;;qDAIP;AAfQ,uBAAuB;IAJnC,gBAAS,CAAC;QACP,QAAQ,EAAE,kBAAkB;QAC5B,WAAW,EAAE,yBAAyB;KACzC,CAAC;qCAyBoC,4BAAY;GAxBrC,uBAAuB,CA0BnC;AA1BY,0DAAuB"}
\ No newline at end of file
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
new file mode 100644
index 000000000..2f3c362b4
--- /dev/null
+++ b/src/app/components/param-field-line/param-field-line.component.ts
@@ -0,0 +1,36 @@
+import { Component, Input, OnInit } from '@angular/core';
+
+import { ParamService } from '../../services/param/param.service';
+import { NgParameter } from '../../services/ngparam';
+
+@Component({
+    selector: "param-field-line",
+    templateUrl: "./param-field-line.html"
+})
+export class ParamFieldLineComponent {
+    private _param: NgParameter;
+
+    /**
+     * associated (localised) label
+     */
+    private _label: string;
+
+    /**
+     * Parameter symbol (Q, Ks, B, ...) input attribute
+     */
+    @Input()
+    private set symbol(s: string) {
+        this._param = this.paramService.getParameter(s);
+        this._label = this._param.label;
+    }
+
+    /**
+     * Parameter symbol string
+     */
+    private get symbol(): string {
+        return this._param.symbol;
+    }
+
+    constructor(private paramService: ParamService) {
+    }
+}
diff --git a/src/app/components/param-field-line/param-field-line.html b/src/app/components/param-field-line/param-field-line.html
new file mode 100644
index 000000000..2a91b84da
--- /dev/null
+++ b/src/app/components/param-field-line/param-field-line.html
@@ -0,0 +1,28 @@
+<tr id="tr_FT_rLargeurFond">
+    <td align="right">{{_label}}</td>
+
+    <td>
+        <!--
+        <input id="champ_FT_rLargeurFond" type="text" value="2.5" maxlength="30" name="FT_rLargeurFond" />
+        -->
+        <param-input [symbol]="symbol"></param-input>
+    </td>
+
+    <!--
+    <td align="center">
+        <input type="radio" id="fix_FT_rLargeurFond" name="choix_champs_FT_rLargeurFond" value="fix" onclick="gestion_radios('FT_rLargeurFond', 'fix')"
+            checked="checked" />
+    </td>
+
+    <td align="center">
+        <input type="radio" id="var_FT_rLargeurFond" name="choix_champs_FT_rLargeurFond" value="var" onclick="gestion_radios('FT_rLargeurFond', 'var')"
+        />
+    </td>
+
+    <td align="center">
+        <input type="radio" id="cal_FT_rLargeurFond" name="choix_champs_FT_rLargeurFond" value="cal" onclick="gestion_radios('FT_rLargeurFond', 'cal')"
+        />
+    </td>
+  -->
+
+</tr>
\ No newline at end of file
diff --git a/src/app/param-input/param-input.component.html b/src/app/components/param-input/param-input.component.html
similarity index 89%
rename from src/app/param-input/param-input.component.html
rename to src/app/components/param-input/param-input.component.html
index 87e6d7b2e..5d2fedc79 100644
--- a/src/app/param-input/param-input.component.html
+++ b/src/app/components/param-input/param-input.component.html
@@ -3,7 +3,7 @@ format de l'attribut i18n :
 i18n="<meaning>|<description>@@<custom id>"
 <p i18n="titre saisie|Titre du contrôle de saisie de paramètre@@titre_saisie_param">Saisie de paramètre</p>
 -->
-<p i18n="@@titre_saisie_param">Saisie de paramètre</p>
+<p *ngIf="displayTitle" i18n="@@titre_saisie_param">Saisie de paramètre</p>
 <md-input-container>
     <input mdInput placeholder="{{_paramDef.symbol}}" [ngModel]="_uiValue.uncheckedValueString" (ngModelChange)="setValue($event)"
     />
diff --git a/src/app/components/param-input/param-input.component.js b/src/app/components/param-input/param-input.component.js
new file mode 100644
index 000000000..da6c4e74c
--- /dev/null
+++ b/src/app/components/param-input/param-input.component.js
@@ -0,0 +1,198 @@
+// cf. https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var core_1 = require("@angular/core");
+var forms_1 = require("@angular/forms");
+var jalhyd_1 = require("jalhyd");
+var param_service_1 = require("../../services/param/param.service");
+var internationalisation_service_1 = require("../../services/internationalisation/internationalisation.service");
+var ParamInputComponent = ParamInputComponent_1 = (function () {
+    function ParamInputComponent(paramService, changeDetector, intlService) {
+        this.paramService = paramService;
+        this.changeDetector = changeDetector;
+        this.intlService = intlService;
+        /**
+         * flag d'affichage du titre
+         */
+        this.displayTitle = false;
+        // ControlValueAccessor interface
+        this.propagateChange = function (_) { };
+        this._id = ParamInputComponent_1._idGen++;
+        if (ParamInputComponent_1._startTime == undefined)
+            ParamInputComponent_1._startTime = new Date().getTime();
+        this._uiValue = new jalhyd_1.NumericalString();
+    }
+    ParamInputComponent.prototype.hasError = function () {
+        var res = (this._message != undefined);
+        if (res)
+            this.log("hasError : true " + this._message);
+        else
+            this.log("hasError : false");
+        return res;
+    };
+    ParamInputComponent.prototype.getSfromUI = function () {
+        return this._fromUI ? " fromUI " : " fromMODEL";
+    };
+    ParamInputComponent.prototype.getSParam = function () {
+        return " " + this._paramDef.symbol + "=" + this._paramDef.toString();
+    };
+    ParamInputComponent.prototype.getSUIvalue = function (v) {
+        if (v === void 0) { v = undefined; }
+        if (v == undefined)
+            return "  uiValue=" + this._uiValue.toString() + "";
+        return "  uiValue=" + v.toString() + "";
+    };
+    ParamInputComponent.prototype.ngOnInit = function () {
+        // retrieve parameter from symbol
+        this._paramDef = this.paramService.getParameter(this._paramSymbol);
+    };
+    // private getValue() {
+    //     if (this._paramDef.isDefined)
+    //         return this._paramDef.v;
+    //     return "";
+    //     // return this._uiValue.value;
+    // }
+    /**
+     * fonction appelée lorsque l'utilisateur fait une saisie
+     * @param event valeur du contrôle
+     */
+    ParamInputComponent.prototype.setValue = function (event) {
+        this._fromUI = true;
+        this._uiValue.value = event;
+        this.log(this._uiValue.toString());
+        return this.validateUIValue();
+    };
+    /**
+     * fonction appelée lors d'un rafraîchissement de l'UI
+     */
+    ParamInputComponent.prototype.ngDoCheck = function () {
+        this.log("ngDoCheck start : " + this.getSParam() + this.getSUIvalue() + this.getSfromUI());
+        if (this._fromUI)
+            this.updateMessage(this._uiValue);
+        else {
+            if (this._paramDef.isDefined) {
+                this.updateMessage(new jalhyd_1.NumericalString(this._paramDef.v));
+                this._uiValue.value = String(this._paramDef.v);
+            }
+            else
+                this.updateMessage(this._uiValue);
+        }
+        this.log("ngDoCheck end : " + this.getSParam() + this.getSUIvalue());
+        this._fromUI = false;
+    };
+    ParamInputComponent.prototype.updateMessage = function (v) {
+        this.log("updateMessage start :" + this.getSParam() + this.getSfromUI() + this.getSUIvalue(v) + "  message=" + this._message);
+        if (v.isNumerical) {
+            this._message = undefined;
+            try {
+                this._paramDef.checkValue(v.numericalValue);
+            }
+            catch (e) {
+                if (e instanceof jalhyd_1.ErrorMessage)
+                    this._message = this.intlService.localizeErrorMessage(e);
+                else
+                    this._message = "invalid value";
+            }
+        }
+        else {
+            switch (this.intlService.lang) {
+                case internationalisation_service_1.Language.FRENCH:
+                    this._message = "Veuillez entrer une valeur numérique";
+                    break;
+                default:
+                    this._message = "Please enter a numerical value";
+            }
+        }
+        this.log("updateMessage end :" + this.getSParam() + this.getSfromUI() + this.getSUIvalue(v) + "  message=" + this._message);
+    };
+    ParamInputComponent.prototype.validateUIValue = function () {
+        this.log("");
+        this.log("validateValue start : val '" + this._uiValue.toString() + "'" + this.getSParam() + this.getSfromUI());
+        var ok = this._uiValue.isNumerical;
+        if (ok) {
+            try {
+                if (!this._paramDef.isDefined || this._paramDef.v != this._uiValue.numericalValue) {
+                    this._paramDef.v = this._uiValue.numericalValue;
+                    this.changeDetector.detectChanges(); // provoque une détection des changements dans les contrôles
+                }
+            }
+            catch (e) {
+                ok = false;
+            }
+        }
+        if (!ok) {
+            this.log("validateValue end : " + this.getSParam());
+            var err = {
+                rangeError: {
+                    // given: val,
+                    given: this._uiValue.toString(),
+                    max: 4,
+                    min: 0
+                }
+            };
+            return err;
+        }
+        this.log("validateValue end : " + this.getSParam());
+        return null;
+    };
+    ParamInputComponent.prototype.log = function (m) {
+        // let t: number = new Date().getTime() - ParamInputComponent._startTime;
+        //   console.log("ParamInputComponent(" + this._id + ") " + t + " : " + m);
+    };
+    /*
+    //From ControlValueAccessor interface
+    writeValue(value: any) {
+        if (value !== this.innerValue) {
+            this.innerValue = value;
+        }
+    }
+    */
+    ParamInputComponent.prototype.writeValue = function (value) {
+        this.log("writeValue " + value);
+    };
+    ParamInputComponent.prototype.registerOnChange = function (fn) {
+        this.propagateChange = fn;
+    };
+    ParamInputComponent.prototype.registerOnTouched = function () { };
+    return ParamInputComponent;
+}());
+ParamInputComponent._idGen = 0; // A VIRER
+__decorate([
+    core_1.Input('symbol'),
+    __metadata("design:type", String)
+], ParamInputComponent.prototype, "_paramSymbol", void 0);
+ParamInputComponent = ParamInputComponent_1 = __decorate([
+    core_1.Component({
+        selector: 'param-input[symbol]',
+        /* OK
+        <input placeholder="{{_paramDef.symbol}}" [ngModel]="_paramDef.v" (ngModelChange)="setValue($event)"/>
+        <p *ngIf="_message">{{_message}}</p>
+        */
+        templateUrl: "./param-input.component.html",
+        providers: [
+            {
+                provide: forms_1.NG_VALUE_ACCESSOR,
+                useExisting: core_1.forwardRef(function () { return ParamInputComponent_1; }),
+                multi: true
+            },
+            {
+                provide: forms_1.NG_VALIDATORS,
+                useExisting: core_1.forwardRef(function () { return ParamInputComponent_1; }),
+                multi: true
+            }
+        ]
+    }),
+    __metadata("design:paramtypes", [param_service_1.ParamService, core_1.ChangeDetectorRef, internationalisation_service_1.InternationalisationService])
+], ParamInputComponent);
+exports.ParamInputComponent = ParamInputComponent;
+var ParamInputComponent_1;
+//# sourceMappingURL=param-input.component.js.map
\ No newline at end of file
diff --git a/src/app/components/param-input/param-input.component.js.map b/src/app/components/param-input/param-input.component.js.map
new file mode 100644
index 000000000..085cf3bd9
--- /dev/null
+++ b/src/app/components/param-input/param-input.component.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"param-input.component.js","sourceRoot":"","sources":["param-input.component.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/src/app/param-input/param-input.component.ts b/src/app/components/param-input/param-input.component.ts
similarity index 94%
rename from src/app/param-input/param-input.component.ts
rename to src/app/components/param-input/param-input.component.ts
index 6a208499f..e87dd7e08 100644
--- a/src/app/param-input/param-input.component.ts
+++ b/src/app/components/param-input/param-input.component.ts
@@ -5,8 +5,9 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl } f
 
 import { ParamDefinition, NumericalString, ErrorMessage } from 'jalhyd';
 
-import { ParamService } from '../param-service/param.service';
-import { InternationalisationService, Language } from '../internationalisation.service';
+import { ParamService } from '../../services/param/param.service';
+import { InternationalisationService, Language } from '../../services/internationalisation/internationalisation.service';
+import { NgParameter } from '../../services/ngparam';
 
 @Component({
     selector: 'param-input[symbol]',
@@ -38,7 +39,7 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec
     /**
      * managed parameter
      */
-    private _paramDef: ParamDefinition;
+    private _paramDef: NgParameter;
 
     private _message: string;
 
@@ -46,6 +47,11 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec
     private _id: number; // A VIRER
     private static _startTime: number;  // A VIRER
 
+    /**
+     * flag d'affichage du titre
+     */
+    public displayTitle: boolean = false;
+
     /**
      * true si la modification du paramètre géré vient de l'interface utilisateur
      *
@@ -93,7 +99,7 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec
     ngOnInit() {
         // retrieve parameter from symbol
         this._paramDef = this.paramService.getParameter(this._paramSymbol);
-   }
+    }
 
     // private getValue() {
     //     if (this._paramDef.isDefined)
diff --git a/src/app/param-service/param.service.ts b/src/app/param-service/param.service.ts
deleted file mode 100644
index 7b6654fea..000000000
--- a/src/app/param-service/param.service.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { ParamDefinition, ParamDomainValue, ParamCalculability } from 'jalhyd';
-
-export class ParamService {
-    private _params: ParamDefinition[];
-
-    constructor() {
-        this._params = [new ParamDefinition('Q', ParamDomainValue.POS_NULL),
-        new ParamDefinition('Ks', ParamDomainValue.POS)];
-        for (let p of this._params)
-            p.calculability = ParamCalculability.DICHO;
-    }
-
-    getParameter(s: string): ParamDefinition {
-        for (let p of this._params) {
-            if (p.symbol == s)
-                return p;
-        }
-
-        return undefined;
-    }
-}
diff --git a/src/app/services/http/http.service.js b/src/app/services/http/http.service.js
new file mode 100644
index 000000000..a16539cfa
--- /dev/null
+++ b/src/app/services/http/http.service.js
@@ -0,0 +1,49 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var core_1 = require("@angular/core");
+var http_1 = require("@angular/http");
+var HttpService = (function () {
+    function HttpService(http) {
+        this.http = http;
+    }
+    HttpService.prototype.concat = function (s1, s2) {
+        if (s1 == undefined)
+            return s2;
+        if (s2 == undefined)
+            return s1;
+        return s1 + s2;
+    };
+    HttpService.prototype.httpGetRequest = function (protocol, host, port, path, processDataCallback) {
+        var url;
+        if (protocol != undefined)
+            url = protocol + "://" + host;
+        else if (host != undefined)
+            url = host;
+        if (port != undefined)
+            url = this.concat(url, ":" + String(port));
+        var p = path === "/" ? "" : path;
+        url = this.concat(url, "/" + p);
+        //console.log(url);
+        var enc = encodeURI(url);
+        var opts = new http_1.RequestOptions();
+        this.http.get(enc, opts)
+            .map(function (res) { return res.text(); })
+            .subscribe(function (data) { return processDataCallback(data); });
+    };
+    return HttpService;
+}());
+HttpService = __decorate([
+    core_1.Injectable(),
+    __metadata("design:paramtypes", [http_1.Http])
+], HttpService);
+exports.HttpService = HttpService;
+//# sourceMappingURL=http.service.js.map
\ No newline at end of file
diff --git a/src/app/services/http/http.service.js.map b/src/app/services/http/http.service.js.map
new file mode 100644
index 000000000..cc04e15fd
--- /dev/null
+++ b/src/app/services/http/http.service.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"http.service.js","sourceRoot":"","sources":["http.service.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,sCAA2C;AAC3C,sCAAkF;AAGlF,IAAa,WAAW;IACpB,qBAAoB,IAAU;QAAV,SAAI,GAAJ,IAAI,CAAM;IAAI,CAAC;IAE3B,4BAAM,GAAd,UAAe,EAAU,EAAE,EAAU;QACjC,EAAE,CAAC,CAAC,EAAE,IAAI,SAAS,CAAC;YAChB,MAAM,CAAC,EAAE,CAAC;QAEd,EAAE,CAAC,CAAC,EAAE,IAAI,SAAS,CAAC;YAChB,MAAM,CAAC,EAAE,CAAC;QAEd,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,CAAC;IAEM,oCAAc,GAArB,UAAsB,QAAgB,EAAE,IAAY,EAAE,IAAY,EAAE,IAAY,EAAE,mBAAwC;QACtH,IAAI,GAAW,CAAC;QAChB,EAAE,CAAC,CAAC,QAAQ,IAAI,SAAS,CAAC;YACtB,GAAG,GAAG,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC;YACvB,GAAG,GAAG,IAAI,CAAC;QAEf,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC;YAClB,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAE/C,IAAI,CAAC,GAAG,IAAI,KAAK,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC;QACjC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;QAEhC,mBAAmB;QACnB,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAEzB,IAAI,IAAI,GAAG,IAAI,qBAAc,EAAE,CAAC;QAEhC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC;aACnB,GAAG,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,IAAI,EAAE,EAAV,CAAU,CAAC;aACtB,SAAS,CACV,UAAA,IAAI,IAAI,OAAA,mBAAmB,CAAC,IAAI,CAAC,EAAzB,CAAyB,CAGpC,CAAC;IACN,CAAC;IACL,kBAAC;AAAD,CAAC,AAvCD,IAuCC;AAvCY,WAAW;IADvB,iBAAU,EAAE;qCAEiB,WAAI;GADrB,WAAW,CAuCvB;AAvCY,kCAAW"}
\ No newline at end of file
diff --git a/src/app/http.service.ts b/src/app/services/http/http.service.ts
similarity index 100%
rename from src/app/http.service.ts
rename to src/app/services/http/http.service.ts
diff --git a/src/app/services/internationalisation/internationalisation.service.js b/src/app/services/internationalisation/internationalisation.service.js
new file mode 100644
index 000000000..53774e8ae
--- /dev/null
+++ b/src/app/services/internationalisation/internationalisation.service.js
@@ -0,0 +1,119 @@
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var core_1 = require("@angular/core");
+var jalhyd_1 = require("jalhyd");
+var http_service_1 = require("../http/http.service");
+/*
+  language tag : fr-FR
+  primary subcode : fr
+  optional subcode : FR
+ */
+var Language;
+(function (Language) {
+    Language[Language["FRENCH"] = 0] = "FRENCH";
+    Language[Language["ENGLISH"] = 1] = "ENGLISH";
+})(Language = exports.Language || (exports.Language = {}));
+var InternationalisationService = (function () {
+    function InternationalisationService(httpService) {
+        this.httpService = httpService;
+    }
+    Object.defineProperty(InternationalisationService.prototype, "lang", {
+        get: function () {
+            return this._lang;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    // public set lang(l: Language) {
+    //     this._lang = l;
+    //     this._sLang = Language[l];
+    // }
+    InternationalisationService.prototype.setLocale = function (tag) {
+        var l = tag.substr(0, 2).toLowerCase();
+        if (l === "en")
+            this._lang = Language.ENGLISH;
+        else if (l === "fr")
+            this._lang = Language.FRENCH;
+        else {
+            var e = new jalhyd_1.ErrorMessage(jalhyd_1.ErrorCode.ERROR_LANG_UNSUPPORTED);
+            e.extraVar["locale"] = tag;
+            throw e;
+        }
+        // this.loadErrorMessages();
+        this.httpGetErrorMessages();
+    };
+    Object.defineProperty(InternationalisationService.prototype, "languageCode", {
+        get: function () {
+            switch (this._lang) {
+                case Language.ENGLISH:
+                    return "en";
+                case Language.FRENCH:
+                    return "fr";
+                default:
+                    throw new jalhyd_1.ErrorMessage(jalhyd_1.ErrorCode.ERROR_LANG_UNSUPPORTED);
+            }
+        },
+        enumerable: true,
+        configurable: true
+    });
+    // private loadErrorMessages() {
+    //     let l;
+    //     switch (this.lang) {
+    //         case Language.FRENCH:
+    //             l = "fr";
+    //             break;
+    //         default:
+    //             l = "en";
+    //     }
+    //     let s: string = fs.readFileSync("src/error_messages." + l + ".json", "utf8");
+    //     this._errorMessages = JSON.parse(s);
+    // }
+    InternationalisationService.prototype.httpGetErrorMessages = function () {
+        var is = this;
+        var processData = function (s) {
+            // fermeture nécessaire pour capturer la valeur de this (undefined sinon)
+            is._errorMessages = JSON.parse(s);
+        };
+        var l;
+        switch (this.lang) {
+            case Language.FRENCH:
+                l = "fr";
+                break;
+            default:
+                l = "en";
+        }
+        var f = "error_messages." + l + ".json";
+        this.httpService.httpGetRequest(undefined, undefined, undefined, "locale/" + f, processData);
+    };
+    InternationalisationService.prototype.getErrorMessageFromCode = function (c) {
+        var sCode = jalhyd_1.ErrorCode[c];
+        return this._errorMessages[jalhyd_1.ErrorCode[c]];
+    };
+    InternationalisationService.prototype.replaceAll = function (str, find, replace) {
+        return str.replace(new RegExp(find, 'g'), replace);
+    };
+    InternationalisationService.prototype.localizeErrorMessage = function (r) {
+        var sCode = jalhyd_1.ErrorCode[r.code];
+        var m = this.getErrorMessageFromCode(r.code);
+        for (var k in r.extraVar) {
+            m = this.replaceAll(m, "%" + k + "%", r.extraVar[k]);
+        }
+        return m;
+    };
+    return InternationalisationService;
+}());
+InternationalisationService = __decorate([
+    core_1.Injectable(),
+    __metadata("design:paramtypes", [http_service_1.HttpService])
+], InternationalisationService);
+exports.InternationalisationService = InternationalisationService;
+//# sourceMappingURL=internationalisation.service.js.map
\ No newline at end of file
diff --git a/src/app/services/internationalisation/internationalisation.service.js.map b/src/app/services/internationalisation/internationalisation.service.js.map
new file mode 100644
index 000000000..e56486869
--- /dev/null
+++ b/src/app/services/internationalisation/internationalisation.service.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"internationalisation.service.js","sourceRoot":"","sources":["internationalisation.service.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/src/app/internationalisation.service.ts b/src/app/services/internationalisation/internationalisation.service.ts
similarity index 96%
rename from src/app/internationalisation.service.ts
rename to src/app/services/internationalisation/internationalisation.service.ts
index f38bc2c52..c7a403b23 100644
--- a/src/app/internationalisation.service.ts
+++ b/src/app/services/internationalisation/internationalisation.service.ts
@@ -2,8 +2,13 @@ import { Injectable } from '@angular/core';
 
 import { ErrorMessage, ErrorCode } from "jalhyd";
 
-import { HttpService } from "./http.service";
+import { HttpService } from "../http/http.service";
 
+/*
+  language tag : fr-FR
+  primary subcode : fr
+  optional subcode : FR
+ */
 export enum Language {
     FRENCH,
 
@@ -27,15 +32,15 @@ export class InternationalisationService {
     //     this._sLang = Language[l];
     // }
 
-    public setLocale(loc: string) {
-        let l: string = loc.substr(0, 2).toLowerCase();
+    public setLocale(tag: string) {
+        let l: string = tag.substr(0, 2).toLowerCase();
         if (l === "en")
             this._lang = Language.ENGLISH;
         else if (l === "fr")
             this._lang = Language.FRENCH;
         else {
             let e = new ErrorMessage(ErrorCode.ERROR_LANG_UNSUPPORTED);
-            e.extraVar["locale"] = loc;
+            e.extraVar["locale"] = tag;
             throw e;
         }
 
@@ -43,6 +48,19 @@ export class InternationalisationService {
         this.httpGetErrorMessages();
     }
 
+    get languageCode() {
+        switch (this._lang) {
+            case Language.ENGLISH:
+                return "en";
+
+            case Language.FRENCH:
+                return "fr";
+
+            default:
+                throw new ErrorMessage(ErrorCode.ERROR_LANG_UNSUPPORTED);
+        }
+    }
+
     // private loadErrorMessages() {
     //     let l;
     //     switch (this.lang) {
diff --git a/src/app/services/ngparam.js b/src/app/services/ngparam.js
new file mode 100644
index 000000000..a82355c0b
--- /dev/null
+++ b/src/app/services/ngparam.js
@@ -0,0 +1,37 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var NgParameter = (function () {
+    function NgParameter(_paramDef) {
+        this._paramDef = _paramDef;
+    }
+    Object.defineProperty(NgParameter.prototype, "symbol", {
+        get: function () {
+            return this._paramDef.symbol;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(NgParameter.prototype, "v", {
+        get: function () {
+            return this._paramDef.v;
+        },
+        set: function (val) {
+            this._paramDef.v = val;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(NgParameter.prototype, "isDefined", {
+        get: function () {
+            return this._paramDef.isDefined;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    NgParameter.prototype.checkValue = function (val) {
+        this._paramDef.checkValue(val);
+    };
+    return NgParameter;
+}());
+exports.NgParameter = NgParameter;
+//# sourceMappingURL=ngparam.js.map
\ No newline at end of file
diff --git a/src/app/services/ngparam.js.map b/src/app/services/ngparam.js.map
new file mode 100644
index 000000000..3247d9c03
--- /dev/null
+++ b/src/app/services/ngparam.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"ngparam.js","sourceRoot":"","sources":["ngparam.ts"],"names":[],"mappings":";;AAEA;IAGI,qBAAoB,SAA0B;QAA1B,cAAS,GAAT,SAAS,CAAiB;IAC9C,CAAC;IAED,sBAAI,+BAAM;aAAV;YACI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;QACjC,CAAC;;;OAAA;IAED,sBAAI,0BAAC;aAAL;YACI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5B,CAAC;aAED,UAAM,GAAW;YACb,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC;QAC3B,CAAC;;;OAJA;IAMD,sBAAI,kCAAS;aAAb;YACI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;QACpC,CAAC;;;OAAA;IAEM,gCAAU,GAAjB,UAAkB,GAAW;QACzB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IACL,kBAAC;AAAD,CAAC,AAzBD,IAyBC;AAzBY,kCAAW"}
\ No newline at end of file
diff --git a/src/app/services/ngparam.ts b/src/app/services/ngparam.ts
new file mode 100644
index 000000000..abe222466
--- /dev/null
+++ b/src/app/services/ngparam.ts
@@ -0,0 +1,28 @@
+import { ParamDefinition } from 'jalhyd';
+
+export class NgParameter {
+    public label: string;
+
+    constructor(private _paramDef: ParamDefinition) {
+    }
+
+    get symbol(): string {
+        return this._paramDef.symbol;
+    }
+
+    get v(): number {
+        return this._paramDef.v;
+    }
+
+    set v(val: number) {
+        this._paramDef.v = val;
+    }
+
+    get isDefined(): boolean {
+        return this._paramDef.isDefined;
+    }
+
+    public checkValue(val: number) {
+        this._paramDef.checkValue(val);
+    }
+}
diff --git a/src/app/services/param/param.service.js b/src/app/services/param/param.service.js
new file mode 100644
index 000000000..d15c94d58
--- /dev/null
+++ b/src/app/services/param/param.service.js
@@ -0,0 +1,52 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var jalhyd_1 = require("jalhyd");
+var ngparam_1 = require("../ngparam");
+var ParamService = (function () {
+    function ParamService() {
+        // this._params = [new ParamDefinition('Q', ParamDomainValue.POS_NULL),
+        // new ParamDefinition('Ks', ParamDomainValue.POS)];
+        // for (let p of this._params)
+        //     p.calculability = ParamCalculability.DICHO;
+        this._params = [];
+        // précision de calcul
+        var pr = new jalhyd_1.ParamDefinition('Pr', jalhyd_1.ParamDomainValue.POS, 0.001);
+        this._params.push(new ngparam_1.NgParameter(pr));
+        this.addParameters("cond_distri");
+    }
+    ParamService.prototype.hasParameter = function (symbol) {
+        for (var _i = 0, _a = this._params; _i < _a.length; _i++) {
+            var p = _a[_i];
+            if (p.symbol === symbol)
+                return true;
+        }
+        return false;
+    };
+    ParamService.prototype.addParameters = function (computeNodeName) {
+        var cdp = jalhyd_1.ComputeNodeParameters.getInstance().getComputeNodeParameters(computeNodeName);
+        // console.log(cdp);
+        for (var pi in cdp) {
+            var p = cdp[pi];
+            if (!this.hasParameter(p.symbol))
+                this._params.push(p);
+        }
+    };
+    ParamService.prototype.getParameter = function (s) {
+        for (var _i = 0, _a = this._params; _i < _a.length; _i++) {
+            var p = _a[_i];
+            if (p.symbol == s)
+                return p;
+        }
+        return undefined;
+    };
+    ParamService.prototype.updateLocalisation = function (loc) {
+        for (var ki in loc) {
+            var p = this.getParameter(ki);
+            if (p != undefined)
+                p.label = loc[ki];
+        }
+    };
+    return ParamService;
+}());
+exports.ParamService = ParamService;
+//# sourceMappingURL=param.service.js.map
\ No newline at end of file
diff --git a/src/app/services/param/param.service.js.map b/src/app/services/param/param.service.js.map
new file mode 100644
index 000000000..f121bd692
--- /dev/null
+++ b/src/app/services/param/param.service.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"param.service.js","sourceRoot":"","sources":["param.service.ts"],"names":[],"mappings":";;AAAA,iCAAuH;AAEvH,sCAAyC;AAEzC;IAII;QACI,uEAAuE;QACvE,oDAAoD;QACpD,8BAA8B;QAC9B,kDAAkD;QAElD,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAElB,sBAAsB;QACtB,IAAI,EAAE,GAAG,IAAI,wBAAe,CAAC,IAAI,EAAE,yBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,qBAAW,CAAC,EAAE,CAAC,CAAC,CAAC;QAEvC,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IACtC,CAAC;IAEO,mCAAY,GAApB,UAAqB,MAAc;QAC/B,GAAG,CAAC,CAAU,UAAY,EAAZ,KAAA,IAAI,CAAC,OAAO,EAAZ,cAAY,EAAZ,IAAY;YAArB,IAAI,CAAC,SAAA;YACN,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC;SACnB;QACD,MAAM,CAAC,KAAK,CAAC;IACjB,CAAC;IAEO,oCAAa,GAArB,UAAsB,eAAuB;QACzC,IAAI,GAAG,GAAoB,8BAAqB,CAAC,WAAW,EAAE,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC;QACzG,oBAAoB;QACpB,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;YACjB,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,mCAAY,GAAZ,UAAa,CAAS;QAClB,GAAG,CAAC,CAAU,UAAY,EAAZ,KAAA,IAAI,CAAC,OAAO,EAAZ,cAAY,EAAZ,IAAY;YAArB,IAAI,CAAC,SAAA;YACN,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;gBACd,MAAM,CAAC,CAAC,CAAC;SAChB;QAED,MAAM,CAAC,SAAS,CAAC;IACrB,CAAC;IAED,yCAAkB,GAAlB,UAAmB,GAA8B;QAC7C,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;YACjB,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAC9B,EAAE,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;gBACf,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC;IACL,CAAC;IACL,mBAAC;AAAD,CAAC,AArDD,IAqDC;AArDY,oCAAY"}
\ No newline at end of file
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
new file mode 100644
index 000000000..b71c2931e
--- /dev/null
+++ b/src/app/services/param/param.service.ts
@@ -0,0 +1,58 @@
+import { ComputeNodeParameters, IParamsEquation, ParamDefinition, ParamDomainValue, ParamCalculability } from 'jalhyd';
+
+import { NgParameter } from "../ngparam";
+
+export class ParamService {
+    // private _params: ParamDefinition[];
+    private _params: NgParameter[];
+
+    constructor() {
+        // this._params = [new ParamDefinition('Q', ParamDomainValue.POS_NULL),
+        // new ParamDefinition('Ks', ParamDomainValue.POS)];
+        // for (let p of this._params)
+        //     p.calculability = ParamCalculability.DICHO;
+
+        this._params = [];
+
+        // précision de calcul
+        let pr = new ParamDefinition('Pr', ParamDomainValue.POS, 0.001);
+        this._params.push(new NgParameter(pr));
+
+        this.addParameters("cond_distri");
+    }
+
+    private hasParameter(symbol: string): boolean {
+        for (let p of this._params) {
+            if (p.symbol === symbol)
+                return true;
+        }
+        return false;
+    }
+
+    private addParameters(computeNodeName: string) {
+        let cdp: IParamsEquation = ComputeNodeParameters.getInstance().getComputeNodeParameters(computeNodeName);
+        // console.log(cdp);
+        for (let pi in cdp) {
+            let p = cdp[pi];
+            if (!this.hasParameter(p.symbol))
+                this._params.push(p);
+        }
+    }
+
+    getParameter(s: string): NgParameter {
+        for (let p of this._params) {
+            if (p.symbol == s)
+                return p;
+        }
+
+        return undefined;
+    }
+
+    updateLocalisation(loc: { [key: string]: string }) {
+        for (let ki in loc) {
+            let p = this.getParameter(ki);
+            if (p != undefined)
+                p.label = loc[ki];
+        }
+    }
+}
-- 
GitLab