diff --git a/e2e/calculate-all-params.e2e-spec.ts b/e2e/calculate-all-params.e2e-spec.ts index 9533c2fca374524be2406530d9c2c63526783d37..f865b65b4acae6de12ea0668c6806f48a2e0e41d 100644 --- a/e2e/calculate-all-params.e2e-spec.ts +++ b/e2e/calculate-all-params.e2e-spec.ts @@ -23,6 +23,7 @@ describe("ngHyd − calculate all parameters of all calculators", () => { 11, 12, 13, 15, 17, 18, 19, 20, 21, // 22 - Solveur is not calculated here because it is not independent + 23, 24, 25 ]; // for each calculator diff --git a/e2e/calculator.po.ts b/e2e/calculator.po.ts index 59910d18d4cca60e5cae4b6dbbace582f84701d2..c324c85c35fd2981e3f79ea227d0dbe962da3a1c 100644 --- a/e2e/calculator.po.ts +++ b/e2e/calculator.po.ts @@ -196,10 +196,12 @@ export class CalculatorPage { const inputs = this.getParamInputs(); await inputs.each(async (i) => { if (await i.isDisplayed()) { + // N in YAXN child of SPP module must not be float + const isN = (await i.getAttribute("id")).includes("_N"); // @TODO strengthen this clodo test const hasDot = (await i.getAttribute("value")).includes("."); const hasExponent = (await i.getAttribute("value")).includes("e"); let keys = "" + Math.floor(Math.random() * 9) + 1; - if (! hasDot && ! hasExponent) { + if (! hasDot && ! hasExponent && ! isN) { keys = "." + keys; } await i.sendKeys(keys); diff --git a/e2e/check-translations.e2e-spec.ts b/e2e/check-translations.e2e-spec.ts index b0c10f97084467c212a1497b3425d4b21b9cbe47..69b622c5962ad22d05a394779a253e3dfdc5c113 100644 --- a/e2e/check-translations.e2e-spec.ts +++ b/e2e/check-translations.e2e-spec.ts @@ -25,7 +25,7 @@ describe("ngHyd − check translation of all calculators", () => { }); // get calculators list (IDs) @TODO read it from config, but can't import jalhyd here :/ - const calcTypes = [ 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 17, 18, 19, 20, 21, 22 ]; + const calcTypes = [ 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25 ]; // options of "Language" selector on preferences page const langs = [ "English", "Français" ]; diff --git a/e2e/clone-all-calc.e2e-spec.ts b/e2e/clone-all-calc.e2e-spec.ts index 8c32c1ff622ac258da4f6cd15fc6e03d7c434146..95168422ee8dd785c34b8602bfb069d271cfbb2c 100644 --- a/e2e/clone-all-calc.e2e-spec.ts +++ b/e2e/clone-all-calc.e2e-spec.ts @@ -23,6 +23,7 @@ describe("ngHyd − clone all calculators with all possible <select> values", () 11, 12, 13, 15, 17, 18, 19, 20, 21, // 22 - Solveur is not cloned here because it is not independent + 23, 24, 25 ]; // for each calculator diff --git a/jalhyd_branch b/jalhyd_branch index 27ca6c76e1b922d9099ed9e32d0ff1db90526ce3..3655f37254651c8ed297a08824278f2d111e642e 100644 --- a/jalhyd_branch +++ b/jalhyd_branch @@ -1 +1 @@ -165-ajout-de-la-loi-d-ouvrage-de-deversoir-noye +160-ajout-du-module-mathematique-y-a-x-b diff --git a/src/app/calculators/spp/spp.config.json b/src/app/calculators/spp/spp.config.json new file mode 100644 index 0000000000000000000000000000000000000000..0c3c2427242c7a15825837810866460d93f825a8 --- /dev/null +++ b/src/app/calculators/spp/spp.config.json @@ -0,0 +1,38 @@ +[ + { + "id": "fs_spp", + "type": "fieldset", + "defaultOperation": "SUM", + "fields": [ + { + "id": "select_spp_operation", + "type": "select", + "source": "spp_operation" + }, + "Y" + ] + }, + { + "id": "fs_yaxn", + "type": "fieldset_template", + "calcType": "YAXN", + "fields": [ + "A", + "X", + "N" + ] + }, + { + "id": "yaxn_container", + "type": "template_container", + "templates": [ + "fs_yaxn" + ] + }, + { + "type": "options", + "idCal": "Y", + "operationSelectId": "select_spp_operation", + "_help": "util/trigo.html" + } +] \ No newline at end of file diff --git a/src/app/calculators/spp/spp.en.json b/src/app/calculators/spp/spp.en.json new file mode 100644 index 0000000000000000000000000000000000000000..cbc4a10f3562024223f4537006b243e6b316b3ec --- /dev/null +++ b/src/app/calculators/spp/spp.en.json @@ -0,0 +1,17 @@ +{ + "fs_spp": "Parameters", + + "select_spp_operation": "Operation", + "select_spp_operation_0": "Sum", + "select_spp_operation_1": "Product", + + "Y": "Y", + + "yaxn_container": "Powers", + + "fs_yaxn": "Power", + + "A": "A", + "X": "X", + "N": "N" +} \ No newline at end of file diff --git a/src/app/calculators/spp/spp.fr.json b/src/app/calculators/spp/spp.fr.json new file mode 100644 index 0000000000000000000000000000000000000000..dd2ae4c5b2f68fead14d3e1e64e0ec221cdd1237 --- /dev/null +++ b/src/app/calculators/spp/spp.fr.json @@ -0,0 +1,17 @@ +{ + "fs_spp": "Paramètres", + + "select_spp_operation": "Opération", + "select_spp_operation_0": "Somme", + "select_spp_operation_1": "Produit", + + "Y": "Y", + + "yaxn_container": "Puissances", + + "fs_yaxn": "Puissance", + + "A": "A", + "X": "X", + "N": "N" +} \ No newline at end of file diff --git a/src/app/calculators/trigo/trigo.config.json b/src/app/calculators/trigo/trigo.config.json new file mode 100644 index 0000000000000000000000000000000000000000..6dbb51a8c4590022f6b10d9fc72652b9c7682b63 --- /dev/null +++ b/src/app/calculators/trigo/trigo.config.json @@ -0,0 +1,32 @@ +[ + { + "id": "fs_trigo", + "type": "fieldset", + "defaultOperation": "COS", + "defaultUnit": "DEG", + "fields": [ + { + "id": "select_operation", + "type": "select", + "source": "trigo_operation" + }, + { + "id": "select_unit", + "type": "select", + "source": "trigo_unit" + } + ] + }, + { + "id": "fs_params", + "type": "fieldset", + "fields": [ "X", "Y" ] + }, + { + "type": "options", + "idCal": "Y", + "operationSelectId": "select_operation", + "unitSelectId": "select_unit", + "_help": "util/trigo.html" + } +] \ No newline at end of file diff --git a/src/app/calculators/trigo/trigo.en.json b/src/app/calculators/trigo/trigo.en.json new file mode 100644 index 0000000000000000000000000000000000000000..9208d6dcaed2d4670e24fe0729678c00fac881dc --- /dev/null +++ b/src/app/calculators/trigo/trigo.en.json @@ -0,0 +1,20 @@ +{ + "fs_trigo": "Trigonometric parameters", + + "select_operation": "Operation", + "select_operation_0": "cos", + "select_operation_1": "sin", + "select_operation_2": "tan", + "select_operation_3": "cosh", + "select_operation_4": "sinh", + "select_operation_5": "tanh", + + "select_unit": "Unit", + "select_unit_0": "Degrees", + "select_unit_1": "Radians", + + "fs_params": "Equation parameters", + + "X": "X", + "Y": "Y" +} \ No newline at end of file diff --git a/src/app/calculators/trigo/trigo.fr.json b/src/app/calculators/trigo/trigo.fr.json new file mode 100644 index 0000000000000000000000000000000000000000..15c5a8a4eaaeb08f0ba37d9cc332e6e2c8a4b52d --- /dev/null +++ b/src/app/calculators/trigo/trigo.fr.json @@ -0,0 +1,20 @@ +{ + "fs_trigo": "Paramètres trigonométriques", + + "select_operation": "Opération", + "select_operation_0": "cos", + "select_operation_1": "sin", + "select_operation_2": "tan", + "select_operation_3": "cosh", + "select_operation_4": "sinh", + "select_operation_5": "tanh", + + "select_unit": "Unité", + "select_unit_0": "Degrés", + "select_unit_1": "Radians", + + "fs_params": "Paramètres de l'équation", + + "X": "X", + "Y": "Y" +} \ No newline at end of file diff --git a/src/app/calculators/yaxb/yaxb.config.json b/src/app/calculators/yaxb/yaxb.config.json new file mode 100644 index 0000000000000000000000000000000000000000..1a02898b73e6ad4d0d99160054e9b9608b6cec18 --- /dev/null +++ b/src/app/calculators/yaxb/yaxb.config.json @@ -0,0 +1,12 @@ +[ + { + "id": "fs_yaxb", + "type": "fieldset", + "fields": [ "Y", "A", "X", "B" ] + }, + { + "type": "options", + "idCal": "Y", + "_help": "util/yaxb.html" + } +] \ No newline at end of file diff --git a/src/app/calculators/yaxb/yaxb.en.json b/src/app/calculators/yaxb/yaxb.en.json new file mode 100644 index 0000000000000000000000000000000000000000..a3595ae59ad8bbdccab7c9c9b2398f64e279f596 --- /dev/null +++ b/src/app/calculators/yaxb/yaxb.en.json @@ -0,0 +1,8 @@ +{ + "fs_yaxb": "Equation parameters", + + "Y": "Y", + "A": "A", + "X": "X", + "B": "B" +} \ No newline at end of file diff --git a/src/app/calculators/yaxb/yaxb.fr.json b/src/app/calculators/yaxb/yaxb.fr.json new file mode 100644 index 0000000000000000000000000000000000000000..97f602e313f8419c7c5cf10da2dfd71ce7faeb5a --- /dev/null +++ b/src/app/calculators/yaxb/yaxb.fr.json @@ -0,0 +1,8 @@ +{ + "fs_yaxb": "Paramètres de l'équation", + + "Y": "Y", + "A": "A", + "X": "X", + "B": "B" +} \ No newline at end of file diff --git a/src/app/components/calculator-list/calculator-list.component.ts b/src/app/components/calculator-list/calculator-list.component.ts index 94552a7d5f97a6680ad543569b18048308af6d1f..7e801fc650a1145c914b44e84d4d7d604fc1a723 100644 --- a/src/app/components/calculator-list/calculator-list.component.ts +++ b/src/app/components/calculator-list/calculator-list.component.ts @@ -12,6 +12,7 @@ import { FormulairePab } from "../../formulaire/definition/concrete/form-pab"; import { HttpService } from "../../services/http.service"; import { AppComponent } from "../../app.component"; import { FormulaireMacrorugoCompound } from "../../formulaire/definition/concrete/form-macrorugo-compound"; +import { FormulaireSPP } from "../../formulaire/definition/concrete/form-spp"; @Component({ @@ -87,6 +88,7 @@ export class CalculatorListComponent implements OnInit { t !== CalculatorType.Structure && t !== CalculatorType.Section && t !== CalculatorType.CloisonAval + && t !== CalculatorType.YAXN ) { unusedTheme.calculators.push({ type: t, @@ -135,6 +137,15 @@ export class CalculatorListComponent implements OnInit { } } } + // on ajoute un YAXN après l'ouverture du module de calcul "somme / produit de puissances" + if (f instanceof FormulaireSPP) { + for (const e of f.allFormElements) { + if (e instanceof FieldsetContainer) { + e.addFromTemplate(0); + break; + } + } + } }); } @@ -196,7 +207,9 @@ export class CalculatorListComponent implements OnInit { public onKC() { for (const i of this.items) { - i.image.path = "assets/images/themes/sp.jpg"; + const img = [ "assets/images/themes/sp.jpg", "assets/images/themes/autres.jpg" ]; + const idx = Math.floor(Math.random() * 2); + i.image.path = img[idx]; i.image.credits = "lol"; } } diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts index 17b4a031842cd12a666edb9e49018c440fef991b..8f22524ebefbcd33f6350777ceabc413423df9e4 100644 --- a/src/app/components/fieldset-container/fieldset-container.component.ts +++ b/src/app/components/fieldset-container/fieldset-container.component.ts @@ -67,7 +67,7 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit { public constructor(private i18nService: I18nService) {} /** - * Ajoute un nouveau sous-nub (Structure, PabCloisons selon le cas) + * Ajoute un nouveau sous-nub (Structure, PabCloisons, YAXN… selon le cas) * dans un nouveau fieldset */ private addSubNub(after?: FieldSet, clone: boolean = false) { @@ -75,11 +75,12 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit { const newFs = this._container.addFromTemplate(0, after.indexAsKid()); if (clone) { // replace in-place to change properties (overkill) + // @TODO why only those two ? loop over all properties in a generic way ? newFs.setPropValue("structureType", after.properties.getPropValue("structureType")); newFs.setPropValue("loiDebit", after.properties.getPropValue("loiDebit")); - // after.nub.properties + // copy param values for (const p of after.nub.prms) { - newFs.nub.getParameter(p.symbol).singleValue = p.singleValue; + newFs.nub.getParameter(p.symbol).loadObjectRepresentation(p.objectRepresentation()); } } } else { diff --git a/src/app/components/fixedvar-results/fixed-results.component.ts b/src/app/components/fixedvar-results/fixed-results.component.ts index 5d676ff58a6c1cd83ee93042e48aca5179695aa9..ab00d23500b5ffc722e01a3bcae00b68a843ccd4 100644 --- a/src/app/components/fixedvar-results/fixed-results.component.ts +++ b/src/app/components/fixedvar-results/fixed-results.component.ts @@ -8,7 +8,7 @@ import { FormulaireService } from "../../services/formulaire.service"; import { ResultsComponent } from "./results.component"; import { AppComponent } from "../../app.component"; -import { Structure, capitalize } from "jalhyd"; +import { capitalize } from "jalhyd"; import { sprintf } from "sprintf-js"; @@ -95,10 +95,14 @@ export class FixedResultsComponent extends ResultsComponent { for (const fp of this.fixedParams) { if (fp.symbol === symbol) { let label = this.formattedLabel(fp); - // add structure position before label - if (fp.paramDefinition.parentNub instanceof Structure) { - const pos = fp.paramDefinition.parentNub.findPositionInParent(); - label = this.intlService.localizeText("INFO_OUVRAGE") + " n°" + (pos + 1) + ": " + label; + const nub = fp.paramDefinition.parentNub; + // add child type and position before label + if (nub && nub.parent && nub.parent.childrenType) { + const pos = nub.findPositionInParent(); + // label = this.intlService.localizeText("INFO_OUVRAGE") + " n°" + (pos + 1) + ": " + label; + const cn = capitalize(this.intlService.childName(nub.parent)); + label = sprintf(this.intlService.localizeText("INFO_STUFF_N"), cn) + + (pos + 1) + ": " + label; } label += this._fixedResults.getHelpLink(symbol); data.push({ @@ -189,10 +193,14 @@ export class FixedResultsComponent extends ResultsComponent { // 1. fixed parameters for (const fp of this.fixedParams) { let label = this.formattedLabel(fp); - // add structure position before label - if (fp.paramDefinition.parentNub instanceof Structure) { - const pos = fp.paramDefinition.parentNub.findPositionInParent(); - label = this.intlService.localizeText("INFO_OUVRAGE") + " n°" + (pos + 1) + ": " + label; + const nub = fp.paramDefinition.parentNub; + // add child type and position before label + if (nub && nub.parent && nub.parent.childrenType) { + const pos = nub.findPositionInParent(); + // label = this.intlService.localizeText("INFO_OUVRAGE") + " n°" + (pos + 1) + ": " + label; + const cn = capitalize(this.intlService.childName(nub.parent)); + label = sprintf(this.intlService.localizeText("INFO_STUFF_N"), cn) + + (pos + 1) + ": " + label; } label += this._fixedResults.getHelpLink(fp.symbol); data.push({ diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.html b/src/app/components/fixedvar-results/fixedvar-results.component.html index 0b7fc09fc5ae489d93a4520fb4c4083a83c2cae9..7676b026859cc72cbef157cf5b94edaa9a57d1d4 100644 --- a/src/app/components/fixedvar-results/fixedvar-results.component.html +++ b/src/app/components/fixedvar-results/fixedvar-results.component.html @@ -2,7 +2,7 @@ <!-- journal --> <log></log> - <results-chart *ngIf="showVarResults"></results-chart> + <results-chart [hidden]="! showVarResultsChart"></results-chart> <div> <!-- table des résultats fixés --> diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.ts b/src/app/components/fixedvar-results/fixedvar-results.component.ts index 813d377388bd7df11008b45f2c7e470ebfb53494..58bbbf90ce9027236b72fed848e2bbc46a772dbf 100644 --- a/src/app/components/fixedvar-results/fixedvar-results.component.ts +++ b/src/app/components/fixedvar-results/fixedvar-results.component.ts @@ -167,6 +167,13 @@ export class FixedVarResultsComponent extends ResultsComponent implements DoChec return this._varResults && this._varResults.hasResults; } + /** + * affichage du graphique des résultats variés + */ + public get showVarResultsChart(): boolean { + return this._varResults && this._varResults.hasPlottableResults; + } + public getFixedResultClass(i: number) { // tslint:disable-next-line:no-bitwise return "result_id_" + String(i & 1); diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts index ddc8c982456a20fcbb59cfd187fe2c4c48adfab7..55795bf09cad69d49e958d137669b3e6c3110f03 100644 --- a/src/app/components/generic-calculator/calculator.component.ts +++ b/src/app/components/generic-calculator/calculator.component.ts @@ -329,8 +329,9 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe public get calculatorsUsingThisOne(): any { const sources = Session.getInstance().getDependingNubs(this._formulaire.currentNub.uid, undefined, true, true); return sources.map((s) => { + const form = this.formulaireService.getFormulaireFromNubId(s.uid); return { - label: this.formulaireService.getFormulaireFromNubId(s.uid).calculatorName, + label: (form !== undefined) ? form.calculatorName : "unknown Nub", uid: s.uid }; }); diff --git a/src/app/components/generic-input/generic-input.component.ts b/src/app/components/generic-input/generic-input.component.ts index f49b62c0e4ebdfc7d6f8815b6266a017f9db1ae6..0e946cfed7e85da247d361a39223b2c21dee94e4 100644 --- a/src/app/components/generic-input/generic-input.component.ts +++ b/src/app/components/generic-input/generic-input.component.ts @@ -1,6 +1,6 @@ import { Input, Output, EventEmitter, ChangeDetectorRef, OnChanges, ViewChild } from "@angular/core"; import { NgModel } from "@angular/forms"; -import { isNumeric, Structure, Pab, MacrorugoCompound } from "jalhyd"; +import { isNumeric, Structure, Pab, MacrorugoCompound, SPP } from "jalhyd"; import { FormulaireDefinition } from "../../formulaire/definition/form-definition"; import { NgParameter } from "../../formulaire/ngparam"; import { I18nService } from "../../services/internationalisation.service"; @@ -42,10 +42,9 @@ export abstract class GenericInputComponent implements OnChanges { if (this._model instanceof NgParameter) { const param = this._model as NgParameter; id = param.symbol; - // if inside a nested Structure, prefix with Structure position - // to disambiguate + // if inside a child Nub, prefix with child position to disambiguate const nub = param.paramDefinition.parentNub; - if (nub && (nub instanceof Structure || nub.parent instanceof Pab || nub.parent instanceof MacrorugoCompound)) { + if (nub && nub.parent && nub.parent.childrenType) { id = nub.findPositionInParent() + "_" + id; } } diff --git a/src/app/components/param-computed/param-computed.component.ts b/src/app/components/param-computed/param-computed.component.ts index b6779c083d1b94e387982d52039ecf76caa40851..54bbe75fb9a94dcd6d9c9e3b8046aae442fbc1ae 100644 --- a/src/app/components/param-computed/param-computed.component.ts +++ b/src/app/components/param-computed/param-computed.component.ts @@ -25,10 +25,9 @@ export class ParamComputedComponent { */ public get inputId() { let id = "calc_" + this.param.symbol; - // if inside a nested Structure, prefix with Structure position - // to disambiguate + // if inside a child Nub, prefix with child position to disambiguate const nub = this.param.paramDefinition.parentNub; - if (nub && nub instanceof Structure) { + if (nub && nub.parent && nub.parent.childrenType) { id = nub.findPositionInParent() + "_" + id; } return id; diff --git a/src/app/components/param-link/param-link.component.ts b/src/app/components/param-link/param-link.component.ts index ab7b72c470193eb6142cba906fac41e843b88170..0db7fb0376ed46f7d5573de1a52aaa2e2892eb73 100644 --- a/src/app/components/param-link/param-link.component.ts +++ b/src/app/components/param-link/param-link.component.ts @@ -1,7 +1,7 @@ import { Component, Input, Output, EventEmitter, OnChanges, OnDestroy } from "@angular/core"; import { NgParameter } from "../../formulaire/ngparam"; -import { LinkedValue, ParamValueMode, Observer, Structure, acSection, ParamDefinition } from "jalhyd"; +import { LinkedValue, ParamValueMode, Observer, Structure, acSection, ParamDefinition, ChildNub } from "jalhyd"; import { FormulaireService } from "../../services/formulaire.service"; import { I18nService } from "../../services/internationalisation.service"; import { FormulaireDefinition } from "../../formulaire/definition/form-definition"; @@ -41,10 +41,9 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy { public get selectId() { let id = "linked_" + this.param.symbol; - // if inside a nested Structure, prefix with Structure position - // to disambiguate + // if inside a child Nub, prefix with child position to disambiguate const nub = this.param.paramDefinition.parentNub; - if (nub && nub instanceof Structure) { + if (nub && nub.parent && nub.parent.childrenType) { id = nub.findPositionInParent() + "_" + id; } return id; @@ -169,23 +168,16 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy { preview = NgParameter.preview(i.element as ParamDefinition, true); } - // 1. Paramètre / résultat d'un ouvrage dans un Nub de type ParallelStructure - if (i.nub instanceof Structure) { + // 1. Paramètre / résultat d'un Nub enfant au sein d'un Nub parent + if (i.nub instanceof ChildNub) { let pos: number; pos = i.nub.findPositionInParent(); - if (i.isResult()) { - // résultat d'ouvrage - return `${preview} - ` + sprintf( - this.intlService.localizeText("INFO_LINKED_VALUE_DEVICE_RESULT"), - s, c, (pos + 1) - ); - } else { - // paramètre d'ouvrage - return `${preview} - ` + sprintf( - this.intlService.localizeText("INFO_LINKED_VALUE_DEVICE"), - s, c, (pos + 1) - ); - } + return `${preview} - ` + sprintf( + this.intlService.localizeText("INFO_LINKED_VALUE_CHILD"), + s, c, + this.intlService.childName(i.nub.parent).toLowerCase() + , (pos + 1) + ); } else // 2. Paramètre / résultat d'une section dans un Nub de type SectionNub if (i.nub instanceof acSection) { diff --git a/src/app/components/param-values/param-values.component.ts b/src/app/components/param-values/param-values.component.ts index a22cc098c9f4c24ac26af7f548a5473baf3e2c58..6246b682532bdbb0ae75c66e2926be2b2934aec3 100644 --- a/src/app/components/param-values/param-values.component.ts +++ b/src/app/components/param-values/param-values.component.ts @@ -45,10 +45,9 @@ export class ParamValuesComponent implements AfterViewInit, Observer { public get inputId() { let id = "var_" + this.param.symbol; - // if inside a nested Structure, prefix with Structure position - // to disambiguate + // if inside a child Nub, prefix with child position to disambiguate const nub = this.param.paramDefinition.parentNub; - if (nub && nub instanceof Structure) { + if (nub && nub.parent && nub.parent.childrenType) { id = nub.findPositionInParent() + "_" + id; } return id; diff --git a/src/app/config.json b/src/app/config.json index 1b2da220febf7661f5a2d1fed5cf860609dbca72..55c2352e46bbccece0549f96f672334d6f2aac03 100644 --- a/src/app/config.json +++ b/src/app/config.json @@ -56,6 +56,14 @@ }, "calculators": [ 8, 9, 10 ] }, + { + "name": "OUTILS_MATHEMATIQUES", + "image": { + "path": "maths.jpg", + "credits": "Toms Baugis, \"LineÄli\" / CC BY 2.0" + }, + "calculators": [ 22, 23, 24, 25 ] + }, { "_comment": "card for calculators not used in any theme", "image": { diff --git a/src/app/formulaire/definition/concrete/form-spp.ts b/src/app/formulaire/definition/concrete/form-spp.ts new file mode 100644 index 0000000000000000000000000000000000000000..a12a196b676fa84a28b143a0a57e209c051eb016 --- /dev/null +++ b/src/app/formulaire/definition/concrete/form-spp.ts @@ -0,0 +1,152 @@ +import { FormulaireBase } from "./form-base"; +import { FieldsetTemplate } from "../../fieldset-template"; +import { FieldSet } from "../../fieldset"; +import { FormulaireNode } from "../../formulaire-node"; +import { FieldsetContainer } from "../../fieldset-container"; + +import { SPP, Nub, Props, Session, YAXN, IObservable } from "jalhyd"; + +/** + * Formulaire pour "somme / produit de puissances" + */ +export class FormulaireSPP extends FormulaireBase { + + /** id of select configuring operation */ + private _operationSelectId: string; + + public get sppNub(): SPP { + return this.currentNub as SPP; + } + + protected parseOptions(json: {}) { + super.parseOptions(json); + this._operationSelectId = this.getOption(json, "operationSelectId"); + } + + public afterParseFieldset(fs: FieldSet) { + if (this._operationSelectId) { + const sel = fs.getFormulaireNodeById(this._operationSelectId); + if (sel) { + fs.properties.addObserver(this); + } + } + } + + private createYaxnNub(templ: FieldsetTemplate): Nub { + const params = {}; + params["calcType"] = templ.calcTypeFromConfig; + return this.createYaxn(new Props(params)); + } + + /** + * ajoute un nub YAXN + * @param mr nub à ajouter + * @param after position après laquelle insérer le nub, à la fin sinon + */ + private addYaxnNub(mr: YAXN, after?: number) { + this.sppNub.addChild(mr, after); + } + + /** + * Asks JaLHyd to create a YAXN nub as a child of the current Calculator Module + * and return it; does not store it in the Session (for YAXN, not for Calculator Modules) + * @param p properties for the new Nub + */ + protected createYaxn(p: Props): YAXN { + return Session.getInstance().createNub(p, this.sppNub) as YAXN; + } + + /** + * Replaces the given YAXN sn in the current calculator module, + * with a new one built with properties "params" + * @param mr YAXN to replace + * @param params properties to build the new Nub (calcType) + */ + protected replaceNub(mr: YAXN, params: Props): Nub { + const parent = this.sppNub; + const newStructure = this.createYaxn(params); + parent.replaceChildInplace(mr, newStructure); + return newStructure; + } + + public createFieldset(parent: FormulaireNode, json: {}, data?: {}, nub?: Nub): FieldSet { + if (json["calcType"] === "YAXN") { + // indice après lequel insérer le nouveau FieldSet + const after = data["after"]; + + const res: FieldSet = new FieldSet(parent); + let mrn: Nub; + if (nub) { // use existing Nub (build interface based on model) + mrn = nub; + } else { + mrn = this.createYaxnNub(data["template"]); + this.addYaxnNub(mrn as YAXN, after); + } + res.setNub(mrn, false); + + if (after !== undefined) { + parent.kids.splice(after + 1, 0, res); + } else { + parent.kids.push(res); + } + + this.resetResults(); + + return res; + } else { + return super.createFieldset(parent, json, data); + } + } + + public moveFieldsetUp(fs: FieldSet) { + if (fs.nub instanceof YAXN) { + // déplacement du nub + fs.nub.parent.moveChildUp(fs.nub); + // déplacement du fieldset + this.fieldsetContainer.moveFieldsetUp(fs); + + this.resetResults(); + } else { + super.moveFieldsetUp(fs); + } + } + + public moveFieldsetDown(fs: FieldSet) { + if (fs.nub instanceof YAXN) { + // déplacement du nub + fs.nub.parent.moveChildDown(fs.nub); + // déplacement du fieldset + this.fieldsetContainer.moveFieldsetDown(fs); + + this.resetResults(); + } else { super.moveFieldsetDown(fs); } + } + + public removeFieldset(fs: FieldSet) { + if (fs.nub instanceof YAXN) { + // suppression du sous-nub dans le Nub parent + this.sppNub.deleteChild(fs.nub.findPositionInParent()); + // suppression du fieldset + this.fieldsetContainer.removeFieldset(fs); + + this.resetResults(); + } else { super.removeFieldset(fs); } + } + + // interface Observer + + public update(sender: IObservable, data: any) { + super.update(sender, data); + if (data.action === "propertyChange") { + this.reset(); + } + } + + private get fieldsetContainer(): FieldsetContainer { + const n = this.getFormulaireNodeById("yaxn_container"); + if (n === undefined || !(n instanceof FieldsetContainer)) { + throw new Error("l'élément 'yaxn_container' n'est pas du type FieldsetContainer"); + } + return n as FieldsetContainer; + } +} diff --git a/src/app/formulaire/definition/concrete/form-trigo.ts b/src/app/formulaire/definition/concrete/form-trigo.ts new file mode 100644 index 0000000000000000000000000000000000000000..499d6e03a4365f25b74545581edd6c882f84a97f --- /dev/null +++ b/src/app/formulaire/definition/concrete/form-trigo.ts @@ -0,0 +1,46 @@ +import { IObservable } from "jalhyd"; + +import { FormulaireBase } from "./form-base"; +import { FieldSet } from "../../fieldset"; + +/** + * Formulaire pour les fonctions trigonométriques + */ +export class FormulaireTrigo extends FormulaireBase { + + /** id of select configuring operation */ + private _operationSelectId: string; + + /** id of select configuring unit */ + private _unitSelectId: string; + + protected parseOptions(json: {}) { + super.parseOptions(json); + this._operationSelectId = this.getOption(json, "operationSelectId"); + this._unitSelectId = this.getOption(json, "unitSelectId"); + } + + public afterParseFieldset(fs: FieldSet) { + if (this._operationSelectId) { + const sel = fs.getFormulaireNodeById(this._operationSelectId); + if (sel) { + fs.properties.addObserver(this); + } + } + if (this._unitSelectId) { + const sel = fs.getFormulaireNodeById(this._unitSelectId); + if (sel) { + fs.properties.addObserver(this); + } + } + } + + // interface Observer + + public update(sender: IObservable, data: any) { + super.update(sender, data); + if (data.action === "propertyChange") { + this.reset(); + } + } +} diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts index 0681164586f2f3c9ac4b8e798ea6dd2963ee1772..03c9fb022532530ec2e75160563e2bab7cd98712 100644 --- a/src/app/formulaire/fieldset.ts +++ b/src/app/formulaire/fieldset.ts @@ -11,6 +11,9 @@ import { GrilleProfile, BiefRegime, Solveur, + TrigoOperation, + TrigoUnit, + SPPOperation, } from "jalhyd"; import { FormulaireElement } from "./formulaire-element"; @@ -288,6 +291,15 @@ export class FieldSet extends FormulaireElement implements Observer { case "fs_water_line": // Bief this.setSelectValueFromProperty("select_regime", "regime"); break; + + case "fs_trigo": // Trigo + this.setSelectValueFromProperty("select_operation", "trigoOperation"); + this.setSelectValueFromProperty("select_unit", "trigoUnit"); + break; + + case "fs_spp": // SPP + this.setSelectValueFromProperty("select_spp_operation", "sppOperation"); + break; } } @@ -351,6 +363,9 @@ export class FieldSet extends FormulaireElement implements Observer { this.setPropertyValueFromConfig(json, "defaultGridType", "gridType", GrilleType); this.setPropertyValueFromConfig(json, "defaultRegime", "regime", BiefRegime); this.setPropertyValueFromConfig(json, "varCalc", "varCalc"); + this.setPropertyValueFromConfig(json, "defaultOperation", "trigoOperation", TrigoOperation); + this.setPropertyValueFromConfig(json, "defaultUnit", "trigoUnit", TrigoUnit); + this.setPropertyValueFromConfig(json, "defaultOperation", "sppOperation", SPPOperation); this.updateFields(); } @@ -442,6 +457,15 @@ export class FieldSet extends FormulaireElement implements Observer { case "select_regime": // Bief this.setPropValue("regime", data.value.value); break; + case "select_operation": // Trigo + this.setPropValue("trigoOperation", data.value.value); + break; + case "select_unit": // Trigo + this.setPropValue("trigoUnit", data.value.value); + break; + case "select_spp_operation": // SPP + this.setPropValue("sppOperation", data.value.value); + break; } break; } diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts index b2ea54a8c44b80617e149fd9e6f05dc907a57239..eeed82a32dfcc790056c811a20d0f53398c264e5 100644 --- a/src/app/formulaire/select-field.ts +++ b/src/app/formulaire/select-field.ts @@ -9,9 +9,9 @@ import { LoiDebit, GrilleType, GrilleProfile, - Solveur, - ParamValueMode, - Session + TrigoUnit, + TrigoOperation, + SPPOperation } from "jalhyd"; import { Field } from "./field"; @@ -198,6 +198,22 @@ export class SelectField extends Field { this.addEntry(new SelectEntry(this._entriesBaseId + BiefRegime.Fluvial, BiefRegime.Fluvial)); this.addEntry(new SelectEntry(this._entriesBaseId + BiefRegime.Torrentiel, BiefRegime.Torrentiel)); break; + + case "trigo_operation": // Trigo: opération (cos, sin…) + for (let j = 0; j < Object.keys(TrigoOperation).length / 2; j++) { + this.addEntry(new SelectEntry(this._entriesBaseId + j, j)); + } + break; + + case "trigo_unit": // Trigo: unité (degrés, radians) + this.addEntry(new SelectEntry(this._entriesBaseId + TrigoUnit.DEG, TrigoUnit.DEG)); + this.addEntry(new SelectEntry(this._entriesBaseId + TrigoUnit.RAD, TrigoUnit.RAD)); + break; + + case "spp_operation": // SPP: opération (somme, produit) + this.addEntry(new SelectEntry(this._entriesBaseId + SPPOperation.SUM, SPPOperation.SUM)); + this.addEntry(new SelectEntry(this._entriesBaseId + SPPOperation.PRODUCT, SPPOperation.PRODUCT)); + break; } this.afterParseConfig(); diff --git a/src/app/results/calculator-results.ts b/src/app/results/calculator-results.ts index e0bb77520499adbce851ad772bfccc2e5c37fe49..27c0b89b34d23d1e3ec05549ff1fbe174db7e2bb 100644 --- a/src/app/results/calculator-results.ts +++ b/src/app/results/calculator-results.ts @@ -23,11 +23,11 @@ export abstract class CalculatorResults { if (referenceNub) { const children = referenceNub.getChildren(); const parameterNub = p.paramDefinition.parentNub; - const cn = capitalize(ServiceFactory.instance.i18nService.childName(parameterNub)); if (children.includes(parameterNub)) { + const cn = capitalize(ServiceFactory.instance.i18nService.childName(parameterNub.parent)); isChildParam = true; const pos = parameterNub.findPositionInParent() + 1; - res = sprintf(ServiceFactory.instance.i18nService.localizeText("INFO_OUVRAGE_N"), cn) + pos + " : "; + res = sprintf(ServiceFactory.instance.i18nService.localizeText("INFO_STUFF_N"), cn) + pos + " : "; } } if (displaySymbol && ! isChildParam) { diff --git a/src/app/results/param-calc-results.ts b/src/app/results/param-calc-results.ts index 60c0e257d0b40dd636f2d1ab62cb6e9964382674..3f5c8c4b0e8364c7e2486e6300f8103a4304dff4 100644 --- a/src/app/results/param-calc-results.ts +++ b/src/app/results/param-calc-results.ts @@ -36,6 +36,15 @@ export abstract class CalculatedParamResults extends CalculatorResults { } public get hasResults(): boolean { + if (this.result === undefined) { + return false; + } + return true; + // return ! this.result.hasOnlyErrors; + } + + /** return true if there is something to display on the variable results chart */ + public get hasPlottableResults(): boolean { if (this.result === undefined) { return false; } diff --git a/src/app/results/var-results.ts b/src/app/results/var-results.ts index 3594635b688b37996e7779b5684bc136d97a847c..48038a9c60c9610dc522f095f600d22990449666 100644 --- a/src/app/results/var-results.ts +++ b/src/app/results/var-results.ts @@ -1,7 +1,7 @@ import { CalculatorResults } from "./calculator-results"; import { CalculatedParamResults } from "./param-calc-results"; import { NgParameter } from "../formulaire/ngparam"; -import { ResultElement, ParamFamily, capitalize } from "jalhyd"; +import { ResultElement, ParamFamily, capitalize, Nub } from "jalhyd"; import { ServiceFactory } from "../services/service-factory"; import { PlottableData } from "./plottable-data"; import { ChartType } from "./chart-type"; @@ -132,7 +132,7 @@ export class VarResults extends CalculatedParamResults implements PlottableData const match = /^([0-9]+)_(.+)$/.exec(symbol); if (match !== null) { const pos = +match[1]; - ct = sn.getChildren()[pos].calcType; + // only parent translation file is loaded; look for children translations in it // ct = sn.getChildren()[pos].calcType; symbol = match[2]; const cn = capitalize(ServiceFactory.instance.i18nService.childName(sn)); ret += sprintf(ServiceFactory.instance.i18nService.localizeText("INFO_STUFF_N"), cn) + (pos + 1) + " : "; @@ -214,13 +214,15 @@ export class VarResults extends CalculatedParamResults implements PlottableData } } // children results - const sn = this.result.sourceNub; - for (const c of sn.getChildren()) { - if (c.result) { - // using latest ResultElement; results count / types are supposed to be the same on every iteration - for (const k of c.result.resultElement.keys) { - if (k.indexOf("ENUM_") === -1) { // ENUM variables are not plottable - res.push(c.findPositionInParent() + "_" + k); + if (this.result) { + const sn = this.result.sourceNub; + for (const c of sn.getChildren()) { + if (c.result) { + // using latest ResultElement; results count / types are supposed to be the same on every iteration + for (const k of c.result.resultElement.keys) { + if (k.indexOf("ENUM_") === -1) { // ENUM variables are not plottable + res.push(c.findPositionInParent() + "_" + k); + } } } } @@ -254,8 +256,10 @@ export class VarResults extends CalculatedParamResults implements PlottableData const families: { [key: string]: string[] } = {}; // variating parameters for (const v of this._variatedParams) { - const f = ParamFamily[v.paramDefinition.family]; - if (f !== undefined) { + // exclude pseudo-family "ANY" + const fam = v.paramDefinition.family; + if (fam !== undefined && fam !== ParamFamily.ANY) { + const f = ParamFamily[fam]; if (! (f in families)) { families[f] = []; } @@ -264,8 +268,10 @@ export class VarResults extends CalculatedParamResults implements PlottableData } // results for (const erk of this.resultKeys) { - const f = ParamFamily[this.result.sourceNub.getFamily(erk)]; - if (f !== undefined) { + const fam = this.result.sourceNub.getFamily(erk); + // exclude pseudo-family "ANY" + if (fam !== undefined && fam !== ParamFamily.ANY) { + const f = ParamFamily[fam]; if (! (f in families)) { families[f] = []; } @@ -273,17 +279,21 @@ export class VarResults extends CalculatedParamResults implements PlottableData } } // children results - const sn = this.result.sourceNub; - for (const c of sn.getChildren()) { - if (c.result) { - for (const k of c.result.resultElement.keys) { - const f = ParamFamily[this.result.sourceNub.getFamily(k)]; - if (f !== undefined) { - if (! (f in families)) { - families[f] = []; + if (this.result) { + const sn = this.result.sourceNub; + for (const c of sn.getChildren()) { + if (c.result) { + for (const k of c.result.resultElement.keys) { + const fam = this.result.sourceNub.getFamily(k); + // exclude pseudo-family "ANY" + if (fam !== undefined && fam !== ParamFamily.ANY) { + const f = ParamFamily[fam]; + if (! (f in families)) { + families[f] = []; + } + const pos = c.findPositionInParent(); + families[f].push(pos + "_" + k); } - const pos = c.findPositionInParent(); - families[f].push(pos + "_" + k); } } } @@ -296,17 +306,22 @@ export class VarResults extends CalculatedParamResults implements PlottableData * (used by tooltip functions) */ public getVariatingParametersSymbols(): string[] { - const sn = this.result.sourceNub; - return this._variatedParams.map((vp) => { - // detect if variated param is a children param - const parameterNub = vp.paramDefinition.parentNub; - const children = sn.getChildren(); - let symb = vp.symbol; - if (children.includes(parameterNub)) { - symb = parameterNub.findPositionInParent() + "_" + symb; - } - return symb; - }); + if (this.result && this.result.sourceNub) { + return this._variatedParams.map(vp => this.getVariatingParameterSymbol(vp, this.result.sourceNub)); + } else { + return []; + } + } + + public getVariatingParameterSymbol(vp: NgParameter, sourceNub: Nub): string { + // detect if variated param is a children param + const parameterNub = vp.paramDefinition.parentNub; + const children = sourceNub.getChildren(); + let symb = vp.symbol; + if (children.includes(parameterNub)) { + symb = parameterNub.findPositionInParent() + "_" + symb; + } + return symb; } public update() { @@ -346,8 +361,10 @@ export class VarResults extends CalculatedParamResults implements PlottableData if (this.resultKeys.length > 0) { defaultY = this.resultKeys[0]; } - this.chartX = this.chartX || this.variatedParameters[this.longest].symbol; this.chartY = defaultY; + if (this.chartX === undefined || ! this.getAvailableXAxis().includes(this.chartX)) { + this.chartX = this.getVariatingParameterSymbol(this.variatedParameters[this.longest], this.result.sourceNub); + } // calculator type for translation const sn = this.result.sourceNub; diff --git a/src/app/services/formulaire.service.ts b/src/app/services/formulaire.service.ts index 536af784a86eea59425290587c39de106a2af409..e0224f8d6a24e30dbfa8b3293c5e990acfccaef4 100644 --- a/src/app/services/formulaire.service.ts +++ b/src/app/services/formulaire.service.ts @@ -13,7 +13,8 @@ import { Pab, Props, Cloisons, - CloisonAval + CloisonAval, + SPP } from "jalhyd"; import { ApplicationSetupService } from "./app-setup.service"; @@ -40,6 +41,8 @@ import { FormulaireGrille } from "../formulaire/definition/concrete/form-grille" import { FormulaireBief } from "../formulaire/definition/concrete/form-bief"; import { FormulaireSolveur } from "../formulaire/definition/concrete/form-solveur"; import { AppComponent } from "../app.component"; +import { FormulaireSPP } from "../formulaire/definition/concrete/form-spp"; +import { FormulaireTrigo } from "../formulaire/definition/concrete/form-trigo"; @Injectable() export class FormulaireService extends Observable { @@ -86,6 +89,9 @@ export class FormulaireService extends Observable { this.calculatorPaths[CalculatorType.Pente] = "pente"; this.calculatorPaths[CalculatorType.Bief] = "bief"; this.calculatorPaths[CalculatorType.Solveur] = "solveur"; + this.calculatorPaths[CalculatorType.YAXB] = "yaxb"; + this.calculatorPaths[CalculatorType.Trigo] = "trigo"; + this.calculatorPaths[CalculatorType.SPP] = "spp"; } private get _intlService(): I18nService { @@ -335,6 +341,14 @@ export class FormulaireService extends Observable { f = new FormulaireSolveur(); break; + case CalculatorType.SPP: + f = new FormulaireSPP(); + break; + + case CalculatorType.Trigo: + f = new FormulaireTrigo(); + break; + default: f = new FormulaireBase(); } @@ -390,6 +404,18 @@ export class FormulaireService extends Observable { } } + // add fieldsets for existing YAXN if needed + // (when loading session only) + if (f.currentNub instanceof SPP) { + for (const c of f.currentNub.getChildren()) { + for (const e of f.allFormElements) { + if (e instanceof FieldsetContainer) { // @TODO manage many containers one day ? + e.addFromTemplate(0, undefined, c); + } + } + } + } + // when creating a new Pab, add one wall with one device, plus the downwall // (when loading session, those items are already present) if ( diff --git a/src/assets/images/themes/maths.jpg b/src/assets/images/themes/maths.jpg new file mode 100644 index 0000000000000000000000000000000000000000..10f0b30eaf229a4a57e704b3ce5a797b27075d5b Binary files /dev/null and b/src/assets/images/themes/maths.jpg differ diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json index b12fe6900f404f69dad1c63a622f23a2756d659d..cff254e1e0e15cad3b7d547bb8deeeaa27798fd9 100644 --- a/src/locale/messages.en.json +++ b/src/locale/messages.en.json @@ -16,6 +16,7 @@ "ERROR_DICHO_NULL_STEP": "Dichotomy (initial interval search): invalid null step", "ERROR_DICHO_TARGET_TOO_HIGH": "Dichotomy: the solution %targetSymbol%=%targetValue% is greater than the maximum computable value %targetSymbol%(%variableSymbol%=%variableExtremeValue%)=%extremeTarget%)", "ERROR_DICHO_TARGET_TOO_LOW": "Dichotomy: the solution %targetSymbol%=%targetValue% is lower than the minimum computable value %targetSymbol%(%variableSymbol%=%variableExtremeValue%)=%extremeTarget%)", + "ERROR_DIVISION_BY_ZERO": "Division by zero", "ERROR_ELEVATION_ZI_LOWER_THAN_Z2": "Upstream elevation is lower than downstream elevation", "ERROR_IN_CALC_CHAIN": "An error occurred in calculation chain", "WARNING_ERROR_IN_CALC_CHAIN_STEPS": "Errors occurred during chain calculation", @@ -27,6 +28,7 @@ "ERROR_MINMAXSTEP_MIN": "Value is not in [%s,%s[", "ERROR_MINMAXSTEP_STEP": "Value is not in %s", "ERROR_NEWTON_DERIVEE_NULLE": "Null function derivative in Newton computation", + "ERROR_NON_INTEGER_POWER_ON_NEGATIVE_NUMBER": "Exponent of a negative number must be an integer value", "ERROR_PAB_CALC_Z1_CLOISON": "Error in calculating the upstream water elevation of a wall", "ERROR_PAB_Z1_LOWER_THAN_Z2": "Upstream water elevation should be higher than downstream water elevation", "ERROR_PAB_Z1_LOWER_THAN_UPSTREAM_WALL": "Upstream water elevation is too low for water to flow through the first wall", @@ -56,8 +58,9 @@ "ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCOR": "Non convergence of the calculation of the corresponding elevation (Newton's method)", "ERROR_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE": "Non convergence of the calculation of the normal depth (Newton's method)", "ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF": "The slope is negative or zero, the normal depth is infinite", + "ERROR_SECTION_SURFACE_NULLE": "Section: calculation is impossible when surface is null", + "ERROR_SOMETHING_FAILED_IN_CHILD": "Calculation of child module #%number% failed", "ERROR_STRUCTURE_Q_TROP_ELEVE": "The flow passing through the other devices is too high: the requested parameter is not calculable.", - "ERROR_SECTION_SURFACE_NULLE": "Section : calcul impossible à cause d'une surface nulle", "INFO_CALCULATOR_CALC_NAME": "Calculator name", "INFO_CALCULATOR_CALCULER": "Compute", "INFO_CALCULATOR_CLONE": "Duplicate", @@ -152,10 +155,12 @@ "INFO_STUFF_MOVED": "%s #%s moved", "INFO_STUFF_REMOVED": "%s #%s removed", "INFO_STUFF_N": "%s #", - "INFO_CHILD_TYPE_STRUCTURE": "device", - "INFO_CHILD_TYPE_STRUCTURE_PLUR": "devices", + "INFO_CHILD_TYPE_OUVRAGE": "device", + "INFO_CHILD_TYPE_OUVRAGE_PLUR": "devices", "INFO_CHILD_TYPE_MACRORUGO": "apron", "INFO_CHILD_TYPE_MACRORUGO_PLUR": "aprons", + "INFO_CHILD_TYPE_PUISSANCE": "power", + "INFO_CHILD_TYPE_PUISSANCE_PLUR": "powers", "INFO_FIELDSET_ADD": "Add", "INFO_FIELDSET_COPY": "Copy", "INFO_FIELDSET_REMOVE": "Remove", @@ -282,8 +287,7 @@ "INFO_LIB_ZRAM": "Upstream apron elevation", "INFO_LIB_ZRMB": "Downstream basin bottom elevation", "INFO_LIB_ZT": "Triangle top elevation", - "INFO_LINKED_VALUE_DEVICE_RESULT": "%s (%s, device %s)", - "INFO_LINKED_VALUE_DEVICE": "%s (%s, device %s)", + "INFO_LINKED_VALUE_CHILD": "%s (%s, %s %s)", "INFO_LINKED_VALUE_EXTRA_RESULT_OF": "%s (%s)", "INFO_LINKED_VALUE_EXTRA_RESULT": "%s (%s)", "INFO_LINKED_VALUE_RESULT": "%s (%s)", @@ -443,6 +447,8 @@ "INFO_SNACKBAR_SETTINGS_SAVED": "Settings saved on this device", "INFO_SOLVEUR_TITRE": "Multimodule solver", "INFO_SOLVEUR_TITRE_COURT": "Solver", + "INFO_SPP_TITRE": "Sum and product of powers", + "INFO_SPP_TITRE_COURT": "SPP", "INFO_THEME_CREDITS": "Credit", "INFO_THEME_DEVALAISON_TITRE": "Downstream migration", "INFO_THEME_DEVALAISON_DESCRIPTION": "Tools for dimensioning the structures present on the water intakes of hydroelectric power plants known as \"ichthyocompatible\" and consisting of fine grid planes associated with one or more outlets.", @@ -454,6 +460,8 @@ "INFO_THEME_LOIS_D_OUVRAGES_TITRE": "Hydraulic structures", "INFO_THEME_MODULES_INUTILISES_DESCRIPTION": "Various calculation modules", "INFO_THEME_MODULES_INUTILISES_TITRE": "Other calculation modules", + "INFO_THEME_OUTILS_MATHEMATIQUES_TITRE": "Mathematical tools", + "INFO_THEME_OUTILS_MATHEMATIQUES_DESCRIPTION": "Miscellaneous generic mathematical tools", "INFO_THEME_PASSE_A_BASSIN_DESCRIPTION": "Tools for sizing a fish pass made with pools also called fish steps", "INFO_THEME_PASSE_A_BASSIN_TITRE": "Fish ladder", "INFO_THEME_PASSE_NATURELLE_DESCRIPTION": "Tools for sizing a natural fish pass also called macroroughness pass or rock-ramp fish pass", @@ -466,6 +474,10 @@ "INFO_EXAMPLE_LABEL_PAB_COMPLETE": "Standard fish ladder", "INFO_EXAMPLES_TITLE": "Examples", "INFO_EXAMPLES_SUBTITLE": "Load standard examples", + "INFO_YAXB_TITRE": "Linear function", + "INFO_YAXB_TITRE_COURT": "Linear f.", + "INFO_TRIGO_TITRE": "Trigonometric function", + "INFO_TRIGO_TITRE_COURT": "Trigo. f.", "WARNING_WARNINGS_ABSTRACT": "%nb% warnings occurred during calculation", "WARNING_REMOUS_ARRET_CRITIQUE": "Calculation stopped: critical elevation reached at abscissa %x%", "WARNING_STRUCTUREKIVI_HP_TROP_ELEVE": "h/p must not be greater than 2.5. h/p is forced to 2.5", diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json index adf9a72ce481cee7026e216e955fbc6563446343..808e3ae547a622ddd956b324cf43eac9092a9cbb 100644 --- a/src/locale/messages.fr.json +++ b/src/locale/messages.fr.json @@ -16,6 +16,7 @@ "ERROR_DICHO_NULL_STEP": "Dichotomie : le pas pour la recherche de l'intervalle de départ ne devrait pas être nul", "ERROR_DICHO_TARGET_TOO_HIGH": "Dichotomie : la solution %targetSymbol%=%targetValue% est supérieure à la valeur maximale calculable %targetSymbol%(%variableSymbol%=%variableExtremeValue%)=%extremeTarget%)", "ERROR_DICHO_TARGET_TOO_LOW": "Dichotomie : la solution %targetSymbol%=%targetValue% est inférieure à la valeur minimale calculable %targetSymbol%(%variableSymbol%=%variableExtremeValue%)=%extremeTarget%)", + "ERROR_DIVISION_BY_ZERO": "Division par zéro", "ERROR_ELEVATION_ZI_LOWER_THAN_Z2": "La cote amont est plus basse que la cote aval", "ERROR_IN_CALC_CHAIN": "Une erreur est survenue dans la chaîne de calcul", "WARNING_ERROR_IN_CALC_CHAIN_STEPS": "Des erreurs sont survenues durant le calcul en chaîne", @@ -27,6 +28,7 @@ "ERROR_MINMAXSTEP_MIN": "La valeur n'est pas dans [%s,%s[", "ERROR_MINMAXSTEP_STEP": "La valeur n'est pas dans %s", "ERROR_NEWTON_DERIVEE_NULLE": "Dérivée nulle dans un calcul par la méthode de Newton", + "ERROR_NON_INTEGER_POWER_ON_NEGATIVE_NUMBER": "L'exposant d'un nombre négatif doit être une valeur entière", "ERROR_PAB_CALC_Z1_CLOISON": "Erreur de calcul de la cote de l'eau amont d'une cloison", "ERROR_PAB_Z1_LOWER_THAN_Z2": "La cote de l'eau amont doit être supérieure à la cote de l'eau aval", "ERROR_PAB_Z1_LOWER_THAN_UPSTREAM_WALL": "La cote de l'eau amont est trop basse pour que l'eau s'écoule à travers la première cloison", @@ -56,7 +58,8 @@ "ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCOR": "Non convergence du calcul de la hauteur correspondante (Méthode de Newton)", "ERROR_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE": "Non convergence du calcul de la hauteur normale (Méthode de Newton)", "ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF": "La pente est négative ou nulle, la hauteur normale est infinie", - "ERROR_SECTION_SURFACE_NULLE": "Section: calculation is impossible when surface is null", + "ERROR_SECTION_SURFACE_NULLE": "Section : calcul impossible à cause d'une surface nulle", + "ERROR_SOMETHING_FAILED_IN_CHILD": "Le calcul du module enfant n°%number% a échoué", "ERROR_STRUCTURE_Q_TROP_ELEVE": "Le débit passant par les autres ouvrages est trop élevé: le paramètre demandé n'est pas calculable.", "INFO_CALCULATOR_CALC_NAME": "Nom du module de calcul", "INFO_CALCULATOR_CALCULER": "Calculer", @@ -152,10 +155,12 @@ "INFO_STUFF_MOVED": "%s n°%s déplacé(e)", "INFO_STUFF_REMOVED": "%s n°%s supprimé(e)", "INFO_STUFF_N": "%s n°", - "INFO_CHILD_TYPE_STRUCTURE": "ouvrage", - "INFO_CHILD_TYPE_STRUCTURE_PLUR": "ouvrages", + "INFO_CHILD_TYPE_OUVRAGE": "ouvrage", + "INFO_CHILD_TYPE_OUVRAGE_PLUR": "ouvrages", "INFO_CHILD_TYPE_MACRORUGO": "radier", "INFO_CHILD_TYPE_MACRORUGO_PLUR": "radiers", + "INFO_CHILD_TYPE_PUISSANCE": "puissance", + "INFO_CHILD_TYPE_PUISSANCE_PLUR": "puissances", "INFO_FIELDSET_ADD": "Ajouter", "INFO_FIELDSET_COPY": "Copier", "INFO_FIELDSET_REMOVE": "Supprimer", @@ -281,8 +286,7 @@ "INFO_LIB_ZRAM": "Cote du radier amont", "INFO_LIB_ZRMB": "Cote de radier mi-bassin", "INFO_LIB_ZT": "Cote haute du triangle", - "INFO_LINKED_VALUE_DEVICE_RESULT": "%s (%s, ouvrage %s)", - "INFO_LINKED_VALUE_DEVICE": "%s (%s, ouvrage %s)", + "INFO_LINKED_VALUE_CHILD": "%s (%s, %s %s)", "INFO_LINKED_VALUE_EXTRA_RESULT_OF": "%s (%s)", "INFO_LINKED_VALUE_EXTRA_RESULT": "%s (%s)", "INFO_LINKED_VALUE_RESULT": "%s (%s)", @@ -442,6 +446,8 @@ "INFO_SNACKBAR_SETTINGS_SAVED": "Paramètres enregistrés sur cet appareil", "INFO_SOLVEUR_TITRE": "Solveur multimodule", "INFO_SOLVEUR_TITRE_COURT": "Solveur", + "INFO_SPP_TITRE": "Somme et produit de puissances", + "INFO_SPP_TITRE_COURT": "SPP", "INFO_THEME_CREDITS": "Crédit", "INFO_THEME_DEVALAISON_TITRE": "Dévalaison", "INFO_THEME_DEVALAISON_DESCRIPTION": "Outils de dimensionnements des ouvrages présents sur les prises d'eau des centrales hydroélectriques dites \"ichtyocompatibles\" et constituées de plans de grilles fines associés à un ou plusieurs exutoires.", @@ -453,6 +459,8 @@ "INFO_THEME_LOIS_D_OUVRAGES_TITRE": "Lois d'ouvrages", "INFO_THEME_MODULES_INUTILISES_DESCRIPTION": "Modules de calculs divers", "INFO_THEME_MODULES_INUTILISES_TITRE": "Autres modules de calcul", + "INFO_THEME_OUTILS_MATHEMATIQUES_TITRE": "Outils mathématiques", + "INFO_THEME_OUTILS_MATHEMATIQUES_DESCRIPTION": "Divers outils mathématiques génériques", "INFO_THEME_PASSE_A_BASSIN_DESCRIPTION": "Outils de dimensionnement d'une passe à poissons de type passe à bassins ou encore appelée échelle à poisson", "INFO_THEME_PASSE_A_BASSIN_TITRE": "Passe à bassins", "INFO_THEME_PASSE_NATURELLE_DESCRIPTION": "Outils de dimensionnement d'une passe à poissons de type passe naturelle ou encore appelée passe à macro-rugosités", @@ -465,6 +473,10 @@ "INFO_EXAMPLE_LABEL_PAB_COMPLETE": "Passe à bassins type", "INFO_EXAMPLES_TITLE": "Exemples", "INFO_EXAMPLES_SUBTITLE": "Charger des exemples types", + "INFO_YAXB_TITRE": "Fonction affine", + "INFO_YAXB_TITRE_COURT": "F. affine", + "INFO_TRIGO_TITRE": "Fonction trigonométrique", + "INFO_TRIGO_TITRE_COURT": "F. trigo.", "WARNING_WARNINGS_ABSTRACT": "%nb% avertissements rencontrés lors du calcul", "WARNING_REMOUS_ARRET_CRITIQUE": "Arrêt du calcul : hauteur critique atteinte à l'abscisse %x%", "WARNING_STRUCTUREKIVI_HP_TROP_ELEVE": "h/p ne doit pas être supérieur à 2,5. h/p est forcé à 2,5",